diff options
-rw-r--r-- | src/control/Script.cpp | 2 | ||||
-rw-r--r-- | src/control/TrafficLights.cpp | 14 | ||||
-rw-r--r-- | src/control/TrafficLights.h | 2 | ||||
-rw-r--r-- | src/core/EventList.h | 1 | ||||
-rw-r--r-- | src/core/Frontend.cpp | 1 | ||||
-rw-r--r-- | src/core/Pad.cpp | 96 | ||||
-rw-r--r-- | src/core/Stats.cpp | 24 | ||||
-rw-r--r-- | src/core/Stats.h | 1 | ||||
-rw-r--r-- | src/core/re3.cpp | 4 | ||||
-rw-r--r-- | src/peds/Ped.cpp | 901 | ||||
-rw-r--r-- | src/peds/Ped.h | 19 | ||||
-rw-r--r-- | src/render/Fluff.cpp | 6 | ||||
-rw-r--r-- | src/render/Fluff.h | 2 | ||||
-rw-r--r-- | src/render/Hud.cpp | 51 | ||||
-rw-r--r-- | src/text/Text.cpp | 14 | ||||
-rw-r--r-- | src/text/Text.h | 1 |
16 files changed, 814 insertions, 325 deletions
diff --git a/src/control/Script.cpp b/src/control/Script.cpp index 61980d75..c560e500 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -3773,7 +3773,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command) CPed* pNearPed = ped->m_nearPeds[i]; if (pNearPed->m_leader == ped) { pNearPed->Teleport(pos); - pNearPed->PositionPedOutOfCollision(); // TODO(MIAMI): this is PositionAnyPedOutOfCollision!!! + pNearPed->PositionAnyPedOutOfCollision(); } } } diff --git a/src/control/TrafficLights.cpp b/src/control/TrafficLights.cpp index 54c97d06..5559b1c4 100644 --- a/src/control/TrafficLights.cpp +++ b/src/control/TrafficLights.cpp @@ -18,6 +18,8 @@ // TODO: figure out the meaning of this enum { SOME_FLAG = 0x80 }; +bool CTrafficLights::bGreenLightsCheat; + void CTrafficLights::DisplayActualLight(CEntity *ent) { @@ -310,6 +312,12 @@ CTrafficLights::LightForPeds(void) uint8 CTrafficLights::LightForCars1(void) { + if (CWeather::Wind > 1.1f) + return CAR_LIGHTS_GREEN; + + if (bGreenLightsCheat) + return CAR_LIGHTS_GREEN; + uint32 period = CTimer::GetTimeInMilliseconds() % 16384; if(period < 5000) @@ -323,6 +331,12 @@ CTrafficLights::LightForCars1(void) uint8 CTrafficLights::LightForCars2(void) { + if (CWeather::Wind > 1.1f) + return CAR_LIGHTS_GREEN; + + if (bGreenLightsCheat) + return CAR_LIGHTS_GREEN; + uint32 period = CTimer::GetTimeInMilliseconds() % 16384; if(period < 6000) diff --git a/src/control/TrafficLights.h b/src/control/TrafficLights.h index f3df6cd5..6cd5e04a 100644 --- a/src/control/TrafficLights.h +++ b/src/control/TrafficLights.h @@ -16,6 +16,8 @@ enum { class CTrafficLights { public: + static bool bGreenLightsCheat; + static void DisplayActualLight(CEntity *ent); static void ScanForLightsOnMap(void); static int FindTrafficLightType(CEntity *light); diff --git a/src/core/EventList.h b/src/core/EventList.h index 0531aed7..dcca1270 100644 --- a/src/core/EventList.h +++ b/src/core/EventList.h @@ -24,6 +24,7 @@ enum eEventType EVENT_CAR_SET_ON_FIRE, EVENT_ASSAULT_NASTYWEAPON, EVENT_ASSAULT_NASTYWEAPON_POLICE, + EVENT_UNK, // Not on SA it seems EVENT_ICECREAM, EVENT_ATM, EVENT_SHOPSTALL, diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index 715e9061..cdecb8b4 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -5369,6 +5369,7 @@ CMenuManager::ConstructStatLine(int rowIdx) STAT_LINE("FEST_CC", &CStats::CriminalsCaught, false, nil); STAT_LINE("FEST_FE", &CStats::FiresExtinguished, false, nil); STAT_LINE("DAYPLC", &(nTemp = CTimer::GetTimeInMilliseconds() + 100), false, nil); + //TODO(MIAMI): move this function to the CStats and add reading of Stat lines tied with "MEDIA" for the "CHASESTAT" cheatcode return counter; #undef STAT_LINE diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp index 42b26c63..193ca1c5 100644 --- a/src/core/Pad.cpp +++ b/src/core/Pad.cpp @@ -47,6 +47,7 @@ #include "platform.h" #include "Stats.h" #include "CarCtrl.h" +#include "TrafficLights.h" #ifdef GTA_PS2 #include "eetypes.h" @@ -208,15 +209,20 @@ void HealthCheat() } } -void VehicleCheat(bool something, int model) +void VehicleCheat(int model) { CHud::SetHelpMessage(TheText.Get("CHEAT1"), true); - CStreaming::RequestModel(model, 0); - CStreaming::LoadAllRequestedModels(something); + CStreaming::RequestModel(model, STREAMFLAGS_DONT_REMOVE); + CStreaming::LoadAllRequestedModels(false); if (CStreaming::ms_aInfoForModel[model].m_loadState == STREAMSTATE_LOADED) { CHud::SetHelpMessage(TheText.Get("CHEAT1"), true); - int32 node = ThePaths.FindNodeClosestToCoors(FindPlayerCoors(), PATH_CAR, 100.0f); + if (!(CStreaming::ms_aInfoForModel[model].m_loadState & STREAMFLAGS_DONT_REMOVE)) { + CStreaming::SetModelIsDeletable(model); + CStreaming::SetModelTxdIsDeletable(model); + } + + int32 node = ThePaths.FindNodeClosestToCoors(FindPlayerCoors(), PATH_CAR, 100.0f); if (node < 0) return; #ifdef FIX_BUGS @@ -362,16 +368,16 @@ void SunnyWeatherCheat() CWeather::ForceWeatherNow(WEATHER_SUNNY); } -void CloudyWeatherCheat() +void ExtraSunnyWeatherCheat() { CHud::SetHelpMessage(TheText.Get("CHEAT7"), true); - CWeather::ForceWeatherNow(WEATHER_CLOUDY); + CWeather::ForceWeatherNow(WEATHER_EXTRA_SUNNY); } -void StormyWeatherCheat() +void CloudyWeatherCheat() { CHud::SetHelpMessage(TheText.Get("CHEAT7"), true); - CWeather::ForceWeatherNow(WEATHER_HURRICANE); + CWeather::ForceWeatherNow(WEATHER_CLOUDY); } void RainyWeatherCheat() @@ -442,6 +448,12 @@ void PinkCarsCheat() gbPinkCars = true; } +void TrafficLightsCheat() +{ + CHud::SetHelpMessage(TheText.Get("CHEAT1"), true); + CTrafficLights::bGreenLightsCheat = true; +} + void MadCarsCheat() { CHud::SetHelpMessage(TheText.Get("CHEAT1"), true); @@ -548,6 +560,11 @@ void FlyingFishCheat(void) CVehicle::bCheat8 = !CVehicle::bCheat8; } +void DoShowChaseStatCheat(void) { + CHud::SetHelpMessage(TheText.Get("CHEAT1"), true); + CStats::ShowChaseStatOnScreen = 1; +} + bool CControllerState::CheckForInput(void) { @@ -1030,7 +1047,7 @@ void CPad::AddToCheatString(char c) // "CCCCCC321TCT" - CIRCLE CIRCLE CIRCLE CIRCLE CIRCLE CIRCLE R1 L2 L1 TRIANGLE CIRCLE TRIANGLE else if ( !_CHEATCMP("TCT123CCCCCC") ) - VehicleCheat(true, MI_RHINO); + VehicleCheat(MI_RHINO); // "CCCSSSSS1TCT" - CIRCLE CIRCLE CIRCLE SQUARE SQUARE SQUARE SQUARE SQUARE L1 TRIANGLE CIRCLE TRIANGLE else if ( !_CHEATCMP("TCT1SSSSSCCC") ) @@ -1142,19 +1159,22 @@ void CPad::AddToPCCheatString(char c) // "APLEASANTDAY" else if (!Cheat_strncmp(KeyBoardCheatString, "\\FKU[\\VHFW]I")) { KeyBoardCheatString[0] = ' '; - CloudyWeatherCheat(); + SunnyWeatherCheat(); } // "ALOVELYDAY" else if (!Cheat_strncmp(KeyBoardCheatString, "\\FKZY`YVML")) { KeyBoardCheatString[0] = ' '; - SunnyWeatherCheat(); + ExtraSunnyWeatherCheat(); } // "ABITDRIEG" - + else if (!Cheat_strncmp(KeyBoardCheatString, "JJPSQoLIB")) { + KeyBoardCheatString[0] = ' '; + CloudyWeatherCheat(); + } // "CATSANDDOGS" else if (!Cheat_strncmp(KeyBoardCheatString, "VLVEQiDZULP")) { KeyBoardCheatString[0] = ' '; - StormyWeatherCheat(); + RainyWeatherCheat(); } // "CANTSEEATHING" else if (!Cheat_strncmp(KeyBoardCheatString, "JSPIa\\HLT_[IJ")) { @@ -1164,10 +1184,13 @@ void CPad::AddToPCCheatString(char c) // "PANZER" else if (!Cheat_strncmp(KeyBoardCheatString, "UJaONk")) { KeyBoardCheatString[0] = ' '; - VehicleCheat(true, MI_RHINO); + VehicleCheat(MI_RHINO); } // "LIFEISPASSINGMEBY" - + else if (!Cheat_strncmp(KeyBoardCheatString, "\\GLNTiLZTL][PeSOh")) { + KeyBoardCheatString[0] = ' '; + FastWeatherCheat(); + } // "BIGBANG" else if (!Cheat_strncmp(KeyBoardCheatString, "JSHCTdE")) { KeyBoardCheatString[0] = ' '; @@ -1221,6 +1244,7 @@ void CPad::AddToPCCheatString(char c) // "CHASESTAT" else if (!Cheat_strncmp(KeyBoardCheatString, "WF[TRnDOD")) { KeyBoardCheatString[0] = ' '; + DoShowChaseStatCheat(); } // "CHICKSWITHGUNS" else if (!Cheat_strncmp(KeyBoardCheatString, "VS\\HUoL^TVPQOc")) { @@ -1235,6 +1259,7 @@ void CPad::AddToPCCheatString(char c) // "GREENLIGHT" else if (!Cheat_strncmp(KeyBoardCheatString, "WMNJYiHLSR")) { KeyBoardCheatString[0] = ' '; + TrafficLightsCheat(); } // "MIAMITRAFFIC" else if (!Cheat_strncmp(KeyBoardCheatString, "FNMGNmWPNLVU")) { @@ -1254,47 +1279,47 @@ void CPad::AddToPCCheatString(char c) // "TRAVELINSTYLE" else if (!Cheat_strncmp(KeyBoardCheatString, "HQ`U`iLSFaNZ[")) { KeyBoardCheatString[0] = ' '; - VehicleCheat(true, MI_BLOODRA); + VehicleCheat(MI_BLOODRA); } // "THELASTRIDE" else if (!Cheat_strncmp(KeyBoardCheatString, "HIPSanDSFSa")) { KeyBoardCheatString[0] = ' '; - VehicleCheat(true, MI_ROMERO); + VehicleCheat(MI_ROMERO); } // "ROCKANDROLLCAR" else if (!Cheat_strncmp(KeyBoardCheatString, "UFJMYjUKOLXKVr")) { KeyBoardCheatString[0] = ' '; - VehicleCheat(true, MI_LOVEFIST); + VehicleCheat(MI_LOVEFIST); } // "RUBBISHCAR" else if (!Cheat_strncmp(KeyBoardCheatString, "UFJI`dEIV]")) { KeyBoardCheatString[0] = ' '; - VehicleCheat(true, MI_TRASH); + VehicleCheat(MI_TRASH); } // "GETTHEREQUICKLY" else if (!Cheat_strncmp(KeyBoardCheatString, "\\QRDVpTLSPU\\[eT")) { KeyBoardCheatString[0] = ' '; - VehicleCheat(true, MI_BLOODRB); + VehicleCheat(MI_BLOODRB); } // "GETTHEREFAST" else if (!Cheat_strncmp(KeyBoardCheatString, "WXHGRmHOU_RO")) { KeyBoardCheatString[0] = ' '; - VehicleCheat(true, MI_SABRETUR); + VehicleCheat(MI_SABRETUR); } // "BETTERTHANWALKING" else if (!Cheat_strncmp(KeyBoardCheatString, "JSPLY\\ZUBSaZLtaK^")) { KeyBoardCheatString[0] = ' '; - VehicleCheat(true, MI_CADDY); + VehicleCheat(MI_CADDY); } // "GETTHEREFASTINDEED" else if (!Cheat_strncmp(KeyBoardCheatString, "GJLE[dWZBQfZLvRXa[^WHL")) { KeyBoardCheatString[0] = ' '; - VehicleCheat(true, MI_HOTRINA); + VehicleCheat(MI_HOTRINA); } // "GETTHEREAMAZINGLYFAST" else if (!Cheat_strncmp(KeyBoardCheatString, "WXHGfgJUJeNUHe_Kdg^HJ")) { KeyBoardCheatString[0] = ' '; - VehicleCheat(true, MI_HOTRINB); + VehicleCheat(MI_HOTRINB); } // LOOKLIKELANCE else if (!Cheat_strncmp(KeyBoardCheatString, "HHUBY`NPMV\\WS")) { @@ -1346,6 +1371,16 @@ void CPad::AddToPCCheatString(char c) KeyBoardCheatString[0] = ' '; ChangePlayerModel("igdiaz"); } + // DEEPFRIEDMARSBARS + else if (!Cheat_strncmp(KeyBoardCheatString, "VWHC`mDTEPVZMpRK")) { + KeyBoardCheatString[0] = ' '; + gfTommyFatness = 0.26f; + } + // PROGRAMMER + else if (!Cheat_strncmp(KeyBoardCheatString, "UJTNNmJVS[")) { + KeyBoardCheatString[0] = ' '; + gfTommyFatness = -0.3f; + } // SEAWAYS else if (!Cheat_strncmp(KeyBoardCheatString, "V^HXN`V")) { KeyBoardCheatString[0] = ' '; @@ -1366,17 +1401,6 @@ void CPad::AddToPCCheatString(char c) KeyBoardCheatString[0] = ' '; FannyMagnetCheat(); } - // "ILOVESCOTLAND" - if (!_CHEATCMP("DNALTOCSEVOLI")) - RainyWeatherCheat(); - - // "MADWEATHER" - if (!_CHEATCMP("REHTAEWDAM")) - FastWeatherCheat(); - - // "CHITTYCHITTYBB" - if (!_CHEATCMP("BBYTTIHCYTTIHC")) - ChittyChittyBangBangCheat(); // "NASTYLIMBSCHEAT" if (!_CHEATCMP("TAEHCSBMILYTSAN")) @@ -3117,6 +3141,8 @@ void CPad::ResetCheats(void) gbBlackCars = false; gbPinkCars = false; CCarCtrl::bMadDriversCheat = false; + CTrafficLights::bGreenLightsCheat = false; + CStats::ShowChaseStatOnScreen = 0; gbFastTime = false; CTimer::SetTimeScale(1.0f); } diff --git a/src/core/Stats.cpp b/src/core/Stats.cpp index 9a5066ce..373c295d 100644 --- a/src/core/Stats.cpp +++ b/src/core/Stats.cpp @@ -340,6 +340,30 @@ wchar *CStats::FindCriminalRatingString() return TheText.Get(CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney > 10000000 ? "RATNG52" : "RATNG51"); } +wchar *CStats::FindChaseString(float fMediaLevel) { + if (fMediaLevel < 20.0f) return TheText.Get("MEDIA1"); + if (fMediaLevel < 50.0f) return TheText.Get("MEDIA2"); + if (fMediaLevel < 75.0f) return TheText.Get("MEDIA3"); + if (fMediaLevel < 100.0f) return TheText.Get("MEDIA4"); + if (fMediaLevel < 150.0f) return TheText.Get("MEDIA5"); + if (fMediaLevel < 200.0f) return TheText.Get("MEDIA6"); + if (fMediaLevel < 250.0f) return TheText.Get("MEDIA7"); + if (fMediaLevel < 300.0f) return TheText.Get("MEDIA8"); + if (fMediaLevel < 350.0f) return TheText.Get("MEDIA9"); + if (fMediaLevel < 400.0f) return TheText.Get("MEDIA10"); + if (fMediaLevel < 500.0f) return TheText.Get("MEDIA11"); + if (fMediaLevel < 600.0f) return TheText.Get("MEDIA12"); + if (fMediaLevel < 700.0f) return TheText.Get("MEDIA13"); + if (fMediaLevel < 800.0f) return TheText.Get("MEDIA14"); + if (fMediaLevel < 900.0f) return TheText.Get("MEDIA15"); + if (fMediaLevel < 1000.0f) return TheText.Get("MEDIA16"); + if (fMediaLevel < 1200.0f) return TheText.Get("MEDIA17"); + if (fMediaLevel < 1400.0f) return TheText.Get("MEDIA18"); + if (fMediaLevel < 1600.0f) return TheText.Get("MEDIA19"); + if (fMediaLevel < 1800.0f) return TheText.Get("MEDIA20"); + return TheText.Get("MEDIA21"); +} + int32 CStats::FindCriminalRatingNumber() { int32 rating; diff --git a/src/core/Stats.h b/src/core/Stats.h index 21cb67ef..49f84657 100644 --- a/src/core/Stats.h +++ b/src/core/Stats.h @@ -118,6 +118,7 @@ public: static void RegisterLevelFireMission(int32); static void AnotherFireExtinguished(); static wchar *FindCriminalRatingString(); + static wchar *FindChaseString(float fMediaLevel); static void AnotherKillFrenzyPassed(); static void SetTotalNumberKillFrenzies(int32); static void SetTotalNumberMissions(int32); diff --git a/src/core/re3.cpp b/src/core/re3.cpp index 0b80862e..1393314c 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -80,7 +80,7 @@ void WeaponCheat1(); void WeaponCheat2(); void WeaponCheat3(); void HealthCheat(); -void VehicleCheat(bool something, int model); +void VehicleCheat(int model); void BlowUpCarsCheat(); void ChangePlayerCheat(); void MayhemCheat(); @@ -353,7 +353,7 @@ DebugMenuPopulate(void) DebugMenuAddCmd("Cheats", "Health", HealthCheat); DebugMenuAddCmd("Cheats", "Wanted level up", WantedLevelUpCheat); DebugMenuAddCmd("Cheats", "Wanted level down", WantedLevelDownCheat); - DebugMenuAddCmd("Cheats", "Tank", []() { VehicleCheat(true, MI_TAXI); }); + DebugMenuAddCmd("Cheats", "Tank", []() { VehicleCheat(MI_TAXI); }); DebugMenuAddCmd("Cheats", "Blow up cars", BlowUpCarsCheat); DebugMenuAddCmd("Cheats", "Change player", ChangePlayerCheat); DebugMenuAddCmd("Cheats", "Mayhem", MayhemCheat); diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index 0cc5eeaf..f197ae2c 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -65,6 +65,7 @@ #include "Bike.h" #include "WindModifiers.h" #include "CutsceneShadow.h" +#include "Clock.h" #define CAN_SEE_ENTITY_ANGLE_THRESHOLD DEGTORAD(60.0f) @@ -145,6 +146,8 @@ void *CPed::operator new(size_t sz, int handle) { return CPools::GetPedPool()->N void CPed::operator delete(void *p, size_t sz) { CPools::GetPedPool()->Delete((CPed*)p); } void CPed::operator delete(void *p, int handle) { CPools::GetPedPool()->Delete((CPed*)p); } +float gfTommyFatness = 1.0f; + // --MIAMI: Done CPed::~CPed(void) { @@ -285,7 +288,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) m_fleeFromPosX = 0; m_fleeFromPosY = 0; m_fleeTimer = 0; - pThreatEx = nil; + m_threatEx = nil; m_vecSeekPosEx = CVector(0.0f, 0.0f, 0.0f); m_distanceToCountSeekDoneEx = 0.0f; m_nWaitState = WAITSTATE_FALSE; @@ -422,8 +425,8 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) bHasAlreadyUsedAttractor = false; b155_2 = false; bCarPassenger = false; - b155_8 = false; - b155_10 = false; + bFleeWhenStanding = false; + bGotUpOfMyOwnAccord = false; bMiamiViceCop = false; bMoneyHasBeenGivenByScript = false; bHasBeenPhotographed = false; @@ -444,7 +447,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) bDoomAim = true; bCanBeShotInVehicle = true; bPushedAlongByCar = false; - b157_40 = false; + bRemoveMeWhenIGotIntoCar = false; bIgnoreThreatsBehindObjects = false; bNeverEverTargetThisPed = false; @@ -453,7 +456,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) b158_8 = false; bCollectBusFare = false; bBoughtIceCream = false; - b158_40 = false; + bDonePositionOutOfCollision = false; b158_80 = false; if (CGeneral::GetRandomNumber() & 3) @@ -462,9 +465,9 @@ CPed::CPed(uint32 pedType) : m_pedIK(this) bHasACamera = true; if (CGeneral::GetRandomNumberInRange(0.0f, 1.0f) <= 0.95f) - b157_8 = false; + bCanGiveUpSunbathing = false; else - b157_8 = true; + bCanGiveUpSunbathing = true; m_audioEntityId = DMAudio.CreateEntity(AUDIOTYPE_PHYSICAL, this); DMAudio.SetEntityStatus(m_audioEntityId, 1); @@ -2097,6 +2100,8 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase) m_fRotationDest = veh->GetForward().Heading(); } else if (veh->bIsBus) { m_fRotationDest = 0.5f * PI + veh->GetForward().Heading(); + } else if (m_vehEnterType == CAR_WINDSCREEN) { + m_fRotationDest = veh->GetForward().Heading() + PI; } else { m_fRotationDest = veh->GetForward().Heading(); } @@ -2317,7 +2322,6 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase) if (seatPosMult > 0.2f || vehIsUpsideDown || veh->IsBike()) { SetPosition(neededPos); - SetHeading(m_fRotationCur); } else { CMatrix vehDoorMat(veh->GetMatrix()); @@ -4082,7 +4086,7 @@ CPed::ClearAll(void) m_fleeFromPosY = 0.0f; m_fleeFrom = nil; m_fleeTimer = 0; - pThreatEx = nil; + m_threatEx = nil; bUsesCollision = true; ClearPointGunAt(); bIsPointingGunAt = false; @@ -4181,6 +4185,7 @@ CPed::SetStoredState(void) } } +// --MIAMI: Done void CPed::SetDie(AnimationId animId, float delta, float speed) { @@ -4196,6 +4201,7 @@ CPed::SetDie(AnimationId animId, float delta, float speed) if (DyingOrDead()) return; + CAnimBlendAssociation *dieAssoc = nil; if (m_nPedState == PED_FALL || m_nPedState == PED_GETUP) delta *= 0.5f; @@ -4203,7 +4209,7 @@ CPed::SetDie(AnimationId animId, float delta, float speed) ClearAll(); m_fHealth = 0.0f; if (m_nPedState == PED_DRIVING) { - if (!IsPlayer()) + if (!IsPlayer() && (!m_pMyVehicle || !m_pMyVehicle->IsBike())) FlagToDestroyWhenNextProcessed(); } else if (bInVehicle) { if (m_pVehicleAnim) @@ -4212,11 +4218,11 @@ CPed::SetDie(AnimationId animId, float delta, float speed) QuitEnteringCar(); } - m_nPedState = PED_DIE; + SetPedState(PED_DIE); if (animId == NUM_STD_ANIMS) { bIsPedDieAnimPlaying = false; } else { - CAnimBlendAssociation *dieAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, animId, delta); + dieAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, animId, delta); if (speed > 0.0f) dieAssoc->speed = speed; @@ -4230,10 +4236,17 @@ CPed::SetDie(AnimationId animId, float delta, float speed) Say(SOUND_PED_DEATH); if (m_nLastPedState == PED_ENTER_CAR || m_nLastPedState == PED_CARJACK) QuitEnteringCar(); + if (!bInVehicle) StopNonPartialAnims(); m_bloodyFootprintCountOrDeathTime = CTimer::GetTimeInMilliseconds(); + if (!CGame::nastyGame && animId == ANIM_FLOOR_HIT) { + if (dieAssoc) { + dieAssoc->SetCurrentTime(dieAssoc->hierarchy->totalLength - 0.01f); + dieAssoc->SetRun(); + } + } } // --MIAMI: Done except commented things @@ -4787,6 +4800,7 @@ CPed::ClearFall(void) SetGetUp(); } +// --MIAMI: Done void CPed::SetGetUp(void) { @@ -4809,7 +4823,7 @@ CPed::SetGetUp(void) CVehicle *collidingVeh = (CVehicle*)m_pCollidingEntity; CVehicle *veh = (CVehicle*)CPedPlacement::IsPositionClearOfCars(&GetPosition()); - if (veh && veh->m_vehType != VEHICLE_TYPE_BIKE || + if (veh && veh->m_vehType != VEHICLE_TYPE_BIKE && veh != m_attachedTo || collidingVeh && collidingVeh->IsVehicle() && collidingVeh->m_vehType != VEHICLE_TYPE_BIKE && ((uint8)(CTimer::GetFrameCounter() + m_randomSeed + 5) % 8 || CCollision::ProcessColModels(GetMatrix(), *GetColModel(), collidingVeh->GetMatrix(), *collidingVeh->GetColModel(), @@ -4829,6 +4843,7 @@ CPed::SetGetUp(void) bGetUpAnimStarted = true; m_pCollidingEntity = nil; bKnockedUpIntoAir = false; + bKnockedOffBike = false; CAnimBlendAssociation *animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_SPRINT); if (animAssoc) { if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN)) { @@ -4839,12 +4854,21 @@ CPed::SetGetUp(void) animAssoc->flags |= ASSOC_DELETEFADEDOUT; } - if (RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FRONTAL)) + if (m_nWaitState == WAITSTATE_SUN_BATHE_IDLE) { + m_headingRate = 0.0f; + + // TODO(Miami): Looks like that should've been another getup anim but R* forgot it. Visit here later + if (bFleeWhenStanding && m_threatEx) + animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_GETUP1, 1000.0f); + else + animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_GETUP1, 1000.0f); + + } else if (RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FRONTAL)) animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_GETUP_FRONT, 1000.0f); else animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_GETUP1, 1000.0f); - animAssoc->SetFinishCallback(PedGetupCB,this); + animAssoc->SetFinishCallback(PedGetupCB, this); } else { m_fHealth = 0.0f; SetDie(NUM_STD_ANIMS, 4.0f, 0.0f); @@ -6478,7 +6502,7 @@ CPed::SetFlee(CVector2D const &from, int time) } } -// --MIAMI: Only some part is done +// --MIAMI: Done void CPed::SetWaitState(eWaitState state, void *time) { @@ -6630,7 +6654,7 @@ CPed::SetWaitState(eWaitState state, void *time) case WAITSTATE_SIT_DOWN: animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_SEAT_DOWN, 4.0f); animAssoc->SetFinishCallback(FinishedWaitCB, this); - m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 10000; + m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 100000; break; case WAITSTATE_SIT_UP: animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_SEAT_UP, 4.0f); @@ -6638,7 +6662,7 @@ CPed::SetWaitState(eWaitState state, void *time) m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 100000; break; case WAITSTATE_SIT_IDLE: - animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_SEAT_IDLE, 5000.0f); + animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_SEAT_IDLE, 128.f); animAssoc->SetFinishCallback(FinishedWaitCB, this); if (time) m_nWaitTimer = CTimer::GetTimeInMilliseconds() + *(int*)time; @@ -6646,13 +6670,19 @@ CPed::SetWaitState(eWaitState state, void *time) m_nWaitTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(25000, 30000); break; case WAITSTATE_USE_ATM: - animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_ATM, 5000.0f); + animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_ATM, 4.0f); animAssoc->SetFinishCallback(FinishedWaitCB, this); if (time) m_nWaitTimer = CTimer::GetTimeInMilliseconds() + *(int*)time; else m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 100000; break; + case WAITSTATE_SUN_BATHE_IDLE: + m_headingRate = 0.0f; + animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_SUNBATHE, ANIM_SUNBATHE, 4.0f); + animAssoc->SetDeleteCallback(DeleteSunbatheIdleAnimCB, this); + m_nWaitTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(50000, 100000); + break; case WAITSTATE_FAST_FALL: SetFall(-1, ANIM_KO_SKID_FRONT, true); break; @@ -6660,14 +6690,31 @@ CPed::SetWaitState(eWaitState state, void *time) CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_BOMBER, 4.0f); m_nWaitTimer = CTimer::GetTimeInMilliseconds() + *(int*)time; break; + case WAITSTATE_GROUND_ATTACK: + { + CWeaponInfo* currentWeapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType); + if (!currentWeapon) + break; + if (GetFireAnimGround(currentWeapon, false)) { + if (!RpAnimBlendClumpGetAssociation(GetClump(), GetFireAnimGround(currentWeapon, false))) { + m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 5000; + CAnimBlendAssociation* newAnim = CAnimManager::BlendAnimation(GetClump(), + currentWeapon->m_AnimToPlay, GetFireAnimGround(currentWeapon, false), 8.0f); + newAnim->SetDeleteCallback(FinishedWaitCB, this); + } + } + break; + } case WAITSTATE_LANCESITTING: CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_LANCE, ANIM_SUNBATHE, 4.0f); break; - case WAITSTATE_SUN_BATHE_PRE: - case WAITSTATE_SUN_BATHE_DOWN: - case WAITSTATE_SUN_BATHE_IDLE: - case WAITSTATE_GROUND_ATTACK: case WAITSTATE_PLAYANIM_HANDSUP_SIMPLE: + animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_HANDSUP, 4.0f); + animAssoc->flags &= ~ASSOC_FADEOUTWHENDONE; + animAssoc->flags |= ASSOC_DELETEFADEDOUT; + animAssoc->SetDeleteCallback(FinishedWaitCB, this); + m_nWaitTimer = CTimer::GetTimeInMilliseconds() + *(int*)time; + break; default: ClearWaitState(); RestoreHeadingRate(); @@ -8374,7 +8421,7 @@ CPed::FinishedWaitCB(CAnimBlendAssociation *animAssoc, void *arg) ped->Wait(); } -// --MIAMI: Some part is done +// --MIAMI: Done void CPed::Wait(void) { @@ -8575,28 +8622,24 @@ CPed::Wait(void) } else if (m_pedStats->m_fear <= 100 - pedWeLook->m_pedStats->m_temper) { if (GetWeapon()->IsTypeMelee()) { -#ifdef VC_PED_PORTS if(m_pedStats->m_flags & STAT_GUN_PANIC) { -#endif - SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE, m_pLookTarget); - if (m_nPedState == PED_FLEE_ENTITY || m_nPedState == PED_FLEE_POS) { + SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE, m_pLookTarget); + if (m_nPedState == PED_FLEE_ENTITY || m_nPedState == PED_FLEE_POS) { - bUsePedNodeSeek = true; - m_pNextPathNode = nil; - } - if (m_nMoveState != PEDMOVE_RUN) - SetMoveState(PEDMOVE_WALK); + bUsePedNodeSeek = true; + m_pNextPathNode = nil; + } + if (m_nMoveState != PEDMOVE_RUN) + SetMoveState(PEDMOVE_WALK); - if (m_nPedType != PEDTYPE_COP) { - ProcessObjective(); - SetMoveState(PEDMOVE_WALK); - } -#ifdef VC_PED_PORTS + if (m_nPedType != PEDTYPE_COP) { + ProcessObjective(); + SetMoveState(PEDMOVE_WALK); + } } else { SetObjective(OBJECTIVE_NONE); SetWanderPath(CGeneral::GetRandomNumberInRange(0.0f, 8.0f)); } -#endif } else { SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, m_pLookTarget); SetObjectiveTimer(20000); @@ -8646,9 +8689,7 @@ CPed::Wait(void) bBoughtIceCream = true; } ClearWaitState(); - } -#ifdef VC_PED_PORTS - else if (m_nWaitState == WAITSTATE_PLAYANIM_TAXI) { + } else if (m_nWaitState == WAITSTATE_PLAYANIM_TAXI) { if (m_pedInObjective) { if (m_objective == OBJECTIVE_GOTO_CHAR_ON_FOOT || m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT) { @@ -8660,7 +8701,6 @@ CPed::Wait(void) } } } -#endif break; case WAITSTATE_FINISH_FLEE: @@ -8689,7 +8729,14 @@ CPed::Wait(void) if (m_attractor) GetPedAttractorManager()->BroadcastDeparture(this, m_attractor); ClearWaitState(); - //TODO(MIAMI): scan for threats! + if (bFleeWhenStanding) { + if (m_threatEx) { + SetFlee(m_threatEx, 10000); + bFleeWhenStanding = false; + m_threatEx = nil; + Say(SOUND_PED_FLEE_SPRINT); + } + } } break; case WAITSTATE_SIT_IDLE: @@ -8699,10 +8746,26 @@ CPed::Wait(void) m_fRotationDest = m_fRotationCur; bTurnedAroundOnAttractor = false; } - // TODO(MIAMI): scan for threats! if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) { ClearWaitState(); SetWaitState(WAITSTATE_SIT_UP, 0); + } else { + if (m_fleeFrom && m_fleeFrom->IsVehicle()) { + m_pNextPathNode = nil; + m_threatEx = m_threatEntity; + bFleeWhenStanding = true; + ClearWaitState(); + SetWaitState(WAITSTATE_SIT_UP, 0); + } else { + uint32 threatFlag = ScanForThreats(); + if (threatFlag == PED_FLAG_GUN || threatFlag == PED_FLAG_EXPLOSION || threatFlag == PED_FLAG_DEADPEDS) { + m_pNextPathNode = nil; + m_threatEx = m_threatEntity; + bFleeWhenStanding = true; + ClearWaitState(); + SetWaitState(WAITSTATE_SIT_UP, 0); + } + } } break; case WAITSTATE_USE_ATM: @@ -8712,6 +8775,56 @@ CPed::Wait(void) ClearWaitState(); } break; + case WAITSTATE_SUN_BATHE_IDLE: + if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer && bCanGiveUpSunbathing) { + m_pNextPathNode = nil; + bGotUpOfMyOwnAccord = true; + SetGetUp(); + ClearWaitState(); + + } else if (CWeather::Rain <= 0.1f) { + if (CClock::GetHours() <= 18 || CGeneral::GetRandomNumberInRange(0.f, 1.0f) < 0.005f) { + uint32 threatFlag = ScanForThreats(); + if (threatFlag == PED_FLAG_GUN || threatFlag == PED_FLAG_EXPLOSION || threatFlag == PED_FLAG_DEADPEDS) { + // Get up in case of danger + m_pNextPathNode = nil; + m_threatEx = m_threatEntity; + bFleeWhenStanding = true; + SetGetUp(); + ClearWaitState(); + } + CPlayerPed *player = FindPlayerPed(); + if (player) { + // Get up if player coming towards us with a car + if (player->InVehicle()){ + CVector vehSpeedPerSec = player->m_pMyVehicle->m_vecMoveSpeed * GAME_SPEED_TO_METERS_PER_SECOND; + CVector vehPos = player->m_pMyVehicle->GetPosition(); + CVector ourPos = GetPosition(); + float timeUntilVehReachPed = DotProduct(ourPos - vehPos, vehSpeedPerSec) / vehSpeedPerSec.MagnitudeSqr(); + if (timeUntilVehReachPed > 0.0 && timeUntilVehReachPed < 8.0f) { + if ((ourPos - (timeUntilVehReachPed * vehSpeedPerSec + vehPos)).Magnitude() < 5.0f) { + m_pNextPathNode = nil; + m_threatEx = player; + bFleeWhenStanding = true; + SetGetUp(); + ClearWaitState(); + } + } + } + } + } else { + m_pNextPathNode = nil; + bGotUpOfMyOwnAccord = true; + SetGetUp(); + ClearWaitState(); + } + } else { + m_pNextPathNode = nil; + bGotUpOfMyOwnAccord = true; + SetGetUp(); + ClearWaitState(); + } + break; case WAITSTATE_RIOT: if (m_nPedState == PED_FLEE_ENTITY || m_nPedState == PED_ATTACK) { ClearWaitState(); @@ -8741,11 +8854,10 @@ CPed::Wait(void) case WAITSTATE_STRIPPER: PlayRandomAnimationsFromAnimBlock(this, ASSOCGRP_STRIP, ANIM_STRIP_A, ANIM_STRIP_G - ANIM_STRIP_A + 1); break; - case WAITSTATE_SUN_BATHE_PRE: - case WAITSTATE_SUN_BATHE_DOWN: - case WAITSTATE_SUN_BATHE_IDLE: case WAITSTATE_PLAYANIM_HANDSUP_SIMPLE: - assert(0); + if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) + ClearWaitState(); + break; default: break; } @@ -9522,6 +9634,7 @@ CPed::SetLanding(void) bIsLanding = true; } +// --MIAMI: Done void CPed::Initialise(void) { @@ -9694,6 +9807,7 @@ CPed::SetAnimOffsetForEnterOrExitVehicle(void) CAnimManager::RemoveAnimBlockRef(bikedBlock); } +// --MIAMI: Done void CPed::InvestigateEvent(void) { @@ -9707,7 +9821,7 @@ CPed::InvestigateEvent(void) if (CTimer::GetTimeInMilliseconds() > m_standardTimer) { if (m_standardTimer) { - if (m_eventType < EVENT_ASSAULT_NASTYWEAPON) + if (m_eventType < EVENT_UNK) SetWaitState(WAITSTATE_TURN180, nil); m_standardTimer = 0; @@ -9761,13 +9875,14 @@ CPed::InvestigateEvent(void) animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_STANCE); if (animAssoc && animAssoc->animId == ANIM_IDLE_CAM) { - CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 14.0f); + CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 4.0f); SetLookTimer(CGeneral::GetRandomNumberInRange(1000, 2500)); } else if (CGeneral::GetRandomNumber() & 3) { CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_CAM, 4.0f); SetLookTimer(CGeneral::GetRandomNumberInRange(2500, 5000)); - Say(SOUND_PED_CHAT_EVENT); + if (!CGame::germanGame) + Say(SOUND_PED_CHAT_EVENT); } else { m_standardTimer = 0; @@ -9788,7 +9903,7 @@ CPed::InvestigateEvent(void) animToPlay = ANIM_XPRESS_SCRATCH; CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, animToPlay, 4.0f); - SetLookTimer(CGeneral::GetRandomNumberInRange(1000, 2500)); + SetLookTimer(CGeneral::GetRandomNumberInRange(1500, 4000)); } else if (animAssoc && animAssoc->animId == ANIM_IDLE_HBHB) { animAssoc->blendDelta = -8.0f; @@ -9816,7 +9931,8 @@ CPed::InvestigateEvent(void) CAnimManager::BlendAnimation(GetClump(), animGroup, animToPlay, 4.0f); SetLookTimer(CGeneral::GetRandomNumberInRange(1000, 2500)); } - Say(SOUND_PED_CHAT_EVENT); + if (!CGame::germanGame) + Say(SOUND_PED_CHAT_EVENT); } break; case EVENT_ICECREAM: @@ -9878,19 +9994,22 @@ CPed::InvestigateEvent(void) SetMoveState(PEDMOVE_WALK); return; } - if (distSqr > 1.44f) { + if (distSqr > sq(1.2f)) { SetMoveState(PEDMOVE_WALK); return; } + bool willStandStill = false; for (int i = 0; i < m_numNearPeds; i++) { if ((m_eventOrThreat - m_nearPeds[i]->GetPosition()).MagnitudeSqr() < sq(0.4f)) { SetMoveState(PEDMOVE_STILL); - return; + willStandStill = true; + break; } } - SetMoveState(PEDMOVE_WALK); + if (!willStandStill) + SetMoveState(PEDMOVE_WALK); } } @@ -10184,12 +10303,12 @@ CPed::Look(void) TurnBody(); } +// --MIAMI: Done bool CPed::LookForInterestingNodes(void) { CBaseModelInfo *model; CPtrNode *ptrNode; - CVector effectPos; CVector effectDist; C2dEffect *effect; CMatrix *objMat; @@ -10230,7 +10349,7 @@ CPed::LookForInterestingNodes(void) effect = model->Get2dEffect(e); if (effect->type == EFFECT_ATTRACTOR && effect->attractor.probability >= randVal) { objMat = &veh->GetMatrix(); - effectPos = veh->GetMatrix() * effect->pos; + CVector effectPos = veh->GetMatrix() * effect->pos; effectDist = effectPos - GetPosition(); if (effectDist.MagnitudeSqr() < sq(8.0f)) { found = true; @@ -10248,7 +10367,7 @@ CPed::LookForInterestingNodes(void) effect = model->Get2dEffect(e); if (effect->type == EFFECT_ATTRACTOR && effect->attractor.probability >= randVal) { objMat = &obj->GetMatrix(); - effectPos = obj->GetMatrix() * effect->pos; + CVector effectPos = obj->GetMatrix() * effect->pos; effectDist = effectPos - GetPosition(); if (effectDist.MagnitudeSqr() < sq(8.0f)) { found = true; @@ -10266,7 +10385,7 @@ CPed::LookForInterestingNodes(void) effect = model->Get2dEffect(e); if (effect->type == EFFECT_ATTRACTOR && effect->attractor.probability >= randVal) { objMat = &building->GetMatrix(); - effectPos = building->GetMatrix() * effect->pos; + CVector effectPos = building->GetMatrix() * effect->pos; effectDist = effectPos - GetPosition(); if (effectDist.MagnitudeSqr() < sq(8.0f)) { found = true; @@ -10284,7 +10403,7 @@ CPed::LookForInterestingNodes(void) effect = model->Get2dEffect(e); if (effect->type == EFFECT_ATTRACTOR && effect->attractor.probability >= randVal) { objMat = &building->GetMatrix(); - effectPos = building->GetMatrix() * effect->pos; + CVector effectPos = building->GetMatrix() * effect->pos; effectDist = effectPos - GetPosition(); if (effectDist.MagnitudeSqr() < sq(8.0f)) { found = true; @@ -10310,12 +10429,13 @@ CPed::LookForInterestingNodes(void) return false; } + CVector2D effectPos = *objMat * effect->pos; switch (effect->attractor.type) { case ATTRACTORTYPE_ICECREAM: - SetInvestigateEvent(EVENT_ICECREAM, CVector2D(effectPos), 0.1f, 15000, angleToFace); + SetInvestigateEvent(EVENT_ICECREAM, effectPos, 0.1f, 15000, angleToFace); break; case ATTRACTORTYPE_STARE: - SetInvestigateEvent(EVENT_SHOPSTALL, CVector2D(effectPos), 1.0f, + SetInvestigateEvent(EVENT_SHOPSTALL, effectPos, 1.0f, CGeneral::GetRandomNumberInRange(8000, 10 * effect->attractor.probability + 8500), angleToFace); break; @@ -10325,6 +10445,7 @@ CPed::LookForInterestingNodes(void) return true; } +// --MIAMI: Done void CPed::SetInvestigateEvent(eEventType event, CVector2D pos, float distanceToCountDone, uint16 time, float angle) { @@ -10333,7 +10454,7 @@ CPed::SetInvestigateEvent(eEventType event, CVector2D pos, float distanceToCount SetStoredState(); bFindNewNodeAfterStateRestore = false; - m_nPedState = PED_INVESTIGATE; + SetPedState(PED_INVESTIGATE); m_standardTimer = CTimer::GetTimeInMilliseconds() + time; m_eventType = event; m_eventOrThreat = pos; @@ -10861,7 +10982,7 @@ CPed::ProcessControl(void) CVisibilityPlugins::SetClumpAlpha(GetClump(), alpha); bIsShooting = false; - b158_40 = false; + bDonePositionOutOfCollision = false; BuildPedLists(); bIsInWater = false; bIsDrowning = false; @@ -13017,8 +13138,8 @@ CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg) } } - if (ped->b157_40) { - ped->b157_40 = false; + if (ped->bRemoveMeWhenIGotIntoCar) { + ped->bRemoveMeWhenIGotIntoCar = false; ped->bRemoveFromWorld = true; } if (ped->bCollectBusFare) { @@ -13435,6 +13556,7 @@ CPed::ReactToPointGun(CEntity *entWithGun) } } +// --MIAMI: Done void CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg) { @@ -13458,8 +13580,17 @@ CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg) } ped->bInVehicle = false; - if (veh && (veh->IsCar() || veh->IsBike()) && !veh->IsRoomForPedToLeaveCar(ped->m_vehEnterType, nil)) { - ped->PositionPedOutOfCollision(); + if (veh && (veh->IsCar() || veh->IsBike())) { + CWorld::pIgnoreEntity = veh; + if (CWorld::TestSphereAgainstWorld(ped->GetPosition() - CVector(0.f, 0.f, 0.2f), + 0.4f, veh, true, true, false, false, false, false) + || CWorld::TestSphereAgainstWorld(ped->GetPosition() + CVector(0.f, 0.f, 0.2f), + 0.4f, veh, true, true, false, false, false, false) + || !CWorld::GetIsLineOfSightClear(veh->GetPosition(), ped->GetPosition(), true, false, false, true, false, false, false)) { + CWorld::pIgnoreEntity = nil; + ped->PositionPedOutOfCollision(); + } + CWorld::pIgnoreEntity = nil; } if (ped->m_nPedState == PED_EXIT_CAR) { @@ -13543,6 +13674,7 @@ CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg) } } } + // NB: Probably VC doesn't use a function for that, so it's GetBikeDoorFlag doesn't check for CAR_WINDSCREEN if (veh && veh->IsBike()) veh->m_nGettingOutFlags &= ~GetBikeDoorFlag(ped->m_vehEnterType); else @@ -13555,6 +13687,11 @@ CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg) veh->m_nDoorLock = CARLOCK_UNLOCKED; if (ped->m_nPedType == PEDTYPE_COP && veh->IsLawEnforcementVehicle()) veh->ChangeLawEnforcerState(false); + if (veh->IsBike()) { + if (Abs(veh->m_vecMoveSpeed.x) < 0.1 && Abs(veh->m_vecMoveSpeed.y) < 0.1f) { + ((CBike*)veh)->bIsStanding = true; + } + } } else { veh->RemovePassenger(ped); } @@ -13818,6 +13955,146 @@ CPed::PedSetQuickDraggedOutCarPositionCB(CAnimBlendAssociation *animAssoc, void bool CPed::PositionPedOutOfCollision(void) { + CVehicle *veh = m_pMyVehicle; + if (!veh) + return false; + + if (bDonePositionOutOfCollision) + return true; + + bool foundAPos = false; + CColModel *vehCol = veh->GetColModel(); + CVector vehPos = veh->GetPosition(); + CVector ourPos = GetPosition(); + CVector newPos = ourPos; + CWorld::pIgnoreEntity = veh; + bUsesCollision = false; + bJustCheckCollision = true; + m_vecMoveSpeed = CVector(0.f, 0.f, 0.f); + if (veh->IsOnItsSide()) { + // Top of the veh. + newPos = vehPos; + newPos.z = FEET_OFFSET + vehCol->boundingBox.max.x + vehPos.z; + GetMatrix().SetTranslate(newPos); + if (!CheckCollision()) { + if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false)) + foundAPos = true; + } + + } else if (m_vehEnterType != 0) { + // Try the normal way + CVector pos = GetPositionToOpenCarDoor(m_pMyVehicle, m_vehEnterType); + newPos = pos; + GetMatrix().SetTranslate(newPos); + if (!CheckCollision()) { + if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false)) + foundAPos = true; + } + } + + float vehRelativeExitX = vehCol->boundingBox.min.x - 0.355f; + if (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR) + vehRelativeExitX = 0.355f + vehCol->boundingBox.max.x; + + if (!foundAPos) { + // Check sides of veh., respective to seat column-veh. center difference(why?) + float exitOffset = vehRelativeExitX - DotProduct(ourPos - vehPos, veh->GetRight()); + newPos = exitOffset * veh->GetRight() + ourPos; + GetMatrix().SetTranslate(newPos); + if (!CheckCollision()) { + if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false)) + foundAPos = true; + } + } + if (!foundAPos) { + // Iterate through sections of veh. length + static offset on X + float minY = vehCol->boundingBox.min.y; + float ySection = (vehCol->boundingBox.max.y - minY) / 3.f; + for (int i = 0; i < 4; i++) { + float fwdMult = i * ySection + minY; + newPos = vehRelativeExitX * veh->GetRight() + fwdMult * veh->GetForward() + vehPos; + GetMatrix().SetTranslate(newPos); + if (!CheckCollision()) { + if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false)) { + foundAPos = true; + break; + } + } + } + } + if (!foundAPos) { + // Back of veh. + newPos = (vehCol->boundingBox.min.y - 0.355f) * veh->GetForward() + vehPos; + GetMatrix().SetTranslate(newPos); + if (!CheckCollision()) { + if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false)) + foundAPos = true; + } + } + if (!foundAPos) { + // Front of veh. + newPos = (0.355f + vehCol->boundingBox.max.y) * veh->GetForward() + vehPos; + GetMatrix().SetTranslate(newPos); + if (!CheckCollision()) { + if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false)) + foundAPos = true; + } + } + if (!foundAPos) { + // Opposite X side + back + newPos = vehCol->boundingBox.min.y * veh->GetForward() + vehPos - vehRelativeExitX * veh->GetRight(); + GetMatrix().SetTranslate(newPos); + if (!CheckCollision()) { + if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false)) + foundAPos = true; + } + } + if (!foundAPos) { + // Opposite X side + front + newPos = vehCol->boundingBox.max.y * veh->GetForward() + vehPos - vehRelativeExitX * veh->GetRight(); + GetMatrix().SetTranslate(newPos); + if (!CheckCollision()) { + if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false)) + foundAPos = true; + } + } + if (!foundAPos) { + // Top of veh. + if (veh->m_vehType == 0) { + newPos = vehCol->boundingBox.max.z * veh->GetUp() + vehPos; + newPos.z += FEET_OFFSET; + GetMatrix().SetTranslate(newPos); + if (!CheckCollision()) { + if (CWorld::GetIsLineOfSightClear(vehPos, newPos, true, false, false, true, false, false, false)) + foundAPos = true; + } + } + } + m_vecMoveSpeed = CVector(0.f, 0.f, 0.f); + m_vecTurnSpeed = CVector(0.f, 0.f, 0.f); + veh->m_vecMoveSpeed = CVector(0.f, 0.f, 0.f); + veh->m_vecTurnSpeed = CVector(0.f, 0.f, 0.f); + CWorld::pIgnoreEntity = nil; + bUsesCollision = true; + bJustCheckCollision = false; + bDonePositionOutOfCollision = true; + if (foundAPos) + return true; + int foundNode = ThePaths.FindNodeClosestToCoors(vehPos, PATH_PED, 999999.9f, true, false, false, false); + if (foundNode < 0) + return false; + newPos = ThePaths.m_pathNodes[foundNode].GetPosition(); + CPedPlacement::FindZCoorForPed(&newPos); + GetMatrix().SetTranslate(newPos); + SetHeading(m_pMyVehicle->GetForward().Heading()); + return true; +} + +// --MIAMI: Done +// "Any" means he shouldn't have to be in vehicle. +bool +CPed::PositionAnyPedOutOfCollision(void) +{ CVehicle *veh; CVector posNearVeh; CVector posSomewhereClose; @@ -13826,9 +14103,6 @@ CPed::PositionPedOutOfCollision(void) int smallestDistNearVeh = 999; int smallestDistSomewhereClose = 999; - if (!m_pMyVehicle) - return false; - CVector vehPos = m_pMyVehicle->GetPosition(); CVector potentialPos; potentialPos.y = GetPosition().y - 3.5f; @@ -13839,15 +14113,7 @@ CPed::PositionPedOutOfCollision(void) for (int xTry = 0; xTry < 15; xTry++) { CPedPlacement::FindZCoorForPed(&potentialPos); - CVector distVec = potentialPos - vehPos; - float dist = distVec.Magnitude(); - - // Makes close distances bigger for some reason. - float mult = (0.6f + dist) / dist; - CVector adjustedPotentialPos = distVec * mult + vehPos; - if (CWorld::GetIsLineOfSightClear(vehPos, adjustedPotentialPos, true, false, false, true, false, false, false) - && !CWorld::TestSphereAgainstWorld(potentialPos, 0.6f, this, true, false, false, true, false, false)) { - + if (!CWorld::TestSphereAgainstWorld(potentialPos, 0.6f, this, true, false, false, true, false, false)) { float potentialChangeSqr = (potentialPos - GetPosition()).MagnitudeSqr(); veh = (CVehicle*)CWorld::TestSphereAgainstWorld(potentialPos, 0.6f, this, false, true, false, false, false, false); if (veh) { @@ -13881,6 +14147,7 @@ CPed::PositionPedOutOfCollision(void) return true; } +// --MIAMI: Done bool CPed::PossiblyFindBetterPosToSeekCar(CVector *pos, CVehicle *veh) { @@ -14060,6 +14327,7 @@ CPed::Render(void) } } +// --MIAMI: Done void CPed::ProcessObjective(void) { @@ -14097,15 +14365,6 @@ CPed::ProcessObjective(void) } switch (m_objective) { - case OBJECTIVE_NONE: - case OBJECTIVE_GUARD_AREA: - case OBJECTIVE_FOLLOW_CAR_IN_CAR: - case OBJECTIVE_FIRE_AT_OBJECT_FROM_VEHICLE: - case OBJECTIVE_DESTROY_OBJECT: - case OBJECTIVE_GOTO_AREA_IN_CAR: - case OBJECTIVE_FOLLOW_CAR_ON_FOOT_WITH_OFFSET: - case OBJECTIVE_SET_LEADER: - break; case OBJECTIVE_WAIT_ON_FOOT: if (GetPedState() == PED_DRIVING) m_objective = OBJECTIVE_NONE; @@ -14190,7 +14449,7 @@ CPed::ProcessObjective(void) { if (m_pedInObjective) { if (m_pedInObjective->IsPlayer() && CharCreatedBy != MISSION_CHAR - && m_nPedType != PEDTYPE_COP && FindPlayerPed()->m_pWanted->m_CurrentCops + && m_nPedType != PEDTYPE_COP && FindPlayerPed()->m_pWanted->m_CurrentCops != 0 && !bKindaStayInSamePlace) { SetObjective(OBJECTIVE_FLEE_ON_FOOT_TILL_SAFE); @@ -14230,7 +14489,7 @@ CPed::ProcessObjective(void) float closestVehDist = 60.0f; int16 lastVehicle; CEntity* vehicles[8]; - CWorld::FindObjectsInRange(GetPosition(), 30.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false); + CWorld::FindObjectsInRange(GetPosition(), ENTER_CAR_MAX_DIST, true, &lastVehicle, 6, vehicles, false, true, false, false, false); CVehicle *foundVeh = nil; for(int i = 0; i < lastVehicle; i++) { CVehicle *nearVeh = (CVehicle*)vehicles[i]; @@ -14303,7 +14562,6 @@ CPed::ProcessObjective(void) SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle); break; } - if (!m_pedInObjective || m_pedInObjective->DyingOrDead()) { bObjectiveCompleted = true; ClearLookFlag(); @@ -14553,7 +14811,7 @@ CPed::ProcessObjective(void) if (m_carInObjective && m_carInObjective->m_fHealth > 0.0f) { distWithTarget = m_carInObjective->GetPosition() - GetPosition(); if (!bInVehicle) { - if (nEnterCarRangeMultiplier * 30.0f < distWithTarget.Magnitude()) { + if (nEnterCarRangeMultiplier * ENTER_CAR_MAX_DIST < distWithTarget.Magnitude()) { if (!m_carInObjective->pDriver && !m_carInObjective->GetIsOnScreen() && !GetIsOnScreen()) WarpPedToNearEntityOffScreen(m_carInObjective); @@ -14579,6 +14837,15 @@ CPed::ProcessObjective(void) } break; } + case OBJECTIVE_DESTROY_OBJECT: + if (m_pPointGunAt) { + if (m_nPedState != PED_ATTACK) + SetAttack(m_pPointGunAt); + } else { + bScriptObjectiveCompleted = true; + RestorePreviousObjective(); + } + break; case OBJECTIVE_DESTROY_CAR: { if (!m_carInObjective) { @@ -14602,9 +14869,7 @@ CPed::ProcessObjective(void) break; } - if (m_attackTimer < CTimer::GetTimeInMilliseconds() && wepInfo->m_eWeaponFire != WEAPON_FIRE_MELEE - && distWithTargetSc < wepRange) { - + if (m_attackTimer < CTimer::GetTimeInMilliseconds() && distWithTargetSc < wepRange) { // I hope so CVector ourHead = GetMatrix() * CVector(0.5f, 0.0f, 0.6f); CVector maxShotPos = m_carInObjective->GetPosition() - ourHead; @@ -14619,6 +14884,8 @@ CPed::ProcessObjective(void) CWorld::bIncludeDeadPeds = false; if (foundEnt == m_carInObjective) { SetAttack(m_carInObjective); + if (m_pPointGunAt) + m_pPointGunAt->CleanUpOldReference((CEntity**)&m_pPointGunAt); m_pPointGunAt = m_carInObjective; if (m_pPointGunAt) m_pPointGunAt->RegisterReference((CEntity **) &m_pPointGunAt); @@ -14632,75 +14899,30 @@ CPed::ProcessObjective(void) } } } else if (m_nPedState != PED_ATTACK && !bKindaStayInSamePlace) { + if (wepRange <= 5.0f) { + if (Abs(distWithTarget.x) > wepRange || Abs(distWithTarget.y) > wepRange || + (distWithTarget.z > -1.0f && distWithTarget.z < 0.3)) { + SetSeek(m_carInObjective, 3.0f); + SetMoveState(PEDMOVE_RUN); + } else { + SetIdle(); + } + } else { + float safeDistance = wepRange * 0.25f; - float safeDistance; - if (wepRange <= 5.0f) - safeDistance = 3.0f; - else - safeDistance = wepRange * 0.25f; - - SetSeek(m_carInObjective, safeDistance); - SetMoveState(PEDMOVE_RUN); + SetSeek(m_carInObjective, safeDistance); + SetMoveState(PEDMOVE_RUN); + } } SetLookFlag(m_carInObjective, false); TurnBody(); break; } - case OBJECTIVE_GOTO_AREA_ANY_MEANS: - { - distWithTarget = m_nextRoutePointPos - GetPosition(); - distWithTarget.z = 0.0f; - if (InVehicle()) { - CCarAI::GetCarToGoToCoors(m_pMyVehicle, &m_nextRoutePointPos); - CCarCtrl::RegisterVehicleOfInterest(m_pMyVehicle); - if (distWithTarget.MagnitudeSqr() < sq(20.0f)) { - m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0; - ForceStoredObjective(OBJECTIVE_GOTO_AREA_ANY_MEANS); - SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle); - } - break; - } - if (distWithTarget.Magnitude() > 30.0f) { - if (m_pMyVehicle) { - m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0; - } else { - float closestVehDist = SQR(60.0f); - int16 lastVehicle; - CEntity* vehicles[8]; - CWorld::FindObjectsInRange(GetPosition(), 25.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false); - CVehicle* foundVeh = nil; - for (int i = 0; i < lastVehicle; i++) { - CVehicle* nearVeh = (CVehicle*)vehicles[i]; - /* - Not used. - CVector vehSpeed = nearVeh->GetSpeed(); - CVector ourSpeed = GetSpeed(); - */ - CVector vehDistVec = nearVeh->GetPosition() - GetPosition(); - if (vehDistVec.MagnitudeSqr() < closestVehDist - && m_pedInObjective->m_pMyVehicle != nearVeh) - { - foundVeh = nearVeh; - closestVehDist = vehDistVec.MagnitudeSqr(); - } - } - m_pMyVehicle = foundVeh; - if (m_pMyVehicle) { - m_pMyVehicle->RegisterReference((CEntity **) &m_pMyVehicle); - m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0; - SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, m_pMyVehicle); - } - } - break; - } - // fall through - } case OBJECTIVE_GOTO_AREA_ON_FOOT: case OBJECTIVE_RUN_TO_AREA: case OBJECTIVE_SPRINT_TO_AREA: { - if ((m_objective == OBJECTIVE_GOTO_AREA_ON_FOOT || m_objective == OBJECTIVE_RUN_TO_AREA || m_objective == OBJECTIVE_SPRINT_TO_AREA) - && InVehicle()) { + if (InVehicle()) { SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle); } else { distWithTarget = m_nextRoutePointPos - GetPosition(); @@ -14717,7 +14939,6 @@ CPed::ProcessObjective(void) if (!m_pNextPathNode) { bool found = FindBestCoordsFromNodes(m_vecSeekPos, &bestCoords); if (m_pNextPathNode) { - // Because it already does that if it finds better coords. if (!found) { bestCoords = CPathFind::TakeWidthIntoAccountForWandering(m_pNextPathNode, m_randomSeed); @@ -14731,6 +14952,7 @@ CPed::ProcessObjective(void) if (m_pNextPathNode) m_vecSeekPos = CPathFind::TakeWidthIntoAccountForWandering(m_pNextPathNode, m_randomSeed); } + CVector seekPos = m_vecSeekPos; SetSeek(m_vecSeekPos, m_distanceToCountSeekDone); } } @@ -14767,7 +14989,8 @@ CPed::ProcessObjective(void) int nextPoint = GetNextPointOnRoute(); m_nextRoutePointPos = CRouteNode::GetPointPosition(nextPoint); } else { - SetSeek(m_nextRoutePointPos, 0.8f); + CVector seekPos = m_nextRoutePointPos; + SetSeek(seekPos, 0.8f); } break; case OBJECTIVE_SOLICIT_VEHICLE: @@ -14831,31 +15054,27 @@ CPed::ProcessObjective(void) } case OBJECTIVE_BUY_ICE_CREAM: if (m_carInObjective) { - if (m_nPedState != PED_FLEE_ENTITY && m_nPedState != PED_BUY_ICECREAM) + if (m_nPedState != PED_FLEE_ENTITY && m_nPedState != PED_BUY_ICECREAM && m_nPedState != PED_CHAT) SetSeekCar(m_carInObjective, 0); - } else { - RestorePreviousObjective(); - RestorePreviousState(); - if (IsPedInControl()) - m_pMyVehicle = nil; } break; case OBJECTIVE_STEAL_ANY_CAR: + case OBJECTIVE_STEAL_ANY_MISSION_CAR: { if (bInVehicle) { bScriptObjectiveCompleted = true; RestorePreviousObjective(); } else if (m_hitRecoverTimer < CTimer::GetTimeInMilliseconds()) { CVehicle *carToSteal = nil; - float closestCarDist = 30.0f; + float closestCarDist = nEnterCarRangeMultiplier * ENTER_CAR_MAX_DIST; CVector pos = GetPosition(); int16 lastVehicle; CEntity *vehicles[8]; - CWorld::FindObjectsInRange(pos, CHECK_NEARBY_THINGS_MAX_DIST, true, &lastVehicle, 6, vehicles, false, true, false, false, false); + CWorld::FindObjectsInRange(pos, closestCarDist, true, &lastVehicle, 6, vehicles, false, true, false, false, false); for(int i = 0; i < lastVehicle; i++) { CVehicle *nearVeh = (CVehicle*)vehicles[i]; - if (nearVeh->VehicleCreatedBy != MISSION_VEHICLE) { + if (m_objective == OBJECTIVE_STEAL_ANY_MISSION_CAR || nearVeh->VehicleCreatedBy != MISSION_VEHICLE) { if (nearVeh->m_vecMoveSpeed.Magnitude() <= 0.1f) { if (nearVeh->CanPedOpenLocks(this)) { CVector vehDistVec = GetPosition() - nearVeh->GetPosition(); @@ -14968,60 +15187,6 @@ CPed::ProcessObjective(void) CPed::SetWanderPath(m_nPathDir); } break; - case OBJECTIVE_FLEE_CAR: - if (!bInVehicle && m_nPedState != PED_FLEE_ENTITY && m_pMyVehicle) { - RestorePreviousObjective(); - SetFlee(m_pMyVehicle, 6000); - break; - } - // fall through - case OBJECTIVE_LEAVE_CAR: - if (CTimer::GetTimeInMilliseconds() > m_leaveCarTimer) { - if (InVehicle() && - (FindPlayerPed() != this || !CPad::GetPad(0)->GetAccelerate() || bBusJacked)) { - - if (m_nPedState != PED_EXIT_CAR && m_nPedState != PED_DRAG_FROM_CAR && m_nPedState != PED_EXIT_TRAIN - && (m_nPedType != PEDTYPE_COP - || m_pMyVehicle->IsBoat() - || m_pMyVehicle->m_vecMoveSpeed.MagnitudeSqr2D() < sq(0.005f))) { -#ifdef GTA_TRAIN - if (m_pMyVehicle->IsTrain()) - SetExitTrain(m_pMyVehicle); - else -#endif - if (m_pMyVehicle->IsBoat()) - SetExitBoat(m_pMyVehicle); - else - SetExitCar(m_pMyVehicle, 0); - } - } else { - RestorePreviousObjective(); - } - } - if (bHeldHostageInCar) { - if (CTheScripts::IsPlayerOnAMission()) { - CVehicle *playerVeh = FindPlayerVehicle(); - if (playerVeh && playerVeh->IsPassenger(this)) { - if (m_leaveCarTimer != 0) - m_leaveCarTimer = 0; - } - } - } - break; - case OBJECTIVE_AIM_GUN_AT: - if (m_pedInObjective) { - if (!bObstacleShowedUpDuringKillObjective) - SetPointGunAt(m_pedInObjective); - - if (m_nMoveState == PEDMOVE_STILL && IsPedInControl()) { - SetLookFlag(m_pedInObjective, false); - TurnBody(); - } - } else { - ClearObjective(); - } - break; -#ifdef VC_PED_PORTS case OBJECTIVE_LEAVE_CAR_AND_DIE: { if (CTimer::GetTimeInMilliseconds() > m_leaveCarTimer) { @@ -15049,6 +15214,59 @@ CPed::ProcessObjective(void) } break; } + case OBJECTIVE_GOTO_AREA_ANY_MEANS: + { + distWithTarget = m_nextRoutePointPos - GetPosition(); + distWithTarget.z = 0.0f; + if (InVehicle()) { + CCarAI::GetCarToGoToCoors(m_pMyVehicle, &m_nextRoutePointPos); + CCarCtrl::RegisterVehicleOfInterest(m_pMyVehicle); + if (distWithTarget.MagnitudeSqr() < sq(20.0f)) { + m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0; + ForceStoredObjective(OBJECTIVE_GOTO_AREA_ANY_MEANS); + SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle); + } + break; + } + if (distWithTarget.Magnitude() > 30.0f) { + if (m_pMyVehicle) { + m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0; + } else { + float closestVehDist = SQR(60.0f); + int16 lastVehicle; + CEntity* vehicles[8]; + // NB: 25.0f in here is prolly a forgotten setting, all other places now use 30.0f (ENTER_CAR_MAX_DIST) + CWorld::FindObjectsInRange(GetPosition(), 25.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false); + CVehicle* foundVeh = nil; + for (int i = 0; i < lastVehicle; i++) { + CVehicle* nearVeh = (CVehicle*)vehicles[i]; + /* + Not used. + CVector vehSpeed = nearVeh->GetSpeed(); + CVector ourSpeed = GetSpeed(); + */ + CVector vehDistVec = nearVeh->GetPosition() - GetPosition(); + if (vehDistVec.MagnitudeSqr() < closestVehDist && m_pedInObjective->m_pMyVehicle != nearVeh) { + foundVeh = nearVeh; + closestVehDist = vehDistVec.MagnitudeSqr(); + } + } + m_pMyVehicle = foundVeh; + if (m_pMyVehicle) { + m_pMyVehicle->RegisterReference((CEntity **) &m_pMyVehicle); + m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0; + SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, m_pMyVehicle); + } + } + break; + } + // Falls to different objectives in III and VC +#ifdef FIX_BUGS + break; +#else + // fall through +#endif + } case OBJECTIVE_GOTO_SEAT_ON_FOOT: case OBJECTIVE_GOTO_ATM_ON_FOOT: case OBJECTIVE_GOTO_BUS_STOP_ON_FOOT: @@ -15059,8 +15277,7 @@ CPed::ProcessObjective(void) m_objectiveTimer = 0; if (m_attractor) GetPedAttractorManager()->DeRegisterPed(this, m_attractor); - } - else { + } else { CVector distance = m_nextRoutePointPos - GetPosition(); distance.z = 0.0f; if (m_objective == OBJECTIVE_GOTO_SHELTER_ON_FOOT) { @@ -15176,6 +15393,59 @@ CPed::ProcessObjective(void) } } return; + case OBJECTIVE_FLEE_CAR: + if (!bInVehicle && m_nPedState != PED_FLEE_ENTITY && m_pMyVehicle) { + RestorePreviousObjective(); + SetFlee(m_pMyVehicle, 6000); + break; + } + // fall through + case OBJECTIVE_LEAVE_CAR: + if (CTimer::GetTimeInMilliseconds() > m_leaveCarTimer) { + if (InVehicle() && + (FindPlayerPed() != this || !CPad::GetPad(0)->GetAccelerate() || bBusJacked)) { + + if (m_nPedState != PED_EXIT_CAR && m_nPedState != PED_DRAG_FROM_CAR && m_nPedState != PED_EXIT_TRAIN + && (m_nPedType != PEDTYPE_COP + || m_pMyVehicle->IsBoat() + || m_pMyVehicle->m_vecMoveSpeed.MagnitudeSqr2D() < sq(0.005f))) { +#ifdef GTA_TRAIN + if (m_pMyVehicle->IsTrain()) + SetExitTrain(m_pMyVehicle); + else +#endif + if (m_pMyVehicle->IsBoat()) + SetExitBoat(m_pMyVehicle); + else + SetExitCar(m_pMyVehicle, 0); + } + } else { + RestorePreviousObjective(); + } + } + if (bHeldHostageInCar) { + if (CTheScripts::IsPlayerOnAMission()) { + CVehicle *playerVeh = FindPlayerVehicle(); + if (playerVeh && playerVeh->IsPassenger(this)) { + if (m_leaveCarTimer != 0) + m_leaveCarTimer = 0; + } + } + } + break; + case OBJECTIVE_AIM_GUN_AT: + if (m_pedInObjective) { + if (!bObstacleShowedUpDuringKillObjective) + SetPointGunAt(m_pedInObjective); + + if (m_nMoveState == PEDMOVE_STILL && IsPedInControl()) { + SetLookFlag(m_pedInObjective, false); + TurnBody(); + } + } else { + ClearObjective(); + } + break; case OBJECTIVE_WAIT_ON_FOOT_AT_SHELTER: SetIdle(); if (m_attractor && CWeather::Rain < 0.2f) @@ -15207,8 +15477,8 @@ CPed::ProcessObjective(void) } else if (m_pedInObjective) { SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS, m_pedInObjective); } - } else { SetMoveAnim(); + } else { ClearLookFlag(); SetMoveAnim(); if (m_pCurrentPhysSurface && m_pCurrentPhysSurface->IsVehicle()) @@ -15268,7 +15538,7 @@ CPed::ProcessObjective(void) GetPedAttractorManager()->DeRegisterPed(this, m_attractor); SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, pBus); bDontDragMeOutCar = true; - b157_40 = true; + bRemoveMeWhenIGotIntoCar = true; CPlayerPed *player = FindPlayerPed(); if (pBus->IsPassenger(player) || pBus->IsDriver(player)) { bCollectBusFare = true; @@ -15309,7 +15579,6 @@ CPed::ProcessObjective(void) } break; } -#endif } if (bObjectiveCompleted || m_objectiveTimer > 0 && CTimer::GetTimeInMilliseconds() > m_objectiveTimer) { @@ -15329,6 +15598,7 @@ CPed::ProcessObjective(void) } } +// --MIAMI: Done void CPed::SetShootTimer(uint32 time) { @@ -16441,7 +16711,78 @@ CPed::PreRender(void) RwMatrixScale(head, &zero, rwCOMBINEPRECONCAT); } - // TODO(Miami): Some cheat?? + if (IsPlayer() && gfTommyFatness != 1.0f) { + RpHAnimHierarchy* hier = GetAnimHierarchyFromSkinClump(GetClump()); + int32 idx; + RwV3d scale; + + scale.x = 1.0f; + scale.y = 1.0f + gfTommyFatness * 0.7f; + scale.z = 1.0f + gfTommyFatness * 0.7f; + idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_HEAD)); + RwMatrix* head = &RpHAnimHierarchyGetMatrixArray(hier)[idx]; + RwMatrixScale(head, &scale, rwCOMBINEPRECONCAT); + + scale.y = 1.0f + gfTommyFatness * 0.2f; + scale.z = 1.0f + gfTommyFatness * 0.2f; + idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_NECK)); + RwMatrix* neck = &RpHAnimHierarchyGetMatrixArray(hier)[idx]; + RwMatrixScale(neck, &scale, rwCOMBINEPRECONCAT); + + scale.y = 1.0f + gfTommyFatness * 0.5f; + scale.z = 1.0f + gfTommyFatness * 0.5f; + idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_MID)); + RwMatrix* mid = &RpHAnimHierarchyGetMatrixArray(hier)[idx]; + RwMatrixScale(mid, &scale, rwCOMBINEPRECONCAT); + + scale.y = 1.0f + gfTommyFatness; + scale.z = 1.0f + gfTommyFatness; + idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_UPPERLEGL)); + RwMatrix* upperLegL = &RpHAnimHierarchyGetMatrixArray(hier)[idx]; + RwMatrixScale(upperLegL, &scale, rwCOMBINEPRECONCAT); + + idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_UPPERLEGR)); + RwMatrix* upperLegR = &RpHAnimHierarchyGetMatrixArray(hier)[idx]; + RwMatrixScale(upperLegR, &scale, rwCOMBINEPRECONCAT); + + scale.y = 1.0f + gfTommyFatness * 0.5f; + scale.z = 1.0f + gfTommyFatness * 0.5f; + idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_LOWERLEGR)); + RwMatrix* lowerLegR = &RpHAnimHierarchyGetMatrixArray(hier)[idx]; + RwMatrixScale(lowerLegR, &scale, rwCOMBINEPRECONCAT); + + idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_LOWERLEGL)); + RwMatrix* lowerLegL = &RpHAnimHierarchyGetMatrixArray(hier)[idx]; + RwMatrixScale(lowerLegL, &scale, rwCOMBINEPRECONCAT); + + scale.y = 1.0f + gfTommyFatness * 0.23f; + scale.z = 1.0f + gfTommyFatness * 0.23f; + idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_FOOTL)); + RwMatrix* footL = &RpHAnimHierarchyGetMatrixArray(hier)[idx]; + RwMatrixScale(footL, &scale, rwCOMBINEPRECONCAT); + + idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_FOOTR)); + RwMatrix* footR = &RpHAnimHierarchyGetMatrixArray(hier)[idx]; + RwMatrixScale(footR, &scale, rwCOMBINEPRECONCAT); + + idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_UPPERARML)); + RwMatrix* upperArmL = &RpHAnimHierarchyGetMatrixArray(hier)[idx]; + RwMatrixScale(upperArmL, &scale, rwCOMBINEPRECONCAT); + + idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_UPPERARMR)); + RwMatrix* upperArmR = &RpHAnimHierarchyGetMatrixArray(hier)[idx]; + RwMatrixScale(upperArmR, &scale, rwCOMBINEPRECONCAT); + + scale.y = 1.0f + gfTommyFatness * 0.2f; + scale.z = 1.0f + gfTommyFatness * 0.2f; + idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_FOREARML)); + RwMatrix* foreArmL = &RpHAnimHierarchyGetMatrixArray(hier)[idx]; + RwMatrixScale(foreArmL, &scale, rwCOMBINEPRECONCAT); + + idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_FOREARMR)); + RwMatrix* foreArmR = &RpHAnimHierarchyGetMatrixArray(hier)[idx]; + RwMatrixScale(foreArmR, &scale, rwCOMBINEPRECONCAT); + } if (bBodyPartJustCameOff && bIsPedDieAnimPlaying && m_bodyPartBleeding != -1 && (CTimer::GetFrameCounter() & 7) > 3) { CVector bloodDir(0.0f, 0.0f, 0.0f); @@ -16512,15 +16853,14 @@ CPed::PreRender(void) } } +// --MIAMI: Done void CPed::ProcessBuoyancy(void) { + float buoyancyLevel = 1.1f; static uint32 nGenerateRaindrops = 0; static uint32 nGenerateWaterCircles = 0; - CRGBA color(((0.5f * CTimeCycle::GetDirectionalRed() + CTimeCycle::GetAmbientRed()) * 127.5f), - ((0.5f * CTimeCycle::GetDirectionalBlue() + CTimeCycle::GetAmbientBlue()) * 127.5f), - ((0.5f * CTimeCycle::GetDirectionalGreen() + CTimeCycle::GetAmbientGreen()) * 127.5f), - (CGeneral::GetRandomNumber() % 256 * 48.0f) + 48); + CRGBA color; if (bInVehicle) return; @@ -16528,26 +16868,27 @@ CPed::ProcessBuoyancy(void) CVector buoyancyPoint; CVector buoyancyImpulse; -#ifndef VC_PED_PORTS - float buoyancyLevel = (m_nPedState == PED_DEAD ? 1.5f : 1.3f); -#else - float buoyancyLevel = (m_nPedState == PED_DEAD ? 1.8f : 1.1f); -#endif + if (DyingOrDead()) + buoyancyLevel = 1.8f; if (mod_Buoyancy.ProcessBuoyancy(this, GRAVITY * m_fMass * buoyancyLevel, &buoyancyPoint, &buoyancyImpulse)) { bTouchingWater = true; CEntity *entity; CColPoint point; if (CWorld::ProcessVerticalLine(GetPosition(), GetPosition().z - 3.0f, point, entity, false, true, false, false, false, false, nil) - && entity->IsVehicle() && ((CVehicle*)entity)->IsBoat()) { + && entity->IsVehicle() && ((CVehicle*)entity)->IsBoat() && !entity->bRenderScorched) { bIsInWater = false; return; } + color.r = (0.5f * CTimeCycle::GetDirectionalRed() + CTimeCycle::GetAmbientRed()) * 127.5f; + color.g = (0.5f * CTimeCycle::GetDirectionalBlue() + CTimeCycle::GetAmbientBlue()) * 127.5f; + color.b = (0.5f * CTimeCycle::GetDirectionalGreen() + CTimeCycle::GetAmbientGreen()) * 127.5f; + color.a = (CGeneral::GetRandomNumber() % 256 * 48.0f) + 48; bIsInWater = true; ApplyMoveForce(buoyancyImpulse); if (!DyingOrDead()) { if (bTryingToReachDryLand) { - if (buoyancyImpulse.z / m_fMass > 0.0032f * CTimer::GetTimeStep()) { + if (buoyancyImpulse.z / m_fMass > GRAVITY * 0.4f * CTimer::GetTimeStep()) { bTryingToReachDryLand = false; CVector pos = GetPosition(); if (PlacePedOnDryLand()) { @@ -16559,19 +16900,15 @@ CPed::ProcessBuoyancy(void) bIsInTheAir = false; } pos.z = pos.z - 0.8f; -#ifdef PC_PARTICLE CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, pos, CVector(0.0f, 0.0f, 0.0f), 0.0f, 50, color, true); -#else - CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, pos, CVector(0.0f, 0.0f, 0.0f), 0.0f, 50, CRGBA(0, 0, 0, 0), true); -#endif m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f); - m_nPedState = PED_IDLE; + SetPedState(PED_IDLE); return; } } } float speedMult = 0.0f; - if (buoyancyImpulse.z / m_fMass > 0.006f * CTimer::GetTimeStep() + if (buoyancyImpulse.z / m_fMass > GRAVITY * CTimer::GetTimeStep() || mod_Buoyancy.m_waterlevel > GetPosition().z) { speedMult = pow(0.9f, CTimer::GetTimeStep()); m_vecMoveSpeed.x *= speedMult; @@ -16581,7 +16918,7 @@ CPed::ProcessBuoyancy(void) bIsDrowning = true; InflictDamage(nil, WEAPONTYPE_DROWNING, 3.0f * CTimer::GetTimeStep(), PEDPIECE_TORSO, 0); } - if (buoyancyImpulse.z / m_fMass > 0.002f * CTimer::GetTimeStep()) { + if (buoyancyImpulse.z / m_fMass > GRAVITY * 0.25f * CTimer::GetTimeStep()) { if (speedMult == 0.0f) { speedMult = pow(0.9f, CTimer::GetTimeStep()); } @@ -16593,7 +16930,6 @@ CPed::ProcessBuoyancy(void) } else { m_vecMoveSpeed.z = -0.01f; DMAudio.PlayOneShot(m_audioEntityId, SOUND_SPLASH, 0.0f); -#ifdef PC_PARTICLE CVector aBitForward = 2.2f * m_vecMoveSpeed + GetPosition(); float level = 0.0f; if (CWaterLevel::GetWaterLevel(aBitForward, &level, false)) @@ -16602,18 +16938,6 @@ CPed::ProcessBuoyancy(void) CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, aBitForward, CVector(0.0f, 0.0f, 0.1f), 0.0f, 200, color, true); nGenerateRaindrops = CTimer::GetTimeInMilliseconds() + 80; nGenerateWaterCircles = CTimer::GetTimeInMilliseconds() + 100; -#else - CVector aBitForward = 1.6f * m_vecMoveSpeed + GetPosition(); - float level = 0.0f; - if (CWaterLevel::GetWaterLevel(aBitForward, &level, false)) - aBitForward.z = level + 0.5f; - - CVector vel = m_vecMoveSpeed * 0.1f; - vel.z = 0.18f; - CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, aBitForward, vel, 0.0f, 350, CRGBA(0, 0, 0, 0), true); - nGenerateRaindrops = CTimer::GetTimeInMilliseconds() + 300; - nGenerateWaterCircles = CTimer::GetTimeInMilliseconds() + 60; -#endif } } } else @@ -16630,15 +16954,9 @@ CPed::ProcessBuoyancy(void) if (pos.z != 0.0f) { nGenerateWaterCircles = 0; for(int i = 0; i < 4; i++) { -#ifdef PC_PARTICLE pos.x += CGeneral::GetRandomNumberInRange(-0.75f, 0.75f); pos.y += CGeneral::GetRandomNumberInRange(-0.75f, 0.75f); CParticle::AddParticle(PARTICLE_RAIN_SPLASH_BIGGROW, pos, CVector(0.0f, 0.0f, 0.0f), nil, 0.0f, color, 0, 0, 0, 0); -#else - pos.x += CGeneral::GetRandomNumberInRange(-2.5f, 2.5f); - pos.y += CGeneral::GetRandomNumberInRange(-2.5f, 2.5f); - CParticle::AddParticle(PARTICLE_RAIN_SPLASH_BIGGROW, pos+CVector(0.0f, 0.0f, 1.0f), CVector(0.0f, 0.0f, 0.0f)); -#endif } } } @@ -16650,17 +16968,9 @@ CPed::ProcessBuoyancy(void) pos.z = level; if (pos.z >= 0.0f) { -#ifdef PC_PARTICLE pos.z += 0.25f; -#else - pos.z += 0.5f; -#endif nGenerateRaindrops = 0; -#ifdef PC_PARTICLE CParticleObject::AddObject(POBJECT_SPLASHES_AROUND, pos, CVector(0.0f, 0.0f, 0.0f), 4.5f, 1500, CRGBA(0,0,0,0), true); -#else - CParticleObject::AddObject(POBJECT_SPLASHES_AROUND, pos, CVector(0.0f, 0.0f, 0.0f), 4.5f, 2500, CRGBA(0,0,0,0), true); -#endif } } } @@ -19399,10 +19709,7 @@ CPed::Solicit(void) void CPed::SetExitBoat(CVehicle *boat) { - if (m_nPedState == PED_FOLLOW_PATH) { - ClearFollowPath(); - } - m_nPedState = PED_IDLE; + SetPedState(PED_IDLE); CVector newPos = GetPosition(); RemoveInCarAnims(); CColModel* boatCol = boat->GetColModel(); @@ -20873,6 +21180,46 @@ CPed::ScanForDelayedResponseThreats(void) // --MIAMI: Done void +CPed::DeleteSunbatheIdleAnimCB(CAnimBlendAssociation *assoc, void *arg) +{ + CPed *ped = (CPed*) arg; + + if (CTimer::GetTimeInMilliseconds() <= ped->m_nWaitTimer + && !ped->bGotUpOfMyOwnAccord && !ped->bFleeWhenStanding && !ped->m_threatEx) { + ped->m_pNextPathNode = nil; + ped->bFleeWhenStanding = true; + ped->m_threatEx = FindPlayerPed(); + ped->SetGetUp(); + ped->ClearWaitState(); + } + ped->m_nWaitTimer = 0; + ped->RestoreHeadingRate(); + ped->Wait(); +} + +// --MIAMI: Done +void +CPed::PedSetPreviousStateCB(CAnimBlendAssociation* assoc, void* arg) +{ + CPed* ped = (CPed*)arg; + ped->RestorePreviousState(); + ped->m_pVehicleAnim = nil; +} + +// --MIAMI: Done +void +CPed::PedAnimShuffleCB(CAnimBlendAssociation* assoc, void* arg) +{ + CPed *ped = (CPed*)arg; + if (ped->EnteringCar()) { + PedSetInCarCB(nil, ped); + } else if (ped->m_nPedState != PED_DRIVING) { + ped->QuitEnteringCar(); + } +} + +// --MIAMI: Done +void PlayRandomAnimationsFromAnimBlock(CPed* ped, AssocGroupId animGroup, uint32 first, uint32 amount) { if (!ped->IsPedInControl()) diff --git a/src/peds/Ped.h b/src/peds/Ped.h index 815d9c2d..752973bc 100644 --- a/src/peds/Ped.h +++ b/src/peds/Ped.h @@ -14,6 +14,7 @@ #define FEET_OFFSET 1.04f #define CHECK_NEARBY_THINGS_MAX_DIST 15.0f +#define ENTER_CAR_MAX_DIST 30.0f class CAccident; class CObject; @@ -358,6 +359,8 @@ enum eMoveState { PEDMOVE_THROWN }; +extern float gfTommyFatness; + class CVehicle; class CPed : public CPhysical @@ -457,8 +460,8 @@ public: uint32 bHasAlreadyUsedAttractor : 1; uint32 b155_2 : 1; uint32 bCarPassenger : 1; - uint32 b155_8 : 1; - uint32 b155_10 : 1; + uint32 bFleeWhenStanding : 1; + uint32 bGotUpOfMyOwnAccord : 1; uint32 bMiamiViceCop : 1; uint32 bMoneyHasBeenGivenByScript : 1; // uint32 bHasBeenPhotographed : 1; // @@ -475,10 +478,10 @@ public: uint32 bDontFight : 1; uint32 bDoomAim : 1; uint32 bCanBeShotInVehicle : 1; - uint32 b157_8 : 1; + uint32 bCanGiveUpSunbathing : 1; uint32 bMakeFleeScream : 1; uint32 bPushedAlongByCar : 1; - uint32 b157_40 : 1; + uint32 bRemoveMeWhenIGotIntoCar : 1; uint32 bIgnoreThreatsBehindObjects : 1; uint32 bNeverEverTargetThisPed : 1; @@ -487,7 +490,7 @@ public: uint32 b158_8 : 1; uint32 bCollectBusFare : 1; uint32 bBoughtIceCream : 1; - uint32 b158_40 : 1; + uint32 bDonePositionOutOfCollision : 1; uint32 b158_80 : 1; // our own flags @@ -580,7 +583,7 @@ public: float m_fleeFromPosY; CEntity *m_fleeFrom; uint32 m_fleeTimer; - CEntity* pThreatEx; // TODO(Miami): What is this? + CEntity* m_threatEx; // TODO(Miami): What is this? CEntity* m_collidingEntityWhileFleeing; uint32 m_collidingThingTimer; CEntity *m_pCollidingEntity; @@ -831,6 +834,7 @@ public: void ReactToPointGun(CEntity*); void SeekCar(void); bool PositionPedOutOfCollision(void); + bool PositionAnyPedOutOfCollision(void); bool RunToReportCrime(eCrimeType); bool PlacePedOnDryLand(void); bool PossiblyFindBetterPosToSeekCar(CVector*, CVehicle*); @@ -905,6 +909,9 @@ public: static void RestoreHeadingRateCB(CAnimBlendAssociation *assoc, void *arg); static void PedSetQuickDraggedOutCarPositionCB(CAnimBlendAssociation *assoc, void *arg); static void PedSetDraggedOutCarPositionCB(CAnimBlendAssociation *assoc, void *arg); + static void DeleteSunbatheIdleAnimCB(CAnimBlendAssociation *assoc, void *arg); + static void PedSetPreviousStateCB(CAnimBlendAssociation *assoc, void *arg); + static void PedAnimShuffleCB(CAnimBlendAssociation *assoc, void *arg); bool IsPlayer(void); bool IsFemale(void) { return m_nPedType == PEDTYPE_CIVFEMALE || m_nPedType == PEDTYPE_PROSTITUTE; } diff --git a/src/render/Fluff.cpp b/src/render/Fluff.cpp index 77d2af2a..31bf92a8 100644 --- a/src/render/Fluff.cpp +++ b/src/render/Fluff.cpp @@ -1611,13 +1611,13 @@ void CScriptPath::Clear(void) { m_state = SCRIPT_PATH_DISABLED; } -void CScriptPath::InitialiseOne(int32 numNodes, float width) { +void CScriptPath::InitialiseOne(int32 numNodes, float length) { char Dest[32]; sprintf(Dest, "data\\paths\\spath%d.dat", numNodes); m_pNode = CPlane::LoadPath(Dest, m_numNodes, m_fTotalLength, false); m_fSpeed = 1.0f; m_fPosition = 0.0f; - m_fObjectLength = width; + m_fObjectLength = length; m_state = SCRIPT_PATH_INITIALIZED; } @@ -1697,7 +1697,7 @@ INITSAVEBUF VALIDATESAVEBUF(*size); } -CObject* g_pScriptPathObjects[18]; +CObject *g_pScriptPathObjects[18]; void CScriptPaths::Load_ForReplay(void) { for (int i = 0; i < 3; i++) { diff --git a/src/render/Fluff.h b/src/render/Fluff.h index a31ac335..0fc57c73 100644 --- a/src/render/Fluff.h +++ b/src/render/Fluff.h @@ -24,7 +24,7 @@ public: void Clear(void); void Update(void); - void InitialiseOne(int32 numNodes, float width); + void InitialiseOne(int32 numNodes, float length); void FindCoorsFromDistanceOnPath(float t, float *pX, float *pY, float *pZ); void SetObjectToControl(CObject *pObj); }; diff --git a/src/render/Hud.cpp b/src/render/Hud.cpp index cbf3c7f2..c05a3d31 100644 --- a/src/render/Hud.cpp +++ b/src/render/Hud.cpp @@ -21,6 +21,8 @@ #include "User.h" #include "World.h" #include "CutsceneMgr.h" +#include "Stats.h" +#include "main.h" // Game has colors inlined in code. // For easier modification we collect them here: @@ -91,6 +93,8 @@ float CHud::PagerXOffset; int16 CHud::PagerTimer; int16 CHud::PagerOn; +wchar *prevChaseString; + uint32 CHud::m_WantedFadeTimer; uint32 CHud::m_WantedState; uint32 CHud::m_WantedTimer; @@ -524,6 +528,53 @@ void CHud::Draw() } } + static int32 nMediaLevelCounter = 0; + if (CStats::ShowChaseStatOnScreen != 0) { + float fCurAttentionLevel = CWorld::Players[CWorld::PlayerInFocus].m_fMediaAttention; + if (0.7f * CStats::HighestChaseValue > fCurAttentionLevel + || fCurAttentionLevel <= 40.0f || CTheScripts::IsPlayerOnAMission()) { + nMediaLevelCounter = 0; + } + else { + if (fCurAttentionLevel == CStats::HighestChaseValue) { + sprintf(gString, "%s %d", UnicodeToAscii(TheText.Get("CHSE")), (int32)fCurAttentionLevel); + } + else { + sprintf(gString, "%s %d" "-%d-", UnicodeToAscii(TheText.Get("CHSE")), (int32)fCurAttentionLevel, (int32)CStats::HighestChaseValue); + } + AsciiToUnicode(gString, gUString); + CFont::SetBackgroundOff(); + CFont::SetScale(SCREEN_SCALE_X(HUD_TEXT_SCALE_X), SCREEN_SCALE_Y(HUD_TEXT_SCALE_Y)); + CFont::SetCentreOff(); + CFont::SetRightJustifyOn(); + CFont::SetRightJustifyWrap(0.0f); + CFont::SetBackGroundOnlyTextOff(); + CFont::SetFontStyle(FONT_HEADING); + CFont::SetPropOff(); + CFont::SetDropShadowPosition(2); + CFont::SetDropColor(CRGBA(0, 0, 0, 255)); + + CRGBA colour; + if (CTimer::GetTimeInMilliseconds() & 0x200) + colour = CRGBA(204, 0, 185, 180); + else + colour = CRGBA(178, 0, 162, 180); + CFont::SetColor(colour); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f), SCREEN_SCALE_Y(113.0f), gUString); + + if (CStats::FindChaseString(fCurAttentionLevel) != prevChaseString) { + prevChaseString = CStats::FindChaseString(fCurAttentionLevel); + nMediaLevelCounter = 100; + } + + if (nMediaLevelCounter != 0) { + nMediaLevelCounter--; + UnicodeMakeUpperCase(gUString, CStats::FindChaseString(fCurAttentionLevel)); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f), SCREEN_SCALE_Y(138.0f), gUString); + } + } + } + /* DrawZoneName */ diff --git a/src/text/Text.cpp b/src/text/Text.cpp index dab1cae3..64f303eb 100644 --- a/src/text/Text.cpp +++ b/src/text/Text.cpp @@ -495,6 +495,20 @@ UnicodeToAsciiForMemoryCard(wchar *src) } void +UnicodeMakeUpperCase(wchar *dst, wchar *src) //idk what to do with it, seems to be incorrect implementation by R* +{ + while (*src != '\0') { + if (*src < 'a' || *src > 'z') + *dst = *src; + else + *dst = *src - 32; + dst++; + src++; + } + *dst = '\0'; +} + +void UnicodeStrcpy(wchar *dst, const wchar *src) { while((*dst++ = *src++) != '\0'); diff --git a/src/text/Text.h b/src/text/Text.h index d163b9c9..0bad9a83 100644 --- a/src/text/Text.h +++ b/src/text/Text.h @@ -8,6 +8,7 @@ void UnicodeStrcpy(wchar *dst, const wchar *src); void UnicodeStrcat(wchar *dst, wchar *append); int UnicodeStrlen(const wchar *str); void TextCopy(wchar *dst, const wchar *src); +void UnicodeMakeUpperCase(wchar *dst, wchar *src); struct CKeyEntry { |