2020-09-05 20:12:14 +02:00
|
|
|
#include "DRIVER2.H"
|
2020-03-27 21:47:29 +01:00
|
|
|
#include "FELONY.H"
|
2020-05-17 09:46:45 +02:00
|
|
|
#include "STRINGS.H"
|
2020-05-27 12:03:46 +02:00
|
|
|
#include "COP_AI.H"
|
2020-06-17 12:28:40 +02:00
|
|
|
#include "CIV_AI.H"
|
|
|
|
|
2020-05-27 12:03:46 +02:00
|
|
|
#include "PLAYERS.H"
|
|
|
|
#include "CARS.H"
|
|
|
|
#include "MISSION.H"
|
|
|
|
#include "CONVERT.H"
|
|
|
|
#include "GAMESND.H"
|
2020-06-17 12:28:40 +02:00
|
|
|
#include "DR2ROADS.H"
|
|
|
|
#include "OVERLAY.H"
|
|
|
|
#include "MISSION.H"
|
|
|
|
|
|
|
|
#include "ABS.H"
|
2020-03-27 21:47:29 +01:00
|
|
|
|
|
|
|
short initialOccurrenceDelay[12] = { 0x18, 0, 0, 0, 0, 0, 0, 0, 0x18, 0, 0x18, 0 };
|
|
|
|
short initialReccurrenceDelay[12] = { 0x80, 0, 0x80, 0x40, 0x40, 0x20, 0x20, 0, 0x80, 0x100 };
|
|
|
|
|
|
|
|
FELONY_VALUE initialFelonyValue[12] =
|
|
|
|
{
|
|
|
|
{ 659, 0 },
|
|
|
|
{ 659, 75 },
|
|
|
|
{ 659, 0 },
|
|
|
|
{ 659, 0 },
|
|
|
|
{ 659, 659 },
|
|
|
|
{ 1318, 659 },
|
|
|
|
{ 659, 659 },
|
|
|
|
{ 659, 25 },
|
|
|
|
{ 659, 0 },
|
|
|
|
{ 659, 0 },
|
|
|
|
{ 659, 0 },
|
|
|
|
{ 4096, 0 }
|
|
|
|
};
|
|
|
|
|
2020-05-01 08:08:36 +02:00
|
|
|
FELONY_DATA felonyData;
|
|
|
|
|
2020-05-17 09:46:45 +02:00
|
|
|
int FelonyIncreaseTime = 0;
|
|
|
|
int FelonyDecreaseTime = 0;
|
|
|
|
|
|
|
|
int FelonyIncreaseTimer = 0;
|
|
|
|
int FelonyDecreaseTimer = 0;
|
|
|
|
|
|
|
|
|
2020-03-27 21:47:29 +01:00
|
|
|
// decompiled code
|
|
|
|
// original method signature:
|
|
|
|
// void /*$ra*/ InitFelonyDelayArray(struct FELONY_DELAY *pFelonyDelay /*$a0*/, short *pMaximum /*$a1*/, int count /*$a2*/)
|
|
|
|
// line 413, offset 0x0004d364
|
|
|
|
/* begin block 1 */
|
|
|
|
// Start line: 414
|
|
|
|
// Start offset: 0x0004D364
|
|
|
|
// Variables:
|
|
|
|
// struct FELONY_DELAY *pCurrent; // $a0
|
|
|
|
/* end block 1 */
|
|
|
|
// End offset: 0x0004D3A0
|
|
|
|
// End Line: 422
|
|
|
|
|
|
|
|
/* begin block 2 */
|
|
|
|
// Start line: 826
|
|
|
|
/* end block 2 */
|
|
|
|
// End Line: 827
|
|
|
|
|
|
|
|
/* begin block 3 */
|
|
|
|
// Start line: 1334
|
|
|
|
/* end block 3 */
|
|
|
|
// End Line: 1335
|
|
|
|
|
2020-09-19 22:10:41 +02:00
|
|
|
// [D] [T]
|
2020-04-17 21:55:31 +02:00
|
|
|
void InitFelonyDelayArray(FELONY_DELAY *pFelonyDelay, short *pMaximum, int count)
|
2020-03-27 21:47:29 +01:00
|
|
|
{
|
2020-09-19 22:10:41 +02:00
|
|
|
FELONY_DELAY *pCurrent;
|
2020-04-17 21:55:31 +02:00
|
|
|
|
2020-09-19 22:10:41 +02:00
|
|
|
pCurrent = pFelonyDelay + count;
|
2020-05-17 09:46:45 +02:00
|
|
|
|
2020-09-19 22:10:41 +02:00
|
|
|
if (pFelonyDelay < pCurrent)
|
2020-05-17 09:46:45 +02:00
|
|
|
{
|
2020-04-17 21:55:31 +02:00
|
|
|
do {
|
|
|
|
pFelonyDelay->current = 0;
|
2020-05-17 09:46:45 +02:00
|
|
|
pFelonyDelay->maximum = *pMaximum++;
|
|
|
|
|
|
|
|
pFelonyDelay++;
|
2020-09-19 22:10:41 +02:00
|
|
|
} while (pFelonyDelay < pCurrent);
|
2020-04-17 21:55:31 +02:00
|
|
|
}
|
|
|
|
return;
|
2020-03-27 21:47:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// decompiled code
|
|
|
|
// original method signature:
|
|
|
|
// void /*$ra*/ InitFelonyData(struct FELONY_DATA *pFelonyData /*$s0*/)
|
|
|
|
// line 431, offset 0x0004d3a0
|
|
|
|
/* begin block 1 */
|
|
|
|
// Start line: 432
|
|
|
|
// Start offset: 0x0004D3A0
|
|
|
|
|
|
|
|
/* begin block 1.1 */
|
|
|
|
// Start line: 432
|
|
|
|
// Start offset: 0x0004D3A0
|
|
|
|
// Variables:
|
|
|
|
// struct FELONY_VALUE *pSrc; // $v1
|
|
|
|
// struct FELONY_VALUE *pDest; // $s0
|
|
|
|
// struct FELONY_VALUE *pEnd; // $a0
|
|
|
|
/* end block 1.1 */
|
|
|
|
// End offset: 0x0004D420
|
|
|
|
// End Line: 445
|
|
|
|
/* end block 1 */
|
|
|
|
// End offset: 0x0004D420
|
|
|
|
// End Line: 446
|
|
|
|
|
|
|
|
/* begin block 2 */
|
|
|
|
// Start line: 1363
|
|
|
|
/* end block 2 */
|
|
|
|
// End Line: 1364
|
|
|
|
|
|
|
|
/* begin block 3 */
|
|
|
|
// Start line: 1373
|
|
|
|
/* end block 3 */
|
|
|
|
// End Line: 1374
|
|
|
|
|
2020-09-19 22:10:41 +02:00
|
|
|
// [D] [T]
|
2020-03-27 21:47:29 +01:00
|
|
|
void InitFelonyData(FELONY_DATA *pFelonyData)
|
|
|
|
{
|
2020-05-17 09:46:45 +02:00
|
|
|
InitFelonyDelayArray(pFelonyData->occurrenceDelay, initialOccurrenceDelay, 12);
|
|
|
|
InitFelonyDelayArray(pFelonyData->reoccurrenceDelay, initialReccurrenceDelay, 12);
|
|
|
|
|
|
|
|
memcpy(&pFelonyData->value, &initialFelonyValue, sizeof(initialFelonyValue));
|
2020-03-27 21:47:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// decompiled code
|
|
|
|
// original method signature:
|
|
|
|
// int /*$ra*/ GetCarHeading(int direction /*$a0*/)
|
|
|
|
// line 450, offset 0x0004d420
|
|
|
|
/* begin block 1 */
|
|
|
|
// Start line: 1408
|
|
|
|
/* end block 1 */
|
|
|
|
// End Line: 1409
|
|
|
|
|
|
|
|
/* begin block 2 */
|
|
|
|
// Start line: 1409
|
|
|
|
/* end block 2 */
|
|
|
|
// End Line: 1410
|
|
|
|
|
|
|
|
/* begin block 3 */
|
|
|
|
// Start line: 1414
|
|
|
|
/* end block 3 */
|
|
|
|
// End Line: 1415
|
|
|
|
|
|
|
|
/* begin block 4 */
|
|
|
|
// Start line: 1415
|
|
|
|
/* end block 4 */
|
|
|
|
// End Line: 1416
|
|
|
|
|
2020-09-19 22:10:41 +02:00
|
|
|
// [D] [T]
|
2020-03-27 21:47:29 +01:00
|
|
|
int GetCarHeading(int direction)
|
|
|
|
{
|
2020-04-17 21:55:31 +02:00
|
|
|
return (direction + 0x200U & 0xfff) >> 10;
|
2020-03-27 21:47:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// decompiled code
|
|
|
|
// original method signature:
|
|
|
|
// char /*$ra*/ GetCarDirectionOfTravel(struct _CAR_DATA *cp /*$s0*/)
|
|
|
|
// line 454, offset 0x0004d430
|
|
|
|
/* begin block 1 */
|
|
|
|
// Start line: 455
|
|
|
|
// Start offset: 0x0004D430
|
|
|
|
// Variables:
|
|
|
|
// int direction; // $v0
|
|
|
|
/* end block 1 */
|
|
|
|
// End offset: 0x0004D478
|
|
|
|
// End Line: 466
|
|
|
|
|
|
|
|
/* begin block 2 */
|
|
|
|
// Start line: 1422
|
|
|
|
/* end block 2 */
|
|
|
|
// End Line: 1423
|
|
|
|
|
2020-09-19 22:10:41 +02:00
|
|
|
// [D] [T]
|
2020-03-27 21:47:29 +01:00
|
|
|
char GetCarDirectionOfTravel(_CAR_DATA *cp)
|
|
|
|
{
|
2020-09-19 22:10:41 +02:00
|
|
|
int direction;
|
2020-04-17 21:55:31 +02:00
|
|
|
|
2020-09-19 22:10:41 +02:00
|
|
|
direction = GetCarHeading(cp->hd.direction);;
|
2020-04-17 21:55:31 +02:00
|
|
|
|
|
|
|
if (cp->hd.wheel_speed < 0)
|
2020-09-19 22:10:41 +02:00
|
|
|
direction = direction + 2 & 3;
|
2020-04-17 21:55:31 +02:00
|
|
|
|
2020-09-19 22:10:41 +02:00
|
|
|
return direction;
|
2020-03-27 21:47:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// decompiled code
|
|
|
|
// original method signature:
|
|
|
|
// void /*$ra*/ NoteFelony(struct FELONY_DATA *pFelonyData /*$a3*/, char type /*$s3*/, short scale /*$t0*/)
|
|
|
|
// line 476, offset 0x0004c330
|
|
|
|
/* begin block 1 */
|
|
|
|
// Start line: 477
|
|
|
|
// Start offset: 0x0004C330
|
|
|
|
// Variables:
|
|
|
|
// int felonyTooLowForRoadblocks; // $s4
|
|
|
|
|
|
|
|
/* begin block 1.1 */
|
|
|
|
// Start line: 478
|
|
|
|
// Start offset: 0x0004C3A8
|
|
|
|
// Variables:
|
|
|
|
// struct FELONY_DELAY *pFelonyDelay; // $v1
|
|
|
|
/* end block 1.1 */
|
|
|
|
// End offset: 0x0004C3CC
|
|
|
|
// End Line: 495
|
|
|
|
|
|
|
|
/* begin block 1.2 */
|
|
|
|
// Start line: 512
|
|
|
|
// Start offset: 0x0004C400
|
|
|
|
// Variables:
|
|
|
|
// int additionalFelonyPoints; // $a0
|
|
|
|
/* end block 1.2 */
|
|
|
|
// End offset: 0x0004C514
|
|
|
|
// End Line: 528
|
|
|
|
|
|
|
|
/* begin block 1.3 */
|
|
|
|
// Start line: 553
|
|
|
|
// Start offset: 0x0004C630
|
|
|
|
// Variables:
|
|
|
|
// char rnd; // $s1
|
|
|
|
// int dir; // $a3
|
|
|
|
/* end block 1.3 */
|
|
|
|
// End offset: 0x0004C804
|
|
|
|
// End Line: 583
|
|
|
|
/* end block 1 */
|
|
|
|
// End offset: 0x0004C894
|
|
|
|
// End Line: 588
|
|
|
|
|
|
|
|
/* begin block 2 */
|
|
|
|
// Start line: 952
|
|
|
|
/* end block 2 */
|
|
|
|
// End Line: 953
|
|
|
|
|
2020-05-27 12:03:46 +02:00
|
|
|
// [D]
|
2020-04-17 21:55:31 +02:00
|
|
|
void NoteFelony(FELONY_DATA *pFelonyData, char type, short scale)
|
2020-03-27 21:47:29 +01:00
|
|
|
{
|
2020-09-19 22:10:41 +02:00
|
|
|
int felonyTooLowForRoadblocks;
|
|
|
|
char rnd; // $s1
|
|
|
|
int dir; // $a3
|
2020-05-27 12:03:46 +02:00
|
|
|
short *felony;
|
2020-04-17 21:55:31 +02:00
|
|
|
int phrase;
|
2020-09-19 22:10:41 +02:00
|
|
|
int additionalFelonyPoints;
|
2020-04-17 21:55:31 +02:00
|
|
|
|
2020-05-27 12:03:46 +02:00
|
|
|
if (player[0].playerCarId < 0)
|
|
|
|
felony = &pedestrianFelony;
|
|
|
|
else
|
|
|
|
felony = &car_data[player[0].playerCarId].felonyRating;
|
|
|
|
|
2020-09-19 22:10:41 +02:00
|
|
|
felonyTooLowForRoadblocks = *felony;
|
|
|
|
|
|
|
|
if (pFelonyData->occurrenceDelay[type].current < pFelonyData->occurrenceDelay[type].maximum)
|
2020-04-17 21:55:31 +02:00
|
|
|
return;
|
2020-05-27 12:03:46 +02:00
|
|
|
|
2020-06-17 12:28:40 +02:00
|
|
|
#ifdef FELONY_DEBUG
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
SetPlayerMessage(0, "Scaring pedestrians", 0, 1);
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
SetPlayerMessage(0, "Speeding", 0, 1);
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
SetPlayerMessage(0, "Red light crossing", 0, 1);
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
SetPlayerMessage(0, "Collision with another vehicle", 0, 1);
|
|
|
|
break;
|
|
|
|
case 5:
|
|
|
|
SetPlayerMessage(0, "Collision with cop", 0, 1);
|
|
|
|
break;
|
|
|
|
case 6:
|
|
|
|
SetPlayerMessage(0, "Collision with building", 0, 1);
|
|
|
|
break;
|
|
|
|
case 7:
|
|
|
|
SetPlayerMessage(0, "Damaging propery", 0, 1);
|
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
SetPlayerMessage(0, "Wrong way", 0, 1);
|
|
|
|
break;
|
|
|
|
case 9:
|
|
|
|
SetPlayerMessage(0, "Driving without lights", 0, 1);
|
|
|
|
break;
|
|
|
|
case 10:
|
|
|
|
SetPlayerMessage(0, "Reckless driving", 0, 1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2020-05-27 12:03:46 +02:00
|
|
|
if (CopsCanSeePlayer == 0 && (type != 11))
|
2020-04-17 21:55:31 +02:00
|
|
|
return;
|
2020-05-27 12:03:46 +02:00
|
|
|
|
2020-09-19 22:10:41 +02:00
|
|
|
if (pFelonyData->reoccurrenceDelay[type].current != 0)
|
2020-04-17 21:55:31 +02:00
|
|
|
return;
|
2020-05-27 12:03:46 +02:00
|
|
|
|
2020-09-19 22:10:41 +02:00
|
|
|
pFelonyData->reoccurrenceDelay[type].current = pFelonyData->reoccurrenceDelay[type].maximum;
|
2020-05-27 12:03:46 +02:00
|
|
|
|
|
|
|
if (*felony < 0x293)
|
2020-09-19 22:10:41 +02:00
|
|
|
additionalFelonyPoints = pFelonyData->value[type].placid;
|
2020-05-27 12:03:46 +02:00
|
|
|
else
|
2020-09-19 22:10:41 +02:00
|
|
|
additionalFelonyPoints = pFelonyData->value[type].angry * pFelonyData->pursuitFelonyScale >> 0xc;
|
2020-05-27 12:03:46 +02:00
|
|
|
|
2020-09-19 22:10:41 +02:00
|
|
|
*felony += (additionalFelonyPoints * scale >> 12);
|
2020-05-27 12:03:46 +02:00
|
|
|
|
|
|
|
if (player[0].playerCarId < 0)
|
|
|
|
felony = &pedestrianFelony;
|
|
|
|
else
|
|
|
|
felony = &car_data[player[0].playerCarId].felonyRating;
|
|
|
|
|
|
|
|
if (0x1000 < *felony)
|
|
|
|
*felony = 0x1000;
|
|
|
|
|
2020-09-19 22:10:41 +02:00
|
|
|
// KILL PEDESTRIAN FELONY HERE
|
2020-05-27 12:03:46 +02:00
|
|
|
if (player[0].playerType == 2)
|
|
|
|
*felony = 0;
|
|
|
|
|
2020-09-19 22:10:41 +02:00
|
|
|
if (first_offence == 0 && numActiveCops)
|
2020-05-27 12:03:46 +02:00
|
|
|
{
|
2020-09-19 22:10:41 +02:00
|
|
|
// say something..
|
|
|
|
rnd = Random2(1) & 0xff;
|
|
|
|
dir = GetCarDirectionOfTravel(&car_data[player[0].playerCarId]);
|
2020-05-27 12:03:46 +02:00
|
|
|
|
2020-09-19 22:10:41 +02:00
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
case 5:
|
|
|
|
case 6:
|
|
|
|
case 7:
|
|
|
|
case 11:
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
if ((rnd & 3) != 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
CopSay(5, 0);
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
if ((rnd - (((uint)((long long)rnd * 0xaaaaaaab >> 0x20) & 0xfffffffe) + rnd / 3) & 0xff) != 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
CopSay((rnd & 1) + 7, 0);
|
|
|
|
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if ((rnd - (((uint)((long long)rnd * 0xf0f0f0f1 >> 0x20) & 0xfffffff0) + rnd / 0x11) & 0xff) == 0)
|
2020-05-27 12:03:46 +02:00
|
|
|
{
|
2020-09-19 22:10:41 +02:00
|
|
|
if (MaxPlayerDamage[0] * 3 >> 2 < car_data[player[0].playerCarId].totalDamage)
|
|
|
|
phrase = rnd & 3;
|
2020-05-27 12:03:46 +02:00
|
|
|
else
|
2020-09-19 22:10:41 +02:00
|
|
|
phrase = rnd - (((uint)((long long)rnd * 0xaaaaaaab >> 0x20) & 0xfffffffe) + rnd / 3) & 0xff;
|
2020-05-27 12:03:46 +02:00
|
|
|
|
2020-09-19 22:10:41 +02:00
|
|
|
if (last_cop_phrase != phrase && 0 < TimeSinceLastSpeech)
|
|
|
|
{
|
|
|
|
if (phrase < 3)
|
|
|
|
CopSay(phrase + 15, dir);
|
|
|
|
else
|
|
|
|
CopSay(6, 0);
|
2020-05-27 12:03:46 +02:00
|
|
|
|
2020-09-19 22:10:41 +02:00
|
|
|
last_cop_phrase = phrase;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2020-04-17 21:55:31 +02:00
|
|
|
}
|
2020-05-27 12:03:46 +02:00
|
|
|
|
2020-09-19 22:10:41 +02:00
|
|
|
if (felonyTooLowForRoadblocks < 0x527)
|
2020-05-27 12:03:46 +02:00
|
|
|
{
|
2020-09-19 22:10:41 +02:00
|
|
|
if (*felony > 0x526)
|
2020-05-27 12:03:46 +02:00
|
|
|
{
|
2020-09-19 22:10:41 +02:00
|
|
|
roadblockCount = roadblockDelayDiff[gCopDifficultyLevel] + (Random2(0) & 0xff);
|
2020-04-17 21:55:31 +02:00
|
|
|
}
|
|
|
|
}
|
2020-03-27 21:47:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// decompiled code
|
|
|
|
// original method signature:
|
|
|
|
// void /*$ra*/ AdjustFelony(struct FELONY_DATA *pFelonyData /*$a0*/)
|
|
|
|
// line 597, offset 0x0004c8b4
|
|
|
|
/* begin block 1 */
|
|
|
|
// Start line: 598
|
|
|
|
// Start offset: 0x0004C8B4
|
|
|
|
|
|
|
|
/* begin block 1.1 */
|
|
|
|
// Start line: 649
|
|
|
|
// Start offset: 0x0004CBE8
|
|
|
|
// Variables:
|
|
|
|
// struct FELONY_DELAY *pFelonyDelay; // $v1
|
|
|
|
/* end block 1.1 */
|
|
|
|
// End offset: 0x0004CC28
|
|
|
|
// End Line: 658
|
|
|
|
/* end block 1 */
|
|
|
|
// End offset: 0x0004CC28
|
|
|
|
// End Line: 659
|
|
|
|
|
|
|
|
/* begin block 2 */
|
|
|
|
// Start line: 1231
|
|
|
|
/* end block 2 */
|
|
|
|
// End Line: 1232
|
|
|
|
|
|
|
|
/* begin block 3 */
|
|
|
|
// Start line: 1242
|
|
|
|
/* end block 3 */
|
|
|
|
// End Line: 1243
|
|
|
|
|
2020-09-19 22:10:41 +02:00
|
|
|
// [D] [T]
|
2020-03-27 21:47:29 +01:00
|
|
|
void AdjustFelony(FELONY_DATA *pFelonyData)
|
|
|
|
{
|
2020-04-17 21:55:31 +02:00
|
|
|
bool bVar1;
|
|
|
|
short *psVar2;
|
2020-05-27 12:03:46 +02:00
|
|
|
FELONY_DELAY *pFelonyDelay;
|
|
|
|
short *felony;
|
2020-04-17 21:55:31 +02:00
|
|
|
|
2020-05-27 12:03:46 +02:00
|
|
|
if (player[0].playerCarId < 0)
|
|
|
|
felony = &pedestrianFelony;
|
|
|
|
else
|
|
|
|
felony = &car_data[player[0].playerCarId].felonyRating;
|
|
|
|
|
|
|
|
if (*felony != 0 && *felony < 0x293)
|
|
|
|
{
|
|
|
|
if (FelonyDecreaseTimer++ == FelonyDecreaseTime)
|
|
|
|
{
|
|
|
|
*felony--;
|
|
|
|
|
|
|
|
FelonyDecreaseTimer = 0;
|
2020-04-17 21:55:31 +02:00
|
|
|
}
|
|
|
|
}
|
2020-05-27 12:03:46 +02:00
|
|
|
else if (CopsCanSeePlayer)
|
|
|
|
{
|
|
|
|
if (*felony > 0x292 && FelonyIncreaseTimer++ == FelonyIncreaseTime)
|
|
|
|
{
|
|
|
|
*felony++;
|
|
|
|
|
|
|
|
if (*felony > 0x1000)
|
|
|
|
*felony = 0x1000;
|
|
|
|
|
2020-04-17 21:55:31 +02:00
|
|
|
FelonyIncreaseTimer = 0;
|
|
|
|
}
|
|
|
|
}
|
2020-05-27 12:03:46 +02:00
|
|
|
|
|
|
|
pFelonyDelay = pFelonyData->reoccurrenceDelay;
|
|
|
|
|
|
|
|
while (pFelonyDelay <= &pFelonyData->reoccurrenceDelay[11])
|
|
|
|
{
|
|
|
|
if (pFelonyDelay->current != 0)
|
|
|
|
pFelonyDelay->current--;
|
|
|
|
|
|
|
|
pFelonyDelay++;
|
2020-04-17 21:55:31 +02:00
|
|
|
}
|
2020-03-27 21:47:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// decompiled code
|
|
|
|
// original method signature:
|
|
|
|
// void /*$ra*/ CheckPlayerMiscFelonies()
|
|
|
|
// line 668, offset 0x0004cc28
|
|
|
|
/* begin block 1 */
|
|
|
|
// Start line: 670
|
|
|
|
// Start offset: 0x0004CC28
|
|
|
|
// Variables:
|
|
|
|
// struct FELONY_DATA *pFelonyData; // $s4
|
|
|
|
// struct DRIVER2_CURVE *cv; // $s5
|
|
|
|
// struct DRIVER2_STRAIGHT *st; // $s6
|
|
|
|
// struct _CAR_DATA *cp; // $s3
|
|
|
|
// struct VECTOR *carPos; // $s2
|
|
|
|
// int surfInd; // $s0
|
|
|
|
|
|
|
|
/* begin block 1.1 */
|
|
|
|
// Start line: 690
|
|
|
|
// Start offset: 0x0004CCC0
|
|
|
|
// Variables:
|
|
|
|
// char i; // $a1
|
|
|
|
|
|
|
|
/* begin block 1.1.1 */
|
|
|
|
// Start line: 699
|
|
|
|
// Start offset: 0x0004CD64
|
|
|
|
// Variables:
|
|
|
|
// struct DRIVER2_JUNCTION *jn; // $a2
|
|
|
|
// short exitId; // $s1
|
|
|
|
/* end block 1.1.1 */
|
|
|
|
// End offset: 0x0004CE0C
|
|
|
|
// End Line: 715
|
|
|
|
/* end block 1.1 */
|
|
|
|
// End offset: 0x0004CE0C
|
|
|
|
// End Line: 716
|
|
|
|
|
|
|
|
/* begin block 1.2 */
|
|
|
|
// Start line: 716
|
|
|
|
// Start offset: 0x0004CE0C
|
|
|
|
// Variables:
|
|
|
|
// char goingWrongWay; // $s7
|
|
|
|
// int lane; // $s0
|
|
|
|
// int dx; // $v1
|
|
|
|
// int dz; // $a0
|
|
|
|
|
|
|
|
/* begin block 1.2.1 */
|
|
|
|
// Start line: 738
|
|
|
|
// Start offset: 0x0004CFAC
|
|
|
|
/* end block 1.2.1 */
|
|
|
|
// End offset: 0x0004D0D8
|
|
|
|
// End Line: 748
|
|
|
|
/* end block 1.2 */
|
|
|
|
// End offset: 0x0004D0F8
|
|
|
|
// End Line: 758
|
|
|
|
|
|
|
|
/* begin block 1.3 */
|
|
|
|
// Start line: 779
|
|
|
|
// Start offset: 0x0004D198
|
|
|
|
// Variables:
|
|
|
|
// int maxSpeed; // $a0
|
|
|
|
// int limit; // $v1
|
|
|
|
/* end block 1.3 */
|
|
|
|
// End offset: 0x0004D250
|
|
|
|
// End Line: 805
|
|
|
|
/* end block 1 */
|
|
|
|
// End offset: 0x0004D250
|
|
|
|
// End Line: 806
|
|
|
|
|
|
|
|
/* begin block 2 */
|
|
|
|
// Start line: 1367
|
|
|
|
/* end block 2 */
|
|
|
|
// End Line: 1368
|
|
|
|
|
|
|
|
/* begin block 3 */
|
|
|
|
// Start line: 1368
|
|
|
|
/* end block 3 */
|
|
|
|
// End Line: 1369
|
|
|
|
|
|
|
|
/* begin block 4 */
|
|
|
|
// Start line: 1378
|
|
|
|
/* end block 4 */
|
|
|
|
// End Line: 1379
|
|
|
|
|
|
|
|
/* begin block 5 */
|
|
|
|
// Start line: 1379
|
|
|
|
/* end block 5 */
|
|
|
|
// End Line: 1380
|
|
|
|
|
|
|
|
/* begin block 6 */
|
|
|
|
// Start line: 1380
|
|
|
|
/* end block 6 */
|
|
|
|
// End Line: 1381
|
|
|
|
|
|
|
|
/* WARNING: Removing unreachable block (ram,0x0004d214) */
|
|
|
|
/* WARNING: Unknown calling convention yet parameter storage is locked */
|
|
|
|
|
2020-06-17 12:28:40 +02:00
|
|
|
short playerLastRoad = 0;
|
|
|
|
|
2020-09-21 22:31:12 +02:00
|
|
|
// [D] [T]
|
2020-03-27 21:47:29 +01:00
|
|
|
void CheckPlayerMiscFelonies(void)
|
|
|
|
{
|
2020-09-21 22:31:12 +02:00
|
|
|
int i;
|
2020-06-17 12:28:40 +02:00
|
|
|
bool goingWrongWay;
|
|
|
|
int surfInd;
|
|
|
|
int maxSpeed;
|
|
|
|
int limit;
|
|
|
|
int exitId;
|
|
|
|
int _exitId;
|
|
|
|
VECTOR *carPos;
|
2020-09-30 20:20:03 +02:00
|
|
|
DRIVER2_ROAD_INFO roadInfo;
|
2020-06-17 12:28:40 +02:00
|
|
|
DRIVER2_JUNCTION *jn;
|
|
|
|
_CAR_DATA* cp;
|
2020-04-17 21:55:31 +02:00
|
|
|
|
2020-06-17 12:28:40 +02:00
|
|
|
if (player[0].playerType == 2 || player[0].playerCarId < 0 || FelonyBar.active == 0)
|
2020-04-17 21:55:31 +02:00
|
|
|
return;
|
2020-06-17 12:28:40 +02:00
|
|
|
|
|
|
|
cp = &car_data[player[0].playerCarId];
|
|
|
|
carPos = (VECTOR *)cp->hd.where.t;
|
|
|
|
|
|
|
|
surfInd = GetSurfaceIndex(carPos);
|
|
|
|
|
|
|
|
// check junctions
|
2020-09-21 22:31:12 +02:00
|
|
|
if (IS_JUNCTION_SURFACE(surfInd))
|
2020-06-17 12:28:40 +02:00
|
|
|
{
|
|
|
|
jn = GET_JUNCTION(surfInd);
|
|
|
|
|
|
|
|
if( (IS_CURVED_SURFACE(playerLastRoad) || IS_STRAIGHT_SURFACE(playerLastRoad)) && (jn->flags & 0x1))
|
|
|
|
{
|
2020-09-21 22:31:12 +02:00
|
|
|
exitId = 0;
|
|
|
|
i = 0;
|
|
|
|
while (i < 4)
|
2020-06-17 12:28:40 +02:00
|
|
|
{
|
2020-09-21 22:31:12 +02:00
|
|
|
if (jn->ExitIdx[i] == playerLastRoad)
|
|
|
|
{
|
|
|
|
exitId = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
i++;
|
2020-04-17 21:55:31 +02:00
|
|
|
}
|
2020-06-17 12:28:40 +02:00
|
|
|
|
2020-09-21 22:31:12 +02:00
|
|
|
// Run a red light!
|
|
|
|
if (junctionLightsPhase[exitId & 1] == 1)
|
2020-06-17 12:28:40 +02:00
|
|
|
NoteFelony(&felonyData, 3, 0x1000);
|
2020-04-17 21:55:31 +02:00
|
|
|
}
|
|
|
|
}
|
2020-06-17 12:28:40 +02:00
|
|
|
|
|
|
|
playerLastRoad = surfInd;
|
|
|
|
goingWrongWay = false;
|
|
|
|
|
2020-09-30 20:20:03 +02:00
|
|
|
if(GetSurfaceRoadInfo(&roadInfo, surfInd))
|
2020-06-17 12:28:40 +02:00
|
|
|
{
|
2020-09-21 22:31:12 +02:00
|
|
|
int lane_count;
|
2020-09-30 20:20:03 +02:00
|
|
|
int lane;
|
|
|
|
int dx;
|
|
|
|
int dz;
|
|
|
|
int crd;
|
2020-09-21 22:31:12 +02:00
|
|
|
|
2020-09-30 20:20:03 +02:00
|
|
|
lane_count = ROAD_WIDTH_IN_LANES(&roadInfo);
|
2020-09-21 22:31:12 +02:00
|
|
|
|
2020-09-30 20:20:03 +02:00
|
|
|
if(roadInfo.straight)
|
2020-06-17 12:28:40 +02:00
|
|
|
{
|
2020-09-30 20:20:03 +02:00
|
|
|
dx = carPos->vx - roadInfo.straight->Midx;
|
|
|
|
dz = carPos->vz - roadInfo.straight->Midz;
|
2020-06-17 12:28:40 +02:00
|
|
|
|
2020-09-30 20:20:03 +02:00
|
|
|
lane = ROAD_LANES_COUNT(&roadInfo) - (FIXEDH(dx * rcossin_tbl[(roadInfo.straight->angle & 0xfff) * 2 + 1] - dz * rcossin_tbl[(roadInfo.straight->angle & 0xfff) * 2]) + 512 >> 9);
|
2020-09-21 22:31:12 +02:00
|
|
|
|
2020-09-30 20:20:03 +02:00
|
|
|
if (lane < 0)
|
|
|
|
lane = 0;
|
2020-09-21 22:31:12 +02:00
|
|
|
|
2020-09-30 20:20:03 +02:00
|
|
|
if (lane_count <= lane)
|
|
|
|
lane = lane_count - 1;
|
2020-06-17 12:28:40 +02:00
|
|
|
|
2020-09-30 20:20:03 +02:00
|
|
|
crd = (roadInfo.straight->angle - cp->hd.direction) + 0x400U >> 0xb & 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
dx = carPos->vx - roadInfo.curve->Midx;
|
|
|
|
dz = carPos->vz - roadInfo.curve->Midz;
|
2020-06-17 12:28:40 +02:00
|
|
|
|
2020-09-30 20:20:03 +02:00
|
|
|
lane = (SquareRoot0(dx * dx + dz * dz) >> 9) - roadInfo.curve->inside * 2;
|
|
|
|
if (lane < 0)
|
|
|
|
lane = 0;
|
|
|
|
|
|
|
|
if (lane >= lane_count)
|
|
|
|
lane = lane_count - 1;
|
2020-06-17 12:28:40 +02:00
|
|
|
|
2020-09-30 20:20:03 +02:00
|
|
|
crd = NotTravellingAlongCurve(carPos->vx, carPos->vz, cp->hd.direction, roadInfo.curve);
|
|
|
|
}
|
2020-06-17 12:28:40 +02:00
|
|
|
|
2020-09-21 22:31:12 +02:00
|
|
|
// check if on correct lane
|
2020-09-30 20:20:03 +02:00
|
|
|
if (ROAD_IS_AI_LANE(&roadInfo, lane))
|
2020-06-17 12:28:40 +02:00
|
|
|
{
|
2020-09-30 20:20:03 +02:00
|
|
|
if (ROAD_LANE_DIR(&roadInfo, lane) == 0)
|
2020-06-17 12:28:40 +02:00
|
|
|
{
|
2020-09-30 20:20:03 +02:00
|
|
|
if (crd == 1)
|
2020-09-22 19:07:26 +02:00
|
|
|
goingWrongWay = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (crd == 0)
|
|
|
|
goingWrongWay = true;
|
2020-04-17 21:55:31 +02:00
|
|
|
}
|
|
|
|
}
|
2020-09-21 22:31:12 +02:00
|
|
|
|
2020-10-05 17:26:22 +02:00
|
|
|
#if 0
|
2020-09-30 20:20:03 +02:00
|
|
|
printInfo("ROAD lane: %d / %d, (%d). AI drive: %d, flg: %d%d%d, dir: %d, spd: %d (wrong way: %d)\n",
|
2020-09-21 22:31:12 +02:00
|
|
|
lane + 1,
|
2020-09-30 20:20:03 +02:00
|
|
|
((u_char)roadInfo.NumLanes & 0xF) * 2, // lane count. * 2 for both sides as roads are symmetric
|
|
|
|
IS_NARROW_ROAD(&roadInfo),
|
|
|
|
((u_char)roadInfo.AILanes >> (lane / 2) & 1U), // lane AI driveable flag
|
|
|
|
(roadInfo.NumLanes & 0x20) > 0, // flag 0 - first lane?
|
|
|
|
(roadInfo.NumLanes & 0x40) > 0, // flag 1 - leftmost park
|
|
|
|
(roadInfo.NumLanes & 0x80) > 0, // flag 2 - rightmost park
|
|
|
|
((u_char)roadInfo.LaneDirs >> (lane / 2) & 1U), // direction bit
|
|
|
|
((u_char)roadInfo.NumLanes >> 4) & 3, // speed limit id
|
2020-09-21 22:31:12 +02:00
|
|
|
goingWrongWay);
|
|
|
|
#endif
|
2020-09-30 20:20:03 +02:00
|
|
|
|
|
|
|
// get road speed limit
|
|
|
|
maxSpeed = speedLimits[ROAD_SPEED_LIMIT(&roadInfo)];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
maxSpeed = speedLimits[2];
|
2020-04-17 21:55:31 +02:00
|
|
|
}
|
2020-06-17 12:28:40 +02:00
|
|
|
|
|
|
|
// wrong way
|
|
|
|
if (goingWrongWay)
|
|
|
|
felonyData.occurrenceDelay[8].current++;
|
|
|
|
else
|
2020-04-17 21:55:31 +02:00
|
|
|
felonyData.occurrenceDelay[8].current = 0;
|
2020-06-17 12:28:40 +02:00
|
|
|
|
|
|
|
NoteFelony(&felonyData, 8, 0x1000);
|
|
|
|
|
|
|
|
// if lights are off (broken)
|
|
|
|
if (gTimeOfDay == 3 && cp->ap.damage[0] > 1000 && cp->ap.damage[1] > 1000)
|
|
|
|
NoteFelony(&felonyData, 9, 0x1000);
|
|
|
|
|
|
|
|
// reckless driving.
|
|
|
|
// for that checking if rear wheels are sliding
|
|
|
|
if (cp->wheelspin == 0)
|
|
|
|
{
|
|
|
|
if (ABS(cp->hd.rear_vel) > 11100)
|
|
|
|
felonyData.occurrenceDelay[10].current++;
|
|
|
|
else
|
|
|
|
felonyData.occurrenceDelay[10].current = 0;
|
2020-04-17 21:55:31 +02:00
|
|
|
}
|
2020-06-17 12:28:40 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
felonyData.occurrenceDelay[10].current++;
|
2020-04-17 21:55:31 +02:00
|
|
|
}
|
2020-06-17 12:28:40 +02:00
|
|
|
|
|
|
|
NoteFelony(&felonyData, 10, 0x1000);
|
|
|
|
|
|
|
|
// check the speed limit
|
|
|
|
if (speedLimits[2] == maxSpeed)
|
|
|
|
limit = (maxSpeed * 19) >> 4;
|
|
|
|
else
|
|
|
|
limit = (maxSpeed * 3) >> 1;
|
|
|
|
|
2020-09-11 11:30:58 +02:00
|
|
|
if (FIXEDH(cp->hd.wheel_speed) > limit)
|
2020-06-17 12:28:40 +02:00
|
|
|
NoteFelony(&felonyData, 2, 0x1000);
|
2020-03-27 21:47:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// decompiled code
|
|
|
|
// original method signature:
|
|
|
|
// void /*$ra*/ InitFelonySystem()
|
|
|
|
// line 810, offset 0x0004d280
|
|
|
|
/* begin block 1 */
|
|
|
|
// Start line: 1682
|
|
|
|
/* end block 1 */
|
|
|
|
// End Line: 1683
|
|
|
|
|
|
|
|
/* begin block 2 */
|
|
|
|
// Start line: 1687
|
|
|
|
/* end block 2 */
|
|
|
|
// End Line: 1688
|
|
|
|
|
|
|
|
/* WARNING: Unknown calling convention yet parameter storage is locked */
|
|
|
|
|
2020-09-19 22:10:41 +02:00
|
|
|
// [D] [T]
|
2020-03-27 21:47:29 +01:00
|
|
|
void InitFelonySystem(void)
|
|
|
|
{
|
2020-09-19 22:10:41 +02:00
|
|
|
FelonyIncreaseTime = 31;
|
|
|
|
FelonyDecreaseTime = 31;
|
2020-04-17 21:55:31 +02:00
|
|
|
FelonyIncreaseTimer = 0;
|
|
|
|
FelonyDecreaseTimer = 0;
|
2020-05-17 09:46:45 +02:00
|
|
|
|
2020-04-17 21:55:31 +02:00
|
|
|
InitFelonyData(&felonyData);
|
2020-03-27 21:47:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// decompiled code
|
|
|
|
// original method signature:
|
|
|
|
// void /*$ra*/ CarHitByPlayer(struct _CAR_DATA *victim /*$a0*/, int howHard /*$a2*/)
|
|
|
|
// line 824, offset 0x0004d2b8
|
|
|
|
/* begin block 1 */
|
|
|
|
// Start line: 1714
|
|
|
|
/* end block 1 */
|
|
|
|
// End Line: 1715
|
|
|
|
|
2020-09-19 22:10:41 +02:00
|
|
|
// [D] [T]
|
2020-04-17 21:55:31 +02:00
|
|
|
void CarHitByPlayer(_CAR_DATA *victim, int howHard)
|
2020-03-27 21:47:29 +01:00
|
|
|
{
|
2020-04-17 21:55:31 +02:00
|
|
|
char type;
|
|
|
|
|
2020-09-27 11:03:11 +02:00
|
|
|
if ((0 < howHard) && (victim->controlType != CONTROL_TYPE_PURSUER_AI))
|
2020-05-17 09:46:45 +02:00
|
|
|
{
|
|
|
|
if ((victim->controlFlags & 1) == 0)
|
|
|
|
{
|
|
|
|
if (howHard < 0x20)
|
|
|
|
{
|
|
|
|
NoteFelony(&felonyData, 4, (howHard << 0x17) >> 0x10);
|
2020-04-17 21:55:31 +02:00
|
|
|
return;
|
|
|
|
}
|
2020-05-17 09:46:45 +02:00
|
|
|
type = 4;
|
2020-04-17 21:55:31 +02:00
|
|
|
}
|
2020-05-17 09:46:45 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if (howHard < 0x10)
|
|
|
|
{
|
|
|
|
NoteFelony(&felonyData, 5, (howHard << 0x18) >> 0x10);
|
2020-04-17 21:55:31 +02:00
|
|
|
return;
|
|
|
|
}
|
2020-05-17 09:46:45 +02:00
|
|
|
type = 5;
|
2020-04-17 21:55:31 +02:00
|
|
|
}
|
2020-05-17 09:46:45 +02:00
|
|
|
|
2020-04-17 21:55:31 +02:00
|
|
|
NoteFelony(&felonyData, type, 0x1000);
|
|
|
|
}
|
2020-03-27 21:47:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|