diff options
author | Fire_Head <Fire-Head@users.noreply.github.com> | 2019-07-24 20:00:08 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-07-24 20:00:08 +0200 |
commit | 81ee1c509a8d05189901dd59c268bf47a6188eb8 (patch) | |
tree | d836f70678f2ce7b5d86a6745f34b45232ff71d0 /src/control | |
parent | update (diff) | |
parent | Merge branch 'master' into master (diff) | |
download | re3-81ee1c509a8d05189901dd59c268bf47a6188eb8.tar re3-81ee1c509a8d05189901dd59c268bf47a6188eb8.tar.gz re3-81ee1c509a8d05189901dd59c268bf47a6188eb8.tar.bz2 re3-81ee1c509a8d05189901dd59c268bf47a6188eb8.tar.lz re3-81ee1c509a8d05189901dd59c268bf47a6188eb8.tar.xz re3-81ee1c509a8d05189901dd59c268bf47a6188eb8.tar.zst re3-81ee1c509a8d05189901dd59c268bf47a6188eb8.zip |
Diffstat (limited to 'src/control')
-rw-r--r-- | src/control/AutoPilot.h | 7 | ||||
-rw-r--r-- | src/control/Bridge.cpp | 49 | ||||
-rw-r--r-- | src/control/CarAI.cpp | 6 | ||||
-rw-r--r-- | src/control/CarAI.h | 10 | ||||
-rw-r--r-- | src/control/CarCtrl.cpp | 13 | ||||
-rw-r--r-- | src/control/CarCtrl.h | 6 | ||||
-rw-r--r-- | src/control/Darkel.cpp | 4 | ||||
-rw-r--r-- | src/control/Darkel.h | 2 | ||||
-rw-r--r-- | src/control/Garages.cpp | 2 | ||||
-rw-r--r-- | src/control/Garages.h | 1 | ||||
-rw-r--r-- | src/control/PathFind.cpp | 2 | ||||
-rw-r--r-- | src/control/PathFind.h | 1 | ||||
-rw-r--r-- | src/control/Phones.cpp | 161 | ||||
-rw-r--r-- | src/control/Phones.h | 21 | ||||
-rw-r--r-- | src/control/Population.cpp | 2 | ||||
-rw-r--r-- | src/control/Population.h | 3 | ||||
-rw-r--r-- | src/control/Remote.cpp | 5 | ||||
-rw-r--r-- | src/control/Remote.h | 7 | ||||
-rw-r--r-- | src/control/Replay.cpp | 56 | ||||
-rw-r--r-- | src/control/Replay.h | 2 | ||||
-rw-r--r-- | src/control/Script.cpp | 831 | ||||
-rw-r--r-- | src/control/Script.h | 2 |
22 files changed, 1108 insertions, 85 deletions
diff --git a/src/control/AutoPilot.h b/src/control/AutoPilot.h index 364cb633..b1c824d8 100644 --- a/src/control/AutoPilot.h +++ b/src/control/AutoPilot.h @@ -72,8 +72,8 @@ public: int8 m_nPreviousDirection; int8 m_nCurrentDirecton; int8 m_nNextDirection; - int8 m_nPreviousPathDirection; - int8 m_nCurrentPathDirection; + int8 m_nPreviousLane; + int8 m_nCurrentLane; eCarDrivingStyle m_nDrivingStyle; eCarMission m_nCarMission; eCarTempAction m_nAnimationId; @@ -101,8 +101,7 @@ public: m_nCurrentPathNodeInfo = m_nNextPathNodeInfo; m_nNextDirection = 1; m_nCurrentDirecton = m_nNextDirection; - m_nCurrentPathDirection = 0; - m_nPreviousPathDirection = m_nCurrentPathDirection; + m_nPreviousLane = m_nCurrentLane = 0; m_nDrivingStyle = DRIVINGSTYLE_STOP_FOR_CARS; m_nCarMission = MISSION_NONE; m_nAnimationId = TEMPACT_NONE; diff --git a/src/control/Bridge.cpp b/src/control/Bridge.cpp index 3215ea2d..81f43f32 100644 --- a/src/control/Bridge.cpp +++ b/src/control/Bridge.cpp @@ -46,6 +46,7 @@ void CBridge::Update() float liftHeight; + // Set bridge height and state if (CStats::CommercialPassed) { if (TimeOfBridgeBecomingOperational == 0) @@ -81,30 +82,6 @@ void CBridge::Update() liftHeight = 25.0; State = STATE_LIFT_PART_IS_UP; } - - // Move bridge part - if (liftHeight != OldLift) - { - pLiftPart->GetPosition().z = DefaultZLiftPart + liftHeight; - pLiftPart->GetMatrix().UpdateRW(); - pLiftPart->UpdateRwFrame(); - if (pLiftRoad) - { - pLiftRoad->GetPosition().z = DefaultZLiftRoad + liftHeight; - pLiftRoad->GetMatrix().UpdateRW(); - pLiftRoad->UpdateRwFrame(); - } - pWeight->GetPosition().z = DefaultZLiftWeight - liftHeight; - pWeight->GetMatrix().UpdateRW(); - pWeight->UpdateRwFrame(); - - OldLift = liftHeight; - } - - if (State == STATE_LIFT_PART_ABOUT_TO_MOVE_UP && OldState == STATE_LIFT_PART_IS_DOWN) - ThePaths.SetLinksBridgeLights(-330.0, -230.0, -700.0, -588.0, true); - else if (State == STATE_LIFT_PART_IS_DOWN && OldState == STATE_LIFT_PART_MOVING_DOWN) - ThePaths.SetLinksBridgeLights(-330.0, -230.0, -700.0, -588.0, false); } else { @@ -112,6 +89,30 @@ void CBridge::Update() TimeOfBridgeBecomingOperational = 0; State = STATE_BRIDGE_LOCKED; } + + // Move bridge part + if (liftHeight != OldLift) + { + pLiftPart->GetPosition().z = DefaultZLiftPart + liftHeight; + pLiftPart->GetMatrix().UpdateRW(); + pLiftPart->UpdateRwFrame(); + if (pLiftRoad) + { + pLiftRoad->GetPosition().z = DefaultZLiftRoad + liftHeight; + pLiftRoad->GetMatrix().UpdateRW(); + pLiftRoad->UpdateRwFrame(); + } + pWeight->GetPosition().z = DefaultZLiftWeight - liftHeight; + pWeight->GetMatrix().UpdateRW(); + pWeight->UpdateRwFrame(); + + OldLift = liftHeight; + } + + if (State == STATE_LIFT_PART_ABOUT_TO_MOVE_UP && OldState == STATE_LIFT_PART_IS_DOWN) + ThePaths.SetLinksBridgeLights(-330.0, -230.0, -700.0, -588.0, true); + else if (State == STATE_LIFT_PART_IS_DOWN && OldState == STATE_LIFT_PART_MOVING_DOWN) + ThePaths.SetLinksBridgeLights(-330.0, -230.0, -700.0, -588.0, false); } bool CBridge::ShouldLightsBeFlashing() { return State != STATE_LIFT_PART_IS_DOWN; } diff --git a/src/control/CarAI.cpp b/src/control/CarAI.cpp new file mode 100644 index 00000000..faf27788 --- /dev/null +++ b/src/control/CarAI.cpp @@ -0,0 +1,6 @@ +#include "common.h" +#include "patcher.h" +#include "CarAI.h" + +WRAPPER void CCarAI::UpdateCarAI(CVehicle*) { EAXJMP(0x413E50); } +WRAPPER void CCarAI::MakeWayForCarWithSiren(CVehicle *veh) { EAXJMP(0x416280); } diff --git a/src/control/CarAI.h b/src/control/CarAI.h new file mode 100644 index 00000000..5112f769 --- /dev/null +++ b/src/control/CarAI.h @@ -0,0 +1,10 @@ +#pragma once + +class CVehicle; + +class CCarAI +{ +public: + static void UpdateCarAI(CVehicle*); + static void MakeWayForCarWithSiren(CVehicle *veh); +}; diff --git a/src/control/CarCtrl.cpp b/src/control/CarCtrl.cpp index b0f4c1ed..5e436c84 100644 --- a/src/control/CarCtrl.cpp +++ b/src/control/CarCtrl.cpp @@ -12,3 +12,16 @@ WRAPPER void CCarCtrl::SwitchVehicleToRealPhysics(CVehicle*) { EAXJMP(0x41F7F0); WRAPPER void CCarCtrl::AddToCarArray(int32 id, int32 vehclass) { EAXJMP(0x4182F0); } WRAPPER void CCarCtrl::UpdateCarCount(CVehicle*, bool) { EAXJMP(0x4202E0); } WRAPPER int32 CCarCtrl::ChooseCarModel(int32 vehclass) { EAXJMP(0x418110); } +WRAPPER bool CCarCtrl::JoinCarWithRoadSystemGotoCoors(CVehicle*, CVector, bool) { EAXJMP(0x41FA00); } +WRAPPER void CCarCtrl::JoinCarWithRoadSystem(CVehicle*) { EAXJMP(0x41F820); } +WRAPPER void CCarCtrl::SteerAICarWithPhysics(CVehicle*) { EAXJMP(0x41DA60); } +WRAPPER void CCarCtrl::UpdateCarOnRails(CVehicle*) { EAXJMP(0x418880); } +WRAPPER void CCarCtrl::ScanForPedDanger(CVehicle *veh) { EAXJMP(0x418F40); } + +bool +CCarCtrl::MapCouldMoveInThisArea(float x, float y) +{ + // bridge moves up and down + return x > -342.0f && x < -219.0f && + y > -677.0f && y < -580.0f; +} diff --git a/src/control/CarCtrl.h b/src/control/CarCtrl.h index c54f747f..677dcf36 100644 --- a/src/control/CarCtrl.h +++ b/src/control/CarCtrl.h @@ -9,6 +9,12 @@ public: static void AddToCarArray(int32 id, int32 vehclass); static void UpdateCarCount(CVehicle*, bool); static int32 ChooseCarModel(int32 vehclass); + static bool JoinCarWithRoadSystemGotoCoors(CVehicle*, CVector, bool); + static void JoinCarWithRoadSystem(CVehicle*); + static void SteerAICarWithPhysics(CVehicle*); + static void UpdateCarOnRails(CVehicle*); + static bool MapCouldMoveInThisArea(float x, float y); + static void ScanForPedDanger(CVehicle *veh); static int32 &NumLawEnforcerCars; static int32 &NumAmbulancesOnDuty; diff --git a/src/control/Darkel.cpp b/src/control/Darkel.cpp index ab28f96e..ad8d1176 100644 --- a/src/control/Darkel.cpp +++ b/src/control/Darkel.cpp @@ -141,7 +141,7 @@ void CDarkel::RegisterKillByPlayer(CPed *victim, eWeaponType weapontype, bool he } #endif -void CDarkel::RegisterKillNotByPlayer() +void CDarkel::RegisterKillNotByPlayer(CPed* victim, eWeaponType weapontype) { ++CStats::NumberKillFrenziesPassed; } @@ -300,7 +300,7 @@ void CDarkel::Update() TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds(); - FindPlayerPed()->m_pWanted->SetWantedLevel(NOTWANTED); + FindPlayerPed()->m_pWanted->SetWantedLevel(0); if (WeaponType == WEAPONTYPE_UZI_DRIVEBY) WeaponType = WEAPONTYPE_UZI; diff --git a/src/control/Darkel.h b/src/control/Darkel.h index 35d849d2..77a14bb8 100644 --- a/src/control/Darkel.h +++ b/src/control/Darkel.h @@ -42,7 +42,7 @@ public: static eKillFrenzyStatus ReadStatus(); static void RegisterCarBlownUpByPlayer(CVehicle *vehicle); static void RegisterKillByPlayer(CPed *victim, eWeaponType weapontype, bool headshot = false); - static void RegisterKillNotByPlayer(); + static void RegisterKillNotByPlayer(CPed* victim, eWeaponType weapontype); static void ResetModelsKilledByPlayer(); static void ResetOnPlayerDeath(); static void StartFrenzy(eWeaponType weaponType, int32 time, int16 kill, int32 modelId0, wchar *text, int32 modelId2, int32 modelId3, int32 modelId4, bool standardSound, bool needHeadShot); diff --git a/src/control/Garages.cpp b/src/control/Garages.cpp index d601db8e..acc2b459 100644 --- a/src/control/Garages.cpp +++ b/src/control/Garages.cpp @@ -63,6 +63,8 @@ CGarages::IsModelIndexADoor(uint32 id) id == MI_CRUSHERLID; } +WRAPPER void CGarages::TriggerMessage(char *text, int16, uint16 time, int16) { EAXJMP(0x426B20); } + #if 0 WRAPPER void CGarages::PrintMessages(void) { EAXJMP(0x426310); } #else diff --git a/src/control/Garages.h b/src/control/Garages.h index f018401c..69f9d256 100644 --- a/src/control/Garages.h +++ b/src/control/Garages.h @@ -22,5 +22,6 @@ public: public: static bool IsModelIndexADoor(uint32 id); + static void TriggerMessage(char *text, int16, uint16 time, int16); static void PrintMessages(void); }; diff --git a/src/control/PathFind.cpp b/src/control/PathFind.cpp index a92882db..f90e0c8f 100644 --- a/src/control/PathFind.cpp +++ b/src/control/PathFind.cpp @@ -5,7 +5,7 @@ CPathFind &ThePaths = *(CPathFind*)0x8F6754; WRAPPER int32 CPathFind::FindNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bool disabled, bool betweenLevels) { EAXJMP(0x42CC30); } - +WRAPPER CPathNode** CPathFind::FindNextNodeWandering(uint8, CVector, CPathNode**, CPathNode**, uint8, uint8*) { EAXJMP(0x42B9F0); } int TempListLength; enum diff --git a/src/control/PathFind.h b/src/control/PathFind.h index 9b6be573..9d97de3f 100644 --- a/src/control/PathFind.h +++ b/src/control/PathFind.h @@ -129,6 +129,7 @@ public: void StoreNodeInfoCar(int16 id, int16 node, int8 type, int8 next, int16 x, int16 y, int16 z, int16 width, int8 numLeft, int8 numRight); void RegisterMapObject(CTreadable *mapObject); int32 FindNodeClosestToCoors(CVector coors, uint8 type, float distLimit, bool disabled, bool betweenLevels); + CPathNode** FindNextNodeWandering(uint8, CVector, CPathNode**, CPathNode**, uint8, uint8*); bool IsPathObject(int id) { return id < PATHNODESIZE && (InfoForTileCars[id*12].type != 0 || InfoForTilePeds[id*12].type != 0); } diff --git a/src/control/Phones.cpp b/src/control/Phones.cpp index 028d80a9..376e2757 100644 --- a/src/control/Phones.cpp +++ b/src/control/Phones.cpp @@ -2,12 +2,18 @@ #include "patcher.h" #include "Phones.h" #include "Pools.h" +#include "ModelIndices.h" +#include "Ped.h" +#include "Pad.h" +#include "Messages.h" CPhoneInfo &gPhoneInfo = *(CPhoneInfo*)0x732A20; bool &CPhoneInfo::isPhonePickedUp = *(bool*)0x6283AC; -bool &CPhoneInfo::isPhoneBeingPickedUp = *(bool*)0x6283B4; +uint32 &CPhoneInfo::phoneMessagesTimer = *(uint32*)0x6283A8; CPhone *&CPhoneInfo::pickedUpPhone = *(CPhone**)0x6283B0; +bool &CPhoneInfo::isPhoneBeingPickedUp = *(bool*)0x6283B4; +CPed *&CPhoneInfo::pedWhoPickingUpPhone = *(CPed**)0x6283B8; int CPhoneInfo::FindNearestFreePhone(CVector *pos) @@ -69,21 +75,20 @@ CPhoneInfo::Load(CPhoneInfo *source, uint8 buffer) CPhone *phone = &source->m_aPhones[phoneId]; m_aPhones[phoneId].m_vecPos = phone->m_vecPos; - memcpy(m_aPhones[phoneId].m_apMessages, phone->m_apMessages, sizeof(uint16*) * 6); + memcpy(m_aPhones[phoneId].m_apMessages, phone->m_apMessages, sizeof(wchar*) * 6); m_aPhones[phoneId].m_pEntity = phone->m_pEntity; m_aPhones[phoneId].m_nState = phone->m_nState; m_aPhones[phoneId].field_30 = phone->field_30; + // It's saved as building pool index in save file, convert it to true entity if (phone->m_pEntity) { - // It's saved as building pool index in save file, convert it to true entity - CBuilding *actualEntity = CPools::GetBuildingPool()->GetSlot((int)phone->m_pEntity - 1); - m_aPhones[phoneId].m_pEntity = actualEntity; + m_aPhones[phoneId].m_pEntity = CPools::GetBuildingPool()->GetSlot((int)phone->m_pEntity - 1); } } } void -CPhoneInfo::SetPhoneMessage_JustOnce(int phoneId, uint16 *msg1, uint16 *msg2, uint16 *msg3, uint16 *msg4, uint16 *msg5, uint16 *msg6) +CPhoneInfo::SetPhoneMessage_JustOnce(int phoneId, wchar *msg1, wchar *msg2, wchar *msg3, wchar *msg4, wchar *msg5, wchar *msg6) { // If there is at least one message, it should be msg1. if (msg1) { @@ -100,7 +105,7 @@ CPhoneInfo::SetPhoneMessage_JustOnce(int phoneId, uint16 *msg1, uint16 *msg2, ui } void -CPhoneInfo::SetPhoneMessage_Repeatedly(int phoneId, uint16 *msg1, uint16 *msg2, uint16 *msg3, uint16 *msg4, uint16 *msg5, uint16 *msg6) +CPhoneInfo::SetPhoneMessage_Repeatedly(int phoneId, wchar *msg1, wchar *msg2, wchar *msg3, wchar *msg4, wchar *msg5, wchar *msg6) { // If there is at least one message, it should be msg1. if (msg1) { @@ -116,6 +121,137 @@ CPhoneInfo::SetPhoneMessage_Repeatedly(int phoneId, uint16 *msg1, uint16 *msg2, } } +int +CPhoneInfo::GrabPhone(float xPos, float yPos) +{ + // "Grab" doesn't mean picking up the phone, it means allocating some particular phone to + // whoever called the 024A opcode first with the position parameters closest to phone. + // Same phone won't be available on next run of this function. + + int nearestPhoneId = -1; + CVector pos(xPos, yPos, 0.0f); + float nearestPhoneDist = 100.0f; + + for (int phoneId = m_nNum; phoneId < m_nMax; phoneId++) { + float phoneDistance = (m_aPhones[phoneId].m_vecPos - pos).Magnitude2D(); + if (phoneDistance < nearestPhoneDist) { + nearestPhoneDist = phoneDistance; + nearestPhoneId = phoneId; + } + } + m_aPhones[nearestPhoneId].m_nState = PHONE_STATE_MESSAGE_REMOVED; + + CPhone oldFirstPhone = m_aPhones[m_nNum]; + m_aPhones[m_nNum] = m_aPhones[nearestPhoneId]; + m_aPhones[nearestPhoneId] = oldFirstPhone; + m_nNum++; + return m_nNum - 1; +} + +void +CPhoneInfo::Initialise(void) +{ + CBuildingPool *pool = CPools::GetBuildingPool(); + pedWhoPickingUpPhone = nil; + isPhonePickedUp = false; + isPhoneBeingPickedUp = false; + pickedUpPhone = nil; + m_nMax = 0; + m_nNum = 0; + for (int v5 = pool->GetSize() - 1; v5 >= 0; v5--) { + CBuilding *building = pool->GetSlot(v5); + if (building) { + if (building->m_modelIndex == MI_PHONEBOOTH1) { + CPhone *maxPhone = &m_aPhones[m_nMax]; + maxPhone->m_nState = PHONE_STATE_FREE; + maxPhone->m_vecPos = *(building->GetPosition()); + maxPhone->m_pEntity = building; + m_nMax++; + } + } + } +} + +void +CPhoneInfo::Save(CPhoneInfo *destination, uint32 *size) +{ + *size = sizeof(CPhoneInfo); + destination->m_nMax = this->m_nMax; + destination->m_nNum = m_nNum; + for(int phoneId = 0; phoneId < 50; phoneId++) { + CPhone* phone = &destination->m_aPhones[phoneId]; + + phone->m_vecPos = m_aPhones[phoneId].m_vecPos; + memcpy(phone->m_apMessages, m_aPhones[phoneId].m_apMessages, sizeof(wchar*) * 6); + phone->m_pEntity = m_aPhones[phoneId].m_pEntity; + phone->m_nState = m_aPhones[phoneId].m_nState; + phone->field_30 = m_aPhones[phoneId].field_30; + + // Convert entity pointer to building pool index while saving + if (phone->m_pEntity) { + phone->m_pEntity = (CEntity*) CPools::GetBuildingPool()->GetJustIndex((CBuilding*)phone->m_pEntity) + 1; + } + } +} + +void +CPhoneInfo::Shutdown(void) +{ + m_nMax = 0; + m_nNum = 0; +} + +void +PhonePutDownCB(CAnimBlendAssociation *assoc, void *arg) +{ + assoc->flags |= ASSOC_DELETEFADEDOUT; + assoc->blendDelta = -1000.0f; + CPad::GetPad(0)->DisablePlayerControls &= ~PLAYERCONTROL_DISABLED_40; + CPed *ped = (CPed*)arg; + + if (assoc->blendAmount > 0.5f) + ped->m_ped_flagC10 = true; + + if (ped->m_nPedState == PED_MAKE_CALL) + ped->m_nPedState = PED_IDLE; +} + +void +PhonePickUpCB(CAnimBlendAssociation *assoc, void *arg) +{ + CPhone *phone = (CPhone*)arg; + int messagesDisplayTime = 0; + + for(int i=0; i < 6; i++) { + wchar *msg = phone->m_apMessages[i]; + if (msg) { + CMessages::AddMessage(msg, 3000, 0); + messagesDisplayTime += 3000; + } + } + + CPhoneInfo::isPhoneBeingPickedUp = false; + CPhoneInfo::isPhonePickedUp = true; + CPhoneInfo::pickedUpPhone = phone; + CPhoneInfo::phoneMessagesTimer = CTimer::GetTimeInMilliseconds() + messagesDisplayTime; + + if (phone->m_nState == PHONE_STATE_ONETIME_MESSAGE_SET) { + phone->m_nState = PHONE_STATE_ONETIME_MESSAGE_SHOWN; + } else { + phone->m_nState = PHONE_STATE_REPEATED_MESSAGE_SHOWN; + phone->m_lastTimeRepeatedMsgShown = CTimer::GetTimeInMilliseconds(); + } + + CPed *ped = CPhoneInfo::pedWhoPickingUpPhone; + ped->m_nMoveState = PEDMOVE_STILL; + CAnimManager::BlendAnimation((RpClump*)ped->m_rwObject, ASSOCGRP_STD, ANIM_IDLE_STANCE, 8.0f); + + if (assoc->blendAmount > 0.5f && ped) + CAnimManager::BlendAnimation((RpClump*)ped->m_rwObject, ASSOCGRP_STD, ANIM_PHONE_TALK, 8.0f); + + CPhoneInfo::pedWhoPickingUpPhone = nil; +} + STARTPATCHES InjectHook(0x42F720, &CPhoneInfo::FindNearestFreePhone, PATCH_JUMP); InjectHook(0x42FD50, &CPhoneInfo::PhoneAtThisPosition, PATCH_JUMP); @@ -124,7 +260,10 @@ STARTPATCHES InjectHook(0x430120, &CPhoneInfo::Load, PATCH_JUMP); InjectHook(0x42FF90, &CPhoneInfo::SetPhoneMessage_JustOnce, PATCH_JUMP); InjectHook(0x42FF30, &CPhoneInfo::SetPhoneMessage_Repeatedly, PATCH_JUMP); -ENDPATCHES - -WRAPPER void PhonePutDownCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x42F570); } -WRAPPER void PhonePickUpCB(CAnimBlendAssociation *assoc, void *arg) { EAXJMP(0x42F470); } + InjectHook(0x430060, &CPhoneInfo::Save, PATCH_JUMP); + InjectHook(0x42F710, &CPhoneInfo::Shutdown, PATCH_JUMP); + InjectHook(0x42F640, &CPhoneInfo::Initialise, PATCH_JUMP); + InjectHook(0x42FDB0, &CPhoneInfo::GrabPhone, PATCH_JUMP); + InjectHook(0x42F570, &PhonePutDownCB, PATCH_JUMP); + InjectHook(0x42F470, &PhonePickUpCB, PATCH_JUMP); +ENDPATCHES
\ No newline at end of file diff --git a/src/control/Phones.h b/src/control/Phones.h index 74f24d25..35389f3f 100644 --- a/src/control/Phones.h +++ b/src/control/Phones.h @@ -1,7 +1,9 @@ #pragma once #include "Physical.h" -#include "AnimBlendAssociation.h" + +class CPed; +class CAnimBlendAssociation; enum { PHONE_STATE_FREE, @@ -19,7 +21,7 @@ enum { struct CPhone { CVector m_vecPos; - uint16 *m_apMessages[6]; + wchar *m_apMessages[6]; uint32 m_lastTimeRepeatedMsgShown; CEntity *m_pEntity; // it's building pool index in save files int32 m_nState; @@ -29,10 +31,13 @@ struct CPhone static_assert(sizeof(CPhone) == 0x34, "CPhone: error"); class CPhoneInfo { +public: static bool &isPhonePickedUp; - static bool &isPhoneBeingPickedUp; + static uint32 &phoneMessagesTimer; static CPhone *&pickedUpPhone; -public: + static bool &isPhoneBeingPickedUp; + static CPed *&pedWhoPickingUpPhone; + int32 m_nMax; int32 m_nNum; CPhone m_aPhones[50]; @@ -45,8 +50,12 @@ public: bool HasMessageBeenDisplayed(int); bool IsMessageBeingDisplayed(int); void Load(CPhoneInfo *source, uint8 buffer); - void SetPhoneMessage_JustOnce(int phoneId, uint16 *msg1, uint16 *msg2, uint16 *msg3, uint16 *msg4, uint16 *msg5, uint16 *msg6); - void SetPhoneMessage_Repeatedly(int phoneId, uint16 *msg1, uint16 *msg2, uint16 *msg3, uint16 *msg4, uint16 *msg5, uint16 *msg6); + void SetPhoneMessage_JustOnce(int phoneId, wchar *msg1, wchar *msg2, wchar *msg3, wchar *msg4, wchar *msg5, wchar *msg6); + void SetPhoneMessage_Repeatedly(int phoneId, wchar *msg1, wchar *msg2, wchar *msg3, wchar *msg4, wchar *msg5, wchar *msg6); + int GrabPhone(float, float); + void Initialise(void); + void Save(CPhoneInfo*, uint32*); + void Shutdown(void); }; extern CPhoneInfo &gPhoneInfo; diff --git a/src/control/Population.cpp b/src/control/Population.cpp index 1ae5962d..31c475f0 100644 --- a/src/control/Population.cpp +++ b/src/control/Population.cpp @@ -7,7 +7,9 @@ PedGroup *CPopulation::ms_pPedGroups = (PedGroup*)0x6E9248; bool &CPopulation::ms_bGivePedsWeapons = *(bool*)0x95CCF6; int32 &CPopulation::m_AllRandomPedsThisType = *(int32*)0x5FA570; float &CPopulation::PedDensityMultiplier = *(float*)0x5FA56C; +uint32 &CPopulation::ms_nTotalMissionPeds = *(uint32*)0x8F5F70; WRAPPER void CPopulation::UpdatePedCount(uint32, bool) { EAXJMP(0x4F5A60); } WRAPPER void CPopulation::DealWithZoneChange(eLevelName oldLevel, eLevelName newLevel, bool) { EAXJMP(0x4F6200); } WRAPPER CPed *CPopulation::AddPedInCar(CVehicle *vehicle) { EAXJMP(0x4F5800); } +WRAPPER bool CPopulation::IsPointInSafeZone(CVector *coors) { EAXJMP(0x4F60C0); } diff --git a/src/control/Population.h b/src/control/Population.h index 6bd2e3ae..e067562a 100644 --- a/src/control/Population.h +++ b/src/control/Population.h @@ -2,6 +2,7 @@ class CPed; class CVehicle; +enum eLevelName; struct PedGroup { @@ -15,8 +16,10 @@ public: static bool &ms_bGivePedsWeapons; static int32 &m_AllRandomPedsThisType; static float &PedDensityMultiplier; + static uint32 &ms_nTotalMissionPeds; static void UpdatePedCount(uint32, bool); static void DealWithZoneChange(eLevelName oldLevel, eLevelName newLevel, bool); static CPed *AddPedInCar(CVehicle *vehicle); + static bool IsPointInSafeZone(CVector *coors); }; diff --git a/src/control/Remote.cpp b/src/control/Remote.cpp new file mode 100644 index 00000000..8d8d08f2 --- /dev/null +++ b/src/control/Remote.cpp @@ -0,0 +1,5 @@ +#include "common.h" +#include "patcher.h" +#include "Remote.h" + +WRAPPER void CRemote::TakeRemoteControlledCarFromPlayer(void) { EAXJMP(0x435DA0); } diff --git a/src/control/Remote.h b/src/control/Remote.h new file mode 100644 index 00000000..f8ef96bf --- /dev/null +++ b/src/control/Remote.h @@ -0,0 +1,7 @@ +#pragma once + +class CRemote +{ +public: + static void TakeRemoteControlledCarFromPlayer(void); +}; diff --git a/src/control/Replay.cpp b/src/control/Replay.cpp index 3ce9085f..d9453ad6 100644 --- a/src/control/Replay.cpp +++ b/src/control/Replay.cpp @@ -11,7 +11,7 @@ #include "FileMgr.h" #include "Heli.h" #include "main.h" -#include "math/Matrix.h" +#include "Matrix.h" #include "ModelIndices.h" #include "ModelInfo.h" #include "Object.h" @@ -25,7 +25,7 @@ #include "RpAnimBlend.h" #include "RwHelper.h" #include "CutsceneMgr.h" -#include "render/Skidmarks.h" +#include "Skidmarks.h" #include "Streaming.h" #include "Timer.h" #include "Train.h" @@ -625,9 +625,9 @@ void CReplay::StoreCarUpdate(CVehicle *vehicle, int id) vp->health = vehicle->m_fHealth / 4.0f; /* Not anticipated that health can be > 1000. */ vp->acceleration = vehicle->m_fGasPedal * 100.0f; vp->panels = vehicle->IsCar() ? ((CAutomobile*)vehicle)->Damage.m_panelStatus : 0; - vp->velocityX = 8000.0f * max(-4.0f, min(4.0f, vehicle->GetSpeed().x)); /* 8000!? */ - vp->velocityY = 8000.0f * max(-4.0f, min(4.0f, vehicle->GetSpeed().y)); - vp->velocityZ = 8000.0f * max(-4.0f, min(4.0f, vehicle->GetSpeed().z)); + vp->velocityX = 8000.0f * max(-4.0f, min(4.0f, vehicle->GetMoveSpeed().x)); /* 8000!? */ + vp->velocityY = 8000.0f * max(-4.0f, min(4.0f, vehicle->GetMoveSpeed().y)); + vp->velocityZ = 8000.0f * max(-4.0f, min(4.0f, vehicle->GetMoveSpeed().z)); vp->mi = vehicle->GetModelIndex(); vp->primary_color = vehicle->m_currentColour1; vp->secondary_color = vehicle->m_currentColour2; @@ -718,7 +718,7 @@ void CReplay::ProcessCarUpdate(CVehicle *vehicle, float interpolation, CAddressI } vehicle->bEngineOn = true; if (vehicle->IsCar()) - ((CAutomobile*)vehicle)->m_nWheelsOnGround = 4; + ((CAutomobile*)vehicle)->m_nDriveWheelsOnGround = 4; CWorld::Remove(vehicle); CWorld::Add(vehicle); if (vehicle->IsBoat()) @@ -850,10 +850,10 @@ bool CReplay::PlayBackThisFrameInterpolation(CAddressInReplayBuffer *buffer, flo TheCamera.GetMatrix().GetPosition() *= split; TheCamera.GetMatrix() += CMatrix(interpolation) * pg->camera_pos; RwMatrix* pm = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)); - pm->pos = *(RwV3d*)TheCamera.GetMatrix().GetPosition(); - pm->at = *(RwV3d*)TheCamera.GetMatrix().GetForward(); - pm->up = *(RwV3d*)TheCamera.GetMatrix().GetUp(); - pm->right = *(RwV3d*)TheCamera.GetMatrix().GetRight(); + pm->pos = *(RwV3d*)TheCamera.GetPosition(); + pm->at = *(RwV3d*)TheCamera.GetForward(); + pm->up = *(RwV3d*)TheCamera.GetUp(); + pm->right = *(RwV3d*)TheCamera.GetRight(); CameraFocusX = split * CameraFocusX + interpolation * pg->player_pos.x; CameraFocusY = split * CameraFocusY + interpolation * pg->player_pos.y; CameraFocusZ = split * CameraFocusZ + interpolation * pg->player_pos.z; @@ -979,15 +979,15 @@ void CReplay::ProcessReplayCamera(void) switch (CameraMode) { case REPLAYCAMMODE_TOPDOWN: { - TheCamera.GetMatrix().GetPosition() = CVector(CameraFocusX, CameraFocusY, CameraFocusZ + 15.0f); - TheCamera.GetMatrix().GetForward() = CVector(0.0f, 0.0f, -1.0f); - TheCamera.GetMatrix().GetUp() = CVector(0.0f, 1.0f, 0.0f); - TheCamera.GetMatrix().GetRight() = CVector(1.0f, 0.0f, 0.0f); + TheCamera.GetPosition() = CVector(CameraFocusX, CameraFocusY, CameraFocusZ + 15.0f); + TheCamera.GetForward() = CVector(0.0f, 0.0f, -1.0f); + TheCamera.GetUp() = CVector(0.0f, 1.0f, 0.0f); + TheCamera.GetRight() = CVector(1.0f, 0.0f, 0.0f); RwMatrix* pm = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)); - pm->pos = *(RwV3d*)&TheCamera.GetMatrix().GetPosition(); - pm->at = *(RwV3d*)&TheCamera.GetMatrix().GetForward(); - pm->up = *(RwV3d*)&TheCamera.GetMatrix().GetUp(); - pm->right = *(RwV3d*)&TheCamera.GetMatrix().GetRight(); + pm->pos = *(RwV3d*)&TheCamera.GetPosition(); + pm->at = *(RwV3d*)&TheCamera.GetForward(); + pm->up = *(RwV3d*)&TheCamera.GetUp(); + pm->right = *(RwV3d*)&TheCamera.GetRight(); break; } case REPLAYCAMMODE_FIXED: @@ -1113,7 +1113,7 @@ void CReplay::StoreStuffInMem(void) TimeStep = CTimer::GetTimeStep(); TimeScale = CTimer::GetTimeScale(); int size = CPools::GetPedPool()->GetSize(); - pPedAnims = (CStoredDetailedAnimationState*)malloc(size * sizeof(CStoredDetailedAnimationState)); + pPedAnims = new CStoredDetailedAnimationState[size]; for (int i = 0; i < size; i++) { CPed* ped = CPools::GetPedPool()->GetSlot(i); if (ped) @@ -1279,7 +1279,7 @@ void CReplay::RestoreStuffFromMem(void) continue; RetrieveDetailedPedAnimation(ped, &pPedAnims[i]); } - free(pPedAnims); + delete[] pPedAnims; pPedAnims = nil; DMAudio.ChangeMusicMode(0); DMAudio.SetRadioInCar(OldRadioStation); @@ -1525,15 +1525,15 @@ void CReplay::ProcessLookAroundCam(void) right.Normalise(); CVector up = CrossProduct(forward, right); up.Normalise(); - TheCamera.GetMatrix().GetForward() = forward; - TheCamera.GetMatrix().GetUp() = up; - TheCamera.GetMatrix().GetRight() = right; - TheCamera.GetMatrix().GetPosition() = camera_pt; + TheCamera.GetForward() = forward; + TheCamera.GetUp() = up; + TheCamera.GetRight() = right; + TheCamera.GetPosition() = camera_pt; RwMatrix* pm = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)); - pm->pos = *(RwV3d*)&TheCamera.GetMatrix().GetPosition(); - pm->at = *(RwV3d*)&TheCamera.GetMatrix().GetForward(); - pm->up = *(RwV3d*)&TheCamera.GetMatrix().GetUp(); - pm->right = *(RwV3d*)&TheCamera.GetMatrix().GetRight(); + pm->pos = *(RwV3d*)&TheCamera.GetPosition(); + pm->at = *(RwV3d*)&TheCamera.GetForward(); + pm->up = *(RwV3d*)&TheCamera.GetUp(); + pm->right = *(RwV3d*)&TheCamera.GetRight(); TheCamera.CalculateDerivedValues(); RwMatrixUpdate(RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera))); RwFrameUpdateObjects(RwCameraGetFrame(TheCamera.m_pRwCamera)); diff --git a/src/control/Replay.h b/src/control/Replay.h index cd8d9a45..6b11da75 100644 --- a/src/control/Replay.h +++ b/src/control/Replay.h @@ -176,7 +176,7 @@ class CReplay int8 velocityZ; union{ int8 car_gun; - uint8 wheel_state; + int8 wheel_state; }; uint8 wheel_susp_dist[4]; uint8 wheel_rotation[4]; diff --git a/src/control/Script.cpp b/src/control/Script.cpp index b50c101e..bd43d301 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -4,10 +4,17 @@ #include "Script.h" #include "ScriptCommands.h" +#include "Boat.h" #include "Camera.h" #include "CarCtrl.h" +#include "CivilianPed.h" +#include "Clock.h" +#include "CopPed.h" #include "DMAudio.h" +#include "EmergencyPed.h" #include "FileMgr.h" +#include "General.h" +#include "HandlingMgr.h" #include "Hud.h" #include "Messages.h" #include "ModelIndices.h" @@ -18,9 +25,11 @@ #include "Population.h" #include "Replay.h" #include "Streaming.h" +#include "Text.h" #include "User.h" #include "Weather.h" #include "World.h" +#include "Zones.h" uint8 (&CTheScripts::ScriptSpace)[SIZE_SCRIPT_SPACE] = *(uint8(*)[SIZE_SCRIPT_SPACE])*(uintptr*)0x74B248; CRunningScript(&CTheScripts::ScriptsArray)[MAX_NUM_SCRIPTS] = *(CRunningScript(*)[MAX_NUM_SCRIPTS])*(uintptr*)0x6F5C08; @@ -70,6 +79,7 @@ CMissionCleanup::CMissionCleanup() void CMissionCleanup::Init() { + m_nCount = 0; for (int i = 0; i < MAX_CLEANUP; i++){ m_sEntities[i].type = CLEANUP_UNUSED; m_sEntities[i].id = 0; @@ -93,7 +103,7 @@ void CMissionCleanup::AddEntityToList(int32 id, uint8 type) return; pNew->id = id; pNew->type = type; - m_bCount++; + m_nCount++; } void CMissionCleanup::RemoveEntityFromList(int32 id, uint8 type) @@ -102,6 +112,7 @@ void CMissionCleanup::RemoveEntityFromList(int32 id, uint8 type) if (m_sEntities[i].type == type && m_sEntities[i].id == id){ m_sEntities[i].id = 0; m_sEntities[i].type = CLEANUP_UNUSED; + m_nCount--; } } } @@ -124,8 +135,8 @@ void CMissionCleanup::Process() CHud::m_ItemToFlash = -1; CHud::SetHelpMessage(nil, false); CUserDisplay::OnscnTimer.m_bDisabled = false; - CWorld::Players[0].m_pPed->m_pWanted->m_IsIgnoredByCops = false; - CWorld::Players[0].m_pPed->m_pWanted->m_IsIgnoredByEveryOne = false; + CWorld::Players[0].m_pPed->m_pWanted->m_bIgnoredByCops = false; + CWorld::Players[0].m_pPed->m_pWanted->m_bIgnoredByEveryone = false; CWorld::Players[0].MakePlayerSafe(false); CTheScripts::StoreVehicleIndex = -1; CTheScripts::StoreVehicleWasRandom = true; @@ -594,7 +605,7 @@ void CTheScripts::Process() if (UseTextCommands){ for (int i = 0; i < MAX_NUM_INTRO_TEXT_LINES; i++) IntroTextLines[i].Reset(); - NumberOfIntroRectanglesThisFrame = 0; + NumberOfIntroTextLinesThisFrame = 0; for (int i = 0; i < MAX_NUM_INTRO_RECTANGLES; i++){ IntroRectangles[i].m_bIsUsed = false; IntroRectangles[i].m_bBeforeFade = false; @@ -701,7 +712,7 @@ int8 CRunningScript::ProcessCommandsFrom0To99(int32 command) return 0; case COMMAND_SHAKE_CAM: CollectParameters(&m_nIp, 1); - TheCamera.CamShake(ScriptParams[0] / 1000.0f); + CamShakeNoPos(&TheCamera, ScriptParams[0] / 1000.0f); return 0; case COMMAND_SET_VAR_INT: { @@ -1342,6 +1353,7 @@ int8 CRunningScript::ProcessCommandsFrom0To99(int32 command) *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) -= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); return 0; default: + assert(0); break; } return -1; @@ -1374,7 +1386,814 @@ void CRunningScript::UpdateCompareFlag(bool flag) } -WRAPPER int8 CRunningScript::ProcessCommandsFrom100To199(int32 command) { EAXJMP(0x43AEA0); } +int8 CRunningScript::ProcessCommandsFrom100To199(int32 command) +{ + switch (command) { + case COMMAND_SUB_INT_LVAR_FROM_INT_VAR: + *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) -= *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + return 0; + case COMMAND_SUB_INT_VAR_FROM_INT_LVAR: + *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) -= *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + return 0; + case COMMAND_SUB_FLOAT_LVAR_FROM_FLOAT_VAR: + *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) -= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + return 0; + case COMMAND_SUB_FLOAT_VAR_FROM_FLOAT_LVAR: + *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) -= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + return 0; + case COMMAND_MULT_INT_VAR_BY_INT_VAR: + *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) *= *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + return 0; + case COMMAND_MULT_INT_LVAR_BY_INT_VAR: + *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) *= *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + return 0; + case COMMAND_MULT_INT_VAR_BY_INT_LVAR: + *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) *= *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + return 0; + case COMMAND_MULT_INT_LVAR_BY_INT_LVAR: + *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) *= *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + return 0; + case COMMAND_MULT_FLOAT_VAR_BY_FLOAT_VAR: + *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) *= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + return 0; + case COMMAND_MULT_FLOAT_LVAR_BY_FLOAT_VAR: + *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) *= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + return 0; + case COMMAND_MULT_FLOAT_VAR_BY_FLOAT_LVAR: + *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) *= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + return 0; + case COMMAND_MULT_FLOAT_LVAR_BY_FLOAT_LVAR: + *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) *= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + return 0; + case COMMAND_DIV_INT_VAR_BY_INT_VAR: + *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) /= *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + return 0; + case COMMAND_DIV_INT_LVAR_BY_INT_VAR: + *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) /= *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + return 0; + case COMMAND_DIV_INT_VAR_BY_INT_LVAR: + *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) /= *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + return 0; + case COMMAND_DIV_INT_LVAR_BY_INT_LVAR: + *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) /= *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + return 0; + case COMMAND_DIV_FLOAT_VAR_BY_FLOAT_VAR: + *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) /= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + return 0; + case COMMAND_DIV_FLOAT_LVAR_BY_FLOAT_VAR: + *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) /= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + return 0; + case COMMAND_DIV_FLOAT_VAR_BY_FLOAT_LVAR: + *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) /= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + return 0; + case COMMAND_DIV_FLOAT_LVAR_BY_FLOAT_LVAR: + *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) /= *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + return 0; + case COMMAND_ADD_TIMED_VAL_TO_FLOAT_VAR: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + CollectParameters(&m_nIp, 1); + *(float*)ptr += CTimer::GetTimeStep() * *(float*)&ScriptParams[0]; + return 0; + } + case COMMAND_ADD_TIMED_VAL_TO_FLOAT_LVAR: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + CollectParameters(&m_nIp, 1); + *(float*)ptr += CTimer::GetTimeStep() * *(float*)&ScriptParams[0]; + return 0; + } + case COMMAND_ADD_TIMED_FLOAT_VAR_TO_FLOAT_VAR: + *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) += CTimer::GetTimeStep() * *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + return 0; + case COMMAND_ADD_TIMED_FLOAT_LVAR_TO_FLOAT_VAR: + *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) += CTimer::GetTimeStep() * *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + return 0; + case COMMAND_ADD_TIMED_FLOAT_VAR_TO_FLOAT_LVAR: + *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) += CTimer::GetTimeStep() * *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + return 0; + case COMMAND_ADD_TIMED_FLOAT_LVAR_TO_FLOAT_LVAR: + *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) += CTimer::GetTimeStep() * *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + return 0; + case COMMAND_SUB_TIMED_VAL_FROM_FLOAT_VAR: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + CollectParameters(&m_nIp, 1); + *(float*)ptr -= CTimer::GetTimeStep() * *(float*)&ScriptParams[0]; + return 0; + } + case COMMAND_SUB_TIMED_VAL_FROM_FLOAT_LVAR: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + CollectParameters(&m_nIp, 1); + *(float*)ptr -= CTimer::GetTimeStep() * *(float*)&ScriptParams[0]; + return 0; + } + case COMMAND_SUB_TIMED_FLOAT_VAR_FROM_FLOAT_VAR: + *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) -= CTimer::GetTimeStep() * *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + return 0; + case COMMAND_SUB_TIMED_FLOAT_LVAR_FROM_FLOAT_VAR: + *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) -= CTimer::GetTimeStep() * *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + return 0; + case COMMAND_SUB_TIMED_FLOAT_VAR_FROM_FLOAT_LVAR: + *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) -= CTimer::GetTimeStep() * *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + return 0; + case COMMAND_SUB_TIMED_FLOAT_LVAR_FROM_FLOAT_LVAR: + *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL) -= CTimer::GetTimeStep() * *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + return 0; + case COMMAND_SET_VAR_INT_TO_VAR_INT: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + *ptr = *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + return 0; + } + case COMMAND_SET_LVAR_INT_TO_VAR_INT: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + *ptr = *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + return 0; + } + case COMMAND_SET_VAR_INT_TO_LVAR_INT: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + *ptr = *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + return 0; + } + case COMMAND_SET_LVAR_INT_TO_LVAR_INT: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + *ptr = *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + return 0; + } + case COMMAND_SET_VAR_FLOAT_TO_VAR_FLOAT: + { + float* ptr = (float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + *ptr = *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + return 0; + } + case COMMAND_SET_LVAR_FLOAT_TO_VAR_FLOAT: + { + float* ptr = (float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + *ptr = *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + return 0; + } + case COMMAND_SET_VAR_FLOAT_TO_LVAR_FLOAT: + { + float* ptr = (float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + *ptr = *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + return 0; + } + case COMMAND_SET_LVAR_FLOAT_TO_LVAR_FLOAT: + { + float* ptr = (float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + *ptr = *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + return 0; + } + case COMMAND_CSET_VAR_INT_TO_VAR_FLOAT: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + *ptr = *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + return 0; + } + case COMMAND_CSET_LVAR_INT_TO_VAR_FLOAT: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + *ptr = *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + return 0; + } + case COMMAND_CSET_VAR_INT_TO_LVAR_FLOAT: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + *ptr = *(float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + return 0; + } + case COMMAND_CSET_LVAR_INT_TO_LVAR_FLOAT: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + *ptr = *(float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + return 0; + } + case COMMAND_CSET_VAR_FLOAT_TO_VAR_INT: + { + float* ptr = (float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + *ptr = *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + return 0; + } + case COMMAND_CSET_LVAR_FLOAT_TO_VAR_INT: + { + float* ptr = (float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + *ptr = *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + return 0; + } + case COMMAND_CSET_VAR_FLOAT_TO_LVAR_INT: + { + float* ptr = (float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + *ptr = *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + return 0; + } + case COMMAND_CSET_LVAR_FLOAT_TO_LVAR_INT: + { + float* ptr = (float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + *ptr = *GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + return 0; + } + case COMMAND_ABS_VAR_INT: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + *ptr = ABS(*ptr); + return 0; + } + case COMMAND_ABS_LVAR_INT: + { + int32* ptr = GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + *ptr = ABS(*ptr); + return 0; + } + case COMMAND_ABS_VAR_FLOAT: + { + float* ptr = (float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + *ptr = ABS(*ptr); + return 0; + } + case COMMAND_ABS_LVAR_FLOAT: + { + float* ptr = (float*)GetPointerToScriptVariable(&m_nIp, VAR_LOCAL); + *ptr = ABS(*ptr); + return 0; + } + case COMMAND_GENERATE_RANDOM_FLOAT: + { + float* ptr = (float*)GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL); + CGeneral::GetRandomNumber(); + CGeneral::GetRandomNumber(); + CGeneral::GetRandomNumber(); /* To make it EXTRA random! */ + *ptr = CGeneral::GetRandomNumber() / 65536.0f; + /* Between 0 and 0.5 on PC (oh well...), never used in original script. */ + return 0; + } + case COMMAND_GENERATE_RANDOM_INT: + /* On PC between 0 and 32767, even though script expects values between 0 and 65536 */ + *GetPointerToScriptVariable(&m_nIp, VAR_GLOBAL) = CGeneral::GetRandomNumber(); + return 0; + case COMMAND_CREATE_CHAR: + { + CollectParameters(&m_nIp, 5); + switch (ScriptParams[1]) { + case MI_COP: + if (ScriptParams[0] == PEDTYPE_COP) + ScriptParams[1] = COP_STREET; + break; + case MI_SWAT: + if (ScriptParams[0] == PEDTYPE_COP) + ScriptParams[1] = COP_SWAT; + break; + case MI_FBI: + if (ScriptParams[0] == PEDTYPE_COP) + ScriptParams[1] = COP_FBI; + break; + case MI_ARMY: + if (ScriptParams[0] == PEDTYPE_COP) + ScriptParams[1] = COP_ARMY; + break; + case MI_MEDIC: + if (ScriptParams[0] == PEDTYPE_EMERGENCY) + ScriptParams[1] = PEDTYPE_EMERGENCY; + break; + case MI_FIREMAN: + if (ScriptParams[0] == PEDTYPE_FIREMAN) + ScriptParams[1] = PEDTYPE_FIREMAN; + break; + default: + break; + } + CPed* ped; + if (ScriptParams[0] == PEDTYPE_COP) + ped = new CCopPed((eCopType)ScriptParams[1]); + else if (ScriptParams[0] == PEDTYPE_EMERGENCY || ScriptParams[0] == PEDTYPE_FIREMAN) + ped = new CEmergencyPed(ScriptParams[1]); + else + ped = new CCivilianPed(ScriptParams[0], ScriptParams[1]); + ped->CharCreatedBy = MISSION_CHAR; + ped->bRespondsToThreats = false; + ped->m_ped_flagG2 = false; + CVector pos = *(CVector*)&ScriptParams[2]; + if (pos.z <= -100.0f) + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); + pos.z += 1.0f; + ped->GetPosition() = pos; + ped->SetOrientation(0.0f, 0.0f, 0.0f); + CTheScripts::ClearSpaceForMissionEntity(pos, ped); + CWorld::Add(ped); + ped->m_level = CTheZones::GetLevelFromPosition(pos); + CPopulation::ms_nTotalMissionPeds++; + ScriptParams[0] = CPools::GetPedPool()->GetIndex(ped); + StoreParameters(&m_nIp, 1); + if (m_bIsMissionScript) + CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CHAR); + return 0; + } + case COMMAND_DELETE_CHAR: + { + CollectParameters(&m_nIp, 1); + CPed* ped = CPools::GetPedPool()->GetAt(ScriptParams[0]); + if (ped) { + if (ped->bInVehicle && ped->m_pMyVehicle) { + if (ped->m_pMyVehicle->pDriver == ped) { + ped->m_pMyVehicle->RemoveDriver(); + ped->m_pMyVehicle->m_status = STATUS_ABANDONED; + if (ped->m_pMyVehicle->m_nDoorLock == CARLOCK_LOCKED_INITIALLY) + ped->m_pMyVehicle->m_nDoorLock = CARLOCK_UNLOCKED; + if (ped->m_nPedType == PEDTYPE_COP && ped->m_pMyVehicle->IsLawEnforcementVehicle()) + ped->m_pMyVehicle->ChangeLawEnforcerState(0); + } + else { + ped->m_pMyVehicle->RemovePassenger(ped); + } + } + CWorld::RemoveReferencesToDeletedObject(ped); + delete ped; + --CPopulation::ms_nTotalMissionPeds; + } + if (m_bIsMissionScript) + CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR); + return 0; + } + case COMMAND_CHAR_WANDER_DIR: + { + CollectParameters(&m_nIp, 2); + CPed* ped = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(ped); + ped->ClearAll(); + int8 path = ScriptParams[1]; + if (ScriptParams[1] < 0 || ScriptParams[1] > 7) + path = CGeneral::GetRandomNumberInRange(0, 7); + ped->SetWanderPath(path); + return 0; + } + case COMMAND_CHAR_FOLLOW_PATH: + { + CollectParameters(&m_nIp, 4); + CPed* ped = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(ped); + CVector pos = *(CVector*)&ScriptParams[1]; + if (pos.z <= -100.0f) + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); + ped->ClearAll(); + ped->SetFollowPath(pos); + return 0; + } + case COMMAND_CHAR_SET_IDLE: + { + CollectParameters(&m_nIp, 1); + CPed* ped = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(ped); + ped->m_bScriptObjectiveCompleted = false; + ped->SetObjective(OBJECTIVE_IDLE); + return 0; + } + case COMMAND_GET_CHAR_COORDINATES: + { + CollectParameters(&m_nIp, 1); + CPed* ped = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(ped); + CVehicle* vehicle; + CVector pos; + /* Seems a bit clumsy but I'll leave original flow */ + if (ped->bInVehicle) + vehicle = ped->m_pMyVehicle; + else + vehicle = nil; + if (vehicle) + pos = vehicle->GetPosition(); + else + pos = ped->GetPosition(); + *(CVector*)&ScriptParams[0] = pos; + StoreParameters(&m_nIp, 3); + return 0; + } + case COMMAND_SET_CHAR_COORDINATES: + { + CollectParameters(&m_nIp, 4); + CPed* ped = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(ped); + CVehicle* vehicle; + if (ped->bInVehicle) + vehicle = ped->m_pMyVehicle; + else + vehicle = nil; + CVector pos = *(CVector*)&ScriptParams[1]; + if (pos.z <= -100.0f) + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); + /* The following block was once again written + * by someone not familiar with virtual functions. + * It doesn't require any ifs at all. + * To keep as close to original as possible, I'll keep it. + * Maybe there was more commented out/debug + * stuff, but I doubt it. + */ + if (!vehicle) { + pos.z += ped->GetDistanceFromCentreOfMassToBaseOfModel(); + ped->Teleport(pos); + CTheScripts::ClearSpaceForMissionEntity(pos, ped); + } + else if (vehicle->IsBoat()) { + pos.z += vehicle->GetDistanceFromCentreOfMassToBaseOfModel(); + vehicle->Teleport(pos); + CTheScripts::ClearSpaceForMissionEntity(pos, vehicle); + } + else { + pos.z += vehicle->GetDistanceFromCentreOfMassToBaseOfModel(); + vehicle->Teleport(pos); + CTheScripts::ClearSpaceForMissionEntity(pos, vehicle); + } + /* Short version of this command. + * + * CollectParameters(&m_nIp, 4); + * CPed* ped = CPools::GetPedPool()->GetAt(ScriptParams[0]); + * assert(ped); + * CEntity* entityToMove = ped->bInVehicle ? ped->m_pMyVehicle : ped; + * CVector pos = *(CVector*)&ScriptParams[1]; + * if (pos.z <= -100.0f) + * pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); + * pos.z += entityToMove->GetDistanceFromCentreOfMassToBaseOfModel(); + * entityToMove->Teleport(pos); + * CTheScripts::ClearSpaceForMissionEntity(pos, entityToMove); + * + */ + return 0; + } + case COMMAND_IS_CHAR_STILL_ALIVE: + { + CollectParameters(&m_nIp, 1); + CPed* ped = CPools::GetPedPool()->GetAt(ScriptParams[0]); + UpdateCompareFlag(ped && ped->m_status != PED_DEAD && ped->m_status != PED_DIE); + return 0; + } + case COMMAND_IS_CHAR_IN_AREA_2D: + { + CollectParameters(&m_nIp, 6); + CPed* ped = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(ped); + CVehicle* vehicle; + if (ped->bInVehicle) + vehicle = ped->m_pMyVehicle; + else + vehicle = nil; + float x1, y1, x2, y2; + x1 = *(float*)&ScriptParams[1]; + y1 = *(float*)&ScriptParams[2]; + x2 = *(float*)&ScriptParams[3]; + y2 = *(float*)&ScriptParams[4]; + if (vehicle) + UpdateCompareFlag(ped->m_pMyVehicle->IsWithinArea(x1, y1, x2, y2)); + else + UpdateCompareFlag(ped->IsWithinArea(x1, y1, x2, y2)); + CTheScripts::HighlightImportantArea((uint32)this + m_nIp, x1, y1, x2, y2, -100.0f); + if (CTheScripts::DbgFlag) + CTheScripts::DrawDebugSquare(x1, y1, x2, y2); + return 0; + } + case COMMAND_IS_CHAR_IN_AREA_3D: + { + CollectParameters(&m_nIp, 8); + CPed* ped = CPools::GetPedPool()->GetAt(ScriptParams[0]); + assert(ped); + CVehicle* vehicle; + if (ped->bInVehicle) + vehicle = ped->m_pMyVehicle; + else + vehicle = nil; + float x1, y1, z1, x2, y2, z2; + x1 = *(float*)&ScriptParams[1]; + y1 = *(float*)&ScriptParams[2]; + z1 = *(float*)&ScriptParams[3]; + x2 = *(float*)&ScriptParams[4]; + y2 = *(float*)&ScriptParams[5]; + z2 = *(float*)&ScriptParams[6]; + if (vehicle) + UpdateCompareFlag(ped->m_pMyVehicle->IsWithinArea(x1, y1, z1, x2, y2, z2)); + else + UpdateCompareFlag(ped->IsWithinArea(x1, y1, z1, x2, y2, z2)); + CTheScripts::HighlightImportantArea((uint32)this + m_nIp, x1, y1, x2, y2, -100.0f); + if (CTheScripts::DbgFlag) + CTheScripts::DrawDebugCube(x1, y1, z1, x2, y2, z2); + return 0; + } + case COMMAND_CREATE_CAR: + { + CollectParameters(&m_nIp, 4); + int32 handle; + if (CModelInfo::IsBoatModel(ScriptParams[0])) { + CBoat* boat = new CBoat(ScriptParams[0], MISSION_VEHICLE); + CVector pos = *(CVector*)&ScriptParams[1]; + if (pos.z <= -100.0f) + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); + pos.z += boat->GetDistanceFromCentreOfMassToBaseOfModel(); + boat->GetPosition() = pos; + CTheScripts::ClearSpaceForMissionEntity(pos, boat); + boat->m_status = STATUS_ABANDONED; + boat->bIsLocked = true; + boat->AutoPilot.m_nCarMission = MISSION_NONE; + boat->AutoPilot.m_nAnimationId = TEMPACT_NONE; /* Animation ID? */ + boat->AutoPilot.m_nCruiseSpeed = boat->AutoPilot.m_fMaxTrafficSpeed = 20.0f; + CWorld::Add(boat); + handle = CPools::GetVehiclePool()->GetIndex(boat); + } + else { + CVehicle* car; + if (!CModelInfo::IsBikeModel(ScriptParams[0])) + car = new CAutomobile(ScriptParams[0], MISSION_VEHICLE); + CVector pos = *(CVector*)&ScriptParams[1]; + if (pos.z <= -100.0f) + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); + pos.z += car->GetDistanceFromCentreOfMassToBaseOfModel(); + car->GetPosition() = pos; + CTheScripts::ClearSpaceForMissionEntity(pos, car); + car->m_status = STATUS_ABANDONED; + car->bIsLocked = true; + CCarCtrl::JoinCarWithRoadSystem(car); + car->AutoPilot.m_nCarMission = MISSION_NONE; + car->AutoPilot.m_nAnimationId = TEMPACT_NONE; /* Animation ID? */ + car->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_STOP_FOR_CARS; + car->AutoPilot.m_nCruiseSpeed = car->AutoPilot.m_fMaxTrafficSpeed = 9.0f; + car->AutoPilot.m_nPreviousLane = car->AutoPilot.m_nCurrentLane = 0; + car->bEngineOn = false; + car->m_level = CTheZones::GetLevelFromPosition(pos); + car->bHasBeenOwnedByPlayer = true; + CWorld::Add(car); + handle = CPools::GetVehiclePool()->GetIndex(car); + } + ScriptParams[0] = handle; + StoreParameters(&m_nIp, 1); + if (m_bIsMissionScript) + CTheScripts::MissionCleanup.AddEntityToList(handle, CLEANUP_CAR); + return 0; + } + case COMMAND_DELETE_CAR: + { + CollectParameters(&m_nIp, 1); + CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + if (car) { + CWorld::Remove(car); + CWorld::RemoveReferencesToDeletedObject(car); + delete car; + } + if (m_bIsMissionScript) + CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CAR); + return 0; + } + case COMMAND_CAR_GOTO_COORDINATES: + { + CollectParameters(&m_nIp, 4); + CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(car); + CVector pos = *(CVector*)&ScriptParams[1]; + if (pos.z <= -100.0f) + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); + pos.z += car->GetDistanceFromCentreOfMassToBaseOfModel(); + if (CCarCtrl::JoinCarWithRoadSystemGotoCoors(car, pos, false)) + car->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS_STRAIGHT; + else + car->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS; + car->m_status = STATUS_PHYSICS; + car->bEngineOn = true; + car->AutoPilot.m_nCruiseSpeed = max(car->AutoPilot.m_nCruiseSpeed, 6); + car->AutoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds(); + return 0; + } + case COMMAND_CAR_WANDER_RANDOMLY: + { + CollectParameters(&m_nIp, 1); + CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(car); + CCarCtrl::JoinCarWithRoadSystem(car); + car->AutoPilot.m_nCarMission = MISSION_CRUISE; + car->bEngineOn = true; + car->AutoPilot.m_nCruiseSpeed = max(car->AutoPilot.m_nCruiseSpeed, 6); + car->AutoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds(); + return 0; + } + case COMMAND_CAR_SET_IDLE: + { + CollectParameters(&m_nIp, 1); + CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(car); + car->AutoPilot.m_nCarMission = MISSION_NONE; + return 0; + } + case COMMAND_GET_CAR_COORDINATES: + { + CollectParameters(&m_nIp, 1); + CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(car); + *(CVector*)&ScriptParams[0] = car->GetPosition(); + StoreParameters(&m_nIp, 3); + return 0; + } + case COMMAND_SET_CAR_COORDINATES: + { + CollectParameters(&m_nIp, 4); + CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(car); + CVector pos = *(CVector*)&ScriptParams[1]; + if (pos.z <= -100.0f) + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); + pos.z += car->GetDistanceFromCentreOfMassToBaseOfModel(); + car->bIsStatic = false; + /* Again weird usage of virtual functions. */ + if (car->IsBoat()) { + car->Teleport(pos); + CTheScripts::ClearSpaceForMissionEntity(pos, car); + } + else { + car->Teleport(pos); + CTheScripts::ClearSpaceForMissionEntity(pos, car); + /* May the following be inlined CCarCtrl function? */ + switch (car->AutoPilot.m_nCarMission) { + case MISSION_CRUISE: + CCarCtrl::JoinCarWithRoadSystem(car); + break; + case MISSION_RAMPLAYER_FARAWAY: + case MISSION_RAMPLAYER_CLOSE: + case MISSION_BLOCKPLAYER_FARAWAY: + case MISSION_BLOCKPLAYER_CLOSE: + case MISSION_BLOCKPLAYER_HANDBRAKESTOP: + CCarCtrl::JoinCarWithRoadSystemGotoCoors(car, FindPlayerCoors(), false); + break; + case MISSION_GOTOCOORDS: + case MISSION_GOTOCOORDS_STRAIGHT: + CCarCtrl::JoinCarWithRoadSystemGotoCoors(car, car->AutoPilot.m_vecDestinationCoors, false); + break; + case MISSION_GOTOCOORDS_ACCURATE: + case MISSION_GOTO_COORDS_STRAIGHT_ACCURATE: + CCarCtrl::JoinCarWithRoadSystemGotoCoors(car, car->AutoPilot.m_vecDestinationCoors, false); + break; + case MISSION_RAMCAR_FARAWAY: + case MISSION_RAMCAR_CLOSE: + case MISSION_BLOCKCAR_FARAWAY: + case MISSION_BLOCKCAR_CLOSE: + case MISSION_BLOCKCAR_HANDBRAKESTOP: + CCarCtrl::JoinCarWithRoadSystemGotoCoors(car, car->AutoPilot.m_pTargetCar->GetPosition(), false); + break; + default: + break; + } + } + return 0; + } + case COMMAND_IS_CAR_STILL_ALIVE: + { + CollectParameters(&m_nIp, 4); + CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + UpdateCompareFlag(car && car->m_status != STATUS_WRECKED && (car->IsBoat() || !car->bIsInWater)); + return 0; + } + case COMMAND_SET_CAR_CRUISE_SPEED: + { + CollectParameters(&m_nIp, 2); + CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(car); + car->AutoPilot.m_nCruiseSpeed = min(*(float*)&ScriptParams[1], 60.0f * car->pHandling->Transmission.fUnkMaxVelocity); + return 0; + } + case COMMAND_SET_CAR_DRIVING_STYLE: + { + CollectParameters(&m_nIp, 2); + CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(car); + car->AutoPilot.m_nDrivingStyle = (eCarDrivingStyle)ScriptParams[1]; + return 0; + } + case COMMAND_SET_CAR_MISSION: + { + CollectParameters(&m_nIp, 2); + CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(car); + car->AutoPilot.m_nCarMission = (eCarMission)ScriptParams[1]; + car->AutoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds(); + car->bEngineOn = true; + return 0; + } + case COMMAND_IS_CAR_IN_AREA_2D: + { + CollectParameters(&m_nIp, 6); + CVehicle* vehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(vehicle); + float x1, y1, x2, y2; + x1 = *(float*)&ScriptParams[1]; + y1 = *(float*)&ScriptParams[2]; + x2 = *(float*)&ScriptParams[3]; + y2 = *(float*)&ScriptParams[4]; + UpdateCompareFlag(vehicle->IsWithinArea(x1, y1, x2, y2)); + CTheScripts::HighlightImportantArea((uint32)this + m_nIp, x1, y1, x2, y2, -100.0f); + if (CTheScripts::DbgFlag) + CTheScripts::DrawDebugSquare(x1, y1, x2, y2); + return 0; + } + case COMMAND_IS_CAR_IN_AREA_3D: + { + CollectParameters(&m_nIp, 8); + CVehicle* vehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]); + assert(vehicle); + float x1, y1, z1, x2, y2, z2; + x1 = *(float*)&ScriptParams[1]; + y1 = *(float*)&ScriptParams[2]; + z1 = *(float*)&ScriptParams[3]; + x2 = *(float*)&ScriptParams[4]; + y2 = *(float*)&ScriptParams[5]; + z2 = *(float*)&ScriptParams[6]; + UpdateCompareFlag(vehicle->IsWithinArea(x1, y1, z1, x2, y2, z2)); + CTheScripts::HighlightImportantArea((uint32)this + m_nIp, x1, y1, x2, y2, -100.0f); + if (CTheScripts::DbgFlag) + CTheScripts::DrawDebugCube(x1, y1, z1, x2, y2, z2); + return 0; + } + case COMMAND_SPECIAL_0: + case COMMAND_SPECIAL_1: + case COMMAND_SPECIAL_2: + case COMMAND_SPECIAL_3: + case COMMAND_SPECIAL_4: + case COMMAND_SPECIAL_5: + case COMMAND_SPECIAL_6: + case COMMAND_SPECIAL_7: + assert(0); + return 0; + case COMMAND_PRINT_BIG: + { + wchar* key = TheText.Get((char*)&CTheScripts::ScriptSpace[m_nIp]); + m_nIp += 8; + CollectParameters(&m_nIp, 2); + CMessages::AddBigMessage(key, ScriptParams[0], ScriptParams[1] - 1); + return 0; + } + case COMMAND_PRINT: + { + wchar* key = TheText.Get((char*)&CTheScripts::ScriptSpace[m_nIp]); + m_nIp += 8; + CollectParameters(&m_nIp, 2); + CMessages::AddMessage(key, ScriptParams[0], ScriptParams[1]); + return 0; + } + case COMMAND_PRINT_NOW: + { + wchar* key = TheText.Get((char*)&CTheScripts::ScriptSpace[m_nIp]); + m_nIp += 8; + CollectParameters(&m_nIp, 2); + CMessages::AddMessageJumpQ(key, ScriptParams[0], ScriptParams[1]); + return 0; + } + case COMMAND_PRINT_SOON: + { + wchar* key = TheText.Get((char*)&CTheScripts::ScriptSpace[m_nIp]); + m_nIp += 8; + CollectParameters(&m_nIp, 2); + CMessages::AddMessage(key, ScriptParams[0], ScriptParams[1]); + return 0; + } + case COMMAND_CLEAR_PRINTS: + CMessages::ClearMessages(); + return 0; + case COMMAND_GET_TIME_OF_DAY: + ScriptParams[0] = CClock::GetHours(); + ScriptParams[1] = CClock::GetMinutes(); + StoreParameters(&m_nIp, 2); + return 0; + case COMMAND_SET_TIME_OF_DAY: + CollectParameters(&m_nIp, 2); + CClock::SetGameClock(ScriptParams[0], ScriptParams[1]); + return 0; + case COMMAND_GET_MINUTES_TO_TIME_OF_DAY: + CollectParameters(&m_nIp, 2); + ScriptParams[0] = CClock::GetGameClockMinutesUntil(ScriptParams[0], ScriptParams[1]); + StoreParameters(&m_nIp, 1); + return 0; + case COMMAND_IS_POINT_ON_SCREEN: + { + CollectParameters(&m_nIp, 4); + CVector pos = *(CVector*)&ScriptParams[0]; + if (pos.z <= -100) + pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y); + UpdateCompareFlag(TheCamera.IsSphereVisible(pos, *(float*)&ScriptParams[3])); + } + case COMMAND_DEBUG_ON: + CTheScripts::DbgFlag = true; + return 0; + case COMMAND_DEBUG_OFF: + CTheScripts::DbgFlag = false; + return 0; + case COMMAND_RETURN_TRUE: + UpdateCompareFlag(true); + return 0; + case COMMAND_RETURN_FALSE: + UpdateCompareFlag(false); + return 0; + default: + assert(0); + break; + } + return -1; +} + WRAPPER int8 CRunningScript::ProcessCommandsFrom200To299(int32 command) { EAXJMP(0x43D530); } WRAPPER int8 CRunningScript::ProcessCommandsFrom300To399(int32 command) { EAXJMP(0x43ED30); } WRAPPER int8 CRunningScript::ProcessCommandsFrom400To499(int32 command) { EAXJMP(0x440CB0); } diff --git a/src/control/Script.h b/src/control/Script.h index 0cbd40c0..9e9d9ab6 100644 --- a/src/control/Script.h +++ b/src/control/Script.h @@ -137,7 +137,7 @@ enum { class CMissionCleanup { CMissionCleanupEntity m_sEntities[MAX_CLEANUP]; - uint8 m_bCount; + uint8 m_nCount; public: CMissionCleanup(); |