Merge pull request #1 from GTAmodding/miami

Miami
This commit is contained in:
Fire_Head
2020-07-29 12:20:02 +03:00
committed by GitHub
267 changed files with 23832 additions and 29992 deletions

View File

@ -170,9 +170,13 @@ CCivilianPed::CivilianAI(void)
}
}
// --MIAMI: Done except comments
void
CCivilianPed::ProcessControl(void)
{
if (CharCreatedBy == TODO_CHAR)
return;
CPed::ProcessControl();
if (bWasPostponed)
@ -198,7 +202,8 @@ CCivilianPed::ProcessControl(void)
// fall through
case PED_SEEK_POS:
if (Seek()) {
if ((m_objective == OBJECTIVE_GOTO_AREA_ON_FOOT || m_objective == OBJECTIVE_RUN_TO_AREA || IsUseAttractorObjective(m_objective)) && m_pNextPathNode) {
if ((m_objective == OBJECTIVE_GOTO_AREA_ON_FOOT || m_objective == OBJECTIVE_RUN_TO_AREA || m_objective == OBJECTIVE_SPRINT_TO_AREA ||
IsUseAttractorObjective(m_objective)) && m_pNextPathNode) {
m_pNextPathNode = nil;
} else if (bRunningToPhone) {
@ -207,10 +212,10 @@ CCivilianPed::ProcessControl(void)
m_phoneId = -1;
} else {
gPhoneInfo.m_aPhones[m_phoneId].m_nState = PHONE_STATE_REPORTING_CRIME;
m_nPedState = PED_FACE_PHONE;
SetPedState(PED_FACE_PHONE);
}
} else if (m_objective != OBJECTIVE_KILL_CHAR_ANY_MEANS && m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT) {
if (m_objective == OBJECTIVE_FOLLOW_CHAR_IN_FORMATION) {
if (m_pedInObjective && m_objective == OBJECTIVE_FOLLOW_CHAR_IN_FORMATION) {
if (m_moved.Magnitude() == 0.0f) {
if (m_pedInObjective->m_nMoveState == PEDMOVE_STILL)
m_fRotationDest = m_pedInObjective->m_fRotationCur;
@ -218,7 +223,8 @@ CCivilianPed::ProcessControl(void)
} else if (m_objective == OBJECTIVE_GOTO_CHAR_ON_FOOT
&& m_pedInObjective && m_pedInObjective->m_nMoveState != PEDMOVE_STILL) {
SetMoveState(m_pedInObjective->m_nMoveState);
} else if (m_objective == OBJECTIVE_GOTO_AREA_ON_FOOT || m_objective == OBJECTIVE_RUN_TO_AREA || IsUseAttractorObjective(m_objective)) {
} else if (m_objective == OBJECTIVE_GOTO_AREA_ON_FOOT || m_objective == OBJECTIVE_RUN_TO_AREA || m_objective == OBJECTIVE_SPRINT_TO_AREA ||
IsUseAttractorObjective(m_objective)) {
SetIdle();
} else {
RestorePreviousState();
@ -228,7 +234,7 @@ CCivilianPed::ProcessControl(void)
break;
case PED_FACE_PHONE:
if (FacePhone())
m_nPedState = PED_MAKE_CALL;
SetPedState(PED_MAKE_CALL);
break;
case PED_MAKE_CALL:
if (MakePhonecall())
@ -284,6 +290,8 @@ CCivilianPed::ProcessControl(void)
GetPosition().x - m_pMyVehicle->GetPosition().x, GetPosition().y - m_pMyVehicle->GetPosition().y, 0.0f);
DMAudio.PlayOneShot(m_pMyVehicle->m_audioEntityId, SOUND_CAR_JERK, 0.0f);
m_pMyVehicle->pDriver->Say(SOUND_PED_PLAYER_BEFORESEX);
Say(SOUND_PED_PLAYER_BEFORESEX);
int playerSexFrequency = CWorld::Players[CWorld::PlayerInFocus].m_nSexFrequency;
if (CWorld::Players[CWorld::PlayerInFocus].m_nMoney >= 10 && playerSexFrequency > 250) {
@ -300,13 +308,17 @@ CCivilianPed::ProcessControl(void)
} else {
bWanderPathAfterExitingCar = true;
CWorld::Players[CWorld::PlayerInFocus].m_pHooker = nil;
ClearLeader();
SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
m_pMyVehicle->pDriver->Say(SOUND_PED_PLAYER_AFTERSEX);
}
} else {
bWanderPathAfterExitingCar = true;
CWorld::Players[CWorld::PlayerInFocus].m_pHooker = nil;
m_pMyVehicle->pDriver->m_fHealth = CWorld::Players[0].m_nMaxHealth + 25.0f;
ClearLeader();
SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
m_pMyVehicle->pDriver->Say(SOUND_PED_PLAYER_AFTERSEX);
}
} else {
CWorld::Players[CWorld::PlayerInFocus].m_nNextSexFrequencyUpdateTime = CTimer::GetTimeInMilliseconds() + 3000;
@ -319,6 +331,7 @@ CCivilianPed::ProcessControl(void)
} else {
bWanderPathAfterExitingCar = true;
CWorld::Players[CWorld::PlayerInFocus].m_pHooker = nil;
ClearLeader();
SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
}
}
@ -340,6 +353,7 @@ CCivilianPed::ProcessControl(void)
CivilianAI();
if (CharCreatedBy == RANDOM_CHAR) {
// TODO(Miami): EnterVacantNearbyCars();
UseNearbyAttractors();
}

View File

@ -16,6 +16,8 @@
#include "CarCtrl.h"
#include "Renderer.h"
#include "Camera.h"
#include "PedPlacement.h"
#include "Ropes.h"
CCopPed::CCopPed(eCopType copType, int32 modifier) : CPed(PEDTYPE_COP)
{
@ -39,12 +41,13 @@ CCopPed::CCopPed(eCopType copType, int32 modifier) : CPed(PEDTYPE_COP)
m_wepAccuracy = 76;
break;
case COP_SWAT:
case COP_HELI_SWAT:
SetModelIndex(MI_SWAT);
GiveDelayedWeapon(WEAPONTYPE_UZI, 1000);
SetCurrentWeapon(WEAPONTYPE_UZI);
m_fArmour = 50.0f;
m_wepSkills = 32; /* TODO: what is this? seems unused */
m_wepAccuracy = 64;
m_wepAccuracy = 68;
break;
case COP_ARMY:
SetModelIndex(MI_ARMY);
@ -77,14 +80,20 @@ CCopPed::CCopPed(eCopType copType, int32 modifier) : CPed(PEDTYPE_COP)
field_5FE = 1;
m_bIsDisabledCop = false;
m_attackTimer = 0;
m_bBeatingSuspect = false;
m_bStopAndShootDisabledZone = false;
field_601 = false;
m_bZoneDisabled = false;
field_628 = -1;
m_nRoadblockNode = -1; // TODO(Miami): this will be nil
field_5FF = 0;
m_bThrowsSpikeTrap = false;
m_pRopeEntity = nil;
m_fAbseilPos = 0.0f;
m_bBeatingSuspect = false;
m_nHassleTimer = 0;
field_61C = 0;
field_624 = 0;
if (m_pPointGunAt)
m_pPointGunAt->CleanUpOldReference((CEntity**)&m_pPointGunAt);
m_pPointGunAt = nil;
}
@ -93,24 +102,17 @@ CCopPed::~CCopPed()
ClearPursuit();
}
// --MIAMI: Done
// Parameter should always be CPlayerPed, but it seems they considered making civilians arrestable at some point
void
CCopPed::SetArrestPlayer(CPed *player)
{
if (!IsPedInControl() || !player)
return;
/*
switch (m_nCopType) {
case COP_FBI:
Say(SOUND_PED_ARREST_FBI);
break;
case COP_SWAT:
Say(SOUND_PED_ARREST_SWAT);
break;
default:
Say(SOUND_PED_ARREST_COP);
break;
} */
player->Say(SOUND_PED_PLAYER_REACTTOCOP);
Say(SOUND_PED_ARREST_COP);
if (player->EnteringCar()) {
if (CTimer::GetTimeInMilliseconds() > m_nPedStateTimer)
return;
@ -125,14 +127,14 @@ CCopPed::SetArrestPlayer(CPed *player)
} else if (player->m_nPedState != PED_DIE && player->m_nPedState != PED_DEAD && player->m_nPedState != PED_ARRESTED) {
player->m_nLastPedState = player->m_nPedState;
player->m_nPedState = PED_ARRESTED;
player->SetPedState(PED_ARRESTED);
FindPlayerPed()->m_bCanBeDamaged = false;
((CPlayerPed*)player)->m_pArrestingCop = this;
this->RegisterReference((CEntity**) &((CPlayerPed*)player)->m_pArrestingCop);
}
m_nPedState = PED_ARREST_PLAYER;
SetPedState(PED_ARREST_PLAYER);
SetObjective(OBJECTIVE_NONE);
m_prevObjective = OBJECTIVE_NONE;
bIsPointingGunAt = false;
@ -145,10 +147,11 @@ CCopPed::SetArrestPlayer(CPed *player)
player->m_pMyVehicle->bIsHandbrakeOn = true;
player->m_pMyVehicle->SetStatus(STATUS_PLAYER_DISABLED);
}
if (GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED)
if (GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED || GetWeapon()->m_eWeaponType == WEAPONTYPE_BRASSKNUCKLE)
SetCurrentWeapon(WEAPONTYPE_COLT45);
}
// --MIAMI: Done
void
CCopPed::ClearPursuit(void)
{
@ -187,6 +190,7 @@ CCopPed::ClearPursuit(void)
bNotAllowedToDuck = false;
bKindaStayInSamePlace = false;
m_bStopAndShootDisabledZone = false;
field_601 = false;
m_bZoneDisabled = false;
ClearObjective();
if (IsPedInControl()) {
@ -204,10 +208,14 @@ CCopPed::ClearPursuit(void)
}
}
// --MIAMI: Done
// TODO: I don't know why they needed that parameter.
void
CCopPed::SetPursuit(bool ignoreCopLimit)
{
if (CTimer::GetTimeInMilliseconds() < field_61C)
return;
CWanted *wanted = FindPlayerPed()->m_pWanted;
if (m_bIsInPursuit || !IsPedInControl())
return;
@ -233,6 +241,7 @@ CCopPed::SetPursuit(bool ignoreCopLimit)
}
}
// --MIAMI: Done
void
CCopPed::ArrestPlayer(void)
{
@ -298,6 +307,7 @@ CCopPed::ScanForCrimes(void)
}
}
// --MIAMI: Done
void
CCopPed::CopAI(void)
{
@ -315,11 +325,6 @@ CCopPed::CopAI(void)
if (bHitSomethingLastFrame) {
m_bZoneDisabled = true;
m_bIsDisabledCop = true;
#ifdef FIX_BUGS
m_nRoadblockNode = -1;
#else
m_nRoadblockNode = 0;
#endif
bKindaStayInSamePlace = true;
bIsRunning = false;
bNotAllowedToDuck = false;
@ -346,6 +351,27 @@ CCopPed::CopAI(void)
}
if (wantedLevel > 0) {
if (!m_bIsDisabledCop) {
// Turn and shoot the player's vehicle, if possible
if (!m_bIsInPursuit && !GetWeapon()->IsTypeMelee() && FindPlayerVehicle() && m_fDistanceToTarget < CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_fRange) {
if (FindPlayerVehicle()->m_vecMoveSpeed.Magnitude2D() > 0.1f) {
CVector2D distToVeh = GetPosition() - FindPlayerVehicle()->GetPosition();
distToVeh.Normalise();
CVector2D vehSpeed = FindPlayerVehicle()->m_vecMoveSpeed;
vehSpeed.Normalise();
if (DotProduct2D(distToVeh, vehSpeed) > 0.8f) {
SetLookFlag(playerOrHisVeh, true);
SetMoveState(PEDMOVE_STILL);
if (TurnBody()) {
SetAttack(FindPlayerVehicle());
SetShootTimer(CGeneral::GetRandomNumberInRange(500.0f, 1000.0f));
SetAttackTimer(CGeneral::GetRandomNumberInRange(200.0f, 300.0f));
}
} else if (m_nPedState == PED_ATTACK)
RestorePreviousState();
}
}
if (!m_bIsInPursuit || wanted->m_CurrentCops > wanted->m_MaxCops) {
CCopPed *copFarthestToTarget = nil;
float copFarthestToTargetDist = m_fDistanceToTarget;
@ -388,11 +414,14 @@ CCopPed::CopAI(void)
if (wantedLevel > 1 && GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED)
SetCurrentWeapon(WEAPONTYPE_COLT45);
else if (wantedLevel == 1 && GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED && !FindPlayerPed()->m_pCurrentPhysSurface) {
else if (wantedLevel == 1 && GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED && !FindPlayerPed()->m_pCurrentPhysSurface) {
// i.e. if player is on top of car, cop will still use colt45.
SetCurrentWeapon(WEAPONTYPE_UNARMED);
SetCurrentWeapon(GetWeaponSlot(WEAPONTYPE_NIGHTSTICK) >= 0 ? WEAPONTYPE_NIGHTSTICK : WEAPONTYPE_UNARMED);
}
if (m_bBeatingSuspect && GetWeapon()->m_eWeaponType == WEAPONTYPE_NIGHTSTICK)
Say(SOUND_PED_PULLOUTWEAPON);
if (FindPlayerVehicle()) {
if (m_bBeatingSuspect) {
--wanted->m_CopsBeatingSuspect;
@ -403,18 +432,18 @@ CCopPed::CopAI(void)
}
return;
}
float weaponRange = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_fRange;
SetCurrentWeapon(WEAPONTYPE_COLT45);
CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
float weaponRange = weaponInfo->m_fRange;
SetLookFlag(playerOrHisVeh, true);
TurnBody();
SetCurrentWeapon(WEAPONTYPE_COLT45);
if (!bIsDucking) {
if (!bIsDucking || bCrouchWhenShooting && GetCrouchFireAnim(weaponInfo)) {
if (m_attackTimer >= CTimer::GetTimeInMilliseconds()) {
if (m_nPedState != PED_ATTACK && m_nPedState != PED_FIGHT && !m_bZoneDisabled) {
CVector targetDist = playerOrHisVeh->GetPosition() - GetPosition();
if (m_fDistanceToTarget > 30.0f) {
CAnimBlendAssociation* crouchShootAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RBLOCK_CSHOOT);
if (crouchShootAssoc)
crouchShootAssoc->blendDelta = -1000.0f;
if (bIsDucking)
ClearDuck();
// Target is coming onto us
if (DotProduct(playerOrHisVeh->m_vecMoveSpeed, targetDist) > 0.0f) {
@ -432,42 +461,23 @@ CCopPed::CopAI(void)
bNotAllowedToDuck = false;
bDuckAndCover = false;
} else {
// VC checks for != nil compared to buggy behaviour of III. I check for != -1 here.
#ifdef VC_PED_PORTS
// TODO(Miami): Roadblock system is still III
float dotProd;
if (m_nRoadblockNode != -1) {
// TODO(MIAMI): check this, i'm only getting this compile here....
CPathNode *roadBlockNode = &ThePaths.m_pathNodes[CRoadBlocks::RoadBlockNodes[m_nRoadblockNode]];
dotProd = DotProduct2D(playerOrHisVeh->GetPosition() - roadBlockNode->GetPosition(), GetPosition() - roadBlockNode->GetPosition());
} else
dotProd = -1.0f;
if(dotProd >= 0.0f) {
#else
#ifndef FIX_BUGS
float copRoadDotProd, targetRoadDotProd;
#else
float copRoadDotProd = 1.0f, targetRoadDotProd = 1.0f;
if (m_nRoadblockNode != -1)
#endif
{
CTreadable* roadBlockRoad = ThePaths.m_mapObjects[CRoadBlocks::RoadBlockObjects[m_nRoadblockNode]];
CVector2D roadFwd = roadBlockRoad->GetForward();
copRoadDotProd = DotProduct2D(GetPosition() - roadBlockRoad->GetPosition(), roadFwd);
targetRoadDotProd = DotProduct2D(playerOrHisVeh->GetPosition() - roadBlockRoad->GetPosition(), roadFwd);
}
// Roadblock may be towards road's fwd or opposite, so check both
if ((copRoadDotProd >= 0.0f || targetRoadDotProd >= 0.0f)
&& (copRoadDotProd <= 0.0f || targetRoadDotProd <= 0.0f)) {
#endif
bIsPointingGunAt = true;
} else {
if (bIsDucking)
ClearDuck();
m_bIsDisabledCop = false;
bKindaStayInSamePlace = false;
bNotAllowedToDuck = false;
bCrouchWhenShooting = false;
bIsDucking = false;
bDuckAndCover = false;
SetPursuit(false);
}
@ -475,7 +485,6 @@ CCopPed::CopAI(void)
}
} else {
if (m_fDistanceToTarget < weaponRange) {
CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
CVector gunPos = weaponInfo->m_vecFireOffset;
TransformToNode(gunPos, PED_HANDR);
@ -484,6 +493,9 @@ CCopPed::CopAI(void)
if (!CWorld::ProcessLineOfSight(gunPos, playerOrHisVeh->GetPosition(), foundCol, foundEnt,
false, true, false, false, true, false, false)
|| foundEnt && foundEnt == playerOrHisVeh) {
if (m_pPointGunAt)
m_pPointGunAt->CleanUpOldReference((CEntity**) &m_pPointGunAt);
m_pPointGunAt = playerOrHisVeh;
if (playerOrHisVeh)
playerOrHisVeh->RegisterReference((CEntity**) &m_pPointGunAt);
@ -491,7 +503,7 @@ CCopPed::CopAI(void)
SetAttack(playerOrHisVeh);
SetShootTimer(CGeneral::GetRandomNumberInRange(500, 1000));
}
SetAttackTimer(CGeneral::GetRandomNumberInRange(100, 300));
SetAttackTimer(CGeneral::GetRandomNumberInRange(200, 300));
}
SetMoveState(PEDMOVE_STILL);
}
@ -521,10 +533,8 @@ CCopPed::CopAI(void)
ClearObjective();
SetWanderPath(CGeneral::GetRandomNumber() & 7);
}
}
#ifdef VC_PED_PORTS
else {
if (m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT && CharCreatedBy == RANDOM_CHAR) {
} else {
if (m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT && m_objective != OBJECTIVE_HASSLE_CHAR && CharCreatedBy == RANDOM_CHAR) {
for (int i = 0; i < m_numNearPeds; i++) {
CPed *nearPed = m_nearPeds[i];
if (nearPed->CharCreatedBy == RANDOM_CHAR) {
@ -544,12 +554,30 @@ CCopPed::CopAI(void)
nearPed->bBeingChasedByPolice = true;
return;
}
} else {
if (nearPed->m_nPedType != PEDTYPE_COP && !nearPed->IsPlayer()
&& nearPed->IsPedInControl() && m_nHassleTimer < CTimer::GetTimeInMilliseconds()) {
if (nearPed->m_objective == OBJECTIVE_NONE && nearPed->m_nPedState == PED_WANDER_PATH
&& !nearPed->m_pLookTarget && nearPed->m_lookTimer < CTimer::GetTimeInMilliseconds()) {
if ((GetPosition() - nearPed->GetPosition()).MagnitudeSqr() < sq(5.0f)) {
if (CWorld::GetIsLineOfSightClear(GetPosition(), nearPed->GetPosition(),
true, false, false, false, false, false, false)) {
Say(SOUND_PED_COP_REACTION);
SetObjective(OBJECTIVE_HASSLE_CHAR, nearPed);
nearPed->SetObjective(OBJECTIVE_WAIT_ON_FOOT_FOR_COP, this);
m_nHassleTimer = CTimer::GetTimeInMilliseconds() + 100000;
}
}
}
}
}
}
}
}
}
#endif
}
}
} else {
@ -560,18 +588,35 @@ CCopPed::CopAI(void)
bKindaStayInSamePlace = false;
bNotAllowedToDuck = false;
bCrouchWhenShooting = false;
bIsDucking = false;
bDuckAndCover = false;
if (bIsDucking)
ClearDuck();
if (m_pMyVehicle)
SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, m_pMyVehicle);
}
}
}
// --MIAMI: Done except commented things
void
CCopPed::ProcessControl(void)
{
if (m_nCopType == COP_HELI_SWAT)
ProcessHeliSwat();
CPed::ProcessControl();
if (m_bThrowsSpikeTrap) {
// TODO(Miami)
/*
if (CGame::currArea != AREA_MALL)
ProcessStingerCop();
*/
return;
}
// TODO(Miami): CStinger::Process
if (bWasPostponed)
return;
@ -603,25 +648,36 @@ CCopPed::ProcessControl(void)
if (IsPedInControl())
SetIdle();
}
/*
if (m_bIsInPursuit) {
if (player->m_nPedState != PED_ARRESTED && !player->DyingOrDead()) {
switch (m_nCopType) {
case COP_FBI:
Say(SOUND_PED_PURSUIT_FBI);
break;
case COP_SWAT:
Say(SOUND_PED_PURSUIT_SWAT);
break;
case COP_ARMY:
Say(SOUND_PED_PURSUIT_ARMY);
break;
default:
Say(SOUND_PED_PURSUIT_COP);
break;
if (player->m_pWanted->m_CurrentCops == 1) {
Say(SOUND_PED_COP_ALONE);
} else {
int numCopsNear = 0;
for (int i = 0; i < player->m_numNearPeds; ++i) {
CPed *nearPed = player->m_nearPeds[i];
if (nearPed->m_nPedType == PEDTYPE_COP && nearPed->m_nPedState != PED_DEAD)
++numCopsNear;
}
if (numCopsNear <= 3) {
Say(SOUND_PED_COP_LITTLECOPSAROUND);
if (!player->bInVehicle) {
CVector distToPlayer = player->GetPosition() - GetPosition();
if (distToPlayer.MagnitudeSqr() < sq(20.0f)) {
player->Say(SOUND_PED_PLAYER_FARFROMCOPS);
if (player->m_nPedState != PED_ATTACK && player->m_nPedState != PED_AIM_GUN) {
player->SetLookFlag(this, false);
player->SetLookTimer(1000);
}
}
}
} else if ((CGeneral::GetRandomNumber() % 16) == 1) {
Say(SOUND_PED_COP_MANYCOPSAROUND);
}
}
}
} */
}
if (IsPedInControl()) {
CopAI();
@ -668,23 +724,10 @@ CCopPed::ProcessControl(void)
RestorePreviousObjective();
} else {
if (player->m_pMyVehicle && player->m_pMyVehicle->m_nNumGettingIn != 0) {
// This is 1.3f when arresting in car without seeking first (in above)
#if defined(VC_PED_PORTS) || defined(FIX_BUGS)
m_distanceToCountSeekDone = 1.3f;
#else
m_distanceToCountSeekDone = 2.0f;
#endif
}
if (bDuckAndCover) {
#if !defined(GTA3_1_1_PATCH) && !defined(VC_PED_PORTS)
if (!bNotAllowedToDuck && Seek()) {
SetMoveState(PEDMOVE_STILL);
SetMoveAnim();
SetPointGunAt(m_pedInObjective);
}
#endif
} else if (Seek()) {
if (!bDuckAndCover && Seek()) {
CVehicle *playerVeh = FindPlayerVehicle();
if (!playerVeh && player && player->EnteringCar()) {
SetArrestPlayer(player);
@ -715,35 +758,100 @@ CCopPed::ProcessControl(void)
}
}
}
if (!m_bStopAndShootDisabledZone)
return;
bool dontShoot = false;
if (GetIsOnScreen()) {
if (((CTimer::GetFrameCounter() + m_randomSeed) & 0x1F) == 17) {
CEntity *foundBuilding = nil;
CColPoint foundCol;
CVector lookPos = GetPosition() + CVector(0.0f, 0.0f, 0.7f);
CVector camPos = TheCamera.GetGameCamPosition();
CWorld::ProcessLineOfSight(camPos, lookPos, foundCol, foundBuilding,
true, false, false, false, false, false, false);
if (m_pPointGunAt)
Say(SOUND_PED_COP_UNK_129);
// He's at least 15.0 far, in disabled zone, collided into somewhere (that's why m_bStopAndShootDisabledZone set),
// and now has building on front of him. He's stupid, we don't need him.
if (foundBuilding) {
FlagToDestroyWhenNextProcessed();
dontShoot = true;
if (m_bStopAndShootDisabledZone) {
bool dontShoot = false;
if (GetIsOnScreen()) {
if (((CTimer::GetFrameCounter() + m_randomSeed) & 0x1F) == 17) {
CEntity* foundBuilding = nil;
CColPoint foundCol;
CVector lookPos = GetPosition() + CVector(0.0f, 0.0f, 0.7f);
CVector camPos = TheCamera.GetGameCamPosition();
CWorld::ProcessLineOfSight(camPos, lookPos, foundCol, foundBuilding,
true, false, false, false, false, false, false);
// He's at least 15.0 far, in disabled zone, collided into somewhere (that's why m_bStopAndShootDisabledZone set),
// and now has building on front of him. He's stupid, we don't need him.
if (foundBuilding) {
FlagToDestroyWhenNextProcessed();
dontShoot = true;
}
}
} else {
FlagToDestroyWhenNextProcessed();
dontShoot = true;
}
if (!dontShoot) {
bStopAndShoot = true;
bKindaStayInSamePlace = true;
bIsPointingGunAt = true;
SetAttack(m_pedInObjective);
}
}
if (field_624 >= 2 && m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT) {
CVector centre = GetPosition() + CVector(0.f, 0.f, 0.65f);
if (CWorld::TestSphereAgainstWorld(centre, 0.35f, this, true, false, false, false, false, false)) {
field_624 = 0;
m_bStopAndShootDisabledZone = true;
ClearPursuit();
SetObjective(OBJECTIVE_NONE);
SetWanderPath(CGeneral::GetRandomNumberInRange(0,8));
field_61C = CTimer::GetTimeInMilliseconds() + 30000;
} else {
field_624 = 0;
if (GetWeapon()->IsTypeMelee()) {
// TODO(Miami): enum
for (int i = 3; i < 7; i++) {
if (HasWeaponSlot(i)) {
SetCurrentWeapon(i);
break;
}
}
SetMoveState(PEDMOVE_STILL);
bStopAndShoot = true;
}
}
} else {
FlagToDestroyWhenNextProcessed();
dontShoot = true;
}
if (!dontShoot) {
bStopAndShoot = true;
bKindaStayInSamePlace = true;
bIsPointingGunAt = true;
SetAttack(m_pedInObjective);
}
} else if (CTimer::GetTimeStep() / 100.f <= m_fDistanceTravelled)
field_624 = 0;
}
// --MIAMI: Done
void
CCopPed::ProcessHeliSwat(void)
{
CVector bestPos = GetPosition();
SetPedState(PED_ABSEIL);
CPedPlacement::FindZCoorForPed(&bestPos);
if (GetPosition().z - 2.0f >= bestPos.z && m_pRopeEntity) {
m_fAbseilPos += 0.003f * CTimer::GetTimeStep();
m_vecMoveSpeed.z = -0.03f;
m_vecTurnSpeed = CVector(0.f, 0.f, (m_randomSeed % 32) * 0.003f - 0.05f);
CPhysical::ApplyTurnSpeed();
GetMatrix().Reorthogonalise();
CVector posOnRope;
if (CRopes::FindCoorsAlongRope(m_nRopeID, m_fAbseilPos, &posOnRope)) {
SetPosition(posOnRope);
} else {
bUsesCollision = true;
m_vecMoveSpeed = CVector(0.f, 0.f, 0.f);
SetPedState(PED_IDLE);
m_nCopType = COP_SWAT;
SetInTheAir();
bKnockedUpIntoAir = true;
}
Say(SOUND_PED_COP_HELIPILOTPHRASE);
} else {
bUsesCollision = true;
m_vecMoveSpeed = CVector(0.f, 0.f, 0.f);
SetPedState(PED_IDLE);
m_nCopType = COP_SWAT;
SetInTheAir();
bKnockedUpIntoAir = true;
}
}

View File

@ -6,7 +6,8 @@ enum eCopType
COP_STREET = 0,
COP_FBI = 1,
COP_SWAT = 2,
COP_ARMY = 3,
COP_HELI_SWAT = 3,
COP_ARMY = 4,
COP_MIAMIVICE = 5
};
@ -18,13 +19,18 @@ public:
bool m_bIsInPursuit;
bool m_bIsDisabledCop;
int8 field_5FE;
int8 field_5FF;
bool m_bBeatingSuspect;
bool m_bStopAndShootDisabledZone;
bool field_601; // set when police dragging player from car
bool m_bZoneDisabled;
float m_fAbseilPos;
eCopType m_nCopType;
bool m_bThrowsSpikeTrap;
CEntity *m_pRopeEntity; // CHeli or 1
uintptr m_nRopeID;
uint32 m_nHassleTimer;
uint32 field_61C;
int32 field_624;
int8 field_628;
CCopPed(eCopType, int32 modifier = 0);
@ -37,6 +43,7 @@ public:
void ArrestPlayer(void);
void ScanForCrimes(void);
void CopAI(void);
void ProcessHeliSwat(void);
};
#ifndef PED_SKIN

File diff suppressed because it is too large Load Diff

View File

@ -30,6 +30,13 @@ struct PedAudioData
int m_nMaxRandomDelayTime;
};
enum
{
ATTACK_IN_PROGRESS,
CANT_ATTACK,
WATCH_UNTIL_HE_DISAPPEARS,
};
enum eFormation
{
FORMATION_UNDEFINED,
@ -98,7 +105,6 @@ enum PedFightMoves
FIGHTMOVE_PUNCHHOOK,
FIGHTMOVE_PUNCHJAB,
FIGHTMOVE_PUNCH,
FIGHTMOVE_BODYBLOW = FIGHTMOVE_PUNCH,
FIGHTMOVE_LONGKICK,
FIGHTMOVE_ROUNDHOUSE,
// Directionals
@ -460,11 +466,9 @@ public:
uint32 bIsDrowning : 1;
uint32 bDrownsInWater : 1;
//uint32 b156_4
uint32 b156_8 : 1;
uint32 bHeldHostageInCar : 1;
uint32 bIsPlayerFriend : 1;
#ifdef VC_PED_PORTS
uint32 bHeadStuckInCollision : 1;
#endif
uint32 bDeadPedInFrontOfCar : 1;
uint32 bStayInCarOnJack : 1;
@ -472,22 +476,21 @@ public:
uint32 bDoomAim : 1;
uint32 bCanBeShotInVehicle : 1;
//uint32 b157_8
//uint32 b157_10
//uint32 b157_20
uint32 bMakeFleeScream : 1;
uint32 bPushedAlongByCar : 1;
uint32 b157_40 : 1;
uint32 bIgnoreThreatsBehindObjects : 1;
uint32 bNeverEverTargetThisPed : 1;
uint32 bCrouchWhenScared : 1;
uint32 bKnockedOffBike : 1;
//uint32 b158_8
uint32 b158_8 : 1;
uint32 b158_10 : 1;
uint32 bBoughtIceCream : 1;
//uint32 b158_40
uint32 b158_40 : 1;
//uint32 b158_80
// our own flags
uint32 m_ped_flagI40 : 1; // bMakePedsRunToPhonesToReportCrimes makes use of this as runover by car indicator
uint32 m_ped_flagI80 : 1; // KANGAROO_CHEAT define makes use of this as cheat toggle
uint8 m_gangFlags;
@ -595,8 +598,8 @@ public:
uint8 m_wepAccuracy;
CEntity *m_pPointGunAt;
CVector m_vecHitLastPos;
uint32 m_curFightMove;
uint32 m_lastFightMove;
uint32 m_lastHitState; // TODO(Miami): What's this?
uint8 m_fightButtonPressure;
FightState m_fightState;
bool m_takeAStepAfterAttack;
@ -634,8 +637,8 @@ public:
uint32 m_threatFlags;
uint32 m_threatCheck;
uint32 m_lastThreatCheck;
uint32 m_sayType;
uint32 m_sayTimer;
uint32 m_delayedSoundID;
uint32 m_delayedSoundTimer;
uint32 m_lastSoundStart;
uint32 m_soundStart;
uint16 m_lastQueuedSound;
@ -667,6 +670,7 @@ public:
void AimGun(void);
void KillPedWithCar(CVehicle *veh, float impulse);
void Say(uint16 audio);
void Say(uint16 audio, int32 time);
void SetLookFlag(CEntity* target, bool keepTryingToLook, bool cancelPrevious = false);
void SetLookFlag(float direction, bool keepTryingToLook, bool cancelPrevious = false);
void SetLookTimer(int time);
@ -761,6 +765,8 @@ public:
void SetWaitState(eWaitState, void*);
bool FightStrike(CVector&, bool);
void FightHitPed(CPed*, CVector&, CVector&, int16);
int32 ChooseAttackPlayer(uint8, bool);
int32 ChooseAttackAI(uint8, bool);
int GetLocalDirection(const CVector2D &);
void StartFightDefend(uint8, uint8, uint8);
void PlayHitSound(CPed*);
@ -948,6 +954,8 @@ public:
void ClearWaitState(void);
void Undress(const char*);
void Dress(void);
int32 KillCharOnFootMelee(CVector&, CVector&, CVector&);
int32 KillCharOnFootArmed(CVector&, CVector&, CVector&);
bool HasWeaponSlot(uint8 slot) { return m_weapons[slot].m_eWeaponType != WEAPONTYPE_UNARMED; }
CWeapon& GetWeapon(uint8 slot) { return m_weapons[slot]; }
@ -964,6 +972,7 @@ public:
bool Dying(void) { return m_nPedState == PED_DIE; }
bool DyingOrDead(void) { return m_nPedState == PED_DIE || m_nPedState == PED_DEAD; }
bool OnGround(void) { return m_nPedState == PED_FALL || m_nPedState == PED_DIE || m_nPedState == PED_DEAD; }
bool OnGroundOrGettingUp(void) { return OnGround() || m_nPedState == PED_GETUP; }
bool Driving(void) { return m_nPedState == PED_DRIVING; }
bool InVehicle(void) { return bInVehicle && m_pMyVehicle; } // True when ped is sitting/standing in vehicle, not in enter/exit state.
@ -1032,6 +1041,20 @@ public:
else
return (AnimationId)0;
}
static AnimationId GetFinishingAttackAnim(CWeaponInfo* weapon) {
if (!!weapon->m_bFinish3rd)
return ANIM_MELEE_ATTACK_FINISH;
else
return (AnimationId)0;
}
static AnimationId GetSecondFireAnim(CWeaponInfo* weapon) {
if (!!weapon->m_bUse2nd)
return ANIM_WEAPON_FIRE_2ND; // or ANIM_MELEE_ATTACK_2ND
else
return (AnimationId)0;
}
// --
// My additions, because there were many, many instances of that.

View File

@ -70,17 +70,17 @@ const C2dEffect* CVehicleToEffect::ChooseEffect(const CVector& pos) const
if (!m_pVehicle)
return nil;
if (DotProduct(pos - m_pVehicle->GetPosition(), m_pVehicle->GetRight()) > 0.0f) {
if (DotProduct(pos - m_pVehicle->GetPosition(), m_pVehicle->GetForward()) > 0.0f)
return &m_effects[0];
else
return &m_effects[2];
}
else {
if (DotProduct(pos - m_pVehicle->GetPosition(), m_pVehicle->GetForward()) > 0.0f)
return &m_effects[1];
else
return &m_effects[3];
}
else {
if (DotProduct(pos - m_pVehicle->GetPosition(), m_pVehicle->GetForward()) > 0.0f)
return &m_effects[0];
else
return &m_effects[2];
}
}
bool CVehicleToEffect::HasThisEffect(C2dEffect* pEffect) const
@ -137,8 +137,8 @@ void CPedAttractorManager::RemoveIceCreamVanEffects(C2dEffect* pEffect)
for (std::vector<CVehicleToEffect>::const_iterator assoc = vVehicleToEffect.cbegin(); assoc != vVehicleToEffect.cend();) {
if (assoc->GetVehicle() != pVehicle)
return;
size_t total = 0;
for (size_t j = 0; j < NUM_ATTRACTORS_FOR_ICECREAM_VAN; j++) {
uint32 total = 0;
for (uint32 j = 0; j < NUM_ATTRACTORS_FOR_ICECREAM_VAN; j++) {
if (FindAssociatedAttractor(assoc->GetEffect(j), vIceCreamAttractors))
total++;
}
@ -355,13 +355,13 @@ bool CPedAttractor::BroadcastArrival(CPed* pPed)
bool CPedAttractor::BroadcastDeparture(CPed* pPed)
{
int qid = -1;
for (size_t i = 0; i < vWaitingQueue.size(); i++){
for (uint32 i = 0; i < vWaitingQueue.size(); i++){
if (vWaitingQueue[i] == pPed)
qid = i;
}
if (qid < 0)
return false;
for (size_t i = qid + 1; i < vWaitingQueue.size(); i++) {
for (uint32 i = qid + 1; i < vWaitingQueue.size(); i++) {
CVector pos;
float heading;
float time;
@ -401,7 +401,7 @@ bool CPedAttractor::BroadcastDeparture(CPed* pPed)
bool CPedShelterAttractor::BroadcastDeparture(CPed* pPed)
{
int qid = -1;
for (size_t i = 0; i < vWaitingQueue.size(); i++) {
for (uint32 i = 0; i < vWaitingQueue.size(); i++) {
if (vWaitingQueue[i] == pPed)
qid = i;
}

View File

@ -108,8 +108,8 @@ public:
float ComputeDeltaHeading() const;
float ComputeDeltaPos() const;
void ComputeAttractTime(int32 id, bool, float& time) const;
int32 GetNoOfRegisteredPeds() const { return vWaitingQueue.size() + vApproachingQueue.size(); }
int32 ComputeFreeSlot() const { return vWaitingQueue.size(); }
int32 GetNoOfRegisteredPeds() const { return (int32)(vWaitingQueue.size() + vApproachingQueue.size()); }
int32 ComputeFreeSlot() const { return (int32)vWaitingQueue.size(); }
bool IsInQueue(CPed*) const;
bool RegisterPed(CPed*);
bool BroadcastArrival(CPed*);

View File

@ -155,4 +155,14 @@ CPed::Say(uint16 audio)
m_queuedSound = audioToPlay;
}
}
}
// --MIAMI: Done
void
CPed::Say(uint16 audio, int32 time)
{
if (m_delayedSoundID == -1) {
m_delayedSoundID = audio;
m_delayedSoundTimer = CTimer::GetTimeInMilliseconds() + time;
}
}

View File

@ -7,10 +7,11 @@
#include "Sprite.h"
#include "Text.h"
// TODO(Miami)
static char ObjectiveText[][28] = {
"No Obj",
"Wait on Foot",
"Wait on Foot For Cop",
"Flee on Foot Till Safe",
"Guard Spot",
"Guard Area",
@ -21,6 +22,8 @@ static char ObjectiveText[][28] = {
"Flee Char on Foot Till Safe",
"Flee Char on Foot Always",
"GoTo Char on Foot",
"GoTo Char on Foot Walking",
"Hassle Char",
"Follow Char in Formation",
"Leave Car",
"Enter Car as Passenger",
@ -42,10 +45,9 @@ static char ObjectiveText[][28] = {
"Catch Train",
"Buy IceCream",
"Steal Any Car",
"Steal Any Mission Car",
"Mug Char",
#ifdef VC_PED_PORTS
"Leave Car and Die"
#endif
"Leave Car and Die",
};
static char StateText[][18] = {
@ -82,8 +84,14 @@ static char StateText[][18] = {
"Investigate",
"Step away",
"On Fire",
"Sun Bathe",
"Flash",
"Jog",
"Answer Mobile",
"Unknown",
"STATES_NO_AI",
"Abseil",
"Sit",
"Jump",
"Fall",
"GetUp",
@ -106,6 +114,7 @@ static char StateText[][18] = {
"Exit Car",
"Hands Up",
"Arrested",
"Deploying Stinger"
};
static char PersonalityTypeText[][18] = {
@ -283,7 +292,7 @@ CPed::DebugRenderOnePedText(void)
CFont::SetJustifyOff();
CFont::SetColor(CRGBA(255, 255, 0, 255));
CFont::SetBackGroundOnlyTextOn();
CFont::SetFontStyle(0);
CFont::SetFontStyle(1);
AsciiToUnicode(StateText[m_nPedState], gUString);
CFont::PrintString(screenCoords.x, screenCoords.y, gUString);
AsciiToUnicode(ObjectiveText[m_objective], gUString);

View File

@ -4,7 +4,8 @@
#include "PedPlacement.h"
#include "World.h"
void
// --MIAMI: Done
bool
CPedPlacement::FindZCoorForPed(CVector* pos)
{
float zForPed;
@ -32,8 +33,11 @@ CPedPlacement::FindZCoorForPed(CVector* pos)
zForPed = Max(foundColZ, foundColZ2);
if (zForPed > -99.0f)
if (zForPed > -99.0f) {
pos->z = FEET_OFFSET + zForPed;
return true;
}
return false;
}
CEntity*

View File

@ -2,7 +2,7 @@
class CPedPlacement {
public:
static void FindZCoorForPed(CVector* pos);
static bool FindZCoorForPed(CVector* pos);
static CEntity* IsPositionClearOfCars(Const CVector*);
static bool IsPositionClearForPed(const CVector& pos, float radius = -1.0f, int total = -1, CEntity** entities = nil);
};

View File

@ -47,7 +47,7 @@ CPedStats::LoadPedStats(void)
char *buf;
char line[256];
char name[32];
int bp, buflen;
size_t bp, buflen;
int lp, linelen;
int type;
float fleeDist, headingChangeRate, attackStrength, defendWeakness;

View File

@ -43,7 +43,7 @@ CPedType::LoadPedData(void)
char *buf;
char line[256];
char word[32];
int bp, buflen;
size_t bp, buflen;
int lp, linelen;
int type;
uint32 flags;

View File

@ -35,7 +35,7 @@ CPlayerPed::~CPlayerPed()
delete m_pWanted;
}
// --MIAMI: Done except commented out things
// --MIAMI: Done
CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1)
{
m_fMoveSpeed = 0.0f;
@ -53,10 +53,8 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1)
m_nSpeedTimer = 0;
m_bSpeedTimerFlag = false;
// TODO(Miami)
// if (pPointGunAt)
// m_pPointGunAt->CleanUpOldReference(&m_pPointGunAt);
if (m_pPointGunAt)
m_pPointGunAt->CleanUpOldReference(&m_pPointGunAt);
m_pPointGunAt = nil;
SetPedState(PED_IDLE);
#ifndef FIX_BUGS
@ -69,13 +67,14 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1)
m_fAttackButtonCounter = 0.0f;
m_bHaveTargetSelected = false;
m_bHasLockOnTarget = false;
m_bDrunkVisualsWearOff = true;
m_bCanBeDamaged = true;
m_bDrunkVisualsWearOff = false;
m_fWalkAngle = 0.0f;
m_fFPSMoveHeading = 0.0f;
m_pMinigunTopAtomic = nil;
m_fGunSpinSpeed = 0.0;
m_fGunSpinAngle = 0.0;
m_nPadDownPressedInMilliseconds = 0;
m_nTargettableObjects[0] = m_nTargettableObjects[1] = m_nTargettableObjects[2] = m_nTargettableObjects[3] = -1;
unused1 = false;
for (int i = 0; i < 6; i++) {
@ -85,17 +84,16 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1)
}
m_nCheckPlayersIndex = 0;
m_nPadUpPressedInMilliseconds = 0;
m_nPadDownPressedInMilliseconds = 0;
idleAnimBlockIndex = CAnimManager::GetAnimationBlockIndex("playidles");
}
void CPlayerPed::ClearWeaponTarget()
// --MIAMI: Done
void
CPlayerPed::ClearWeaponTarget()
{
if (m_nPedType == PEDTYPE_PLAYER1) {
// TODO(Miami)
// if (m_pPointGunAt)
// m_pPointGunAt->CleanUpOldReference(&m_pPointGunAt);
if (m_pPointGunAt)
m_pPointGunAt->CleanUpOldReference(&m_pPointGunAt);
m_pPointGunAt = nil;
TheCamera.ClearPlayerWeaponMode();
@ -784,6 +782,7 @@ CPlayerPed::PlayerControlM16(CPad *padUsed)
GetWeapon()->Update(m_audioEntityId, nil);
}
// --MIAMI: Done
void
CPlayerPed::PlayerControlFighter(CPad *padUsed)
{
@ -809,6 +808,7 @@ CPlayerPed::PlayerControlFighter(CPad *padUsed)
}
}
// --MIAMI: Done
void
CPlayerPed::PlayerControl1stPersonRunAround(CPad *padUsed)
{
@ -1814,6 +1814,7 @@ CPlayerPed::PlayIdleAnimations(CPad *padUsed)
}
}
// --MIAMI: Done
void
CPlayerPed::RemovePedFromMeleeList(CPed *ped)
{
@ -1826,6 +1827,100 @@ CPlayerPed::RemovePedFromMeleeList(CPed *ped)
ped->m_attackTimer = 0;
}
// --MIAMI: Done
void
CPlayerPed::GetMeleeAttackCoords(CVector& coords, int8 dir, float dist)
{
coords = GetPosition();
switch (dir) {
case 0:
coords.y += dist;
break;
case 1:
coords.x += Sqrt(3.f / 4.f) * dist;
coords.y += 0.5f * dist;
break;
case 2:
coords.x += Sqrt(3.f / 4.f) * dist;
coords.y -= 0.5f * dist;
break;
case 3:
coords.y -= dist;
break;
case 4:
coords.x -= Sqrt(3.f / 4.f) * dist;
coords.y -= 0.5f * dist;
break;
case 5:
coords.x -= Sqrt(3.f / 4.f) * dist;
coords.y += 0.5f * dist;
break;
default:
break;
}
}
// --MIAMI: Done
int32
CPlayerPed::FindMeleeAttackPoint(CPed *victim, CVector &dist, uint32 &endOfAttackOut)
{
endOfAttackOut = 0;
bool thereIsAnEmptySlot = false;
int dirToAttack = -1;
for (int i = 0; i < ARRAY_SIZE(m_pMeleeList); i++) {
CPed* pedAtThisDir = m_pMeleeList[i];
if (pedAtThisDir) {
if (pedAtThisDir == victim) {
dirToAttack = i;
} else {
if (pedAtThisDir->m_attackTimer > endOfAttackOut)
endOfAttackOut = pedAtThisDir->m_attackTimer;
}
} else {
thereIsAnEmptySlot = true;
}
}
// We don't have victim ped in our melee list
if (dirToAttack == -1 && thereIsAnEmptySlot) {
float angle = Atan2(-dist.x, -dist.y);
float adjustedAngle = angle + DEGTORAD(30.0f);
if (adjustedAngle < 0.f)
adjustedAngle += TWOPI;
int wantedDir = Floor(adjustedAngle / DEGTORAD(60.0f));
// And we have another ped at the direction of victim ped, so store victim to next empty direction to it's real direction. (Bollocks)
if (m_pMeleeList[wantedDir]) {
int closestDirToPreferred = -99;
int preferredDir = wantedDir;
for (int i = 0; i < ARRAY_SIZE(m_pMeleeList); i++) {
if (!m_pMeleeList[i]) {
if (Abs(i - preferredDir) < Abs(closestDirToPreferred - preferredDir))
closestDirToPreferred = i;
}
}
if (closestDirToPreferred > 0)
dirToAttack = closestDirToPreferred;
} else {
// Luckily the direction of victim ped is already empty, good
dirToAttack = wantedDir;
}
if (dirToAttack != -1) {
m_pMeleeList[dirToAttack] = victim;
victim->RegisterReference((CEntity**) &m_pMeleeList[dirToAttack]);
if (endOfAttackOut > CTimer::GetTimeInMilliseconds())
victim->m_attackTimer = endOfAttackOut + CGeneral::GetRandomNumberInRange(1000, 2000);
else
victim->m_attackTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(500, 1000);
}
}
return dirToAttack;
}
#ifdef COMPATIBLE_SAVES
#define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); SkipSaveBuf(buf, sizeof(data));
#define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); SkipSaveBuf(buf, sizeof(data));

View File

@ -34,7 +34,7 @@ public:
bool m_bDrunkVisualsWearOff; // TODO(Miami): That may be something else
CVector m_vecSafePos[6]; // safe places from the player, for example behind a tree
CPed *m_pPedAtSafePos[6];
CPlayerPed* m_pMeleeList[6];
CPed *m_pMeleeList[6]; // reachable peds at each direction(6)
char unused1;
int16 m_nCheckPlayersIndex;
float m_fWalkAngle; //angle between heading and walking direction
@ -85,6 +85,8 @@ public:
bool DoesPlayerWantNewWeapon(eWeaponType, bool);
void PlayIdleAnimations(CPad*);
void RemovePedFromMeleeList(CPed*);
void GetMeleeAttackCoords(CVector&, int8, float);
int32 FindMeleeAttackPoint(CPed*, CVector&, uint32&);
static void SetupPlayerPed(int32);
static void DeactivatePlayerPed(int32);

View File

@ -353,7 +353,7 @@ CPopulation::FindCollisionZoneForCoors(CVector *coors, int *safeZoneOut, eLevelN
}
// Then it's transition area
if (*safeZoneOut >= 0)
*levelOut = LEVEL_NONE;
*levelOut = LEVEL_GENERIC;
else
*levelOut = CTheZones::GetLevelFromPosition(coors);
}
@ -559,16 +559,23 @@ CPopulation::AddToPopulation(float minDist, float maxDist, float minDistOffScree
CZoneInfo zoneInfo;
CPed *gangLeader = nil;
bool addCop = false;
bool forceAddingCop = false;
CPlayerInfo *playerInfo = &CWorld::Players[CWorld::PlayerInFocus];
CVector playerCentreOfWorld = FindPlayerCentreOfWorld(CWorld::PlayerInFocus);
CTheZones::GetZoneInfoForTimeOfDay(&playerCentreOfWorld, &zoneInfo);
CWanted *wantedInfo = playerInfo->m_pPed->m_pWanted;
if (wantedInfo->m_nWantedLevel > 2) {
if (ms_nNumCop < wantedInfo->m_MaxCops && !playerInfo->m_pPed->bInVehicle
&& (CCarCtrl::NumLawEnforcerCars >= wantedInfo->m_MaximumLawEnforcerVehicles
if (!CGame::IsInInterior() && (CGeneral::GetRandomNumber() % 32 == 0) && FindPlayerVehicle())
forceAddingCop = true;
uint32 maxCops = CGame::IsInInterior() ? wantedInfo->m_MaxCops * 1.6f : wantedInfo->m_MaxCops;
if ((ms_nNumCop < maxCops || forceAddingCop) &&
(!playerInfo->m_pPed->bInVehicle &&
(CCarCtrl::NumLawEnforcerCars >= wantedInfo->m_MaximumLawEnforcerVehicles
|| CCarCtrl::NumRandomCars >= playerInfo->m_nTrafficMultiplier * CCarCtrl::CarDensityMultiplier
|| CCarCtrl::NumFiretrucksOnDuty + CCarCtrl::NumAmbulancesOnDuty + CCarCtrl::NumParkedCars
+ CCarCtrl::NumMissionCars + CCarCtrl::NumLawEnforcerCars + CCarCtrl::NumRandomCars >= CCarCtrl::MaxNumberOfCarsInUse)) {
+ CCarCtrl::NumMissionCars + CCarCtrl::NumLawEnforcerCars + CCarCtrl::NumRandomCars >= CCarCtrl::MaxNumberOfCarsInUse) || forceAddingCop)) {
addCop = true;
minDist = PedCreationDistMultiplier() * MIN_CREATION_DIST;
maxDist = PedCreationDistMultiplier() * (MIN_CREATION_DIST + CREATION_RANGE);
@ -693,6 +700,9 @@ CPopulation::AddToPopulation(float minDist, float maxDist, float minDistOffScree
if (!farEnoughToAdd)
break;
CPed *newPed = AddPed((ePedType)pedTypeToAdd, modelToAdd, generatedCoors);
if (forceAddingCop && newPed->m_nPedType == PEDTYPE_COP)
((CCopPed*)newPed)->m_bThrowsSpikeTrap = true;
newPed->SetWanderPath(CGeneral::GetRandomNumberInRange(0, 8));
if (i != 0) {
@ -721,10 +731,11 @@ CPopulation::AddToPopulation(float minDist, float maxDist, float minDistOffScree
}
}
// TODO(Miami)
CPed*
CPopulation::AddPedInCar(CVehicle* car, bool isDriver)
{
int defaultModel = MI_MALE01;
const int defaultModel = MI_MALE01;
int miamiViceIndex = 0;
bool imSureThatModelIsLoaded = true;
CVector coors = FindPlayerCoors();
@ -744,10 +755,6 @@ CPopulation::AddPedInCar(CVehicle* car, bool isDriver)
preferredModel = 0;
pedType = PEDTYPE_EMERGENCY;
break;
case MI_FBICAR:
preferredModel = COP_FBI;
pedType = PEDTYPE_COP;
break;
case MI_POLICE:
case MI_PREDATOR:
preferredModel = COP_STREET;
@ -762,24 +769,24 @@ CPopulation::AddPedInCar(CVehicle* car, bool isDriver)
preferredModel = COP_ARMY;
pedType = PEDTYPE_COP;
break;
case MI_VICECHEE: // TODO(MIAMI): figure out new structure of the function
preferredModel = COP_MIAMIVICE;
case MI_FBIRANCH:
preferredModel = COP_FBI;
pedType = PEDTYPE_COP;
miamiViceIndex = (isDriver ? 2 * CCarCtrl::MiamiViceCycle : 2 * CCarCtrl::MiamiViceCycle + 1);
break;
case MI_TAXI:
case MI_CABBIE:
case MI_ZEBRA:
case MI_KAUFMAN:
if (CGeneral::GetRandomTrueFalse()) {
pedType = PEDTYPE_CIVMALE;
preferredModel = MI_TAXI_D;
default:
if (car->GetModelIndex() == MI_TAXI || car->GetModelIndex() == MI_CABBIE || car->GetModelIndex() == MI_ZEBRA || car->GetModelIndex() == MI_KAUFMAN) {
if (isDriver) {
pedType = PEDTYPE_CIVMALE;
preferredModel = MI_TAXI_D;
break;
}
} else if (car->GetModelIndex() == MI_VICECHEE && car->bIsLawEnforcer) {
preferredModel = COP_MIAMIVICE;
pedType = PEDTYPE_COP;
miamiViceIndex = (isDriver ? 2 * CCarCtrl::MiamiViceCycle : 2 * CCarCtrl::MiamiViceCycle + 1);
break;
}
defaultModel = MI_TAXI_D;
// fall through
default:
int gangOfPed = 0;
imSureThatModelIsLoaded = false;
@ -798,8 +805,12 @@ CPopulation::AddPedInCar(CVehicle* car, bool isDriver)
if (preferredModel == -1)
preferredModel = defaultModel;
if (((CPedModelInfo*)CModelInfo::GetModelInfo(preferredModel))->m_carsCanDrive & (1 << carModelInfo->m_vehicleClass))
break;
if (((CPedModelInfo*)CModelInfo::GetModelInfo(preferredModel))->GetRwObject()) {
if (!car->IsPassenger(preferredModel) && !car->IsDriver(preferredModel)) {
if (((CPedModelInfo*)CModelInfo::GetModelInfo(preferredModel))->m_carsCanDrive & (1 << carModelInfo->m_vehicleClass))
break;
}
}
}
if (i == -1)
preferredModel = defaultModel;