Merge pull request #665 from erorcun/miami

CCopPed, except spike traps
This commit is contained in:
erorcun 2020-07-28 17:05:20 +03:00 committed by GitHub
commit ef7afe5f2f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 256 additions and 129 deletions

View File

@ -88,6 +88,7 @@
#include "Zones.h" #include "Zones.h"
#include "Occlusion.h" #include "Occlusion.h"
#include "debugmenu.h" #include "debugmenu.h"
#include "Ropes.h"
eLevelName CGame::currLevel; eLevelName CGame::currLevel;
int32 CGame::currArea; int32 CGame::currArea;
@ -403,9 +404,11 @@ bool CGame::Initialise(const char* datFile)
CRubbish::Init(); CRubbish::Init();
CClouds::Init(); CClouds::Init();
CSpecialFX::Init(); CSpecialFX::Init();
CRopes::Init();
CWaterCannons::Init(); CWaterCannons::Init();
CBridge::Init(); CBridge::Init();
CGarages::Init(); CGarages::Init();
LoadingScreen("Loading the Game", "Position dynamic objects", nil);
LoadingScreen("Loading the Game", "Initialise vehicle paths", nil); LoadingScreen("Loading the Game", "Initialise vehicle paths", nil);
CTrain::InitTrains(); CTrain::InitTrains();
CPlane::InitPlanes(); CPlane::InitPlanes();
@ -416,6 +419,7 @@ bool CGame::Initialise(const char* datFile)
if ( !TheMemoryCard.m_bWantToLoad ) if ( !TheMemoryCard.m_bWantToLoad )
{ {
#endif #endif
LoadingScreen("Loading the Game", "Start script", nil);
CTheScripts::StartTestScript(); CTheScripts::StartTestScript();
CTheScripts::Process(); CTheScripts::Process();
TheCamera.Process(); TheCamera.Process();
@ -426,6 +430,9 @@ bool CGame::Initialise(const char* datFile)
CCollision::ms_collisionInMemory = currLevel; CCollision::ms_collisionInMemory = currLevel;
for (int i = 0; i < MAX_PADS; i++) for (int i = 0; i < MAX_PADS; i++)
CPad::GetPad(i)->Clear(true); CPad::GetPad(i)->Clear(true);
// TODO(Miami)
// DMAudio.SetStartingTrackPositions(1);
DMAudio.ChangeMusicMode(MUSICMODE_GAME);
return true; return true;
} }
@ -546,6 +553,7 @@ void CGame::ReInitGameObjectVariables(void)
CRemote::Init(); CRemote::Init();
#endif #endif
CSpecialFX::Init(); CSpecialFX::Init();
CRopes::Init();
CWaterCannons::Init(); CWaterCannons::Init();
CParticle::ReloadConfig(); CParticle::ReloadConfig();
@ -718,6 +726,7 @@ void CGame::Process(void)
CGarages::Update(); CGarages::Update();
CRubbish::Update(); CRubbish::Update();
CSpecialFX::Update(); CSpecialFX::Update();
CRopes::Update();
CTimeCycle::Update(); CTimeCycle::Update();
if (CReplay::ShouldStandardCameraBeProcessed()) if (CReplay::ShouldStandardCameraBeProcessed())
TheCamera.Process(); TheCamera.Process();

View File

@ -31,14 +31,14 @@ CRope::Update(void)
for(i = 1; i < ARRAY_SIZE(m_pos); i++){ for(i = 1; i < ARRAY_SIZE(m_pos); i++){
CVector prevPos = m_pos[i]; CVector prevPos = m_pos[i];
m_pos[i] += m_speed[i]*step*CTimer::GetTimeStep(); m_pos[i] += m_speed[i]*step*CTimer::GetTimeStep();
m_pos[0].z -= 0.05f*CTimer::GetTimeStep(); m_pos[i].z -= 0.05f*CTimer::GetTimeStep();
CVector dist = m_pos[i] - m_pos[i-1]; CVector dist = m_pos[i] - m_pos[i-1];
m_pos[i] = m_pos[i-1] + dist/dist.Magnitude()*0.625f; m_pos[i] = m_pos[i-1] + (0.625f/dist.Magnitude())*dist;
m_speed[i] = (m_pos[i] - prevPos)/CTimer::GetTimeStep(); m_speed[i] = (m_pos[i] - prevPos)/CTimer::GetTimeStep();
} }
if(!m_bWasRegistered && m_pos[0].z < 0.0f) if(!m_bWasRegistered && m_pos[0].z < 0.0f)
m_bActive = false; m_bActive = false;
m_bWasRegistered = true; m_bWasRegistered = false;
} }
void void
@ -60,7 +60,11 @@ CRope::Render(void)
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil); RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
if(RwIm3DTransform(TempBufferRenderVertices, ARRAY_SIZE(m_pos), nil, rwIM3D_VERTEXXYZ|rwIM3D_VERTEXRGBA)){ if(RwIm3DTransform(TempBufferRenderVertices, ARRAY_SIZE(m_pos), nil, rwIM3D_VERTEXXYZ|rwIM3D_VERTEXRGBA)){
#ifdef FIX_BUGS
RwIm3DRenderIndexedPrimitive(rwPRIMTYPELINELIST, RopeIndices, 2*(ARRAY_SIZE(m_pos)-1)); RwIm3DRenderIndexedPrimitive(rwPRIMTYPELINELIST, RopeIndices, 2*(ARRAY_SIZE(m_pos)-1));
#else
RwIm3DRenderIndexedPrimitive(rwPRIMTYPEPOLYLINE, RopeIndices, 2*(ARRAY_SIZE(m_pos)-1));
#endif
RwIm3DEnd(); RwIm3DEnd();
} }
} }
@ -159,7 +163,7 @@ CRopes::CreateRopeWithSwatComingDown(CVector pos)
if(!CStreaming::HasModelLoaded(MI_SWAT) || !RegisterRope(ropeId+100, pos, true)) if(!CStreaming::HasModelLoaded(MI_SWAT) || !RegisterRope(ropeId+100, pos, true))
return false; return false;
CCopPed *swat = (CCopPed*)CPopulation::AddPed(PEDTYPE_COP, COP_ARMY, pos); CCopPed *swat = (CCopPed*)CPopulation::AddPed(PEDTYPE_COP, COP_HELI_SWAT, pos);
swat->bUsesCollision = false; swat->bUsesCollision = false;
swat->m_pRopeEntity = (CEntity*)1; swat->m_pRopeEntity = (CEntity*)1;
swat->m_nRopeID = 100 + ropeId; swat->m_nRopeID = 100 + ropeId;

View File

@ -62,6 +62,7 @@
#include "SceneEdit.h" #include "SceneEdit.h"
#include "debugmenu.h" #include "debugmenu.h"
#include "Occlusion.h" #include "Occlusion.h"
#include "Ropes.h"
GlobalScene Scene; GlobalScene Scene;
@ -873,6 +874,7 @@ RenderEffects(void)
CGlass::Render(); CGlass::Render();
CWaterCannons::Render(); CWaterCannons::Render();
CSpecialFX::Render(); CSpecialFX::Render();
CRopes::Render();
CShadows::RenderStaticShadows(); CShadows::RenderStaticShadows();
CShadows::RenderStoredShadows(); CShadows::RenderStoredShadows();
CSkidmarks::Render(); CSkidmarks::Render();

View File

@ -16,6 +16,8 @@
#include "CarCtrl.h" #include "CarCtrl.h"
#include "Renderer.h" #include "Renderer.h"
#include "Camera.h" #include "Camera.h"
#include "PedPlacement.h"
#include "Ropes.h"
CCopPed::CCopPed(eCopType copType, int32 modifier) : CPed(PEDTYPE_COP) 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; m_wepAccuracy = 76;
break; break;
case COP_SWAT: case COP_SWAT:
case COP_HELI_SWAT:
SetModelIndex(MI_SWAT); SetModelIndex(MI_SWAT);
GiveDelayedWeapon(WEAPONTYPE_UZI, 1000); GiveDelayedWeapon(WEAPONTYPE_UZI, 1000);
SetCurrentWeapon(WEAPONTYPE_UZI); SetCurrentWeapon(WEAPONTYPE_UZI);
m_fArmour = 50.0f; m_fArmour = 50.0f;
m_wepSkills = 32; /* TODO: what is this? seems unused */ m_wepSkills = 32; /* TODO: what is this? seems unused */
m_wepAccuracy = 64; m_wepAccuracy = 68;
break; break;
case COP_ARMY: case COP_ARMY:
SetModelIndex(MI_ARMY); SetModelIndex(MI_ARMY);
@ -77,18 +80,21 @@ CCopPed::CCopPed(eCopType copType, int32 modifier) : CPed(PEDTYPE_COP)
field_5FE = 1; field_5FE = 1;
m_bIsDisabledCop = false; m_bIsDisabledCop = false;
m_attackTimer = 0; m_attackTimer = 0;
m_bBeatingSuspect = false;
m_bStopAndShootDisabledZone = false; m_bStopAndShootDisabledZone = false;
field_601 = false; field_601 = false;
m_bZoneDisabled = false; m_bZoneDisabled = false;
field_628 = -1; field_628 = -1;
m_nRoadblockNode = -1; // TODO(Miami): this will be nil m_nRoadblockNode = -1; // TODO(Miami): this will be nil
m_bThrowsSpikeTrap = false; m_bThrowsSpikeTrap = false;
field_5FF = 0;
m_pRopeEntity = nil; m_pRopeEntity = nil;
m_fAbseilPos = 0.0f; m_fAbseilPos = 0.0f;
m_bBeatingSuspect = false; m_nHassleTimer = 0;
m_pPointGunAt = nil; field_61C = 0;
field_624 = 0; field_624 = 0;
if (m_pPointGunAt)
m_pPointGunAt->CleanUpOldReference((CEntity**)&m_pPointGunAt);
m_pPointGunAt = nil;
} }
CCopPed::~CCopPed() CCopPed::~CCopPed()
@ -96,24 +102,17 @@ CCopPed::~CCopPed()
ClearPursuit(); ClearPursuit();
} }
// --MIAMI: Done
// Parameter should always be CPlayerPed, but it seems they considered making civilians arrestable at some point // Parameter should always be CPlayerPed, but it seems they considered making civilians arrestable at some point
void void
CCopPed::SetArrestPlayer(CPed *player) CCopPed::SetArrestPlayer(CPed *player)
{ {
if (!IsPedInControl() || !player) if (!IsPedInControl() || !player)
return; return;
/*
switch (m_nCopType) { player->Say(SOUND_PED_PLAYER_REACTTOCOP);
case COP_FBI:
Say(SOUND_PED_ARREST_FBI);
break;
case COP_SWAT:
Say(SOUND_PED_ARREST_SWAT);
break;
default:
Say(SOUND_PED_ARREST_COP); Say(SOUND_PED_ARREST_COP);
break;
} */
if (player->EnteringCar()) { if (player->EnteringCar()) {
if (CTimer::GetTimeInMilliseconds() > m_nPedStateTimer) if (CTimer::GetTimeInMilliseconds() > m_nPedStateTimer)
return; return;
@ -128,14 +127,14 @@ CCopPed::SetArrestPlayer(CPed *player)
} else if (player->m_nPedState != PED_DIE && player->m_nPedState != PED_DEAD && player->m_nPedState != PED_ARRESTED) { } 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_nLastPedState = player->m_nPedState;
player->m_nPedState = PED_ARRESTED; player->SetPedState(PED_ARRESTED);
FindPlayerPed()->m_bCanBeDamaged = false; FindPlayerPed()->m_bCanBeDamaged = false;
((CPlayerPed*)player)->m_pArrestingCop = this; ((CPlayerPed*)player)->m_pArrestingCop = this;
this->RegisterReference((CEntity**) &((CPlayerPed*)player)->m_pArrestingCop); this->RegisterReference((CEntity**) &((CPlayerPed*)player)->m_pArrestingCop);
} }
m_nPedState = PED_ARREST_PLAYER; SetPedState(PED_ARREST_PLAYER);
SetObjective(OBJECTIVE_NONE); SetObjective(OBJECTIVE_NONE);
m_prevObjective = OBJECTIVE_NONE; m_prevObjective = OBJECTIVE_NONE;
bIsPointingGunAt = false; bIsPointingGunAt = false;
@ -148,10 +147,11 @@ CCopPed::SetArrestPlayer(CPed *player)
player->m_pMyVehicle->bIsHandbrakeOn = true; player->m_pMyVehicle->bIsHandbrakeOn = true;
player->m_pMyVehicle->SetStatus(STATUS_PLAYER_DISABLED); 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); SetCurrentWeapon(WEAPONTYPE_COLT45);
} }
// --MIAMI: Done
void void
CCopPed::ClearPursuit(void) CCopPed::ClearPursuit(void)
{ {
@ -190,6 +190,7 @@ CCopPed::ClearPursuit(void)
bNotAllowedToDuck = false; bNotAllowedToDuck = false;
bKindaStayInSamePlace = false; bKindaStayInSamePlace = false;
m_bStopAndShootDisabledZone = false; m_bStopAndShootDisabledZone = false;
field_601 = false;
m_bZoneDisabled = false; m_bZoneDisabled = false;
ClearObjective(); ClearObjective();
if (IsPedInControl()) { if (IsPedInControl()) {
@ -207,10 +208,14 @@ CCopPed::ClearPursuit(void)
} }
} }
// --MIAMI: Done
// TODO: I don't know why they needed that parameter. // TODO: I don't know why they needed that parameter.
void void
CCopPed::SetPursuit(bool ignoreCopLimit) CCopPed::SetPursuit(bool ignoreCopLimit)
{ {
if (CTimer::GetTimeInMilliseconds() < field_61C)
return;
CWanted *wanted = FindPlayerPed()->m_pWanted; CWanted *wanted = FindPlayerPed()->m_pWanted;
if (m_bIsInPursuit || !IsPedInControl()) if (m_bIsInPursuit || !IsPedInControl())
return; return;
@ -236,6 +241,7 @@ CCopPed::SetPursuit(bool ignoreCopLimit)
} }
} }
// --MIAMI: Done
void void
CCopPed::ArrestPlayer(void) CCopPed::ArrestPlayer(void)
{ {
@ -301,6 +307,7 @@ CCopPed::ScanForCrimes(void)
} }
} }
// --MIAMI: Done
void void
CCopPed::CopAI(void) CCopPed::CopAI(void)
{ {
@ -318,11 +325,6 @@ CCopPed::CopAI(void)
if (bHitSomethingLastFrame) { if (bHitSomethingLastFrame) {
m_bZoneDisabled = true; m_bZoneDisabled = true;
m_bIsDisabledCop = true; m_bIsDisabledCop = true;
#ifdef FIX_BUGS
m_nRoadblockNode = -1;
#else
m_nRoadblockNode = 0;
#endif
bKindaStayInSamePlace = true; bKindaStayInSamePlace = true;
bIsRunning = false; bIsRunning = false;
bNotAllowedToDuck = false; bNotAllowedToDuck = false;
@ -349,6 +351,27 @@ CCopPed::CopAI(void)
} }
if (wantedLevel > 0) { if (wantedLevel > 0) {
if (!m_bIsDisabledCop) { 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) { if (!m_bIsInPursuit || wanted->m_CurrentCops > wanted->m_MaxCops) {
CCopPed *copFarthestToTarget = nil; CCopPed *copFarthestToTarget = nil;
float copFarthestToTargetDist = m_fDistanceToTarget; float copFarthestToTargetDist = m_fDistanceToTarget;
@ -391,11 +414,14 @@ CCopPed::CopAI(void)
if (wantedLevel > 1 && GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED) if (wantedLevel > 1 && GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED)
SetCurrentWeapon(WEAPONTYPE_COLT45); 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. // 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 (FindPlayerVehicle()) {
if (m_bBeatingSuspect) { if (m_bBeatingSuspect) {
--wanted->m_CopsBeatingSuspect; --wanted->m_CopsBeatingSuspect;
@ -406,18 +432,18 @@ CCopPed::CopAI(void)
} }
return; 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); SetLookFlag(playerOrHisVeh, true);
TurnBody(); TurnBody();
SetCurrentWeapon(WEAPONTYPE_COLT45); if (!bIsDucking || bCrouchWhenShooting && GetCrouchFireAnim(weaponInfo)) {
if (!bIsDucking) {
if (m_attackTimer >= CTimer::GetTimeInMilliseconds()) { if (m_attackTimer >= CTimer::GetTimeInMilliseconds()) {
if (m_nPedState != PED_ATTACK && m_nPedState != PED_FIGHT && !m_bZoneDisabled) { if (m_nPedState != PED_ATTACK && m_nPedState != PED_FIGHT && !m_bZoneDisabled) {
CVector targetDist = playerOrHisVeh->GetPosition() - GetPosition(); CVector targetDist = playerOrHisVeh->GetPosition() - GetPosition();
if (m_fDistanceToTarget > 30.0f) { if (m_fDistanceToTarget > 30.0f) {
CAnimBlendAssociation* crouchShootAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RBLOCK_CSHOOT); if (bIsDucking)
if (crouchShootAssoc) ClearDuck();
crouchShootAssoc->blendDelta = -1000.0f;
// Target is coming onto us // Target is coming onto us
if (DotProduct(playerOrHisVeh->m_vecMoveSpeed, targetDist) > 0.0f) { if (DotProduct(playerOrHisVeh->m_vecMoveSpeed, targetDist) > 0.0f) {
@ -435,42 +461,23 @@ CCopPed::CopAI(void)
bNotAllowedToDuck = false; bNotAllowedToDuck = false;
bDuckAndCover = false; bDuckAndCover = false;
} else { } else {
// VC checks for != nil compared to buggy behaviour of III. I check for != -1 here. // TODO(Miami): Roadblock system is still III
#ifdef VC_PED_PORTS
float dotProd; float dotProd;
if (m_nRoadblockNode != -1) { if (m_nRoadblockNode != -1) {
// TODO(MIAMI): check this, i'm only getting this compile here....
CPathNode *roadBlockNode = &ThePaths.m_pathNodes[CRoadBlocks::RoadBlockNodes[m_nRoadblockNode]]; CPathNode *roadBlockNode = &ThePaths.m_pathNodes[CRoadBlocks::RoadBlockNodes[m_nRoadblockNode]];
dotProd = DotProduct2D(playerOrHisVeh->GetPosition() - roadBlockNode->GetPosition(), GetPosition() - roadBlockNode->GetPosition()); dotProd = DotProduct2D(playerOrHisVeh->GetPosition() - roadBlockNode->GetPosition(), GetPosition() - roadBlockNode->GetPosition());
} else } else
dotProd = -1.0f; dotProd = -1.0f;
if(dotProd >= 0.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; bIsPointingGunAt = true;
} else { } else {
if (bIsDucking)
ClearDuck();
m_bIsDisabledCop = false; m_bIsDisabledCop = false;
bKindaStayInSamePlace = false; bKindaStayInSamePlace = false;
bNotAllowedToDuck = false; bNotAllowedToDuck = false;
bCrouchWhenShooting = false; bCrouchWhenShooting = false;
bIsDucking = false;
bDuckAndCover = false; bDuckAndCover = false;
SetPursuit(false); SetPursuit(false);
} }
@ -478,7 +485,6 @@ CCopPed::CopAI(void)
} }
} else { } else {
if (m_fDistanceToTarget < weaponRange) { if (m_fDistanceToTarget < weaponRange) {
CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
CVector gunPos = weaponInfo->m_vecFireOffset; CVector gunPos = weaponInfo->m_vecFireOffset;
TransformToNode(gunPos, PED_HANDR); TransformToNode(gunPos, PED_HANDR);
@ -487,6 +493,9 @@ CCopPed::CopAI(void)
if (!CWorld::ProcessLineOfSight(gunPos, playerOrHisVeh->GetPosition(), foundCol, foundEnt, if (!CWorld::ProcessLineOfSight(gunPos, playerOrHisVeh->GetPosition(), foundCol, foundEnt,
false, true, false, false, true, false, false) false, true, false, false, true, false, false)
|| foundEnt && foundEnt == playerOrHisVeh) { || foundEnt && foundEnt == playerOrHisVeh) {
if (m_pPointGunAt)
m_pPointGunAt->CleanUpOldReference((CEntity**) &m_pPointGunAt);
m_pPointGunAt = playerOrHisVeh; m_pPointGunAt = playerOrHisVeh;
if (playerOrHisVeh) if (playerOrHisVeh)
playerOrHisVeh->RegisterReference((CEntity**) &m_pPointGunAt); playerOrHisVeh->RegisterReference((CEntity**) &m_pPointGunAt);
@ -494,7 +503,7 @@ CCopPed::CopAI(void)
SetAttack(playerOrHisVeh); SetAttack(playerOrHisVeh);
SetShootTimer(CGeneral::GetRandomNumberInRange(500, 1000)); SetShootTimer(CGeneral::GetRandomNumberInRange(500, 1000));
} }
SetAttackTimer(CGeneral::GetRandomNumberInRange(100, 300)); SetAttackTimer(CGeneral::GetRandomNumberInRange(200, 300));
} }
SetMoveState(PEDMOVE_STILL); SetMoveState(PEDMOVE_STILL);
} }
@ -524,10 +533,8 @@ CCopPed::CopAI(void)
ClearObjective(); ClearObjective();
SetWanderPath(CGeneral::GetRandomNumber() & 7); SetWanderPath(CGeneral::GetRandomNumber() & 7);
} }
} } else {
#ifdef VC_PED_PORTS if (m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT && m_objective != OBJECTIVE_HASSLE_CHAR && CharCreatedBy == RANDOM_CHAR) {
else {
if (m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT && CharCreatedBy == RANDOM_CHAR) {
for (int i = 0; i < m_numNearPeds; i++) { for (int i = 0; i < m_numNearPeds; i++) {
CPed *nearPed = m_nearPeds[i]; CPed *nearPed = m_nearPeds[i];
if (nearPed->CharCreatedBy == RANDOM_CHAR) { if (nearPed->CharCreatedBy == RANDOM_CHAR) {
@ -547,12 +554,30 @@ CCopPed::CopAI(void)
nearPed->bBeingChasedByPolice = true; nearPed->bBeingChasedByPolice = true;
return; 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 { } else {
@ -563,18 +588,35 @@ CCopPed::CopAI(void)
bKindaStayInSamePlace = false; bKindaStayInSamePlace = false;
bNotAllowedToDuck = false; bNotAllowedToDuck = false;
bCrouchWhenShooting = false; bCrouchWhenShooting = false;
bIsDucking = false;
bDuckAndCover = false; bDuckAndCover = false;
if (bIsDucking)
ClearDuck();
if (m_pMyVehicle) if (m_pMyVehicle)
SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, m_pMyVehicle); SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, m_pMyVehicle);
} }
} }
} }
// --MIAMI: Done except commented things
void void
CCopPed::ProcessControl(void) CCopPed::ProcessControl(void)
{ {
if (m_nCopType == COP_HELI_SWAT)
ProcessHeliSwat();
CPed::ProcessControl(); CPed::ProcessControl();
if (m_bThrowsSpikeTrap) {
// TODO(Miami)
/*
if (CGame::currArea != AREA_MALL)
ProcessStingerCop();
*/
return;
}
// TODO(Miami): CStinger::Process
if (bWasPostponed) if (bWasPostponed)
return; return;
@ -606,25 +648,36 @@ CCopPed::ProcessControl(void)
if (IsPedInControl()) if (IsPedInControl())
SetIdle(); SetIdle();
} }
/*
if (m_bIsInPursuit) { if (m_bIsInPursuit) {
if (player->m_nPedState != PED_ARRESTED && !player->DyingOrDead()) { if (player->m_nPedState != PED_ARRESTED && !player->DyingOrDead()) {
switch (m_nCopType) { if (player->m_pWanted->m_CurrentCops == 1) {
case COP_FBI: Say(SOUND_PED_COP_ALONE);
Say(SOUND_PED_PURSUIT_FBI); } else {
break; int numCopsNear = 0;
case COP_SWAT: for (int i = 0; i < player->m_numNearPeds; ++i) {
Say(SOUND_PED_PURSUIT_SWAT); CPed *nearPed = player->m_nearPeds[i];
break; if (nearPed->m_nPedType == PEDTYPE_COP && nearPed->m_nPedState != PED_DEAD)
case COP_ARMY: ++numCopsNear;
Say(SOUND_PED_PURSUIT_ARMY); }
break; if (numCopsNear <= 3) {
default: Say(SOUND_PED_COP_LITTLECOPSAROUND);
Say(SOUND_PED_PURSUIT_COP); if (!player->bInVehicle) {
break; 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()) { if (IsPedInControl()) {
CopAI(); CopAI();
@ -671,23 +724,10 @@ CCopPed::ProcessControl(void)
RestorePreviousObjective(); RestorePreviousObjective();
} else { } else {
if (player->m_pMyVehicle && player->m_pMyVehicle->m_nNumGettingIn != 0) { 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; m_distanceToCountSeekDone = 1.3f;
#else
m_distanceToCountSeekDone = 2.0f;
#endif
} }
if (bDuckAndCover) { if (!bDuckAndCover && Seek()) {
#if !defined(GTA3_1_1_PATCH) && !defined(VC_PED_PORTS)
if (!bNotAllowedToDuck && Seek()) {
SetMoveState(PEDMOVE_STILL);
SetMoveAnim();
SetPointGunAt(m_pedInObjective);
}
#endif
} else if (Seek()) {
CVehicle *playerVeh = FindPlayerVehicle(); CVehicle *playerVeh = FindPlayerVehicle();
if (!playerVeh && player && player->EnteringCar()) { if (!playerVeh && player && player->EnteringCar()) {
SetArrestPlayer(player); SetArrestPlayer(player);
@ -718,9 +758,11 @@ CCopPed::ProcessControl(void)
} }
} }
} }
if (!m_bStopAndShootDisabledZone)
return;
if (m_pPointGunAt)
Say(SOUND_PED_COP_UNK_129);
if (m_bStopAndShootDisabledZone) {
bool dontShoot = false; bool dontShoot = false;
if (GetIsOnScreen()) { if (GetIsOnScreen()) {
if (((CTimer::GetFrameCounter() + m_randomSeed) & 0x1F) == 17) { if (((CTimer::GetFrameCounter() + m_randomSeed) & 0x1F) == 17) {
@ -750,3 +792,66 @@ CCopPed::ProcessControl(void)
SetAttack(m_pedInObjective); 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 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_STREET = 0,
COP_FBI = 1, COP_FBI = 1,
COP_SWAT = 2, COP_SWAT = 2,
COP_ARMY = 3, COP_HELI_SWAT = 3,
COP_ARMY = 4,
COP_MIAMIVICE = 5 COP_MIAMIVICE = 5
}; };
@ -18,7 +19,6 @@ public:
bool m_bIsInPursuit; bool m_bIsInPursuit;
bool m_bIsDisabledCop; bool m_bIsDisabledCop;
int8 field_5FE; int8 field_5FE;
int8 field_5FF;
bool m_bBeatingSuspect; bool m_bBeatingSuspect;
bool m_bStopAndShootDisabledZone; bool m_bStopAndShootDisabledZone;
bool field_601; // set when police dragging player from car bool field_601; // set when police dragging player from car
@ -28,6 +28,8 @@ public:
bool m_bThrowsSpikeTrap; bool m_bThrowsSpikeTrap;
CEntity *m_pRopeEntity; // CHeli or 1 CEntity *m_pRopeEntity; // CHeli or 1
uintptr m_nRopeID; uintptr m_nRopeID;
uint32 m_nHassleTimer;
uint32 field_61C;
int32 field_624; int32 field_624;
int8 field_628; int8 field_628;
@ -41,6 +43,7 @@ public:
void ArrestPlayer(void); void ArrestPlayer(void);
void ScanForCrimes(void); void ScanForCrimes(void);
void CopAI(void); void CopAI(void);
void ProcessHeliSwat(void);
}; };
#ifndef PED_SKIN #ifndef PED_SKIN

View File

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

View File

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

View File

@ -731,12 +731,12 @@ CHeli::SendDownSwat(void)
float groundZ = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z, nil); float groundZ = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z, nil);
if(Abs(FindPlayerCoors().z - groundZ) < 2.5f && CRopes::RegisterRope((uintptr)this + m_numSwat-1, pos, false)){ if(Abs(FindPlayerCoors().z - groundZ) < 2.5f && CRopes::RegisterRope((uintptr)this + m_numSwat-1, pos, false)){
CCopPed *swat = (CCopPed*)CPopulation::AddPed(PEDTYPE_COP, COP_ARMY, pos); CCopPed *swat = (CCopPed*)CPopulation::AddPed(PEDTYPE_COP, COP_HELI_SWAT, pos);
swat->bUsesCollision = false; swat->bUsesCollision = false;
swat->m_pRopeEntity = this; swat->m_pRopeEntity = this;
RegisterReference(&swat->m_pRopeEntity); RegisterReference(&swat->m_pRopeEntity);
m_numSwat--; m_numSwat--;
swat->m_nRopeID = m_numSwat; swat->m_nRopeID = (uintptr)this + m_numSwat;
m_aSwatState[m_numSwat] = 255; m_aSwatState[m_numSwat] = 255;
CAnimManager::BlendAnimation(swat->GetClump(), ASSOCGRP_STD, ANIM_ABSEIL, 4.0f); CAnimManager::BlendAnimation(swat->GetClump(), ASSOCGRP_STD, ANIM_ABSEIL, 4.0f);
return true; return true;