mirror of
https://github.com/OpenDriver2/REDRIVER2.git
synced 2024-11-23 19:02:35 +01:00
d424ae16f7
- fix DrawSmashedCones
1895 lines
40 KiB
C
1895 lines
40 KiB
C
#include "THISDUST.H"
|
|
#include "COP_AI.H"
|
|
#include "CIV_AI.H"
|
|
#include "AI.H"
|
|
#include "MISSION.H"
|
|
#include "SYSTEM.H"
|
|
#include "FELONY.H"
|
|
#include "CARS.H"
|
|
#include "PLAYERS.H"
|
|
#include "PATHFIND.H"
|
|
#include "GAMESND.H"
|
|
#include "CUTSCENE.H"
|
|
#include "CONVERT.H"
|
|
#include "MAP.H"
|
|
#include "CAMERA.H"
|
|
|
|
COP_DATA gCopData = { 0, 0, 0, 2048, 0, 4096, 2048, 3000000, { 0, 0, 0, 0, 0 } };
|
|
|
|
int speed1[] = { 0xCB, 0xD2, 0xD9 };
|
|
int speed2[] = { 0xEE, 0x10A, 0x126 };
|
|
|
|
char sqtbl[] = {
|
|
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
|
|
0x81, 0x81, 0x81, 0x82, 0x82, 0x83, 0x83, 0x83, 0x84,
|
|
0x84, 0x85, 0x86, 0x86, 0x87, 0x88, 0x88, 0x89, 0x8A,
|
|
0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x90, 0x91,
|
|
0x92, 0x93, 0x94, 0x95, 0x96, 0x98, 0x99, 0x9A, 0x9B,
|
|
0x9C, 0x9D, 0x9E, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA6,
|
|
0xA7, 0xA8, 0xAA, 0xAB, 0xAC, 0xAE, 0xAF, 0xB0, 0xB2,
|
|
0xB3, 0xB5 };
|
|
|
|
int CopsCanSeePlayer = 0;
|
|
short pedestrianFelony = 0;
|
|
|
|
int numRoadblockCars = 0;
|
|
int roadblockCount = 0;
|
|
int copsAreInPursuit = 0;
|
|
int requestRoadblock = 0;
|
|
int roadblockDelay = 0xfa;
|
|
int roadblockDelayDiff[3] = { 1500, 1000, 800 };
|
|
int requestCopCar = 0;
|
|
int cop_respawn_timer = 0;
|
|
char first_offence = 0;
|
|
|
|
ROADBLOCK Roadblock;
|
|
VECTOR roadblockLoc;
|
|
|
|
static int said_picked_up = 0;
|
|
|
|
char last_cop_phrase = 0;
|
|
|
|
char CopWorkMem[444]; // PVS table
|
|
COP_SIGHT_DATA copSightData;
|
|
|
|
int player_position_known = 0;
|
|
VECTOR lastKnownPosition;
|
|
VECTOR CarTail;
|
|
_CAR_DATA *targetVehicle;
|
|
|
|
int numActiveCops = 0;
|
|
int pathStraight = 0;
|
|
int LastHeading = 0;
|
|
int OutOfSightCount = 0;
|
|
|
|
|
|
// decompiled code
|
|
// original method signature:
|
|
// void /*$ra*/ InitCopState(struct _CAR_DATA *cp /*$s0*/, char *extraData /*$a1*/)
|
|
// line 577, offset 0x0002f680
|
|
/* begin block 1 */
|
|
// Start line: 2675
|
|
/* end block 1 */
|
|
// End Line: 2676
|
|
|
|
/* begin block 2 */
|
|
// Start line: 1154
|
|
/* end block 2 */
|
|
// End Line: 1155
|
|
|
|
// [D]
|
|
void InitCopState(_CAR_DATA *cp, char *extraData)
|
|
{
|
|
ClearMem((char *)&cp->ai.p, sizeof(COP));
|
|
|
|
cp->controlType = 3;
|
|
cp->controlFlags = 0;
|
|
cp->ai.p.justPinged = 1;
|
|
|
|
if (gCopDifficultyLevel == 1)
|
|
{
|
|
cp->hndType = 3;
|
|
}
|
|
else
|
|
{
|
|
cp->hndType = 4;
|
|
if (gCopDifficultyLevel < 2)
|
|
{
|
|
if (gCopDifficultyLevel != 0)
|
|
{
|
|
cp->hndType = 4;
|
|
return;
|
|
}
|
|
cp->hndType = 2;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// decompiled code
|
|
// original method signature:
|
|
// int /*$ra*/ ReplayLog_Fnarr_He_Said_Log(int val /*$a0*/)
|
|
// line 2973, offset 0x0005c81c
|
|
/* begin block 1 */
|
|
// Start line: 5946
|
|
/* end block 1 */
|
|
// End Line: 5947
|
|
|
|
/* begin block 2 */
|
|
// Start line: 9921
|
|
/* end block 2 */
|
|
// End Line: 9922
|
|
|
|
int ReplayLog_Fnarr_He_Said_Log(int val)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
// decompiled code
|
|
// original method signature:
|
|
// void /*$ra*/ WibbleDownTheRoad(struct VECTOR *from /*$a0*/, int distance /*$s1*/, struct VECTOR *to /*$s5*/)
|
|
// line 593, offset 0x0002d78c
|
|
/* begin block 1 */
|
|
// Start line: 594
|
|
// Start offset: 0x0002D78C
|
|
// Variables:
|
|
// int th; // $s0
|
|
// int j; // $s3
|
|
// int thl[4]; // stack offset -136
|
|
// struct VECTOR pos; // stack offset -120
|
|
// struct VECTOR dir; // stack offset -104
|
|
|
|
/* begin block 1.1 */
|
|
// Start line: 604
|
|
// Start offset: 0x0002D810
|
|
// Variables:
|
|
// struct VECTOR p2; // stack offset -88
|
|
// struct VECTOR d2; // stack offset -72
|
|
// int colour[3]; // stack offset -56
|
|
/* end block 1.1 */
|
|
// End offset: 0x0002D89C
|
|
// End Line: 614
|
|
/* end block 1 */
|
|
// End offset: 0x0002D99C
|
|
// End Line: 639
|
|
|
|
/* begin block 2 */
|
|
// Start line: 1186
|
|
/* end block 2 */
|
|
// End Line: 1187
|
|
|
|
int distanceReturnedLog[8];
|
|
int distLogIndex;
|
|
int lastDistanceFound;
|
|
|
|
// [D]
|
|
void WibbleDownTheRoad(VECTOR *from, int distance, VECTOR *to)
|
|
{
|
|
uint val;
|
|
uint uVar1;
|
|
uint *puVar2;
|
|
int iVar3;
|
|
int thl[4];
|
|
VECTOR pos;
|
|
VECTOR dir;
|
|
|
|
pos.vx = from->vx;
|
|
pos.vy = from->vy;
|
|
pos.vz = from->vz;
|
|
pos.pad = from->pad;
|
|
|
|
iVar3 = 0;
|
|
puVar2 = (uint *)thl;
|
|
do {
|
|
ReplayLog_Fnarr_He_Said_Log(pos.vx);
|
|
ReplayLog_Fnarr_He_Said_Log(pos.vy);
|
|
ReplayLog_Fnarr_He_Said_Log(pos.vz);
|
|
|
|
val = getHeadingToPlayer(pos.vx, pos.vy, pos.vz);
|
|
ReplayLog_Fnarr_He_Said_Log(val);
|
|
|
|
if (iVar3 == 0)
|
|
{
|
|
uVar1 = distLogIndex & 7;
|
|
distLogIndex = distLogIndex + 1;
|
|
distanceReturnedLog[uVar1] = lastDistanceFound;
|
|
}
|
|
|
|
dir.vy = 0;
|
|
dir.vx = FIXED((distance >> 2) * rcossin_tbl[(val & 0xfff) * 2]);
|
|
dir.vz = FIXED((distance >> 2) * rcossin_tbl[(val & 0xfff) * 2 + 1]);
|
|
|
|
*puVar2 = val;
|
|
pos.vx = pos.vx + dir.vx;
|
|
puVar2 = puVar2 + 1;
|
|
pos.vy = pos.vy + dir.vy;
|
|
pos.vz = pos.vz + dir.vz;
|
|
|
|
iVar3++;
|
|
} while (iVar3 < 4);
|
|
|
|
to->vx = pos.vx;
|
|
to->vy = pos.vy;
|
|
to->vz = pos.vz;
|
|
to->pad = pos.pad;
|
|
|
|
if (((thl[3] - thl[0]) + 200U & 0xfff) < 400)
|
|
{
|
|
pathStraight = 1;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// decompiled code
|
|
// original method signature:
|
|
// void /*$ra*/ InitCops()
|
|
// line 643, offset 0x0002d99c
|
|
/* begin block 1 */
|
|
// Start line: 1381
|
|
/* end block 1 */
|
|
// End Line: 1382
|
|
|
|
/* begin block 2 */
|
|
// Start line: 1386
|
|
/* end block 2 */
|
|
// End Line: 1387
|
|
|
|
/* begin block 3 */
|
|
// Start line: 1387
|
|
/* end block 3 */
|
|
// End Line: 1388
|
|
|
|
/* WARNING: Unknown calling convention yet parameter storage is locked */
|
|
|
|
// [D]
|
|
void InitCops(void)
|
|
{
|
|
targetVehicle = &car_data[0];
|
|
requestCopCar = 0;
|
|
|
|
InitFelonySystem();
|
|
InitPathFinding();
|
|
|
|
felonyData.pursuitFelonyScale = 3000;
|
|
|
|
gCopDesiredSpeedScale = 0x1000;
|
|
gCopMaxPowerScale = 0x1000;
|
|
gPuppyDogCop = 0;
|
|
|
|
copsAreInPursuit = 0;
|
|
|
|
player_position_known = 2;
|
|
OutOfSightCount = 0;
|
|
|
|
UpdateCopSightData();
|
|
|
|
gCopData.autoMaxPowerScaleLimit = 0;
|
|
gCopData.autoDesiredSpeedScaleLimit = 0;
|
|
|
|
if (GameType == GAME_GETAWAY)
|
|
{
|
|
gCopRespawnTime = 10000;
|
|
}
|
|
else if (GameType == GAME_SURVIVAL)
|
|
{
|
|
gCopRespawnTime = 0;
|
|
gCopDesiredSpeedScale = 4596;
|
|
gCopMaxPowerScale = 4596;
|
|
gCopData.autoMaxPowerScaleLimit = 1024;
|
|
gCopData.autoDesiredSpeedScaleLimit = 1024;
|
|
}
|
|
else
|
|
{
|
|
gCopRespawnTime = 320;
|
|
|
|
if (gCurrentMissionNumber < 0x28)
|
|
gCopRespawnTime = gCurrentMissionNumber * -4 + 0x140;
|
|
}
|
|
|
|
LastHeading = -1;
|
|
pathStraight = 0;
|
|
numActiveCops = 0;
|
|
|
|
OutOfSightCount = 0;
|
|
cop_respawn_timer = 0;
|
|
CopsCanSeePlayer = 0;
|
|
|
|
CarTail.vx = 0;
|
|
CarTail.vy = 0;
|
|
CarTail.vz = 0;
|
|
|
|
lastKnownPosition.vx = 0x7fffffff;
|
|
lastKnownPosition.vy = 0x7fffffff;
|
|
lastKnownPosition.vz = 0x7fffffff;
|
|
|
|
InitCopData(&gCopData);
|
|
|
|
copsAreInPursuit = 0;
|
|
}
|
|
|
|
|
|
|
|
// decompiled code
|
|
// original method signature:
|
|
// void /*$ra*/ ControlCops()
|
|
// line 708, offset 0x0002dad8
|
|
/* begin block 1 */
|
|
// Start line: 710
|
|
// Start offset: 0x0002DAD8
|
|
|
|
/* begin block 1.1 */
|
|
// Start line: 726
|
|
// Start offset: 0x0002DB34
|
|
// Variables:
|
|
// int playerID; // $v1
|
|
/* end block 1.1 */
|
|
// End offset: 0x0002DB74
|
|
// End Line: 729
|
|
|
|
/* begin block 1.2 */
|
|
// Start line: 749
|
|
// Start offset: 0x0002DC6C
|
|
// Variables:
|
|
// int heading; // $s1
|
|
// int rnd; // $s0
|
|
/* end block 1.2 */
|
|
// End offset: 0x0002DD9C
|
|
// End Line: 774
|
|
|
|
/* begin block 1.3 */
|
|
// Start line: 784
|
|
// Start offset: 0x0002DDFC
|
|
// Variables:
|
|
// int copsWereInPursuit; // $a1
|
|
/* end block 1.3 */
|
|
// End offset: 0x0002DE9C
|
|
// End Line: 798
|
|
|
|
/* begin block 1.4 */
|
|
// Start line: 801
|
|
// Start offset: 0x0002DEAC
|
|
/* end block 1.4 */
|
|
// End offset: 0x0002DEE0
|
|
// End Line: 807
|
|
/* end block 1 */
|
|
// End offset: 0x0002DEE0
|
|
// End Line: 809
|
|
|
|
/* begin block 2 */
|
|
// Start line: 1551
|
|
/* end block 2 */
|
|
// End Line: 1552
|
|
|
|
/* begin block 3 */
|
|
// Start line: 1552
|
|
/* end block 3 */
|
|
// End Line: 1553
|
|
|
|
/* begin block 4 */
|
|
// Start line: 1555
|
|
/* end block 4 */
|
|
// End Line: 1556
|
|
|
|
/* WARNING: Globals starting with '_' overlap smaller symbols at the same address */
|
|
/* WARNING: Unknown calling convention yet parameter storage is locked */
|
|
|
|
// [D]
|
|
void ControlCops(void)
|
|
{
|
|
char cVar1;
|
|
long lVar2;
|
|
long lVar3;
|
|
short *psVar4;
|
|
int direction;
|
|
int iVar5;
|
|
|
|
gCopData.autoBatterPlayerTrigger = 0x800;
|
|
|
|
if (CopsAllowed == 0 || gInGameCutsceneActive != 0)
|
|
{
|
|
player_position_known = 0;
|
|
CopsCanSeePlayer = 0;
|
|
requestCopCar = 0;
|
|
direction = copsAreInPursuit;
|
|
}
|
|
else
|
|
{
|
|
if (-1 < player[0].playerCarId)
|
|
targetVehicle = car_data + player[0].playerCarId;
|
|
|
|
if (0 < player_position_known)
|
|
{
|
|
lastKnownPosition.vx = player[0].pos[0];
|
|
lastKnownPosition.vy = player[0].pos[1];
|
|
lastKnownPosition.vz = player[0].pos[2];
|
|
lastKnownPosition.pad = player[0].pos[3];
|
|
}
|
|
|
|
UpdateCopMap();
|
|
direction = LastHeading;
|
|
|
|
if (first_offence == 0 && CopsCanSeePlayer != 0 && numActiveCops != 0)
|
|
{
|
|
if (player[0].playerCarId < 0)
|
|
{
|
|
psVar4 = &pedestrianFelony;
|
|
}
|
|
else
|
|
{
|
|
psVar4 = &car_data[player[0].playerCarId].felonyRating;
|
|
}
|
|
|
|
if (658 < *psVar4 && 720 < TimeSinceLastSpeech && 20 < targetVehicle->hd.speed)
|
|
{
|
|
cVar1 = GetCarDirectionOfTravel(targetVehicle);
|
|
|
|
direction = cVar1;
|
|
lVar2 = Random2(1);
|
|
|
|
if (direction != LastHeading)
|
|
{
|
|
iVar5 = MaxPlayerDamage[0] * 3;
|
|
|
|
if (iVar5 >> 2 < car_data[player[0].playerCarId].totalDamage)
|
|
{
|
|
lVar3 = lVar2;
|
|
iVar5 = (lVar3 >> 2) * -4;
|
|
}
|
|
else
|
|
{
|
|
iVar5 = (lVar2 / 3) * -3;
|
|
}
|
|
|
|
iVar5 = lVar2 + iVar5;
|
|
|
|
if (first_offence == 0 && last_cop_phrase != iVar5 && (720 < TimeSinceLastSpeech))
|
|
{
|
|
if (iVar5 < 3)
|
|
{
|
|
CopSay(iVar5 + 0xf, direction);
|
|
last_cop_phrase = iVar5;
|
|
}
|
|
else
|
|
{
|
|
CopSay(6, 0);
|
|
last_cop_phrase = iVar5;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
LastHeading = direction;
|
|
|
|
if (player[0].playerCarId < 0)
|
|
psVar4 = &pedestrianFelony;
|
|
else
|
|
psVar4 = &car_data[(int)player[0].playerCarId].felonyRating;
|
|
|
|
if (gCopData.autoBatterPlayerTrigger <= *psVar4)
|
|
gBatterPlayer = 1;
|
|
|
|
ControlCopDetection();
|
|
|
|
AdjustFelony(&felonyData);
|
|
|
|
ControlNumberOfCops();
|
|
|
|
direction = 0;
|
|
|
|
if (0 < player_position_known)
|
|
{
|
|
if (player[0].playerCarId < 0)
|
|
psVar4 = &pedestrianFelony;
|
|
else
|
|
psVar4 = &car_data[(int)player[0].playerCarId].felonyRating;
|
|
|
|
if (0x292 < *psVar4)
|
|
{
|
|
direction = 1;
|
|
}
|
|
}
|
|
|
|
if (direction != 0)
|
|
{
|
|
if (copsAreInPursuit == 0)
|
|
Pads[0].alarmShakeCounter = 12;
|
|
|
|
if ((direction != 0) && (copsAreInPursuit = direction, FunkUpDaBGMTunez(1), direction = copsAreInPursuit, first_offence != 0))
|
|
{
|
|
CopSay(9, 0);
|
|
|
|
first_offence = 0;
|
|
said_picked_up = 1;
|
|
direction = copsAreInPursuit;
|
|
}
|
|
}
|
|
}
|
|
copsAreInPursuit = direction;
|
|
}
|
|
|
|
|
|
|
|
// decompiled code
|
|
// original method signature:
|
|
// void /*$ra*/ CopControl(struct _CAR_DATA *cp /*$s1*/)
|
|
// line 824, offset 0x0002f60c
|
|
/* begin block 1 */
|
|
// Start line: 825
|
|
// Start offset: 0x0002F60C
|
|
/* end block 1 */
|
|
// End offset: 0x0002F680
|
|
// End Line: 842
|
|
|
|
/* begin block 2 */
|
|
// Start line: 2903
|
|
/* end block 2 */
|
|
// End Line: 2904
|
|
|
|
/* begin block 3 */
|
|
// Start line: 1648
|
|
/* end block 3 */
|
|
// End Line: 1649
|
|
|
|
// [D]
|
|
void CopControl(_CAR_DATA *cp)
|
|
{
|
|
CopControl1(cp);
|
|
|
|
CheckPingOut(cp);
|
|
|
|
if (cp->ai.p.dying == 0 && cp->controlType == 0)
|
|
{
|
|
numActiveCops--;
|
|
numCopCars--;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// decompiled code
|
|
// original method signature:
|
|
// void /*$ra*/ CopControl1(struct _CAR_DATA *cp /*$s1*/)
|
|
// line 845, offset 0x0002defc
|
|
/* begin block 1 */
|
|
// Start line: 846
|
|
// Start offset: 0x0002DEFC
|
|
// Variables:
|
|
// int currentSpeed; // $s7
|
|
// int desiredSteerAngle; // $s4
|
|
|
|
/* begin block 1.1 */
|
|
// Start line: 893
|
|
// Start offset: 0x0002DFC4
|
|
// Variables:
|
|
// int dx; // $a1
|
|
// int dz; // $a0
|
|
|
|
/* begin block 1.1.1 */
|
|
// Start line: 897
|
|
// Start offset: 0x0002E018
|
|
/* end block 1.1.1 */
|
|
// End offset: 0x0002E058
|
|
// End Line: 905
|
|
/* end block 1.1 */
|
|
// End offset: 0x0002E058
|
|
// End Line: 906
|
|
|
|
/* begin block 1.2 */
|
|
// Start line: 912
|
|
// Start offset: 0x0002E070
|
|
// Variables:
|
|
// struct VECTOR pos; // stack offset -88
|
|
/* end block 1.2 */
|
|
// End offset: 0x0002E23C
|
|
// End Line: 922
|
|
|
|
/* begin block 1.3 */
|
|
// Start line: 935
|
|
// Start offset: 0x0002E23C
|
|
// Variables:
|
|
// enum AIZone targetZone; // $a0
|
|
// struct VECTOR doordir; // stack offset -72
|
|
// int targetFound; // $a1
|
|
// int cx; // $s5
|
|
// int cz; // $s6
|
|
// int dvx; // $s0
|
|
// int dvz; // $s3
|
|
// int dist; // $s2
|
|
// int framesToImpact; // $a1
|
|
|
|
/* begin block 1.3.1 */
|
|
// Start line: 984
|
|
// Start offset: 0x0002E360
|
|
// Variables:
|
|
// int dz; // $a1
|
|
// int idvx; // $v1
|
|
// int idvz; // $v0
|
|
/* end block 1.3.1 */
|
|
// End offset: 0x0002E360
|
|
// End Line: 984
|
|
|
|
/* begin block 1.3.2 */
|
|
// Start line: 1049
|
|
// Start offset: 0x0002E5E4
|
|
// Variables:
|
|
// struct iVectNT path[2]; // stack offset -56
|
|
// int slidevel; // $a3
|
|
|
|
/* begin block 1.3.2.1 */
|
|
// Start line: 1105
|
|
// Start offset: 0x0002E8E8
|
|
// Variables:
|
|
// int plcrspd; // $a1
|
|
/* end block 1.3.2.1 */
|
|
// End offset: 0x0002E954
|
|
// End Line: 1108
|
|
/* end block 1.3.2 */
|
|
// End offset: 0x0002EA28
|
|
// End Line: 1124
|
|
|
|
/* begin block 1.3.3 */
|
|
// Start line: 1140
|
|
// Start offset: 0x0002EA78
|
|
// Variables:
|
|
// int b; // $a0
|
|
/* end block 1.3.3 */
|
|
// End offset: 0x0002EAC0
|
|
// End Line: 1145
|
|
|
|
/* begin block 1.3.4 */
|
|
// Start line: 1149
|
|
// Start offset: 0x0002EAC0
|
|
// Variables:
|
|
// int steerdif; // $v1
|
|
// int speeddif; // $a2
|
|
// int maxPower; // $a1
|
|
|
|
/* begin block 1.3.4.1 */
|
|
// Start line: 1175
|
|
// Start offset: 0x0002EBB8
|
|
// Variables:
|
|
// int sf; // $v1
|
|
/* end block 1.3.4.1 */
|
|
// End offset: 0x0002EBD0
|
|
// End Line: 1177
|
|
/* end block 1.3.4 */
|
|
// End offset: 0x0002EC64
|
|
// End Line: 1188
|
|
/* end block 1.3 */
|
|
// End offset: 0x0002EC64
|
|
// End Line: 1188
|
|
|
|
/* begin block 1.4 */
|
|
// Start line: 1197
|
|
// Start offset: 0x0002EC84
|
|
/* end block 1.4 */
|
|
// End offset: 0x0002ECAC
|
|
// End Line: 1201
|
|
/* end block 1 */
|
|
// End offset: 0x0002ECAC
|
|
// End Line: 1203
|
|
|
|
/* begin block 2 */
|
|
// Start line: 1831
|
|
/* end block 2 */
|
|
// End Line: 1832
|
|
|
|
void CopControl1(_CAR_DATA *cp)
|
|
{
|
|
UNIMPLEMENTED();
|
|
/*
|
|
byte bVar1;
|
|
short sVar2;
|
|
bool bVar3;
|
|
char cVar4;
|
|
short sVar5;
|
|
int dvx;
|
|
undefined3 extraout_var;
|
|
undefined3 extraout_var_00;
|
|
int iVar6;
|
|
int *piVar7;
|
|
short *psVar8;
|
|
uint uVar9;
|
|
int iVar10;
|
|
undefined2 uVar11;
|
|
int x;
|
|
int dvz;
|
|
int unaff_s4;
|
|
int z;
|
|
uint uVar12;
|
|
VECTOR local_58;
|
|
int local_48;
|
|
int local_44;
|
|
int local_40;
|
|
uint local_30;
|
|
int local_2c;
|
|
|
|
dvx = (cp->hd).wheel_speed;
|
|
cp->wheelspin = '\0';
|
|
uVar12 = dvx + 0x800 >> 0xc;
|
|
if (CopsAllowed == 0) {
|
|
LAB_0002e048:
|
|
cp->thrust = 0;
|
|
cp->handbrake = '\x01';
|
|
return;
|
|
}
|
|
bVar1 = cp->ai[0x13];
|
|
if ((bVar1 != 0) || ((27000 < cp->totalDamage && (gCopData.immortal == 0)))) {
|
|
cp->thrust = 0;
|
|
if (0x55 < bVar1) {
|
|
return;
|
|
}
|
|
if (bVar1 == 0) {
|
|
numActiveCops = numActiveCops + -1;
|
|
}
|
|
cp->ai[0x13] = cp->ai[0x13] + 1;
|
|
return;
|
|
}
|
|
if (DAT_000d7c84 != 0) {
|
|
dvx = (cp->hd).where.t[0];
|
|
dvz = dvx - gStopCops;
|
|
if (dvz < 0) {
|
|
dvz = gStopCops - dvx;
|
|
}
|
|
dvx = (cp->hd).where.t[2];
|
|
x = dvx - DAT_000d7c80;
|
|
if (x < 0) {
|
|
x = DAT_000d7c80 - dvx;
|
|
}
|
|
if ((dvz + x < DAT_000d7c84 * 3 >> 1) &&
|
|
(dvx = SquareRoot0(dvz * dvz + x * x), dvx < DAT_000d7c84)) goto LAB_0002e048;
|
|
}
|
|
if ((CameraCnt & 7U) == 0) {
|
|
local_58.vx = (cp->hd).where.t[0] +
|
|
((int)(cp->hd).where.m[2] * 400 + (int)(cp->hd).where.m[0] * -0x96 + 0x800 >> 0xc)
|
|
;
|
|
local_58.vy = (cp->hd).where.t[1] +
|
|
((int)(cp->hd).where.m[5] * 400 + (int)(cp->hd).where.m[3] * -0x96 + 0x800 >> 0xc)
|
|
;
|
|
local_58.vz = (cp->hd).where.t[2] +
|
|
((int)(cp->hd).where.m[8] * 400 + (int)(cp->hd).where.m[6] * -0x96 + 0x800 >> 0xc)
|
|
;
|
|
cVar4 = CellAtPositionEmpty(&local_58, 0x50);
|
|
sVar5 = (cp->hd).where.m[2];
|
|
sVar2 = (cp->hd).where.m[0];
|
|
*(short *)(cp->ai + 0x22) = (short)CONCAT31(extraout_var, cVar4);
|
|
local_58.vx = (cp->hd).where.t[0] + ((int)sVar5 * 400 + (int)sVar2 * 0x96 + 0x800 >> 0xc);
|
|
local_58.vy = (cp->hd).where.t[1] +
|
|
((int)(cp->hd).where.m[5] * 400 + (int)(cp->hd).where.m[3] * 0x96 + 0x800 >> 0xc);
|
|
local_58.vz = (cp->hd).where.t[2] +
|
|
((int)(cp->hd).where.m[8] * 400 + (int)(cp->hd).where.m[6] * 0x96 + 0x800 >> 0xc);
|
|
cVar4 = CellAtPositionEmpty(&local_58, 0x50);
|
|
*(short *)(cp->ai + 0x24) = (short)CONCAT31(extraout_var_00, cVar4);
|
|
}
|
|
local_48 = (int)(cp->hd).where.m[0];
|
|
x = (cp->hd).where.t[0];
|
|
z = (cp->hd).where.t[2];
|
|
local_40 = (int)(cp->hd).where.m[6];
|
|
local_44 = (int)(cp->hd).where.m[3];
|
|
pathStraight = 0;
|
|
dvx = *(int *)(targetVehicle->st + 0x1c) - *(int *)(cp->st + 0x1c);
|
|
dvz = *(int *)(targetVehicle->st + 0x24) - *(int *)(cp->st + 0x24);
|
|
if (((cp->hd).speed < 6) && (*(short *)(cp->ai + 0x16) != 0)) {
|
|
*(short *)(cp->ai + 0x1a) = *(short *)(cp->ai + 0x1a) + 1;
|
|
}
|
|
else {
|
|
*(undefined2 *)(cp->ai + 0x1a) = 0;
|
|
}
|
|
if ((10 < *(short *)(cp->ai + 0x1a)) && (*(short *)(cp->ai + 0x1e) == 0)) {
|
|
uVar11 = 0xff38;
|
|
*(undefined2 *)(cp->ai + 0x1e) = 0x16;
|
|
uVar9 = (uint)*(ushort *)(cp->ai + 0x1c) & 7;
|
|
*(short *)(cp->ai + 0x1c) = (short)uVar9;
|
|
if (*(short *)(cp->ai + 0x16) < 0) {
|
|
uVar11 = 200;
|
|
}
|
|
unaff_s4 = ((uVar9 * 5 & 6) - 3) * 0x80;
|
|
*(undefined2 *)(cp->ai + 0x16) = uVar11;
|
|
*(undefined2 *)(cp->ai + 0x1a) = 0;
|
|
}
|
|
iVar6 = FindCost(x, z, dvx, dvz);
|
|
*(bool *)(cp->ai + 0x12) = iVar6 < 0xaf0;
|
|
bVar3 = false;
|
|
if (*(short *)(cp->ai + 0x1e) < 1) {
|
|
if (iVar6 < 0x20d0) {
|
|
iVar10 = dvx + 0x800 >> 0xc;
|
|
dvx = dvz + 0x800 >> 0xc;
|
|
dvz = iVar10 * iVar10 + dvx * dvx + 1;
|
|
dvx = ((x - (targetVehicle->hd).where.t[0]) * iVar10 -
|
|
((targetVehicle->hd).where.t[2] - z) * dvx) / dvz;
|
|
if (dvz == 0) {
|
|
trap(7);
|
|
}
|
|
if (gBatterPlayer == 0) {
|
|
dvz = dvx * 3;
|
|
dvx = dvz >> 2;
|
|
if (dvz < 0) {
|
|
dvx = dvz + 3 >> 2;
|
|
}
|
|
}
|
|
if (dvx < 0) {
|
|
dvx = 0;
|
|
}
|
|
else {
|
|
if (0x3c < dvx) {
|
|
dvx = 0x3c;
|
|
}
|
|
}
|
|
dvz = (targetVehicle->hd).where.t[0] +
|
|
(*(int *)(targetVehicle->st + 0x1c) * dvx + 0x800 >> 0xc);
|
|
dvx = (targetVehicle->hd).where.t[2] +
|
|
(*(int *)(targetVehicle->st + 0x24) * dvx + 0x800 >> 0xc);
|
|
if (gBatterPlayer == 0) {
|
|
iVar10 = (int)(targetVehicle->hd).where.m[2] * 5;
|
|
if (iVar10 < 0) {
|
|
iVar10 = iVar10 + 0x7f;
|
|
}
|
|
CarTail.vx = dvz - (iVar10 >> 7);
|
|
dvz = (int)(targetVehicle->hd).where.m[8] * 5;
|
|
if (dvz < 0) {
|
|
dvz = dvz + 0x7f;
|
|
}
|
|
CarTail.vz = dvx - (dvz >> 7);
|
|
}
|
|
else {
|
|
iVar10 = (int)(targetVehicle->hd).where.m[0] * 5;
|
|
if (iVar10 < 0) {
|
|
iVar10 = iVar10 + 0xff;
|
|
}
|
|
CarTail.vx = dvz + (iVar10 >> 8);
|
|
dvz = (int)(targetVehicle->hd).where.m[6] * 5;
|
|
if (dvz < 0) {
|
|
dvz = dvz + 0xff;
|
|
}
|
|
CarTail.vz = dvx + (dvz >> 8);
|
|
}
|
|
}
|
|
else {
|
|
CarTail.vx = (targetVehicle->hd).where.t[0];
|
|
CarTail.vz = (targetVehicle->hd).where.t[2];
|
|
}
|
|
if (cp->ai[0x12] == 0) {
|
|
WibbleDownTheRoad((VECTOR *)(cp->hd).where.t, (cp->hd).speed * 10 + 0x2a8, &targetPoint);
|
|
}
|
|
else {
|
|
targetPoint.vx = CarTail.vx;
|
|
targetPoint.vz = CarTail.vz;
|
|
}
|
|
bVar3 = true;
|
|
*(undefined4 *)(cp->ai + 8) = *(undefined4 *)cp->ai;
|
|
*(undefined4 *)(cp->ai + 0xc) = *(undefined4 *)(cp->ai + 4);
|
|
*(long *)cp->ai = targetPoint.vx;
|
|
*(long *)(cp->ai + 4) = targetPoint.vz;
|
|
}
|
|
else {
|
|
*(short *)(cp->ai + 0x1e) = *(short *)(cp->ai + 0x1e) + -1;
|
|
}
|
|
if (gTimeInWater == 0) {
|
|
bVar3 = false;
|
|
}
|
|
if (bVar3) {
|
|
dvz = local_48 * *(int *)(cp->st + 0x1c) + local_40 * *(int *)(cp->st + 0x24) + 0x800 >> 0xc;
|
|
local_2c = (x - targetPoint.vx) * local_40 + (targetPoint.vz - z) * local_48 >> 0xc;
|
|
dvx = ((targetPoint.vx - x) * local_48 + (targetPoint.vz - z) * local_40 >> 0xc) - dvz / 0x8c;
|
|
if (dvx < 1) {
|
|
if ((dvx * -2 < local_2c) && (*(short *)(cp->ai + 0x22) != 0)) goto LAB_0002e728;
|
|
uVar9 = 2;
|
|
bVar3 = -dvx < local_2c << 2;
|
|
LAB_0002e708:
|
|
if ((bVar3) && (cp->ai[0x12] != 0)) {
|
|
uVar9 = 1;
|
|
}
|
|
}
|
|
else {
|
|
if ((local_2c <= dvx * 2) || (*(short *)(cp->ai + 0x24) == 0)) {
|
|
uVar9 = 3;
|
|
bVar3 = dvx < local_2c << 2;
|
|
goto LAB_0002e708;
|
|
}
|
|
LAB_0002e728:
|
|
uVar9 = 0;
|
|
}
|
|
local_30 = dvx + dvz / 0x8c;
|
|
if (uVar9 == 1) {
|
|
*(undefined2 *)(cp->ai + 0x16) = 0xffba;
|
|
unaff_s4 = 0x11c;
|
|
if ((int)(local_30 ^ uVar12) < 0) {
|
|
unaff_s4 = -0x11c;
|
|
}
|
|
}
|
|
else {
|
|
if (uVar9 < 2) {
|
|
if (uVar9 == 0) {
|
|
if (pathStraight == 0) {
|
|
piVar7 = &speed1;
|
|
}
|
|
else {
|
|
piVar7 = &speed2;
|
|
}
|
|
*(undefined2 *)(cp->ai + 0x16) = *(undefined2 *)(piVar7 + gCopDifficultyLevel);
|
|
if (gCopData.cutOffDistance < (int)(uint)*(ushort *)(cp->ai + 0x14)) {
|
|
sVar5 = *(short *)(cp->ai + 0x16);
|
|
if ((int)player.playerCarId < 0) {
|
|
psVar8 = &pedestrianFelony;
|
|
}
|
|
else {
|
|
psVar8 = &car_data[(int)player.playerCarId].felonyRating;
|
|
}
|
|
sVar2 = *psVar8;
|
|
dvx = gCopData.cutOffPowerScale;
|
|
}
|
|
else {
|
|
sVar5 = *(short *)(cp->ai + 0x16);
|
|
if ((int)player.playerCarId < 0) {
|
|
psVar8 = &pedestrianFelony;
|
|
}
|
|
else {
|
|
psVar8 = &car_data[(int)player.playerCarId].felonyRating;
|
|
}
|
|
sVar2 = *psVar8;
|
|
dvx = gCopDesiredSpeedScale;
|
|
}
|
|
*(short *)(cp->ai + 0x16) =
|
|
(short)((int)sVar5 * (dvx + (sVar2 * gCopData.autoDesiredSpeedScaleLimit >> 0xc)) >>
|
|
0xc);
|
|
if ((gPuppyDogCop != 0) && (cp->ai[0x12] != 0)) {
|
|
dvx = (targetVehicle->hd).speed + 10;
|
|
if (iVar6 < 0xfa1) {
|
|
*(short *)(cp->ai + 0x16) = *(short *)&(targetVehicle->hd).speed + 10;
|
|
}
|
|
else {
|
|
dvz = (*(short *)(cp->ai + 0x16) - dvx) * (iVar6 + -4000);
|
|
*(short *)(cp->ai + 0x16) =
|
|
(short)dvx +
|
|
((short)((ulonglong)((longlong)dvz * 0x10624dd3) >> 0x28) - (short)(dvz >> 0x1f))
|
|
;
|
|
}
|
|
}
|
|
unaff_s4 = (int)(local_30 * 0x200) / local_2c;
|
|
if (local_2c == 0) {
|
|
trap(7);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if (uVar9 < 4) {
|
|
*(undefined2 *)(cp->ai + 0x16) = 0x6e;
|
|
if ((*(short *)(cp->ai + 0x22) == 0) || (*(short *)(cp->ai + 0x24) == 0)) {
|
|
*(undefined2 *)(cp->ai + 0x16) = 0xff88;
|
|
}
|
|
else {
|
|
if (((uVar9 == 2) && (-0x82 < *(int *)(cp->st + 0x2c))) ||
|
|
((uVar9 == 3 && (*(int *)(cp->st + 0x2c) < 0x82)))) {
|
|
cp->wheelspin = '\x01';
|
|
}
|
|
}
|
|
unaff_s4 = 0x200;
|
|
if ((int)(local_30 ^ uVar12) < 0) {
|
|
unaff_s4 = -0x200;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if (*(short *)(cp->ai + 0x1e) < 1) {
|
|
*(undefined2 *)(cp->ai + 0x16) = 0;
|
|
unaff_s4 = 0;
|
|
}
|
|
}
|
|
if (((iVar6 < 0x1000) && (0 < (int)*(short *)(cp->ai + 0x16))) && (gBatterPlayer == 0)) {
|
|
dvx = (targetVehicle->hd).speed + -0x14;
|
|
if (dvx < 0x14) {
|
|
dvx = 0x14;
|
|
}
|
|
*(short *)(cp->ai + 0x16) =
|
|
(short)(iVar6 * (int)*(short *)(cp->ai + 0x16) + (0x1000 - iVar6) * dvx + 0x800 >> 0xc);
|
|
}
|
|
dvx = (gCopDifficultyLevel + 8) * 0x400;
|
|
dvz = (int)*(short *)(cp->ai + 0x16) - uVar12;
|
|
if (pathStraight != 0) {
|
|
dvx = dvx + (gCopDifficultyLevel + 4) * 0x400;
|
|
}
|
|
if ((int)player.playerCarId < 0) {
|
|
psVar8 = &pedestrianFelony;
|
|
}
|
|
else {
|
|
psVar8 = &car_data[(int)player.playerCarId].felonyRating;
|
|
}
|
|
dvx = dvx * (gCopMaxPowerScale + (*psVar8 * gCopData.autoMaxPowerScaleLimit >> 0xc)) >> 0xc;
|
|
sVar5 = (short)dvx;
|
|
if (dvz < -0x32) {
|
|
sVar5 = -sVar5;
|
|
}
|
|
else {
|
|
if (0x32 < dvz) {
|
|
cp->thrust = sVar5;
|
|
goto LAB_0002eba4;
|
|
}
|
|
sVar5 = (short)((dvz * dvx) / 0x32);
|
|
}
|
|
cp->thrust = sVar5;
|
|
LAB_0002eba4:
|
|
dvx = (cp->hd).speed;
|
|
if (dvx < 0x30) {
|
|
cp->thrust = (short)((int)cp->thrust * (dvx + 0x50) >> 7);
|
|
}
|
|
if (handlingType[cp->hndType].fourWheelDrive == '\x01') {
|
|
cp->thrust = cp->thrust >> 1;
|
|
}
|
|
cp->thrust = (short)(((int)cp->thrust * 7) / 10);
|
|
dvx = ((unaff_s4 + 0x800U & 0xfff) - 0x800) - (int)cp->wheel_angle;
|
|
sVar5 = (short)dvx;
|
|
if (dvx < -200) {
|
|
sVar5 = -200;
|
|
}
|
|
else {
|
|
if (200 < dvx) {
|
|
sVar5 = 200;
|
|
}
|
|
}
|
|
bVar1 = cp->ai[0x11];
|
|
cp->wheel_angle = cp->wheel_angle + sVar5;
|
|
if (bVar1 == 1) {
|
|
dvx = getHeadingToPlayer((cp->hd).where.t[0], (cp->hd).where.t[1], (cp->hd).where.t[2]);
|
|
(cp->hd).direction = dvx;
|
|
TempBuildHandlingMatrix(cp, 0);
|
|
cp->ai[0x11] = 0;
|
|
}
|
|
return;*/
|
|
}
|
|
|
|
|
|
|
|
// decompiled code
|
|
// original method signature:
|
|
// int /*$ra*/ FindCost(int x /*$a0*/, int z /*$a1*/, int dvx /*$a2*/, int dvz /*$a3*/)
|
|
// line 1231, offset 0x0002f8dc
|
|
/* begin block 1 */
|
|
// Start line: 1232
|
|
// Start offset: 0x0002F8DC
|
|
// Variables:
|
|
// int tx; // $v0
|
|
// int tz; // $v0
|
|
// int dx; // $a2
|
|
// int dz; // $v1
|
|
// int d; // $v0
|
|
/* end block 1 */
|
|
// End offset: 0x0002F994
|
|
// End Line: 1244
|
|
|
|
/* begin block 2 */
|
|
// Start line: 2048
|
|
/* end block 2 */
|
|
// End Line: 2049
|
|
|
|
/* begin block 3 */
|
|
// Start line: 4800
|
|
/* end block 3 */
|
|
// End Line: 4801
|
|
|
|
/* begin block 4 */
|
|
// Start line: 4802
|
|
/* end block 4 */
|
|
// End Line: 4803
|
|
|
|
// [D]
|
|
int FindCost(int x, int z, int dvx, int dvz)
|
|
{
|
|
int iVar1;
|
|
|
|
x = x - (targetVehicle->hd.where.t[0] + (dvx >> 8));
|
|
|
|
if (x < 0)
|
|
x = -x;
|
|
|
|
z = z - (targetVehicle->hd.where.t[2] + (dvz >> 8));
|
|
|
|
if (z < 0)
|
|
z = -z;
|
|
|
|
iVar1 = z;
|
|
|
|
if (x < z)
|
|
{
|
|
iVar1 = x;
|
|
x = z;
|
|
}
|
|
|
|
if (x != 0)
|
|
{
|
|
x = x * sqtbl[(iVar1 << 6) / x];
|
|
|
|
return x >> 7;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
// decompiled code
|
|
// original method signature:
|
|
// void /*$ra*/ InitCopData(struct COP_DATA *pCopData /*$a0*/)
|
|
// line 1267, offset 0x0002f7f8
|
|
/* begin block 1 */
|
|
// Start line: 1268
|
|
// Start offset: 0x0002F7F8
|
|
// Variables:
|
|
// short *pTrigger; // $v1
|
|
// short trigger; // $a2
|
|
/* end block 1 */
|
|
// End offset: 0x0002F844
|
|
// End Line: 1281
|
|
|
|
/* begin block 2 */
|
|
// Start line: 4374
|
|
/* end block 2 */
|
|
// End Line: 4375
|
|
|
|
/* begin block 3 */
|
|
// Start line: 2534
|
|
/* end block 3 */
|
|
// End Line: 2535
|
|
|
|
/* begin block 4 */
|
|
// Start line: 4378
|
|
/* end block 4 */
|
|
// End Line: 4379
|
|
|
|
// [D]
|
|
void InitCopData(COP_DATA *pCopData)
|
|
{
|
|
short *psVar1;
|
|
int iVar2;
|
|
int iVar3;
|
|
|
|
psVar1 = pCopData->trigger;
|
|
iVar3 = 0;
|
|
|
|
if (psVar1 < pCopData->trigger + 4)
|
|
{
|
|
iVar2 = 0x3330000;
|
|
do {
|
|
*psVar1 = iVar3;
|
|
iVar3 = iVar2 >> 0x10;
|
|
psVar1++;
|
|
iVar2 += 0x3330000;
|
|
} while (psVar1 < pCopData->trigger + 4);
|
|
}
|
|
|
|
*psVar1 = 0x7fff;
|
|
said_picked_up = 0;
|
|
}
|
|
|
|
|
|
|
|
// decompiled code
|
|
// original method signature:
|
|
// void /*$ra*/ UpdateCopSightData()
|
|
// line 1308, offset 0x0002f844
|
|
/* begin block 1 */
|
|
// Start line: 1310
|
|
// Start offset: 0x0002F844
|
|
// Variables:
|
|
// int angry; // $v1
|
|
/* end block 1 */
|
|
// End offset: 0x0002F8DC
|
|
// End Line: 1314
|
|
|
|
/* begin block 2 */
|
|
// Start line: 4431
|
|
/* end block 2 */
|
|
// End Line: 4432
|
|
|
|
/* begin block 3 */
|
|
// Start line: 4459
|
|
/* end block 3 */
|
|
// End Line: 4460
|
|
|
|
/* begin block 4 */
|
|
// Start line: 4460
|
|
/* end block 4 */
|
|
// End Line: 4461
|
|
|
|
/* WARNING: Unknown calling convention yet parameter storage is locked */
|
|
|
|
// [D]
|
|
void UpdateCopSightData(void)
|
|
{
|
|
short *psVar1;
|
|
|
|
if (player[0].playerCarId < 0)
|
|
psVar1 = &pedestrianFelony;
|
|
else
|
|
psVar1 = &car_data[player[0].playerCarId].felonyRating;
|
|
|
|
if (*psVar1 < 0x293)
|
|
{
|
|
copSightData.surroundViewDistance = 0xaa0;
|
|
copSightData.frontViewDistance = 0x1e8c;
|
|
copSightData.frontViewAngle = 0x200;
|
|
return;
|
|
}
|
|
|
|
copSightData.surroundViewDistance = 0x1540;
|
|
copSightData.frontViewDistance = 0x3fc0;
|
|
copSightData.frontViewAngle = 0x400;
|
|
}
|
|
|
|
|
|
|
|
// decompiled code
|
|
// original method signature:
|
|
// void /*$ra*/ ControlCopDetection()
|
|
// line 1368, offset 0x0002ecd8
|
|
/* begin block 1 */
|
|
// Start line: 1382
|
|
// Start offset: 0x0002ECD8
|
|
// Variables:
|
|
// int dx; // $v1
|
|
// int dz; // $a0
|
|
// struct VECTOR vec; // stack offset -64
|
|
// int ccx; // stack offset -32
|
|
// int ccz; // stack offset -28
|
|
// char *scratch; // $s4
|
|
// struct _CAR_DATA *lcp; // $s1
|
|
|
|
/* begin block 1.1 */
|
|
// Start line: 1385
|
|
// Start offset: 0x0002ECD8
|
|
|
|
/* begin block 1.1.1 */
|
|
// Start line: 1385
|
|
// Start offset: 0x0002ECD8
|
|
// Variables:
|
|
// int angry; // $v1
|
|
/* end block 1.1.1 */
|
|
// End offset: 0x0002EDA8
|
|
// End Line: 1391
|
|
/* end block 1.1 */
|
|
// End offset: 0x0002EDA8
|
|
// End Line: 1391
|
|
|
|
/* begin block 1.2 */
|
|
// Start line: 1416
|
|
// Start offset: 0x0002EDFC
|
|
// Variables:
|
|
// int dx; // $v1
|
|
// int dz; // $v0
|
|
/* end block 1.2 */
|
|
// End offset: 0x0002EE7C
|
|
// End Line: 1426
|
|
|
|
/* begin block 1.3 */
|
|
// Start line: 1434
|
|
// Start offset: 0x0002EED0
|
|
// Variables:
|
|
// int distanceToPlayer; // $s0
|
|
// int active; // $s2
|
|
|
|
/* begin block 1.3.1 */
|
|
// Start line: 1369
|
|
// Start offset: 0x0002EF70
|
|
// Variables:
|
|
// struct _CAR_DATA *cp; // $s1
|
|
// int distanceToPlayer; // $s0
|
|
|
|
/* begin block 1.3.1.1 */
|
|
// Start line: 1369
|
|
// Start offset: 0x0002EF70
|
|
// Variables:
|
|
// int farDist; // $v1
|
|
// int nearDist; // $v0
|
|
// char result; // $s2
|
|
|
|
/* begin block 1.3.1.1.1 */
|
|
// Start line: 1369
|
|
// Start offset: 0x0002EF90
|
|
// Variables:
|
|
// int theta; // $v1
|
|
// struct VECTOR delta; // stack offset -48
|
|
|
|
/* begin block 1.3.1.1.1.1 */
|
|
// Start line: 1369
|
|
// Start offset: 0x0002F030
|
|
/* end block 1.3.1.1.1.1 */
|
|
// End offset: 0x0002F034
|
|
// End Line: 1369
|
|
/* end block 1.3.1.1.1 */
|
|
// End offset: 0x0002F034
|
|
// End Line: 1369
|
|
/* end block 1.3.1.1 */
|
|
// End offset: 0x0002F034
|
|
// End Line: 1369
|
|
/* end block 1.3.1 */
|
|
// End offset: 0x0002F034
|
|
// End Line: 1369
|
|
/* end block 1.3 */
|
|
// End offset: 0x0002F050
|
|
// End Line: 1452
|
|
|
|
/* begin block 1.4 */
|
|
// Start line: 1478
|
|
// Start offset: 0x0002F164
|
|
/* end block 1.4 */
|
|
// End offset: 0x0002F164
|
|
// End Line: 1478
|
|
|
|
/* begin block 1.5 */
|
|
// Start line: 1491
|
|
// Start offset: 0x0002F190
|
|
|
|
/* begin block 1.5.1 */
|
|
// Start line: 1498
|
|
// Start offset: 0x0002F1B8
|
|
/* end block 1.5.1 */
|
|
// End offset: 0x0002F228
|
|
// End Line: 1518
|
|
/* end block 1.5 */
|
|
// End offset: 0x0002F238
|
|
// End Line: 1520
|
|
|
|
/* begin block 1.6 */
|
|
// Start line: 1525
|
|
// Start offset: 0x0002F25C
|
|
// Variables:
|
|
// int rnd; // $s0
|
|
// int dir; // $s1
|
|
/* end block 1.6 */
|
|
// End offset: 0x0002F2C8
|
|
// End Line: 1529
|
|
|
|
/* begin block 1.7 */
|
|
// Start line: 1534
|
|
// Start offset: 0x0002F2FC
|
|
// Variables:
|
|
// int rnd; // $s0
|
|
// int dir; // $s1
|
|
/* end block 1.7 */
|
|
// End offset: 0x0002F394
|
|
// End Line: 1536
|
|
/* end block 1 */
|
|
// End offset: 0x0002F3CC
|
|
// End Line: 1542
|
|
|
|
/* begin block 2 */
|
|
// Start line: 3020
|
|
/* end block 2 */
|
|
// End Line: 3021
|
|
|
|
/* begin block 3 */
|
|
// Start line: 3033
|
|
/* end block 3 */
|
|
// End Line: 3034
|
|
|
|
/* begin block 4 */
|
|
// Start line: 3036
|
|
/* end block 4 */
|
|
// End Line: 3037
|
|
|
|
/* begin block 5 */
|
|
// Start line: 3042
|
|
/* end block 5 */
|
|
// End Line: 3043
|
|
|
|
/* WARNING: Unknown calling convention yet parameter storage is locked */
|
|
|
|
// [D]
|
|
void ControlCopDetection(void)
|
|
{
|
|
unsigned char uVar1;
|
|
bool bVar2;
|
|
char cVar3;
|
|
short sVar4;
|
|
int y;
|
|
short *psVar5;
|
|
long lVar6;
|
|
|
|
int x;
|
|
int iVar7;
|
|
_CAR_DATA *cp;
|
|
VECTOR vec;
|
|
VECTOR delta;
|
|
int ccx;
|
|
int ccz;
|
|
|
|
vec.vx = player[0].pos[0];
|
|
vec.vz = player[0].pos[2];
|
|
|
|
GetVisSetAtPosition(&vec, CopWorkMem, &ccx, &ccz);
|
|
|
|
if (player[0].playerCarId < 0)
|
|
psVar5 = &pedestrianFelony;
|
|
else
|
|
psVar5 = &car_data[player[0].playerCarId].felonyRating;
|
|
|
|
bVar2 = 0x292 < *psVar5;
|
|
|
|
copSightData.surroundViewDistance = 0xaa0;
|
|
|
|
if (bVar2)
|
|
copSightData.surroundViewDistance = 0x1540;
|
|
|
|
copSightData.frontViewDistance = 0x1e8c;
|
|
|
|
if (bVar2)
|
|
copSightData.frontViewDistance = 0x3fc0;
|
|
|
|
copSightData.frontViewAngle = 0x200;
|
|
|
|
if (bVar2)
|
|
copSightData.frontViewAngle = 0x400;
|
|
|
|
|
|
bVar2 = player_position_known < 1;
|
|
player_position_known = 2;
|
|
|
|
if (bVar2)
|
|
player_position_known = 1;
|
|
|
|
CopsCanSeePlayer = 0;
|
|
|
|
if (player[0].playerType != 2 && -1 < player[0].playerCarId)
|
|
{
|
|
if (numRoadblockCars != 0)
|
|
{
|
|
x = roadblockLoc.vx - player[0].pos[0];
|
|
if (x < 0)
|
|
x = -x;
|
|
|
|
y = roadblockLoc.vz - player[0].pos[2];
|
|
if (y < 0)
|
|
y = -y;
|
|
|
|
if (((x >> 8) * (x >> 8) + (y >> 8) * (y >> 8) < 0x668) && newPositionVisible(&roadblockLoc, CopWorkMem, ccx, ccz) != 0)
|
|
CopsCanSeePlayer = 1;
|
|
}
|
|
|
|
if (CopsCanSeePlayer == 0)
|
|
{
|
|
cp = &car_data[19];
|
|
|
|
while (car_data <= cp)
|
|
{
|
|
uVar1 = cp->controlType;
|
|
|
|
if (uVar1 == 3)
|
|
{
|
|
if (cp->ai.p.dying == 0)
|
|
goto LAB_0002eed0;
|
|
}
|
|
else
|
|
{
|
|
if ((cp->controlFlags & 1) != 0)
|
|
{
|
|
LAB_0002eed0:
|
|
vec.vx = (cp->hd).where.t[0];
|
|
vec.vz = (cp->hd).where.t[2];
|
|
y = (cp->hd).where.t[0];
|
|
x = y - player[0].pos[0];
|
|
|
|
if (x < 0)
|
|
x = player[0].pos[0] - y;
|
|
|
|
iVar7 = (cp->hd).where.t[2];
|
|
y = iVar7 - player[0].pos[2];
|
|
|
|
if (y < 0)
|
|
y = player[0].pos[2] - iVar7;
|
|
|
|
lVar6 = SquareRoot0(x * x + y * y);
|
|
|
|
if ((uVar1 == 3) && (cp->ai.p.DistanceToPlayer = lVar6, cp->ai.p.close_pursuit != 0))
|
|
{
|
|
LAB_0002f040:
|
|
CopsCanSeePlayer = 1;
|
|
break;
|
|
}
|
|
|
|
if (newPositionVisible(&vec, CopWorkMem, ccx, ccz) != 0)
|
|
{
|
|
if (lVar6 < copSightData.surroundViewDistance)
|
|
{
|
|
LAB_0002f030:
|
|
bVar2 = true;
|
|
}
|
|
else
|
|
{
|
|
bVar2 = false;
|
|
if (lVar6 < copSightData.frontViewDistance)
|
|
{
|
|
y = (targetVehicle->hd).where.t[0] - (cp->hd).where.t[0];
|
|
x = (targetVehicle->hd).where.t[2] -(cp->hd).where.t[2];
|
|
|
|
lVar6 = ratan2(y, x);
|
|
|
|
if (lVar6 - (cp->hd).direction < 0)
|
|
{
|
|
lVar6 = ratan2(y, x);
|
|
x = (cp->hd).direction - lVar6;
|
|
}
|
|
else
|
|
{
|
|
lVar6 = ratan2(y, x);
|
|
x = lVar6 - (cp->hd).direction;
|
|
}
|
|
|
|
if ((x < copSightData.frontViewAngle) || (bVar2 = false, x < copSightData.frontViewAngle + 0x200))
|
|
goto LAB_0002f030;
|
|
}
|
|
}
|
|
if (bVar2)
|
|
goto LAB_0002f040;
|
|
}
|
|
}
|
|
}
|
|
cp = cp + -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (numActiveCops == 0 && OutOfSightCount < 0x100 && 8 < CameraCnt)
|
|
{
|
|
OutOfSightCount = 0x100;
|
|
}
|
|
|
|
if (CopsCanSeePlayer == 0)
|
|
{
|
|
x = OutOfSightCount + 1;
|
|
|
|
if (0xff < OutOfSightCount)
|
|
{
|
|
if (OutOfSightCount == 0x100)
|
|
{
|
|
player_position_known = -1;
|
|
OutOfSightCount = 0x101;
|
|
|
|
if (player[0].playerCarId < 0)
|
|
psVar5 = &pedestrianFelony;
|
|
else
|
|
psVar5 = &car_data[player[0].playerCarId].felonyRating;
|
|
|
|
x = OutOfSightCount;
|
|
|
|
if ((0x292 < *psVar5) && (first_offence == '\0'))
|
|
{
|
|
CopSay(0xc, 0);
|
|
FunkUpDaBGMTunez(0);
|
|
|
|
x = OutOfSightCount;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
player_position_known = 0;
|
|
x = OutOfSightCount;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
OutOfSightCount = 0;
|
|
x = OutOfSightCount;
|
|
}
|
|
|
|
OutOfSightCount = x;
|
|
|
|
if (player_position_known < 1)
|
|
{
|
|
cp = &car_data[19];
|
|
|
|
do {
|
|
if (cp->controlType == 3)
|
|
{
|
|
vec.vx = (cp->hd).where.t[0];
|
|
vec.vz = (cp->hd).where.t[2];
|
|
|
|
// make cop lose target if target is hidden
|
|
if (newPositionVisible(&vec, CopWorkMem, ccx, ccz) == 0 && cp->ai.p.hiddenTimer++ > 0x32)
|
|
{
|
|
cp->controlType = 0;
|
|
cp->ai.p.hiddenTimer = 0;
|
|
cp->thrust = 0;
|
|
numCopCars--;
|
|
}
|
|
}
|
|
|
|
cp--;
|
|
} while (car_data <= cp);
|
|
}
|
|
|
|
x = player_position_known;
|
|
|
|
if ((player_position_known == 1) && (first_offence == 0))
|
|
{
|
|
lVar6 = Random2(2);
|
|
cVar3 = GetCarDirectionOfTravel(car_data + player[0].playerCarId);
|
|
|
|
CopSay(lVar6 % 2 + 10, cVar3);
|
|
|
|
said_picked_up = x;
|
|
|
|
LastHeading = cVar3;
|
|
}
|
|
|
|
if (CopsCanSeePlayer == 0)
|
|
said_picked_up = 0;
|
|
|
|
else if ((first_offence == 0) && (said_picked_up == 0))
|
|
{
|
|
lVar6 = Random2(2);
|
|
|
|
x = GetCarDirectionOfTravel(&car_data[player[0].playerCarId]);
|
|
|
|
if ((lVar6 == (lVar6 / 5) * 5) && (x != LastHeading))
|
|
CopSay(lVar6 % 2 + 10, x);
|
|
|
|
said_picked_up = 1;
|
|
LastHeading = x;
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
// decompiled code
|
|
// original method signature:
|
|
// void /*$ra*/ PassiveCopTasks(struct _CAR_DATA *cp /*$s0*/)
|
|
// line 1562, offset 0x0002f6fc
|
|
/* begin block 1 */
|
|
// Start line: 1563
|
|
// Start offset: 0x0002F6FC
|
|
|
|
/* begin block 1.1 */
|
|
// Start line: 1563
|
|
// Start offset: 0x0002F76C
|
|
// Variables:
|
|
// struct _CAR_DATA *cp; // $s0
|
|
/* end block 1.1 */
|
|
// End offset: 0x0002F7C4
|
|
// End Line: 1563
|
|
/* end block 1 */
|
|
// End offset: 0x0002F7F8
|
|
// End Line: 1576
|
|
|
|
/* begin block 2 */
|
|
// Start line: 4648
|
|
/* end block 2 */
|
|
// End Line: 4649
|
|
|
|
/* begin block 3 */
|
|
// Start line: 4654
|
|
/* end block 3 */
|
|
// End Line: 4655
|
|
|
|
// [D]
|
|
void PassiveCopTasks(_CAR_DATA *cp)
|
|
{
|
|
short *psVar2;
|
|
|
|
if (player[0].playerCarId < 0)
|
|
psVar2 = &pedestrianFelony;
|
|
else
|
|
psVar2 = &car_data[player[0].playerCarId].felonyRating;
|
|
|
|
if (*psVar2 < 0x293)
|
|
return;
|
|
|
|
if (player_position_known < 1)
|
|
return;
|
|
|
|
ClearMem((char *)&cp->ai.p, sizeof(COP));
|
|
|
|
cp->controlType = 3;
|
|
cp->controlFlags = 0;
|
|
|
|
cp->ai.p.justPinged = 1;
|
|
|
|
if (gCopDifficultyLevel == 1)
|
|
{
|
|
cp->hndType = 3;
|
|
}
|
|
else
|
|
{
|
|
cp->hndType = 4;
|
|
|
|
if (gCopDifficultyLevel < 2)
|
|
{
|
|
if (gCopDifficultyLevel != 0)
|
|
{
|
|
cp->hndType = 4;
|
|
goto LAB_0002f7c4;
|
|
}
|
|
cp->hndType = 2;
|
|
}
|
|
}
|
|
|
|
LAB_0002f7c4:
|
|
cp->ai.p.justPinged = 0;
|
|
numCivCars--;
|
|
numActiveCops++;
|
|
}
|
|
|
|
|
|
|
|
// decompiled code
|
|
// original method signature:
|
|
// void /*$ra*/ ControlNumberOfCops()
|
|
// line 1583, offset 0x0002f3cc
|
|
/* begin block 1 */
|
|
// Start line: 1585
|
|
// Start offset: 0x0002F3CC
|
|
// Variables:
|
|
// int numWantedCops; // $t2
|
|
|
|
/* begin block 1.1 */
|
|
// Start line: 1588
|
|
// Start offset: 0x0002F3CC
|
|
// Variables:
|
|
// short *pTrigger; // $a2
|
|
/* end block 1.1 */
|
|
// End offset: 0x0002F454
|
|
// End Line: 1596
|
|
|
|
/* begin block 1.2 */
|
|
// Start line: 1609
|
|
// Start offset: 0x0002F4A0
|
|
// Variables:
|
|
// int temp; // $a1
|
|
/* end block 1.2 */
|
|
// End offset: 0x0002F54C
|
|
// End Line: 1624
|
|
|
|
/* begin block 1.3 */
|
|
// Start line: 1633
|
|
// Start offset: 0x0002F570
|
|
// Variables:
|
|
// int num_closer; // $a2
|
|
// int cutOffDistance; // $a1
|
|
|
|
/* begin block 1.3.1 */
|
|
// Start line: 1638
|
|
// Start offset: 0x0002F580
|
|
// Variables:
|
|
// struct _CAR_DATA *lcp; // $a0
|
|
// int tempDist; // $a3
|
|
|
|
/* begin block 1.3.1.1 */
|
|
// Start line: 1647
|
|
// Start offset: 0x0002F5AC
|
|
// Variables:
|
|
// int copDist; // $v1
|
|
/* end block 1.3.1.1 */
|
|
// End offset: 0x0002F5CC
|
|
// End Line: 1658
|
|
/* end block 1.3.1 */
|
|
// End offset: 0x0002F5DC
|
|
// End Line: 1661
|
|
/* end block 1.3 */
|
|
// End offset: 0x0002F5E8
|
|
// End Line: 1664
|
|
/* end block 1 */
|
|
// End offset: 0x0002F60C
|
|
// End Line: 1671
|
|
|
|
/* begin block 2 */
|
|
// Start line: 3514
|
|
/* end block 2 */
|
|
// End Line: 3515
|
|
|
|
/* begin block 3 */
|
|
// Start line: 3556
|
|
/* end block 3 */
|
|
// End Line: 3557
|
|
|
|
/* begin block 4 */
|
|
// Start line: 3557
|
|
/* end block 4 */
|
|
// End Line: 3558
|
|
|
|
/* begin block 5 */
|
|
// Start line: 3560
|
|
/* end block 5 */
|
|
// End Line: 3561
|
|
|
|
/* WARNING: Unknown calling convention yet parameter storage is locked */
|
|
|
|
// [D]
|
|
void ControlNumberOfCops(void)
|
|
{
|
|
short sVar1;
|
|
short *psVar2;
|
|
short *psVar3;
|
|
uint uVar4;
|
|
_CAR_DATA *p_Var5;
|
|
int iVar6;
|
|
uint uVar7;
|
|
int iVar8;
|
|
|
|
psVar2 = gCopData.trigger;
|
|
iVar8 = 0;
|
|
|
|
while (true)
|
|
{
|
|
sVar1 = *psVar2;
|
|
psVar2++;
|
|
|
|
if (player[0].playerCarId < 0)
|
|
psVar3 = &pedestrianFelony;
|
|
else
|
|
psVar3 = &car_data[player[0].playerCarId].felonyRating;
|
|
|
|
if (*psVar3 < sVar1)
|
|
break;
|
|
|
|
iVar8++;
|
|
}
|
|
|
|
iVar6 = gMinimumCops;
|
|
|
|
if ((iVar8 < gMinimumCops) || (iVar6 = maxCopCars, maxCopCars < iVar8))
|
|
{
|
|
iVar8 = iVar6;
|
|
}
|
|
if (numCopCars < iVar8 && gDontPingInCops == 0)
|
|
{
|
|
iVar8 = gCopRespawnTime;
|
|
|
|
if (Roadblock.status == 2)
|
|
iVar8 = Roadblock.copRespawnTime;
|
|
|
|
if (player[0].playerCarId < 0)
|
|
psVar2 = &pedestrianFelony;
|
|
else
|
|
psVar2 = &car_data[(int)player[0].playerCarId].felonyRating;
|
|
|
|
|
|
if (iVar8 * FIXED(0x1000 - FIXED(*psVar2 * gCopData.autoRespawnScaleLimit)) < cop_respawn_timer + 1)
|
|
requestCopCar = 1;
|
|
|
|
cop_respawn_timer++;
|
|
return;
|
|
}
|
|
|
|
if (numCopCars <= iVar8)
|
|
{
|
|
gCopData.cutOffDistance = 0x7fffffff;
|
|
cop_respawn_timer = 0;
|
|
return;
|
|
}
|
|
|
|
gCopData.cutOffDistance = 0x7fffffff;
|
|
|
|
do {
|
|
uVar7 = 0;
|
|
p_Var5 = car_data;
|
|
iVar6 = 0;
|
|
|
|
if (true) {
|
|
do {
|
|
if (p_Var5->controlType == 3)
|
|
{
|
|
uVar4 = p_Var5->ai.p.DistanceToPlayer;
|
|
if ((uVar4 < gCopData.cutOffDistance) && (iVar6 = iVar6 + 1, uVar7 < uVar4))
|
|
{
|
|
uVar7 = uVar4;
|
|
}
|
|
}
|
|
p_Var5++;
|
|
} while (p_Var5 < &car_data[20]);
|
|
}
|
|
gCopData.cutOffDistance = uVar7;
|
|
} while (iVar8 < iVar6);
|
|
|
|
cop_respawn_timer = 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
|