mirror of
https://github.com/OpenDriver2/REDRIVER2.git
synced 2024-11-24 03:12:35 +01:00
e6ef32f08c
- little crash fixes
1618 lines
35 KiB
C
1618 lines
35 KiB
C
#include "THISDUST.H"
|
|
#include "BCOLLIDE.H"
|
|
#include "COSMETIC.H"
|
|
#include "PAD.H"
|
|
#include "DEBRIS.H"
|
|
#include "EVENT.H"
|
|
#include "OBJCOLL.H"
|
|
#include "MODELS.H"
|
|
#include "SOUND.H"
|
|
#include "GAMESND.H"
|
|
#include "GLAUNCH.H"
|
|
#include "MAIN.H"
|
|
#include "MISSION.H"
|
|
#include "FELONY.H"
|
|
#include "WHEELFORCES.H"
|
|
#include "HANDLING.H"
|
|
#include "CAMERA.H"
|
|
#include "OBJANIM.H"
|
|
|
|
#include "STRINGS.H"
|
|
#include "GTEREG.H"
|
|
#include "INLINE_C.H"
|
|
#include <stdlib.h>
|
|
|
|
#define COLLISION_DEBUG
|
|
|
|
// decompiled code
|
|
// original method signature:
|
|
// int /*$ra*/ bcollided2d(struct CDATA2D *body /*$t4*/, int needOverlap /*$fp*/)
|
|
// line 120, offset 0x0001c51c
|
|
/* begin block 1 */
|
|
// Start line: 121
|
|
// Start offset: 0x0001C51C
|
|
// Variables:
|
|
// struct VECTOR delta; // stack offset -56
|
|
// int dtheta; // $v1
|
|
// int ac; // $s6
|
|
// int as; // $s5
|
|
// int i; // $t7
|
|
// int j; // $a2
|
|
// int k; // $t5
|
|
|
|
/* begin block 1.1 */
|
|
// Start line: 160
|
|
// Start offset: 0x0001C738
|
|
// Variables:
|
|
// int xover; // $t0
|
|
// int zover; // $a0
|
|
// int tmp2; // $a2
|
|
// int FE; // $a3
|
|
/* end block 1.1 */
|
|
// End offset: 0x0001C890
|
|
// End Line: 183
|
|
/* end block 1 */
|
|
// End offset: 0x0001C8C0
|
|
// End Line: 185
|
|
|
|
/* begin block 2 */
|
|
// Start line: 240
|
|
/* end block 2 */
|
|
// End Line: 241
|
|
|
|
int boxOverlap = 0;
|
|
|
|
// Checks of two bodies collides (basic check)
|
|
// also initializes axes
|
|
// [D] [A]
|
|
int bcollided2d(CDATA2D *body, int needOverlap)
|
|
{
|
|
short ac;
|
|
short as;
|
|
short sVar3;
|
|
short sVar4;
|
|
int dtheta;
|
|
int iVar6;
|
|
int iVar7;
|
|
int iVar8;
|
|
int iVar9;
|
|
int *piVar10;
|
|
CDATA2D *pCVar11;
|
|
VECTOR *pVVar12;
|
|
int *piVar13;
|
|
int *piVar14;
|
|
int *piVar15;
|
|
int *piVar16;
|
|
int *piVar17;
|
|
int iVar18;
|
|
int iVar19;
|
|
int uVar20;
|
|
VECTOR *pVVar21;
|
|
int *plVar22;
|
|
int *piVar23;
|
|
int iVar24;
|
|
int *piVar25;
|
|
VECTOR delta;
|
|
|
|
iVar19 = 1;
|
|
pCVar11 = body + 1;
|
|
dtheta = body[1].theta - body[0].theta;
|
|
|
|
ac = rcossin_tbl[(dtheta + 0x400 & 0x7ff) * 2];
|
|
as = rcossin_tbl[(dtheta & 0x7ff) * 2];
|
|
|
|
// calc axes of each box
|
|
do {
|
|
dtheta = body[iVar19].theta & 0xfff;
|
|
sVar3 = rcossin_tbl[dtheta * 2];
|
|
sVar4 = rcossin_tbl[dtheta * 2 + 1];
|
|
|
|
body[iVar19].axis[0].vx = sVar3;
|
|
body[iVar19].axis[0].vz = sVar4;
|
|
|
|
body[iVar19].axis[1].vz = -sVar3;
|
|
body[iVar19].axis[1].vx = sVar4;
|
|
|
|
iVar19--;
|
|
} while (iVar19 != -1);
|
|
|
|
dtheta = 0;
|
|
uVar20 = 1;
|
|
|
|
piVar23 = body[1].limit;
|
|
piVar25 = body[1].dist;
|
|
|
|
iVar24 = 100;
|
|
|
|
delta.vx = body[0].x.vx - body[1].x.vx;
|
|
delta.vz = body[0].x.vz - body[1].x.vz;
|
|
|
|
do {
|
|
|
|
piVar15 = piVar23 + 1;
|
|
piVar10 = piVar25 + 1;
|
|
|
|
piVar17 = body[uVar20].length + 1;
|
|
piVar16 = body[dtheta].length + 1;
|
|
piVar14 = body[dtheta].length;
|
|
|
|
pVVar12 = body[uVar20].axis + 1;
|
|
|
|
|
|
iVar18 = 1;
|
|
do {
|
|
*piVar10 = (pVVar12->vx * delta.vx + pVVar12->vz * delta.vz) / 4096;
|
|
iVar7 = *piVar17 + (*piVar16 * ac + *piVar14 * as) / 4096;
|
|
*piVar15 = iVar7;
|
|
|
|
if (iVar7 < *piVar10)
|
|
return 0;
|
|
|
|
if (*piVar10 < -iVar7)
|
|
return 0;
|
|
|
|
piVar15--;
|
|
piVar10--;
|
|
|
|
piVar17--;
|
|
piVar16--;
|
|
|
|
|
|
|
|
pVVar12--;
|
|
iVar18--;
|
|
|
|
piVar14++;
|
|
} while (iVar18 != -1);
|
|
|
|
dtheta = uVar20 & 1;
|
|
|
|
piVar23 -= 25;
|
|
piVar25 = piVar25 - 25;
|
|
iVar24 -= 100;
|
|
|
|
uVar20--;
|
|
|
|
if (uVar20 == -1)
|
|
{
|
|
if (needOverlap != 0)
|
|
{
|
|
iVar19 = body[1].dist[0];
|
|
iVar6 = body[1].limit[0];
|
|
|
|
if (iVar19 < 0)
|
|
iVar19 = -iVar19;
|
|
|
|
if (iVar6 < 0)
|
|
iVar6 = -iVar6;
|
|
|
|
iVar8 = iVar19 - iVar6;
|
|
if (iVar8 < 0)
|
|
iVar8 = iVar6 - iVar19;
|
|
|
|
iVar9 = body[0].axis[0].vx;
|
|
iVar6 = body[0].axis[0].vz;
|
|
|
|
iVar19 = (iVar9 * body[1].axis[0].vx + iVar6 * body[1].axis[0].vz) / 4096;
|
|
|
|
if (iVar19 < 0)
|
|
iVar19 = -iVar19;
|
|
|
|
if (iVar19 < 11)
|
|
iVar8 = -1;
|
|
else
|
|
iVar8 = (iVar8 * 4096) / iVar19;
|
|
|
|
|
|
iVar19 = body[1].dist[1];
|
|
iVar24 = body[1].limit[1];
|
|
|
|
if (iVar19 < 0)
|
|
iVar19 = -iVar19;
|
|
|
|
if (iVar24 < 0)
|
|
iVar24 = -iVar24;
|
|
|
|
iVar18 = iVar19 - iVar24;
|
|
if (iVar18 < 0)
|
|
iVar18 = iVar24 - iVar19;
|
|
|
|
iVar19 = (iVar9 * body[1].axis[1].vx + iVar6 * body[1].axis[1].vz) / 4096;
|
|
if (iVar19 < 0)
|
|
iVar19 = -iVar19;
|
|
|
|
iVar6 = iVar8;
|
|
|
|
if (10 < iVar19)
|
|
iVar6 = (iVar18 * 4096) / iVar19;
|
|
|
|
boxOverlap = iVar6;
|
|
|
|
if (-1 < iVar8)
|
|
{
|
|
boxOverlap = iVar8;
|
|
|
|
if (iVar6 < iVar8)
|
|
boxOverlap = iVar6;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
} while (true);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
// decompiled code
|
|
// original method signature:
|
|
// void /*$ra*/ bFindCollisionPoint(struct CDATA2D *body /*$t6*/, struct CRET2D *collisionResult /*$s0*/)
|
|
// line 195, offset 0x0001c8c0
|
|
/* begin block 1 */
|
|
// Start line: 196
|
|
// Start offset: 0x0001C8C0
|
|
// Variables:
|
|
// int carBarrierCollision; // $s1
|
|
// int i; // $a3
|
|
// int j; // $v1
|
|
// int k; // $t0
|
|
// int smallest; // $t4
|
|
// int besti; // $t5
|
|
// int bestk; // $t7
|
|
// int sign; // $t3
|
|
// int sign0; // $t0
|
|
// int sign1; // $a3
|
|
|
|
/* begin block 1.1 */
|
|
// Start line: 212
|
|
// Start offset: 0x0001C964
|
|
// Variables:
|
|
// int upper; // $a1
|
|
// int lower; // $v1
|
|
/* end block 1.1 */
|
|
// End offset: 0x0001C9BC
|
|
// End Line: 228
|
|
|
|
/* begin block 1.2 */
|
|
// Start line: 235
|
|
// Start offset: 0x0001C9F0
|
|
// Variables:
|
|
// int upper; // $a1
|
|
// int lower; // $a0
|
|
/* end block 1.2 */
|
|
// End offset: 0x0001CA60
|
|
// End Line: 249
|
|
/* end block 1 */
|
|
// End offset: 0x0001CC30
|
|
// End Line: 273
|
|
|
|
/* begin block 2 */
|
|
// Start line: 416
|
|
/* end block 2 */
|
|
// End Line: 417
|
|
|
|
/* begin block 3 */
|
|
// Start line: 427
|
|
/* end block 3 */
|
|
// End Line: 428
|
|
|
|
/* begin block 4 */
|
|
// Start line: 431
|
|
/* end block 4 */
|
|
// End Line: 432
|
|
|
|
// [D]
|
|
void bFindCollisionPoint(CDATA2D *body, CRET2D *collisionResult)
|
|
{
|
|
bool bVar1;
|
|
int iVar2;
|
|
int iVar3;
|
|
int iVar4;
|
|
int iVar5;
|
|
int *piVar6;
|
|
CDATA2D *pCVar7;
|
|
uint uVar8;
|
|
int *piVar9;
|
|
int iVar10;
|
|
int iVar11;
|
|
int local_t1_132;
|
|
int *piVar12;
|
|
int *piVar13;
|
|
int iVar14;
|
|
int iVar15;
|
|
int local_t5_4;
|
|
VECTOR *pVVar16;
|
|
int iVar17;
|
|
|
|
local_t5_4 = 0;
|
|
iVar17 = 0;
|
|
iVar14 = 0;
|
|
bVar1 = false;
|
|
iVar15 = body->limit[0] + 1;
|
|
|
|
if ((body->isCameraOrTanner == 0) && (body[1].isCameraOrTanner == 0))
|
|
{
|
|
if ((body[1].length[0] << 2 <= body[1].length[1]) ||
|
|
(body[1].length[1] << 2 <= body[1].length[0]))
|
|
{
|
|
bVar1 = true;
|
|
}
|
|
}
|
|
|
|
uVar8 = 1;
|
|
do {
|
|
iVar11 = 1;
|
|
local_t1_132 = uVar8 - 1;
|
|
piVar6 = body[uVar8].dist + 1;
|
|
|
|
do {
|
|
iVar5 = piVar6[2] - *piVar6;
|
|
iVar2 = *piVar6 + piVar6[2];
|
|
|
|
if ((iVar5 < iVar15) &&
|
|
(iVar14 = -1, iVar15 = iVar5, local_t5_4 = uVar8, iVar17 = iVar11, uVar8 == 1)) {
|
|
iVar14 = 1;
|
|
}
|
|
|
|
if ((iVar2 < iVar15) &&
|
|
(iVar14 = 1, iVar15 = iVar2, local_t5_4 = uVar8, iVar17 = iVar11, uVar8 == 1)) {
|
|
iVar14 = -1;
|
|
}
|
|
|
|
iVar11--;
|
|
piVar6--;
|
|
} while (iVar11 != -1);
|
|
|
|
iVar11 = 1;
|
|
uVar8 = local_t1_132;
|
|
} while (local_t1_132 != -1);
|
|
|
|
if (bVar1)
|
|
{
|
|
piVar9 = body[1].length + 1;
|
|
piVar6 = body[1].length;
|
|
piVar13 = body[1].dist + 1;
|
|
piVar12 = body[1].limit + 1;
|
|
|
|
do {
|
|
iVar5 = *piVar12 - *piVar13;
|
|
iVar2 = *piVar13 + *piVar12;
|
|
|
|
if ((iVar5 < iVar2) && (*piVar9 < *piVar6 << 2))
|
|
{
|
|
local_t5_4 = 1;
|
|
iVar14 = 1;
|
|
iVar17 = iVar11;
|
|
}
|
|
|
|
if ((iVar2 < iVar5) && (*piVar9 < *piVar6 << 2))
|
|
{
|
|
local_t5_4 = 1;
|
|
iVar14 = -1;
|
|
iVar17 = iVar11;
|
|
}
|
|
|
|
piVar9--;
|
|
piVar6++;
|
|
piVar13--;
|
|
iVar11--;
|
|
piVar12--;
|
|
} while (iVar11 != -1);
|
|
}
|
|
|
|
pCVar7 = body + (local_t5_4 ^ 1);
|
|
pVVar16 = body[local_t5_4].axis + iVar17;
|
|
iVar5 = pCVar7->axis[0].vx;
|
|
iVar2 = pVVar16->vx;
|
|
piVar6 = (int*)&body[local_t5_4].axis[iVar17].vz;
|
|
iVar11 = body[local_t5_4].axis[iVar17].vz;
|
|
iVar17 = iVar14;
|
|
|
|
if (-1 < iVar5 * iVar2 + pCVar7->axis[0].vz * iVar11)
|
|
iVar17 = -iVar14;
|
|
|
|
iVar3 = pCVar7->axis[1].vx;
|
|
iVar10 = iVar14;
|
|
|
|
if (-1 < iVar3 * iVar2 + pCVar7->axis[1].vz * iVar11)
|
|
iVar10 = -iVar14;
|
|
|
|
collisionResult->hit.vx = pCVar7->x.vx + (iVar5 * pCVar7->length[0] * iVar17 + iVar3 * pCVar7->length[1] * iVar10) / 4096;
|
|
|
|
iVar11 = pCVar7->axis[0].vz;
|
|
iVar2 = pCVar7->length[0];
|
|
iVar4 = pCVar7->axis[1].vz;
|
|
iVar5 = pCVar7->length[1];
|
|
iVar3 = pCVar7->x.vz;
|
|
|
|
collisionResult->penetration = iVar15;
|
|
collisionResult->hit.vz = pCVar7->x.vz + (iVar11 * iVar2 * iVar17 + iVar4 * iVar5 * iVar10) / 4096;
|
|
|
|
if (local_t5_4 != 0)
|
|
iVar14 = -iVar14;
|
|
|
|
iVar15 = pVVar16->vx;
|
|
|
|
collisionResult->surfNormal.vy = 0;
|
|
collisionResult->surfNormal.vx = iVar15 * iVar14;
|
|
collisionResult->surfNormal.vz = *piVar6 * iVar14;
|
|
}
|
|
|
|
|
|
|
|
// decompiled code
|
|
// original method signature:
|
|
// int /*$ra*/ bFindCollisionTime(struct CDATA2D *cd /*$s5*/, struct CRET2D *collisionResult /*stack 4*/)
|
|
// line 275, offset 0x0001cc30
|
|
/* begin block 1 */
|
|
// Start line: 276
|
|
// Start offset: 0x0001CC30
|
|
// Variables:
|
|
// int i; // $s4
|
|
// int q; // $s0
|
|
// int hit; // $t2
|
|
// int neverfree; // $fp
|
|
// int time; // $s1
|
|
// int step; // $s3
|
|
// struct CDATA2D original[2]; // stack offset -248
|
|
/* end block 1 */
|
|
// End offset: 0x0001CEEC
|
|
// End Line: 357
|
|
|
|
/* begin block 2 */
|
|
// Start line: 635
|
|
/* end block 2 */
|
|
// End Line: 636
|
|
|
|
/* begin block 3 */
|
|
// Start line: 638
|
|
/* end block 3 */
|
|
// End Line: 639
|
|
|
|
// [D]
|
|
int bFindCollisionTime(CDATA2D *cd, CRET2D *collisionResult)
|
|
{
|
|
int *piVar1;
|
|
VECTOR *pVVar2;
|
|
int iVar3;
|
|
long lVar4;
|
|
CDATA2D *pCVar5;
|
|
int *local_a1_184;
|
|
int iVar6;
|
|
int *piVar7;
|
|
int *piVar8;
|
|
int iVar9;
|
|
int iVar10;
|
|
int iVar11;
|
|
int iVar12;
|
|
int iVar13;
|
|
CDATA2D *pCVar14;
|
|
long *plVar15;
|
|
int iVar16;
|
|
int iVar17;
|
|
int iVar18;
|
|
CDATA2D original[2];
|
|
|
|
iVar11 = 1;
|
|
iVar18 = 1;
|
|
iVar13 = 0x1000;
|
|
iVar16 = 0x800;
|
|
iVar17 = 1;
|
|
pCVar5 = cd + 1;
|
|
iVar10 = 100;
|
|
|
|
do {
|
|
original[iVar17].x.vx = cd[iVar17].x.vx;
|
|
original[iVar17].x.vz = cd[iVar17].x.vz;
|
|
original[iVar17].theta = cd[iVar17].theta;
|
|
|
|
original[iVar17].dist[0] = cd[iVar17].dist[0];
|
|
original[iVar17].limit[0] = cd[iVar17].limit[0];
|
|
original[iVar17].dist[1] = cd[iVar17].dist[1];
|
|
original[iVar17].limit[1] = cd[iVar17].limit[1];
|
|
iVar17--;
|
|
|
|
} while (iVar17 != -1);
|
|
|
|
iVar10 = 7;
|
|
do {
|
|
iVar12 = 1;
|
|
iVar17 = iVar10 + -1;
|
|
pCVar5 = cd + 1;
|
|
do
|
|
{
|
|
iVar6 = pCVar5->vel.vx / 2;
|
|
iVar3 = pCVar5->vel.vz;
|
|
|
|
iVar9 = pCVar5->avel / 2;
|
|
|
|
pCVar5->vel.vx = iVar6;
|
|
pCVar5->avel = iVar9;
|
|
|
|
iVar3 = iVar3 >> 1;
|
|
pCVar5->vel.vz = iVar3;
|
|
|
|
if (iVar11 == 0)
|
|
{
|
|
pCVar5->x.vx += iVar6;
|
|
pCVar5->x.vz += iVar3;
|
|
|
|
iVar6 = pCVar5->theta + iVar9;
|
|
}
|
|
else
|
|
{
|
|
pCVar5->x.vx -= iVar6;
|
|
pCVar5->x.vz -= iVar3;
|
|
iVar6 = pCVar5->theta - iVar9;
|
|
}
|
|
|
|
pCVar5->theta = iVar6;
|
|
iVar12--;
|
|
pCVar5--;
|
|
} while (iVar12 != -1);
|
|
|
|
if (iVar11 == 0)
|
|
{
|
|
iVar18 = 0;
|
|
iVar11 = iVar16;
|
|
}
|
|
else
|
|
{
|
|
iVar11 = -iVar16;
|
|
}
|
|
|
|
iVar13 = iVar13 + iVar11;
|
|
|
|
iVar11 = bcollided2d(cd, 0);
|
|
|
|
if (iVar10 != 0)
|
|
iVar16 = iVar16 >> 1;
|
|
|
|
iVar12 = 1;
|
|
iVar10 = iVar17;
|
|
} while (iVar17 != -1);
|
|
|
|
if (iVar11 == 0)
|
|
{
|
|
pCVar5 = cd + 1;
|
|
|
|
do {
|
|
pCVar5->x.vx += pCVar5->vel.vx;
|
|
pCVar5->x.vz += pCVar5->vel.vz;
|
|
pCVar5->theta += pCVar5->avel;
|
|
|
|
iVar12--;
|
|
pCVar5--;
|
|
} while (iVar12 != -1);
|
|
|
|
bcollided2d(cd, 0);
|
|
iVar13 = iVar13 + iVar16;
|
|
}
|
|
else
|
|
{
|
|
iVar11 = 1;
|
|
if (iVar18 != 0)
|
|
{
|
|
pCVar5 = cd + 1;
|
|
pCVar14 = original + 1;
|
|
|
|
do {
|
|
pCVar5->x.vx = pCVar14->x.vx;
|
|
pCVar5->x.vz = pCVar14->x.vz;
|
|
pCVar5->theta = pCVar14->theta;
|
|
|
|
bcollided2d(cd, 0);
|
|
|
|
pCVar14--;
|
|
pCVar5--;
|
|
iVar11--;
|
|
} while (iVar11 != -1);
|
|
|
|
iVar13 = 0x1000;
|
|
}
|
|
}
|
|
|
|
collisionResult->neverfree = iVar18;
|
|
return iVar13;
|
|
}
|
|
|
|
|
|
|
|
// decompiled code
|
|
// original method signature:
|
|
// void /*$ra*/ ApplyDamage(struct _CAR_DATA *cp /*$a0*/, char region /*$a1*/, int value /*$a2*/, char fakeDamage /*$a3*/)
|
|
// line 384, offset 0x0001ceec
|
|
/* begin block 1 */
|
|
// Start line: 385
|
|
// Start offset: 0x0001CEEC
|
|
// Variables:
|
|
// short *pRegion; // $t0
|
|
/* end block 1 */
|
|
// End offset: 0x0001D0B0
|
|
// End Line: 465
|
|
|
|
/* begin block 2 */
|
|
// Start line: 965
|
|
/* end block 2 */
|
|
// End Line: 966
|
|
|
|
/* begin block 3 */
|
|
// Start line: 993
|
|
/* end block 3 */
|
|
// End Line: 994
|
|
|
|
int wibblewibblewoo = 0;
|
|
|
|
// [D]
|
|
void ApplyDamage(_CAR_DATA *cp, char region, int value, char fakeDamage)
|
|
{
|
|
ushort uVar1;
|
|
int iVar2;
|
|
int iVar3;
|
|
ushort *puVar4;
|
|
short *psVar5;
|
|
|
|
iVar3 = region;
|
|
puVar4 = (ushort *)(cp->ap.damage + region);
|
|
|
|
if (cp->controlType == 1 || cp->controlType == 4)
|
|
value = value * gPlayerDamageFactor / 4096;
|
|
else
|
|
value = value << 1;
|
|
|
|
if (cp->controlType == 3)
|
|
{
|
|
if (gCopDifficultyLevel == 1)
|
|
{
|
|
iVar2 = value * 0xc;
|
|
}
|
|
else
|
|
{
|
|
if (gCopDifficultyLevel != 2)
|
|
goto LAB_0001cf9c;
|
|
|
|
iVar2 = value * 7;
|
|
}
|
|
value = iVar2 >> 4;
|
|
}
|
|
LAB_0001cf9c:
|
|
wibblewibblewoo = region;
|
|
if (fakeDamage == 0) {
|
|
if (cp->totalDamage < 0xffff - value)
|
|
{
|
|
cp->totalDamage = cp->totalDamage + value;
|
|
}
|
|
else {
|
|
cp->totalDamage = 0xffff;
|
|
}
|
|
}
|
|
uVar1 = *puVar4;
|
|
*puVar4 = (uVar1 + value);
|
|
|
|
if (0xfff < ((uVar1 + value) * 0x10000) >> 0x10)
|
|
*puVar4 = 0xfff;
|
|
|
|
if (iVar3 == 1)
|
|
iVar3 = 0;
|
|
else if (iVar3 == 0)
|
|
iVar3 = 1;
|
|
else if (iVar3 == 3)
|
|
iVar3 = 4;
|
|
else if (iVar3 == 4)
|
|
iVar3 = 3;
|
|
else
|
|
iVar3 = -1;
|
|
|
|
|
|
if (iVar3 != -1)
|
|
{
|
|
psVar5 = cp->ap.damage + iVar3;
|
|
value = value >> 1;
|
|
|
|
if (*psVar5 < value)
|
|
{
|
|
if (fakeDamage == 0)
|
|
{
|
|
if (cp->totalDamage < 0xffff - (value - *psVar5))
|
|
cp->totalDamage = cp->totalDamage + (value - *psVar5);
|
|
else
|
|
cp->totalDamage = 0xffff;
|
|
}
|
|
|
|
*psVar5 = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// decompiled code
|
|
// original method signature:
|
|
// int /*$ra*/ DamageCar3D(struct _CAR_DATA *cp /*$s1*/, long (*delta)[4] /*$t4*/, int strikeVel /*$t6*/, struct _CAR_DATA *pOtherCar /*$s2*/)
|
|
// line 470, offset 0x0001d0b0
|
|
/* begin block 1 */
|
|
// Start line: 471
|
|
// Start offset: 0x0001D0B0
|
|
// Variables:
|
|
// int l; // $v1
|
|
// int w; // $v0
|
|
// int region; // $a1
|
|
// long nose[4]; // stack offset -56
|
|
// long door[4]; // stack offset -40
|
|
// int impact; // $s3
|
|
// int QQQ; // $t7
|
|
|
|
/* begin block 1.1 */
|
|
// Start line: 549
|
|
// Start offset: 0x0001D388
|
|
// Variables:
|
|
// char fakeDamage; // $a3
|
|
// char player_id; // $s0
|
|
// char kludge; // $a3
|
|
/* end block 1.1 */
|
|
// End offset: 0x0001D424
|
|
// End Line: 568
|
|
/* end block 1 */
|
|
// End offset: 0x0001D454
|
|
// End Line: 572
|
|
|
|
/* begin block 2 */
|
|
// Start line: 1162
|
|
/* end block 2 */
|
|
// End Line: 1163
|
|
|
|
/* begin block 3 */
|
|
// Start line: 1168
|
|
/* end block 3 */
|
|
// End Line: 1169
|
|
|
|
// [D]
|
|
int DamageCar3D(_CAR_DATA *cp, long(*delta)[4], int strikeVel, _CAR_DATA *pOtherCar)
|
|
{
|
|
char region;
|
|
int value;
|
|
int iVar1;
|
|
bool fakeDamage;
|
|
int iVar2;
|
|
|
|
iVar2 = strikeVel;
|
|
//if (strikeVel < 0)
|
|
// iVar2 = strikeVel + 0x7f;
|
|
|
|
strikeVel = strikeVel * 0x177;
|
|
|
|
value = (uint)(ushort)(((cp->ap).carCos)->colBox).vz << 0x10;
|
|
value = (value >> 0x10) - (value >> 0x1f) >> 1;
|
|
|
|
//if (strikeVel < 0)
|
|
// strikeVel = strikeVel + 255;
|
|
|
|
strikeVel = strikeVel >> 8;
|
|
|
|
if (strikeVel < 0xa000)
|
|
{
|
|
if (cp->totalDamage == 0)
|
|
cp->totalDamage = 1;
|
|
|
|
iVar2 = 0;
|
|
}
|
|
else
|
|
{
|
|
iVar1 = (cp->hd.where.m[0][2] * (*delta)[0] + cp->hd.where.m[1][2] * (*delta)[1] + cp->hd.where.m[2][2] * (*delta)[2]) / 4096;
|
|
|
|
if ((cp->hd.where.m[0][0] * (*delta)[0] + cp->hd.where.m[1][0] * (*delta)[1] + cp->hd.where.m[2][0] * (*delta)[2]) / 4096 < 1)
|
|
{
|
|
region = 0;
|
|
|
|
if ((iVar1 <= value) && (region = 4, -value < iVar1))
|
|
{
|
|
region = 5;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
region = 1;
|
|
if ((iVar1 <= value) && (region = 3, -value < iVar1))
|
|
{
|
|
region = 2;
|
|
}
|
|
}
|
|
|
|
if (cp->controlType == 1)
|
|
{
|
|
value = (strikeVel / 350 + 0x200) * 3;
|
|
//if (value < 0)
|
|
// value = value + 7;
|
|
|
|
value = value >> 3;
|
|
if (0x477 < value)
|
|
value = 0x477;
|
|
|
|
}
|
|
else if (cp->controlType == 4)
|
|
{
|
|
if (pOtherCar->controlType == 1)
|
|
{
|
|
value = (strikeVel / 350 + 0x200) * 3;
|
|
//if (value < 0)
|
|
// value = value + 7;
|
|
|
|
value = value >> 3;
|
|
|
|
if (0x477 < value)
|
|
value = 0x477;
|
|
|
|
cp->ai.l.takeDamage = 0x32;
|
|
}
|
|
else
|
|
{
|
|
value = strikeVel / 350 + 0x200;
|
|
//if (value < 0)
|
|
// value = strikeVel / 350 + 0x203;
|
|
|
|
value = value >> 2;
|
|
if (0x2fa < value)
|
|
value = 0x2fa;
|
|
|
|
if (cp->ai.l.takeDamage == 0)
|
|
value = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
iVar1 = (strikeVel / 400 + 0x400) * 7;
|
|
value = iVar1 >> 3;
|
|
|
|
//if (iVar1 < 0)
|
|
// value = iVar1 + 7 >> 3;
|
|
}
|
|
|
|
fakeDamage = false;
|
|
|
|
if (cp->controlType == 3)
|
|
fakeDamage = pOtherCar->controlType == 3;
|
|
|
|
ApplyDamage(cp, region, value, fakeDamage);
|
|
|
|
value = GetPlayerId(cp);
|
|
region = (char)value;
|
|
|
|
if (region < 0)
|
|
{
|
|
value = GetPlayerId(pOtherCar);
|
|
region = (char)value;
|
|
}
|
|
|
|
value = GetPlayerId(cp);
|
|
|
|
if ((value != 0) || (value = 2, pOtherCar->controlType != 2))
|
|
{
|
|
iVar1 = GetPlayerId(pOtherCar);
|
|
value = 1;
|
|
|
|
if ((iVar1 == 0) && (cp->controlType == 2))
|
|
value = 2;
|
|
}
|
|
|
|
CollisionSound(region, cp, iVar2 >> 7, value);
|
|
|
|
iVar2 = 1;
|
|
}
|
|
|
|
return iVar2;
|
|
}
|
|
|
|
|
|
|
|
// decompiled code
|
|
// original method signature:
|
|
// void /*$ra*/ DamageCar(struct _CAR_DATA *cp /*$s2*/, struct CDATA2D *cd /*$s1*/, struct CRET2D *collisionResult /*$s3*/, int strikeVel /*$s0*/)
|
|
// line 587, offset 0x0001d454
|
|
/* begin block 1 */
|
|
// Start line: 588
|
|
// Start offset: 0x0001D454
|
|
// Variables:
|
|
// struct VECTOR delta; // stack offset -48
|
|
// int l; // $v1
|
|
// int w; // $v0
|
|
// int region; // $a1
|
|
// int damage; // $a2
|
|
// char player_id; // $s5
|
|
// int impact; // $s4
|
|
// int QQQ; // $t0
|
|
/* end block 1 */
|
|
// End offset: 0x0001D668
|
|
// End Line: 633
|
|
|
|
/* begin block 2 */
|
|
// Start line: 1425
|
|
/* end block 2 */
|
|
// End Line: 1426
|
|
|
|
/* begin block 3 */
|
|
// Start line: 1441
|
|
/* end block 3 */
|
|
// End Line: 1442
|
|
|
|
// [D]
|
|
void DamageCar(_CAR_DATA *cp, CDATA2D *cd, CRET2D *collisionResult, int strikeVel)
|
|
{
|
|
int impact;
|
|
int iVar1;
|
|
int value;
|
|
int iVar2;
|
|
int iVar3;
|
|
int iVar4;
|
|
|
|
iVar1 = GetPlayerId(cp);
|
|
value = cp->ap.carCos->colBox.vz << 0x10;
|
|
impact = strikeVel / 600;
|
|
|
|
value = (value >> 0x10) - (value >> 0x1f) >> 1;
|
|
|
|
if (0x4fff < strikeVel && 9 < cp->hd.speed)
|
|
{
|
|
iVar4 = collisionResult->hit.vx - cd->x.vx;
|
|
iVar3 = collisionResult->hit.vz - cd->x.vz;
|
|
|
|
iVar2 = (cd->axis[0].vx * iVar4 + cd->axis[0].vz * iVar3) / 4096;
|
|
|
|
if ((cd->axis[1].vx * iVar4 + cd->axis[1].vz * iVar3) / 4096 < 1)
|
|
{
|
|
iVar3 = 0;
|
|
if ((iVar2 <= value) && (iVar3 = 4, -value < iVar2))
|
|
iVar3 = 5;
|
|
}
|
|
else {
|
|
iVar3 = 1;
|
|
|
|
if ((iVar2 <= value) && (iVar3 = 3, -value < iVar2))
|
|
iVar3 = 2;
|
|
}
|
|
if (0x1f4000 < strikeVel)
|
|
strikeVel = 0x1f4000;
|
|
|
|
value = ((strikeVel / 300) * 0x400) / 0x5dc;
|
|
if (0x800 < value)
|
|
value = 0x800;
|
|
|
|
value -= (value * cp->ap.damage[iVar3] >> 0xd);
|
|
|
|
if (cp->controlType == 4)
|
|
{
|
|
if (cp->ai.l.takeDamage == 0)
|
|
value = 0;
|
|
else
|
|
value = value / 2;
|
|
}
|
|
|
|
ApplyDamage(cp, iVar3, value, 0);
|
|
CollisionSound(iVar1, cp, impact, 0);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// decompiled code
|
|
// original method signature:
|
|
// int /*$ra*/ CarBuildingCollision(struct _CAR_DATA *cp /*$s3*/, struct BUILDING_BOX *building /*$s2*/, struct CELL_OBJECT *cop /*$s6*/, int mightBeABarrier /*$s1*/)
|
|
// line 839, offset 0x0001d68c
|
|
/* begin block 1 */
|
|
// Start line: 840
|
|
// Start offset: 0x0001D68C
|
|
// Variables:
|
|
// static struct CDATA2D cd[2]; // offset 0x0
|
|
// static struct CRET2D collisionResult; // offset 0xd0
|
|
// int debris_colour; // stack offset -48
|
|
// struct VECTOR tempwhere; // stack offset -168
|
|
// struct MODEL *pModel; // $s5
|
|
// int player_id; // stack offset -44
|
|
|
|
/* begin block 1.1 */
|
|
// Start line: 866
|
|
// Start offset: 0x0001D794
|
|
// Variables:
|
|
// struct SVECTOR boxDisp; // stack offset -152
|
|
|
|
/* begin block 1.1.1 */
|
|
// Start line: 908
|
|
// Start offset: 0x0001D8F4
|
|
// Variables:
|
|
// int wbod; // $a1
|
|
/* end block 1.1.1 */
|
|
// End offset: 0x0001D9A4
|
|
// End Line: 918
|
|
/* end block 1.1 */
|
|
// End offset: 0x0001D9A4
|
|
// End Line: 920
|
|
|
|
/* begin block 1.2 */
|
|
// Start line: 977
|
|
// Start offset: 0x0001DA64
|
|
|
|
/* begin block 1.2.1 */
|
|
// Start line: 977
|
|
// Start offset: 0x0001DA64
|
|
// Variables:
|
|
// struct VECTOR velocity; // stack offset -144
|
|
// long pointVel[4]; // stack offset -128
|
|
// long reaction[4]; // stack offset -112
|
|
// long lever[4]; // stack offset -96
|
|
// int strikeVel; // $s1
|
|
|
|
/* begin block 1.2.1.1 */
|
|
// Start line: 1014
|
|
// Start offset: 0x0001DC58
|
|
// Variables:
|
|
// short scale; // $a2
|
|
/* end block 1.2.1.1 */
|
|
// End offset: 0x0001DCA4
|
|
// End Line: 1034
|
|
|
|
/* begin block 1.2.1.2 */
|
|
// Start line: 1050
|
|
// Start offset: 0x0001DD04
|
|
|
|
/* begin block 1.2.1.2.1 */
|
|
// Start line: 1058
|
|
// Start offset: 0x0001DD28
|
|
// Variables:
|
|
// struct SMASHABLE_OBJECT *sip; // $a1
|
|
// struct SMASHABLE_OBJECT *match; // $s0
|
|
// int chan; // $s1
|
|
// int adjust; // $s2
|
|
/* end block 1.2.1.2.1 */
|
|
// End offset: 0x0001DE3C
|
|
// End Line: 1079
|
|
/* end block 1.2.1.2 */
|
|
// End offset: 0x0001DEC4
|
|
// End Line: 1093
|
|
|
|
/* begin block 1.2.1.3 */
|
|
// Start line: 1098
|
|
// Start offset: 0x0001DEF4
|
|
// Variables:
|
|
// struct VECTOR LeafPosition; // stack offset -80
|
|
/* end block 1.2.1.3 */
|
|
// End offset: 0x0001DEF4
|
|
// End Line: 1098
|
|
|
|
/* begin block 1.2.1.4 */
|
|
// Start line: 1116
|
|
// Start offset: 0x0001DF50
|
|
|
|
/* begin block 1.2.1.4.1 */
|
|
// Start line: 1119
|
|
// Start offset: 0x0001DF90
|
|
// Variables:
|
|
// struct VECTOR lamp_velocity; // stack offset -64
|
|
/* end block 1.2.1.4.1 */
|
|
// End offset: 0x0001DFC4
|
|
// End Line: 1123
|
|
/* end block 1.2.1.4 */
|
|
// End offset: 0x0001DFC4
|
|
// End Line: 1124
|
|
|
|
/* begin block 1.2.1.5 */
|
|
// Start line: 1143
|
|
// Start offset: 0x0001E058
|
|
// Variables:
|
|
// int twistY; // $a1
|
|
// int lever_dot_n; // $a0
|
|
// int displacementsquared; // $v1
|
|
// int denom; // $v1
|
|
/* end block 1.2.1.5 */
|
|
// End offset: 0x0001E170
|
|
// End Line: 1155
|
|
/* end block 1.2.1 */
|
|
// End offset: 0x0001E37C
|
|
// End Line: 1184
|
|
/* end block 1.2 */
|
|
// End offset: 0x0001E384
|
|
// End Line: 1188
|
|
/* end block 1 */
|
|
// End offset: 0x0001E3E8
|
|
// End Line: 1195
|
|
|
|
/* begin block 2 */
|
|
// Start line: 1966
|
|
/* end block 2 */
|
|
// End Line: 1967
|
|
|
|
// [D]
|
|
int CarBuildingCollision(_CAR_DATA *cp, BUILDING_BOX *building, CELL_OBJECT *cop, int mightBeABarrier)
|
|
{
|
|
static CDATA2D cd[2] = {0}; // offset 0x0
|
|
static CRET2D collisionResult = { 0 }; // offset 0xd0
|
|
|
|
unsigned char uVar1;
|
|
int iVar2;
|
|
int uVar3;
|
|
long lVar4;
|
|
long lVar5;
|
|
long lVar6;
|
|
long lVar7;
|
|
int strikeVel;
|
|
long lVar8;
|
|
int iVar9;
|
|
int iVar10;
|
|
int uVar11;
|
|
CAR_COSMETICS *pCVar12;
|
|
int iVar13;
|
|
int iVar14;
|
|
SMASHABLE_OBJECT *pSVar15;
|
|
short scale;
|
|
int iVar16;
|
|
int iVar17;
|
|
int iVar18;
|
|
SMASHABLE_OBJECT *pSVar19;
|
|
MODEL *pMVar20;
|
|
VECTOR tempwhere;
|
|
SVECTOR boxDisp;
|
|
VECTOR velocity;
|
|
long pointVel[4];
|
|
long reaction[4];
|
|
long lever[4];
|
|
VECTOR LeafPosition;
|
|
VECTOR lamp_velocity;
|
|
int debris_colour;
|
|
int player_id;
|
|
|
|
pMVar20 = modelpointers[cop->type];
|
|
iVar2 = GetPlayerId(cp);
|
|
|
|
cd[0].isCameraOrTanner = (cp->controlType == 5);
|
|
|
|
if (cp->controlType == 6)
|
|
cd[0].isCameraOrTanner = cd[0].isCameraOrTanner + 2;
|
|
|
|
cd[1].isCameraOrTanner = (mightBeABarrier == 0);
|
|
iVar14 = cp->hd.oBox.location.vy + building->pos.vy;
|
|
|
|
if (iVar14 < 0)
|
|
iVar14 = -iVar14;
|
|
|
|
strikeVel = cp->hd.oBox.length[1] << 0x10;
|
|
uVar3 = 0;
|
|
|
|
pCVar12 = cp->ap.carCos;
|
|
if (pCVar12 == NULL) // [A] potential crash fix
|
|
return 0;
|
|
|
|
if (iVar14 <= building->height / 2 + ((strikeVel >> 0x10) - (strikeVel >> 0x1f) >> 1) && (cop->pos.vx != 0xFD46FEC0) && (pMVar20->shape_flags & 0x10) == 0)
|
|
{
|
|
lVar4 = cp->hd.where.t[0];
|
|
lVar8 = cp->hd.where.t[2];
|
|
|
|
iVar14 = GetDebrisColour(cp);
|
|
gte_SetRotMatrix(&cp->hd.where);
|
|
gte_SetTransMatrix(&cp->hd.where);
|
|
|
|
boxDisp.vx = -pCVar12->cog.vx;
|
|
boxDisp.vy = -pCVar12->cog.vy;
|
|
boxDisp.vz = -pCVar12->cog.vz;
|
|
|
|
gte_ldv0(&boxDisp);
|
|
|
|
docop2(0x480012);
|
|
|
|
cd[0].x.vx = MAC1;
|
|
cd[0].x.vy = MAC2;
|
|
cd[0].x.vz = MAC3;
|
|
|
|
cd[0].theta = cp->hd.direction;
|
|
|
|
if (cp->controlType == 6)
|
|
{
|
|
cd[0].vel.vx = cp->st.n.linearVelocity[0] / 4096;// + 0x800 >> 0xc;
|
|
cd[0].vel.vz = cp->st.n.linearVelocity[2] / 4096;// + 0x800 >> 0xc;
|
|
|
|
cp->hd.where.t[0] += cd[0].vel.vx;
|
|
cp->hd.where.t[2] += cd[0].vel.vz;
|
|
|
|
cd[0].length[0] = 90;
|
|
cd[0].length[1] = 90;
|
|
}
|
|
else if (cp->controlType == 5)
|
|
{
|
|
cd[0].vel.vx = 0;
|
|
cd[0].vel.vz = 0;
|
|
cd[0].length[1] = 5;
|
|
cd[0].length[0] = gCameraDistance / 2;
|
|
}
|
|
else
|
|
{
|
|
cd[0].vel.vx = cp->st.n.linearVelocity[0] / 4096;// +0x800 >> 0xc;
|
|
cd[0].vel.vz = cp->st.n.linearVelocity[2] / 4096;// + 0x800 >> 0xc;
|
|
|
|
cp->hd.where.t[0] += cd[0].vel.vx;
|
|
cp->hd.where.t[2] += cd[0].vel.vz;
|
|
|
|
cd[0].length[0] = cp->ap.carCos->colBox.vz + 15;
|
|
cd[0].length[1] = cp->ap.carCos->colBox.vx + 15;
|
|
|
|
if (handlingType[cp->hndType].fourWheelDrive == 1 || cp->hndType == 5)
|
|
{
|
|
cd[0].length[1] = cd[0].length[1] * 13;
|
|
cd[0].length[1] = cd[0].length[1] >> 4;
|
|
}
|
|
}
|
|
|
|
cd[0].avel = (cp->st.n.angularVelocity[1] / 4096) * 5 >> 5;
|
|
|
|
cd[1].x.vx = cp->hd.where.t[0] + (((building->pos.vx - cp->hd.where.t[0]) << 0x10) >> 0x10);
|
|
cd[1].x.vz = cp->hd.where.t[2] + (((building->pos.vz - cp->hd.where.t[2]) << 0x10) >> 0x10);
|
|
|
|
cd[1].theta = building->theta;
|
|
cd[1].length[0] = building->xsize;
|
|
cd[1].length[1] = building->zsize;
|
|
cd[1].vel.vx = 0;
|
|
cd[1].vel.vz = 0;
|
|
cd[1].avel = 0;
|
|
|
|
if (cp->controlType == 5)
|
|
{
|
|
iVar2 = bcollided2d(cd, 1);
|
|
uVar3 = (iVar2 != 0);
|
|
}
|
|
else
|
|
{
|
|
strikeVel = bcollided2d(cd, 0);
|
|
|
|
#if defined(COLLISION_DEBUG) && !defined(PSX)
|
|
extern int gShowCollisionDebug;
|
|
if (gShowCollisionDebug)
|
|
{
|
|
extern void Debug_AddLine(VECTOR& pointA, VECTOR& pointB, CVECTOR& color);
|
|
extern void Debug_AddLineOfs(VECTOR& pointA, VECTOR& pointB, VECTOR& ofs, CVECTOR& color);
|
|
|
|
CVECTOR bbcv = { 0, 0, 250 };
|
|
CVECTOR rrcv = { 250, 0, 0 };
|
|
CVECTOR yycv = { 250, 250, 0 };
|
|
|
|
// show both box axes
|
|
{
|
|
VECTOR _zero = { 0 };
|
|
VECTOR b1p = cd[0].x;
|
|
VECTOR b2p = cd[1].x;
|
|
b2p.vy = b1p.vy;
|
|
|
|
// show position to position
|
|
//Debug_AddLine(b1p1, b2p1, yycv);
|
|
|
|
VECTOR b1ax[2] = { {0} , {0} };
|
|
b1ax[0].vx = (cd[0].axis[0].vx * cd[0].length[0]) / 4096;
|
|
b1ax[0].vz = (cd[0].axis[0].vz * cd[0].length[0]) / 4096;
|
|
b1ax[1].vx = (cd[0].axis[1].vx * cd[0].length[1]) / 4096;
|
|
b1ax[1].vz = (cd[0].axis[1].vz * cd[0].length[1]) / 4096;
|
|
|
|
// show axis of body 1
|
|
Debug_AddLineOfs(_zero, b1ax[0], b1p, rrcv);
|
|
Debug_AddLineOfs(_zero, b1ax[1], b1p, yycv);
|
|
|
|
// display 2D box 1
|
|
{
|
|
int h = b1ax[0].vy;
|
|
VECTOR box_points[4] = {
|
|
{b1ax[0].vx - b1ax[1].vx, h, b1ax[0].vz - b1ax[1].vz, 0}, // front left
|
|
{b1ax[0].vx + b1ax[1].vx, h, b1ax[0].vz + b1ax[1].vz, 0}, // front right
|
|
|
|
{-b1ax[0].vx + b1ax[1].vx, h, -b1ax[0].vz + b1ax[1].vz, 0}, // back right
|
|
{-b1ax[0].vx - b1ax[1].vx, h, -b1ax[0].vz - b1ax[1].vz, 0} // back left
|
|
};
|
|
|
|
Debug_AddLineOfs(box_points[0], box_points[1], b1p, bbcv);
|
|
Debug_AddLineOfs(box_points[1], box_points[2], b1p, bbcv);
|
|
Debug_AddLineOfs(box_points[2], box_points[3], b1p, bbcv);
|
|
Debug_AddLineOfs(box_points[3], box_points[0], b1p, bbcv);
|
|
}
|
|
|
|
VECTOR b2ax[2] = { {0} , {0} };
|
|
b2ax[0].vx += (cd[1].axis[0].vx * cd[1].length[0]) / 4096;
|
|
b2ax[0].vz += (cd[1].axis[0].vz * cd[1].length[0]) / 4096;
|
|
b2ax[1].vx += (cd[1].axis[1].vx * cd[1].length[1]) / 4096;
|
|
b2ax[1].vz += (cd[1].axis[1].vz * cd[1].length[1]) / 4096;
|
|
|
|
// show axis of body 2
|
|
Debug_AddLineOfs(_zero, b2ax[0], b2p, rrcv);
|
|
Debug_AddLineOfs(_zero, b2ax[1], b2p, yycv);
|
|
|
|
CVECTOR& collColor = strikeVel ? rrcv : yycv;
|
|
|
|
// display 2D box 2
|
|
{
|
|
int h = b2ax[0].vy;
|
|
VECTOR box_points[4] = {
|
|
{b2ax[0].vx - b2ax[1].vx, h, b2ax[0].vz - b2ax[1].vz, 0}, // front left
|
|
{b2ax[0].vx + b2ax[1].vx, h, b2ax[0].vz + b2ax[1].vz, 0}, // front right
|
|
|
|
{-b2ax[0].vx + b2ax[1].vx, h, -b2ax[0].vz + b2ax[1].vz, 0}, // back right
|
|
{-b2ax[0].vx - b2ax[1].vx, h, -b2ax[0].vz - b2ax[1].vz, 0} // back left
|
|
};
|
|
|
|
Debug_AddLineOfs(box_points[0], box_points[1], b2p, collColor);
|
|
Debug_AddLineOfs(box_points[1], box_points[2], b2p, collColor);
|
|
Debug_AddLineOfs(box_points[2], box_points[3], b2p, collColor);
|
|
Debug_AddLineOfs(box_points[3], box_points[0], b2p, collColor);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
if (strikeVel == 0)
|
|
{
|
|
uVar3 = 0;
|
|
}
|
|
else
|
|
{
|
|
bFindCollisionTime(cd, &collisionResult);
|
|
bFindCollisionPoint(cd, &collisionResult);
|
|
|
|
#if defined(COLLISION_DEBUG) && !defined(PSX)
|
|
extern int gShowCollisionDebug;
|
|
if(gShowCollisionDebug)
|
|
{
|
|
extern void Debug_AddLine(VECTOR& pointA, VECTOR& pointB, CVECTOR& color);
|
|
extern void Debug_AddLineOfs(VECTOR& pointA, VECTOR& pointB, VECTOR& ofs, CVECTOR& color);
|
|
|
|
CVECTOR bbcv = { 0, 0, 250 };
|
|
CVECTOR rrcv = { 250, 0, 0 };
|
|
CVECTOR yycv = { 250, 250, 0 };
|
|
|
|
// show collision point and normal
|
|
{
|
|
|
|
VECTOR pb = collisionResult.hit;
|
|
pb.vy += 16;
|
|
|
|
// display collision point
|
|
Debug_AddLine(collisionResult.hit, pb, rrcv);
|
|
|
|
VECTOR nb = collisionResult.hit;
|
|
nb.vx += collisionResult.surfNormal.vx / 16;
|
|
nb.vy += collisionResult.surfNormal.vy / 16;
|
|
nb.vz += collisionResult.surfNormal.vz / 16;
|
|
|
|
// show collision normal
|
|
Debug_AddLine(collisionResult.hit, nb, bbcv);
|
|
}
|
|
}
|
|
#endif
|
|
collisionResult.surfNormal.vx = -collisionResult.surfNormal.vx;
|
|
collisionResult.surfNormal.vy = 0;
|
|
collisionResult.surfNormal.vz = -collisionResult.surfNormal.vz;
|
|
|
|
collisionResult.hit.vy = cp->hd.where.t[1] + 41;
|
|
|
|
cp->hd.where.t[0] += (collisionResult.penetration * collisionResult.surfNormal.vx) / 4096;
|
|
cp->hd.where.t[2] += (collisionResult.penetration * collisionResult.surfNormal.vz) / 4096;
|
|
|
|
iVar13 = cp->st.n.angularVelocity[0];
|
|
iVar18 = cp->st.n.angularVelocity[1];
|
|
iVar10 = cp->st.n.angularVelocity[2];
|
|
|
|
iVar17 = collisionResult.hit.vx - cp->hd.where.t[0];
|
|
iVar16 = collisionResult.hit.vy - cp->hd.where.t[1];
|
|
iVar9 = collisionResult.hit.vz - cp->hd.where.t[2];
|
|
|
|
strikeVel = ((iVar18 * iVar9 - iVar10 * iVar16) / 4096) + cp->st.n.linearVelocity[0];
|
|
iVar10 = ((iVar10 * iVar17 - iVar13 * iVar9) / 4096) + cp->st.n.linearVelocity[1];
|
|
iVar13 = ((iVar13 * iVar16 - iVar18 * iVar17) / 4096) + cp->st.n.linearVelocity[2];
|
|
|
|
lVar5 = collisionResult.surfNormal.vx;
|
|
lVar6 = collisionResult.surfNormal.vy;
|
|
lVar7 = collisionResult.surfNormal.vz;
|
|
|
|
iVar10 = (strikeVel >> 8) * (lVar5 >> 4) + (iVar10 >> 8) * (lVar6 >> 4) + (iVar13 >> 8) * (lVar7 >> 4);
|
|
strikeVel = -iVar10;
|
|
|
|
if (iVar10 < 0)
|
|
{
|
|
if (cp->controlType == 1)
|
|
{
|
|
if (strikeVel < 0x20)
|
|
scale = ((iVar10 << 0x17) >> 0x10);
|
|
else
|
|
scale = 0x1000;
|
|
|
|
if ((pMVar20->flags2 & 0x800) == 0)
|
|
NoteFelony(&felonyData, 6, scale);
|
|
else
|
|
NoteFelony(&felonyData, 7, scale);
|
|
}
|
|
|
|
collisionResult.hit.vy = -collisionResult.hit.vy;
|
|
|
|
velocity.vx = cp->st.n.linearVelocity[0] / 4096;
|
|
velocity.vy = -17;
|
|
velocity.vz = cp->st.n.linearVelocity[2] / 4096;
|
|
|
|
if ((pMVar20->flags2 & 0x800) != 0)
|
|
{
|
|
damage_object(cop, &velocity);
|
|
|
|
if ((pMVar20->shape_flags & 8) == 0)
|
|
{
|
|
pSVar15 = smashable;
|
|
strikeVel = pSVar15->modelIdx;
|
|
pSVar19 = NULL;
|
|
|
|
if (pSVar15->name != NULL)
|
|
{
|
|
while ((pSVar19 = pSVar15, modelpointers[strikeVel] != pMVar20 && (pSVar19 = NULL, pSVar15[1].name != NULL)))
|
|
{
|
|
strikeVel = pSVar15[1].modelIdx;
|
|
pSVar15 = pSVar15 + 1;
|
|
}
|
|
}
|
|
|
|
if (pSVar19 == NULL)
|
|
pSVar19 = smashable;
|
|
|
|
uVar3 = velocity.vx ^ velocity.vz;
|
|
uVar11 = collisionResult.hit.vx ^ collisionResult.hit.vz;
|
|
strikeVel = GetFreeChannel();
|
|
|
|
if ((1 < NumPlayers) && (NoPlayerControl == 0))
|
|
SetPlayerOwnsChannel(strikeVel, iVar2);
|
|
|
|
Start3DSoundVolPitch(strikeVel, 1, pSVar19->sound,
|
|
collisionResult.hit.vx, -collisionResult.hit.vy, collisionResult.hit.vz,
|
|
pSVar19->volume, pSVar19->pitch + ((uVar3 * uVar11 & 0x3ff) - 0x200));
|
|
}
|
|
|
|
cp->hd.where.t[0] = lVar4;
|
|
cp->hd.where.t[2] = lVar8;
|
|
|
|
collisionResult.hit.vy += 30;
|
|
|
|
Setup_Sparks(&collisionResult.hit, &velocity, 10, 0);
|
|
Setup_Debris(&collisionResult.hit, &velocity, 5, 0);
|
|
Setup_Debris(&collisionResult.hit, &velocity, 5, iVar14 << 0x10);
|
|
|
|
if (cp->controlType == 1)
|
|
SetPadVibration((int)cp->ai.padid, 3);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
if ((0x3600 < strikeVel) && (32000 < cp->hd.wheel_speed + 16000U))
|
|
{
|
|
if ((pMVar20->flags2 & 0x2000) == 0)
|
|
{
|
|
if (gNight != 0 && (modelpointers[gLastModelCollisionCheck]->flags2 & 0x1000) != 0)
|
|
{
|
|
iVar2 = damage_lamp(cop);
|
|
if (iVar2 != 0)
|
|
{
|
|
memset(&lamp_velocity, 0, sizeof(lamp_velocity));
|
|
|
|
collisionResult.hit.vy = -730;
|
|
Setup_Sparks(&collisionResult.hit, &lamp_velocity, 0x14, 0);
|
|
collisionResult.hit.vy = 730;
|
|
}
|
|
}
|
|
|
|
velocity.vy -= 20;
|
|
collisionResult.hit.vy += 30;
|
|
|
|
Setup_Sparks(&collisionResult.hit, &velocity, 4, 0);
|
|
|
|
collisionResult.hit.vy -= 30;
|
|
velocity.vy += 20;
|
|
}
|
|
else
|
|
{
|
|
uVar3 = rand();
|
|
LeafPosition.vx = collisionResult.hit.vx;
|
|
LeafPosition.vy = -((uVar3 & 0xfe) + 600) - collisionResult.hit.vy;
|
|
LeafPosition.vz = collisionResult.hit.vz;
|
|
|
|
AddLeaf(&LeafPosition, 3, 1);
|
|
}
|
|
|
|
if ((0x1b000 < strikeVel) && (Setup_Debris(&collisionResult.hit, &velocity, 6, iVar14 << 0x10), cp->controlType == 1))
|
|
{
|
|
SetPadVibration((int)cp->ai.padid, 1);
|
|
}
|
|
}
|
|
|
|
DamageCar(cp, cd, &collisionResult, strikeVel);
|
|
|
|
iVar2 = (iVar17 * collisionResult.surfNormal.vx + iVar16 * collisionResult.surfNormal.vy + iVar9 * collisionResult.surfNormal.vz) / 4096;
|
|
iVar2 = (((iVar17 * iVar17 + iVar9 * iVar9) - iVar2 * iVar2) * car_cosmetics[cp->ap.model].twistRateY) / 4096 + 4096;
|
|
|
|
if (strikeVel < 0x7f001)
|
|
{
|
|
iVar14 = -(iVar10 * 4096) / iVar2;
|
|
if (iVar2 == 0)
|
|
trap(7);
|
|
}
|
|
else
|
|
{
|
|
if (iVar2 == 0)
|
|
trap(7);
|
|
|
|
iVar14 = (strikeVel / iVar2) * 4096;
|
|
}
|
|
|
|
// [A] temporary hack
|
|
cp->st.n.fposition[0] += (collisionResult.penetration * collisionResult.surfNormal.vx) / 512;
|
|
cp->st.n.fposition[2] += (collisionResult.penetration * collisionResult.surfNormal.vz) / 512;
|
|
|
|
iVar14 = iVar14 / 64;
|
|
lVar4 = collisionResult.surfNormal.vx;
|
|
|
|
iVar2 = iVar14 * (lVar4 / 64);
|
|
lVar4 = collisionResult.surfNormal.vy;
|
|
|
|
strikeVel = iVar14 * (lVar4 / 64);
|
|
lVar4 = collisionResult.surfNormal.vz;
|
|
|
|
iVar14 = iVar14 * (lVar4 / 64);
|
|
|
|
if (cp->controlType != 4)
|
|
{
|
|
iVar13 = iVar16 * iVar14;
|
|
iVar10 = iVar13 / 4096;
|
|
if (cp->controlType == 3)
|
|
iVar10 = iVar13 / 8192;
|
|
|
|
iVar10 = cp->hd.aacc[0] + iVar10;
|
|
cp->hd.aacc[0] = iVar10;
|
|
iVar18 = iVar9 * strikeVel;
|
|
iVar13 = iVar18 / 4096;
|
|
|
|
if (cp->controlType == 3)
|
|
iVar13 = iVar18 / 8192;
|
|
|
|
cp->hd.aacc[0] = iVar10 - iVar13;
|
|
}
|
|
|
|
cp->hd.aacc[1] += (iVar9 * iVar2) / 4096 - (iVar17 * iVar14) / 4096;
|
|
|
|
if (cp->controlType != 4)
|
|
{
|
|
iVar10 = iVar17 * strikeVel;
|
|
iVar9 = iVar10 / 4096;
|
|
|
|
if (cp->controlType == 3)
|
|
iVar9 = iVar10 / 8192;
|
|
|
|
iVar9 = cp->hd.aacc[2] + iVar9;
|
|
cp->hd.aacc[2] = iVar9;
|
|
iVar13 = iVar16 * iVar2;
|
|
iVar10 = iVar13 / 4096;
|
|
|
|
if (cp->controlType == 3)
|
|
iVar10 = iVar13 / 8192;
|
|
|
|
cp->hd.aacc[2] = iVar9 - iVar10;
|
|
}
|
|
|
|
cp->st.n.linearVelocity[0] += iVar2;
|
|
|
|
if (cp->controlType != 4)
|
|
cp->st.n.linearVelocity[1] += strikeVel;
|
|
|
|
cp->st.n.linearVelocity[2] += iVar14;
|
|
}
|
|
uVar3 = 1;
|
|
}
|
|
|
|
cp->hd.where.t[0] -= cp->st.n.linearVelocity[0] / 4096;
|
|
cp->hd.where.t[2] -= cp->st.n.linearVelocity[2] / 4096;
|
|
}
|
|
}
|
|
|
|
return uVar3;
|
|
}
|
|
|
|
|
|
|
|
|
|
|