summaryrefslogtreecommitdiff
path: root/src/control/Script.h
diff options
context:
space:
mode:
authorclaude-bot <[email protected]>2026-07-13 12:27:07 +0000
committerclaude-bot <[email protected]>2026-07-13 12:27:07 +0000
commit9f61c9e6ac6b1ac5692cf6352d2ebbd47a31a686 (patch)
treea84756b82513739a2672db3a1f0ec579db6d18ff /src/control/Script.h
downloadre3-miami.tar.gz
re3-miami.zip
Import Cai1Hsu/re3 @ miami (reVC / GTA:VC decompilation)HEADmiami
Snapshot import (no upstream history) into git.ancap.in.ua/claude, per @lzcnt. Source: https://github.com/Cai1Hsu/re3 branch miami.
Diffstat (limited to 'src/control/Script.h')
-rw-r--r--src/control/Script.h601
1 files changed, 601 insertions, 0 deletions
diff --git a/src/control/Script.h b/src/control/Script.h
new file mode 100644
index 0000000..80c0536
--- /dev/null
+++ b/src/control/Script.h
@@ -0,0 +1,601 @@
+#pragma once
+#include "Font.h"
+#include "PedType.h"
+#include "Text.h"
+#include "Sprite2d.h"
+
+class CEntity;
+class CBuilding;
+class CPhysical;
+class CVehicle;
+class CPed;
+class CObject;
+class CPlayerInfo;
+
+class CRunningScript;
+
+extern int32 ScriptParams[32];
+
+void FlushLog();
+#define script_assert(_Expression) FlushLog(); assert(_Expression);
+
+#define PICKUP_PLACEMENT_OFFSET (0.5f)
+#define PED_FIND_Z_OFFSET (5.0f)
+#define COP_PED_FIND_Z_OFFSET (10.0f)
+
+#define UPSIDEDOWN_UP_THRESHOLD (-0.97f)
+#define UPSIDEDOWN_MOVE_SPEED_THRESHOLD (0.01f)
+#define UPSIDEDOWN_TURN_SPEED_THRESHOLD (0.02f)
+#define UPSIDEDOWN_TIMER_THRESHOLD (1000)
+
+#define SPHERE_MARKER_R (252)
+#define SPHERE_MARKER_G (138)
+#define SPHERE_MARKER_B (242)
+#define SPHERE_MARKER_A (228)
+#define SPHERE_MARKER_PULSE_PERIOD 2048
+#define SPHERE_MARKER_PULSE_FRACTION 0.1f
+
+#ifdef USE_PRECISE_MEASUREMENT_CONVERTION
+#define MILES_IN_METER (0.000621371192f)
+#define METERS_IN_FOOT (0.3048f)
+#define FEET_IN_METER (3.28084f)
+#else
+#define MILES_IN_METER (1 / 1670.f)
+#define METERS_IN_FOOT (0.3f)
+#define FEET_IN_METER (3.33f)
+#endif
+
+#define KEY_LENGTH_IN_SCRIPT (8)
+
+//#define GTA_SCRIPT_COLLECTIVE
+
+struct intro_script_rectangle
+{
+ bool m_bIsUsed;
+ bool m_bBeforeFade;
+ int16 m_nTextureId;
+ CRect m_sRect;
+ CRGBA m_sColor;
+
+ intro_script_rectangle() { }
+ ~intro_script_rectangle() { }
+};
+
+VALIDATE_SIZE(intro_script_rectangle, 0x18);
+
+enum {
+ SCRIPT_TEXT_MAX_LENGTH = 100
+};
+
+struct intro_text_line
+{
+ float m_fScaleX;
+ float m_fScaleY;
+ CRGBA m_sColor;
+ bool m_bJustify;
+ bool m_bCentered;
+ bool m_bBackground;
+ bool m_bBackgroundOnly;
+ float m_fWrapX;
+ float m_fCenterSize;
+ CRGBA m_sBackgroundColor;
+ bool m_bTextProportional;
+ bool m_bTextBeforeFade;
+ bool m_bRightJustify;
+ int32 m_nFont;
+ float m_fAtX;
+ float m_fAtY;
+ wchar m_Text[SCRIPT_TEXT_MAX_LENGTH];
+
+ intro_text_line() { }
+ ~intro_text_line() { }
+
+ void Reset()
+ {
+ m_fScaleX = 0.48f;
+ m_fScaleY = 1.12f;
+ m_sColor = CRGBA(225, 225, 225, 255);
+ m_bJustify = false;
+ m_bRightJustify = false;
+ m_bCentered = false;
+ m_bBackground = false;
+ m_bBackgroundOnly = false;
+ m_fWrapX = 182.0f;
+ m_fCenterSize = DEFAULT_SCREEN_WIDTH;
+ m_sBackgroundColor = CRGBA(128, 128, 128, 128);
+ m_bTextProportional = true;
+ m_bTextBeforeFade = false;
+ m_nFont = FONT_STANDARD;
+ m_fAtX = 0.0f;
+ m_fAtY = 0.0f;
+ memset(&m_Text, 0, sizeof(m_Text));
+ }
+};
+
+VALIDATE_SIZE(intro_text_line, 0x414);
+
+struct script_sphere_struct
+{
+ bool m_bInUse;
+ uint16 m_Index;
+ uint32 m_Id;
+ CVector m_vecCenter;
+ float m_fRadius;
+
+ script_sphere_struct() { }
+};
+
+struct CStoredLine
+{
+ CVector vecInf;
+ CVector vecSup;
+ uint32 color1;
+ uint32 color2;
+};
+
+enum {
+ CLEANUP_UNUSED = 0,
+ CLEANUP_CAR,
+ CLEANUP_CHAR,
+ CLEANUP_OBJECT
+};
+
+struct cleanup_entity_struct
+{
+ uint8 type;
+ int32 id;
+};
+
+enum {
+ MAX_CLEANUP = 50,
+ MAX_UPSIDEDOWN_CAR_CHECKS = 6,
+ MAX_STUCK_CAR_CHECKS = 16
+};
+
+class CMissionCleanup
+{
+public:
+ cleanup_entity_struct m_sEntities[MAX_CLEANUP];
+ uint8 m_nCount;
+
+ CMissionCleanup();
+
+ void Init();
+ cleanup_entity_struct* FindFree();
+ void AddEntityToList(int32, uint8);
+ void RemoveEntityFromList(int32, uint8);
+ void Process();
+ void CheckIfCollisionHasLoadedForMissionObjects();
+};
+
+struct upsidedown_car_data
+{
+ int32 m_nVehicleIndex;
+ uint32 m_nUpsideDownTimer;
+};
+
+class CUpsideDownCarCheck
+{
+ upsidedown_car_data m_sCars[MAX_UPSIDEDOWN_CAR_CHECKS];
+
+public:
+ void Init();
+ bool IsCarUpsideDown(int32);
+ bool IsCarUpsideDown(CVehicle*);
+ void UpdateTimers();
+ bool AreAnyCarsUpsideDown();
+ void AddCarToCheck(int32);
+ void RemoveCarFromCheck(int32);
+ bool HasCarBeenUpsideDownForAWhile(int32);
+};
+
+struct stuck_car_data
+{
+ int32 m_nVehicleIndex;
+ CVector m_vecPos;
+ int32 m_nLastCheck;
+ float m_fRadius;
+ uint32 m_nStuckTime;
+ bool m_bStuck;
+
+ stuck_car_data() { }
+ void Reset();
+};
+
+class CStuckCarCheck
+{
+ stuck_car_data m_sCars[MAX_STUCK_CAR_CHECKS];
+
+public:
+ void Init();
+ void Process();
+ void AddCarToCheck(int32, float, uint32);
+ void RemoveCarFromCheck(int32);
+ bool HasCarBeenStuckForAWhile(int32);
+};
+
+enum {
+ ARGUMENT_END = 0,
+ ARGUMENT_INT32,
+ ARGUMENT_GLOBALVAR,
+ ARGUMENT_LOCALVAR,
+ ARGUMENT_INT8,
+ ARGUMENT_INT16,
+ ARGUMENT_FLOAT
+};
+
+struct tCollectiveData
+{
+ int32 colIndex;
+ int32 pedIndex;
+};
+
+enum {
+ USED_OBJECT_NAME_LENGTH = 24
+};
+
+struct tUsedObject
+{
+ char name[USED_OBJECT_NAME_LENGTH];
+ int32 index;
+};
+
+struct tBuildingSwap
+{
+ CBuilding* m_pBuilding;
+ int32 m_nNewModel;
+ int32 m_nOldModel;
+};
+
+
+enum {
+ MAX_STACK_DEPTH = 6,
+ NUM_LOCAL_VARS = 16,
+ NUM_TIMERS = 2
+};
+
+class CRunningScript
+{
+ enum {
+ ANDOR_NONE = 0,
+ ANDS_1 = 1,
+ ANDS_2,
+ ANDS_3,
+ ANDS_4,
+ ANDS_5,
+ ANDS_6,
+ ANDS_7,
+ ANDS_8,
+ ORS_1 = 21,
+ ORS_2,
+ ORS_3,
+ ORS_4,
+ ORS_5,
+ ORS_6,
+ ORS_7,
+ ORS_8
+ };
+
+public:
+ CRunningScript* next;
+ CRunningScript* prev;
+ char m_abScriptName[8];
+ uint32 m_nIp;
+ uint32 m_anStack[MAX_STACK_DEPTH];
+ uint16 m_nStackPointer;
+ int32 m_anLocalVariables[NUM_LOCAL_VARS + NUM_TIMERS];
+ bool m_bIsActive;
+ bool m_bCondResult;
+ bool m_bIsMissionScript;
+ bool m_bSkipWakeTime;
+ uint32 m_nWakeTime;
+ uint16 m_nAndOrState;
+ bool m_bNotFlag;
+ bool m_bDeatharrestEnabled;
+ bool m_bDeatharrestExecuted;
+ bool m_bMissionFlag;
+
+public:
+ void SetIP(uint32 ip) { m_nIp = ip; }
+ CRunningScript* GetNext() const { return next; }
+
+ void Save(uint8*& buf);
+ void Load(uint8*& buf);
+
+ void UpdateTimers(float timeStep) {
+ m_anLocalVariables[NUM_LOCAL_VARS] += timeStep;
+ m_anLocalVariables[NUM_LOCAL_VARS + 1] += timeStep;
+ }
+
+ void Init();
+ void Process();
+
+ void RemoveScriptFromList(CRunningScript**);
+ void AddScriptToList(CRunningScript**);
+
+ static const uint32 nSaveStructSize;
+
+ void CollectParameters(uint32*, int16);
+ int32 CollectNextParameterWithoutIncreasingPC(uint32);
+ int32* GetPointerToScriptVariable(uint32*, int16);
+ void StoreParameters(uint32*, int16);
+
+ int8 ProcessOneCommand();
+ void DoDeatharrestCheck();
+ void UpdateCompareFlag(bool);
+ int16 GetPadState(uint16, uint16);
+
+ int8 ProcessCommands0To99(int32);
+ int8 ProcessCommands100To199(int32);
+ int8 ProcessCommands200To299(int32);
+ int8 ProcessCommands300To399(int32);
+ int8 ProcessCommands400To499(int32);
+ int8 ProcessCommands500To599(int32);
+ int8 ProcessCommands600To699(int32);
+ int8 ProcessCommands700To799(int32);
+ int8 ProcessCommands800To899(int32);
+ int8 ProcessCommands900To999(int32);
+ int8 ProcessCommands1000To1099(int32);
+ int8 ProcessCommands1100To1199(int32);
+ int8 ProcessCommands1200To1299(int32);
+ int8 ProcessCommands1300To1399(int32);
+ int8 ProcessCommands1400To1499(int32);
+
+ void LocatePlayerCommand(int32, uint32*);
+ void LocatePlayerCharCommand(int32, uint32*);
+ void LocatePlayerCarCommand(int32, uint32*);
+ void LocateCharCommand(int32, uint32*);
+ void LocateCharCharCommand(int32, uint32*);
+ void LocateCharCarCommand(int32, uint32*);
+ void LocateCharObjectCommand(int32, uint32*);
+ void LocateCarCommand(int32, uint32*);
+ void LocateSniperBulletCommand(int32, uint32*);
+ void PlayerInAreaCheckCommand(int32, uint32*);
+ void PlayerInAngledAreaCheckCommand(int32, uint32*);
+ void CharInAreaCheckCommand(int32, uint32*);
+ void CarInAreaCheckCommand(int32, uint32*);
+ void LocateObjectCommand(int32, uint32*);
+ void ObjectInAreaCheckCommand(int32, uint32*);
+
+#ifdef GTA_SCRIPT_COLLECTIVE
+ void LocateCollectiveCommand(int32, uint32*);
+ void LocateCollectiveCharCommand(int32, uint32*);
+ void LocateCollectiveCarCommand(int32, uint32*);
+ void LocateCollectivePlayerCommand(int32, uint32*);
+ void CollectiveInAreaCheckCommand(int32, uint32*);
+#endif
+
+#ifdef MISSION_REPLAY
+ bool CanAllowMissionReplay();
+#endif
+
+#ifdef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
+ int CollectParameterForDebug(char* buf, bool& var);
+ void GetStoredParameterForDebug(char* buf);
+#endif
+
+ float LimitAngleOnCircle(float angle) { return angle < 0.0f ? angle + 360.0f : angle; }
+
+ bool ThisIsAValidRandomCop(uint32 mi, int cop, int swat, int fbi, int army, int miami);
+ bool ThisIsAValidRandomPed(uint32 pedtype, int civ, int gang, int criminal);
+
+ bool CheckDamagedWeaponType(int32 actual, int32 type);
+
+};
+
+
+enum {
+ VAR_LOCAL = 1,
+ VAR_GLOBAL = 2,
+};
+
+enum {
+#ifdef PS2
+ SIZE_MAIN_SCRIPT = 205512,
+#else
+ SIZE_MAIN_SCRIPT = 225512,
+#endif
+ SIZE_MISSION_SCRIPT = 35000,
+ SIZE_SCRIPT_SPACE = SIZE_MAIN_SCRIPT + SIZE_MISSION_SCRIPT
+};
+
+enum {
+ MAX_NUM_SCRIPTS = 128,
+ MAX_NUM_INTRO_TEXT_LINES = 48,
+ MAX_NUM_INTRO_RECTANGLES = 16,
+ MAX_NUM_SCRIPT_SRPITES = 16,
+ MAX_NUM_SCRIPT_SPHERES = 16,
+ MAX_NUM_USED_OBJECTS = 220,
+ MAX_NUM_MISSION_SCRIPTS = 120,
+ MAX_NUM_BUILDING_SWAPS = 25,
+ MAX_NUM_INVISIBILITY_SETTINGS = 20,
+ MAX_NUM_STORED_LINES = 1024
+};
+
+class CTheScripts
+{
+public:
+ static uint8 ScriptSpace[SIZE_SCRIPT_SPACE];
+ static CRunningScript ScriptsArray[MAX_NUM_SCRIPTS];
+ static intro_text_line IntroTextLines[MAX_NUM_INTRO_TEXT_LINES];
+ static intro_script_rectangle IntroRectangles[MAX_NUM_INTRO_RECTANGLES];
+ static CSprite2d ScriptSprites[MAX_NUM_SCRIPT_SRPITES];
+ static script_sphere_struct ScriptSphereArray[MAX_NUM_SCRIPT_SPHERES];
+ static tUsedObject UsedObjectArray[MAX_NUM_USED_OBJECTS];
+ static int32 MultiScriptArray[MAX_NUM_MISSION_SCRIPTS];
+ static tBuildingSwap BuildingSwapArray[MAX_NUM_BUILDING_SWAPS];
+ static CEntity* InvisibilitySettingArray[MAX_NUM_INVISIBILITY_SETTINGS];
+ static CStoredLine aStoredLines[MAX_NUM_STORED_LINES];
+ static bool DbgFlag;
+ static uint32 OnAMissionFlag;
+ static CMissionCleanup MissionCleanUp;
+ static CStuckCarCheck StuckCars;
+ static CUpsideDownCarCheck UpsideDownCars;
+ static int32 StoreVehicleIndex;
+ static bool StoreVehicleWasRandom;
+ static CRunningScript *pIdleScripts;
+ static CRunningScript *pActiveScripts;
+ static int32 NextFreeCollectiveIndex;
+ static int32 LastRandomPedId;
+ static uint16 NumberOfUsedObjects;
+ static bool bAlreadyRunningAMissionScript;
+ static bool bUsingAMultiScriptFile;
+ static uint16 NumberOfMissionScripts;
+ static uint32 LargestMissionScriptSize;
+ static uint32 MainScriptSize;
+ static uint8 FailCurrentMission;
+ static uint16 NumScriptDebugLines;
+ static uint16 NumberOfIntroRectanglesThisFrame;
+ static uint16 NumberOfIntroTextLinesThisFrame;
+ static uint8 UseTextCommands;
+ static uint16 CommandsExecuted;
+ static uint16 ScriptsUpdated;
+ static uint32 LastMissionPassedTime;
+ static uint16 NumberOfExclusiveMissionScripts;
+#if (defined GTA_PC && !defined GTAVC_JP_PATCH || defined GTA_XBOX || defined SUPPORT_XBOX_SCRIPT || defined GTA_MOBILE || defined SUPPORT_MOBILE_SCRIPT)
+#define CARDS_IN_SUIT (13)
+#define NUM_SUITS (4)
+#define MAX_DECKS (6)
+#define CARDS_IN_DECK (CARDS_IN_SUIT * NUM_SUITS)
+#define CARDS_IN_STACK (CARDS_IN_DECK * MAX_DECKS)
+ static int16 CardStack[CARDS_IN_STACK];
+ static int16 CardStackPosition;
+#endif
+ static bool bPlayerIsInTheStatium;
+ static uint8 RiotIntensity;
+ static bool bPlayerHasMetDebbieHarry;
+
+ static void Init();
+ static void Process();
+
+ static CRunningScript* StartTestScript();
+ static bool IsPlayerOnAMission();
+ static void ClearSpaceForMissionEntity(const CVector&, CEntity*);
+
+ static void UndoBuildingSwaps();
+ static void UndoEntityInvisibilitySettings();
+
+ static void ScriptDebugLine3D(float x1, float y1, float z1, float x2, float y2, float z2, uint32 col, uint32 col2);
+ static void RenderTheScriptDebugLines();
+
+ static void SaveAllScripts(uint8*, uint32*);
+ static void LoadAllScripts(uint8*, uint32);
+
+ static bool IsDebugOn() { return DbgFlag; };
+ static void InvertDebugFlag() { DbgFlag = !DbgFlag; }
+
+ static int32* GetPointerToScriptVariable(int32 offset) { assert(offset >= 8 && offset < CTheScripts::GetSizeOfVariableSpace()); return (int32*)&ScriptSpace[offset]; }
+
+ static int32 Read4BytesFromScript(uint32* pIp) {
+ int32 retval = ScriptSpace[*pIp + 3] << 24 | ScriptSpace[*pIp + 2] << 16 | ScriptSpace[*pIp + 1] << 8 | ScriptSpace[*pIp];
+ *pIp += 4;
+ return retval;
+ }
+ static int16 Read2BytesFromScript(uint32* pIp) {
+ int16 retval = ScriptSpace[*pIp + 1] << 8 | ScriptSpace[*pIp];
+ *pIp += 2;
+ return retval;
+ }
+ static int8 Read1ByteFromScript(uint32* pIp) {
+ int8 retval = ScriptSpace[*pIp];
+ *pIp += 1;
+ return retval;
+ }
+ static float ReadFloatFromScript(uint32* pIp) {
+ return Read2BytesFromScript(pIp) / 16.0f;
+ }
+ static void ReadTextLabelFromScript(uint32* pIp, char* buf) {
+ strncpy(buf, (const char*)&CTheScripts::ScriptSpace[*pIp], KEY_LENGTH_IN_SCRIPT);
+ }
+ static wchar* GetTextByKeyFromScript(uint32* pIp) {
+ wchar* text = TheText.Get((const char*)&CTheScripts::ScriptSpace[*pIp]);
+ *pIp += KEY_LENGTH_IN_SCRIPT;
+ return text;
+ }
+ static int32 GetSizeOfVariableSpace()
+ {
+ uint32 tmp = 3;
+ return Read4BytesFromScript(&tmp);
+ }
+
+ static CRunningScript* StartNewScript(uint32);
+
+ static void CleanUpThisVehicle(CVehicle*);
+ static void CleanUpThisPed(CPed*);
+ static void CleanUpThisObject(CObject*);
+
+ static bool IsPedStopped(CPed*);
+ static bool IsPlayerStopped(CPlayerInfo*);
+ static bool IsVehicleStopped(CVehicle*);
+
+ static void PrintListSizes();
+ static void ReadObjectNamesFromScript();
+ static void UpdateObjectIndices();
+ static void ReadMultiScriptFileOffsetsFromScript();
+ static void DrawScriptSpheres();
+ static void HighlightImportantArea(uint32, float, float, float, float, float);
+ static void HighlightImportantAngledArea(uint32, float, float, float, float, float, float, float, float, float);
+ static void DrawDebugSquare(float, float, float, float);
+ static void DrawDebugAngledSquare(float, float, float, float, float, float, float, float);
+ static void DrawDebugCube(float, float, float, float, float, float);
+ static void DrawDebugAngledCube(float, float, float, float, float, float, float, float, float, float);
+
+ static void AddToInvisibilitySwapArray(CEntity*, bool);
+ static void AddToBuildingSwapArray(CBuilding*, int32, int32);
+
+ static int32 GetActualScriptSphereIndex(int32 index);
+ static int32 AddScriptSphere(int32 id, CVector pos, float radius);
+ static int32 GetNewUniqueScriptSphereIndex(int32 index);
+ static void RemoveScriptSphere(int32 index);
+ static void RemoveScriptTextureDictionary();
+public:
+ static void RemoveThisPed(CPed* pPed);
+
+ static uint32& GetLastMissionPassedTime() { return LastMissionPassedTime; }
+#ifdef MISSION_SWITCHER
+ static void SwitchToMission(int32 mission);
+#endif
+
+#ifdef GTA_SCRIPT_COLLECTIVE
+ static void AdvanceCollectiveIndex()
+ {
+ if (NextFreeCollectiveIndex == INT32_MAX)
+ NextFreeCollectiveIndex = 0;
+ else
+ NextFreeCollectiveIndex++;
+ }
+
+ static int AddPedsInVehicleToCollective(int);
+ static int AddPedsInAreaToCollective(float, float, float, float);
+ static int FindFreeSlotInCollectiveArray();
+ static void SetObjectiveForAllPedsInCollective(int, eObjective, int16, int16);
+ static void SetObjectiveForAllPedsInCollective(int, eObjective, CVector, float);
+ static void SetObjectiveForAllPedsInCollective(int, eObjective, CVector);
+ static void SetObjectiveForAllPedsInCollective(int, eObjective, void*);
+ static void SetObjectiveForAllPedsInCollective(int, eObjective);
+#endif
+
+};
+
+#ifdef USE_DEBUG_SCRIPT_LOADER
+extern int scriptToLoad;
+#endif
+#ifdef MISSION_REPLAY
+static_assert(false, "Mission replay is not supported");
+extern int AllowMissionReplay;
+extern uint32 WaitForMissionActivate;
+extern uint32 WaitForSave;
+extern uint32 MissionStartTime;
+extern int missionRetryScriptIndex;
+extern bool doingMissionRetry;
+extern bool gbTryingPorn4Again;
+extern int IsInAmmunation;
+extern int MissionSkipLevel;
+
+uint32 AddExtraDeathDelay();
+void RetryMission(int, int);
+#endif
+
+#ifdef USE_DEBUG_SCRIPT_LOADER
+extern int scriptToLoad;
+#endif