2019-06-12 11:46:02 +00:00
|
|
|
#pragma once
|
2019-07-07 16:00:02 +00:00
|
|
|
#include "common.h"
|
2019-07-27 18:28:18 +00:00
|
|
|
#include "Text.h"
|
2019-06-14 23:34:19 +00:00
|
|
|
#include "Sprite2d.h"
|
2019-07-08 06:46:42 +00:00
|
|
|
|
|
|
|
class CEntity;
|
|
|
|
class CBuilding;
|
|
|
|
class CVehicle;
|
|
|
|
class CPed;
|
|
|
|
class CObject;
|
2019-06-14 23:34:19 +00:00
|
|
|
|
|
|
|
struct CScriptRectangle
|
|
|
|
{
|
2019-07-07 21:05:24 +00:00
|
|
|
int8 m_bIsUsed;
|
2019-07-07 17:57:00 +00:00
|
|
|
bool m_bBeforeFade;
|
2019-07-07 16:00:02 +00:00
|
|
|
int16 m_nTextureId;
|
2019-06-14 23:34:19 +00:00
|
|
|
CRect m_sRect;
|
|
|
|
CRGBA m_sColor;
|
|
|
|
};
|
|
|
|
|
2019-07-07 16:00:02 +00:00
|
|
|
static_assert(sizeof(CScriptRectangle) == 0x18, "Script.h: error");
|
|
|
|
|
|
|
|
enum {
|
|
|
|
SCRIPT_TEXT_MAX_LENGTH = 500
|
|
|
|
};
|
|
|
|
|
2019-06-14 23:34:19 +00:00
|
|
|
struct CTextLine
|
|
|
|
{
|
2019-06-16 22:16:38 +00:00
|
|
|
float m_fScaleX;
|
|
|
|
float m_fScaleY;
|
2019-06-14 23:34:19 +00:00
|
|
|
CRGBA m_sColor;
|
2019-06-16 22:16:38 +00:00
|
|
|
bool m_bJustify;
|
|
|
|
bool m_bCentered;
|
|
|
|
bool m_bBackground;
|
|
|
|
bool m_bBackgroundOnly;
|
|
|
|
float m_fWrapX;
|
|
|
|
float m_fCenterSize;
|
2019-06-14 23:34:19 +00:00
|
|
|
CRGBA m_sBackgroundColor;
|
2019-06-16 22:16:38 +00:00
|
|
|
bool m_bTextProportional;
|
2019-07-07 16:00:02 +00:00
|
|
|
bool m_bTextBeforeFade;
|
2019-06-16 22:16:38 +00:00
|
|
|
bool m_bRightJustify;
|
2019-06-14 23:34:19 +00:00
|
|
|
int32 m_nFont;
|
2019-07-07 16:00:02 +00:00
|
|
|
float m_fAtX;
|
|
|
|
float m_fAtY;
|
|
|
|
wchar m_Text[SCRIPT_TEXT_MAX_LENGTH];
|
2019-07-07 17:57:00 +00:00
|
|
|
|
|
|
|
void Reset();
|
2019-07-07 16:00:02 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static_assert(sizeof(CTextLine) == 0x414, "Script.h: error");
|
|
|
|
|
|
|
|
struct CScriptSphere
|
|
|
|
{
|
|
|
|
bool m_bInUse;
|
|
|
|
uint16 m_Index;
|
|
|
|
uint32 m_Id;
|
|
|
|
CVector m_vecCenter;
|
|
|
|
float m_fRadius;
|
|
|
|
};
|
|
|
|
|
|
|
|
enum {
|
|
|
|
MAX_STACK_DEPTH = 6,
|
|
|
|
NUM_LOCAL_VARS = 16,
|
|
|
|
NUM_TIMERS = 2
|
2019-06-14 23:34:19 +00:00
|
|
|
};
|
2019-06-12 11:46:02 +00:00
|
|
|
|
2019-07-07 16:00:02 +00:00
|
|
|
class CRunningScript
|
2019-07-03 22:16:24 +00:00
|
|
|
{
|
|
|
|
CRunningScript *next;
|
|
|
|
CRunningScript *prev;
|
2019-07-07 16:00:02 +00:00
|
|
|
char m_abScriptName[8];
|
2019-07-03 22:16:24 +00:00
|
|
|
uint32 m_nIp;
|
2019-07-07 16:00:02 +00:00
|
|
|
uint32 m_anStack[MAX_STACK_DEPTH];
|
2019-07-03 22:16:24 +00:00
|
|
|
uint16 m_nStackPointer;
|
2019-07-07 16:00:02 +00:00
|
|
|
int32 m_anLocalVariables[NUM_LOCAL_VARS + NUM_TIMERS];
|
2019-07-03 22:16:24 +00:00
|
|
|
bool m_bCondResult;
|
2019-07-07 21:05:24 +00:00
|
|
|
bool m_bIsMissionScript;
|
2019-07-03 22:16:24 +00:00
|
|
|
bool m_bSkipWakeTime;
|
|
|
|
uint32 m_nWakeTime;
|
2019-07-07 16:00:02 +00:00
|
|
|
uint16 m_nAndOrState;
|
2019-07-03 22:16:24 +00:00
|
|
|
bool m_bNotFlag;
|
2019-07-25 20:34:29 +00:00
|
|
|
bool m_bDeatharrestEnabled;
|
|
|
|
bool m_bDeatharrestExecuted;
|
2019-07-03 22:16:24 +00:00
|
|
|
bool m_bMissionFlag;
|
2019-07-07 16:00:02 +00:00
|
|
|
|
|
|
|
public:
|
2019-07-07 17:57:00 +00:00
|
|
|
void SetIP(uint32 ip) { m_nIp = ip; }
|
|
|
|
CRunningScript* GetNext() { return next; }
|
|
|
|
void UpdateTimers(float timeStep){
|
|
|
|
m_anLocalVariables[NUM_LOCAL_VARS] += timeStep;
|
|
|
|
m_anLocalVariables[NUM_LOCAL_VARS + 1] += timeStep;
|
|
|
|
}
|
|
|
|
|
2019-07-07 16:00:02 +00:00
|
|
|
void CollectParameters(uint32*, int16);
|
|
|
|
int32 CollectNextParameterWithoutIncreasingPC(uint32);
|
|
|
|
int32* GetPointerToScriptVariable(uint32*, int16);
|
|
|
|
void StoreParameters(uint32*, int16);
|
|
|
|
void Init();
|
|
|
|
void RemoveScriptFromList(CRunningScript**);
|
|
|
|
void AddScriptToList(CRunningScript**);
|
2019-07-07 17:57:00 +00:00
|
|
|
void Process();
|
2019-07-07 21:05:24 +00:00
|
|
|
int8 ProcessOneCommand();
|
|
|
|
void DoDeatharrestCheck();
|
|
|
|
int8 ProcessCommandsFrom0To99(int32);
|
|
|
|
int8 ProcessCommandsFrom100To199(int32);
|
|
|
|
int8 ProcessCommandsFrom200To299(int32);
|
|
|
|
int8 ProcessCommandsFrom300To399(int32);
|
|
|
|
int8 ProcessCommandsFrom400To499(int32);
|
|
|
|
int8 ProcessCommandsFrom500To599(int32);
|
|
|
|
int8 ProcessCommandsFrom600To699(int32);
|
|
|
|
int8 ProcessCommandsFrom700To799(int32);
|
|
|
|
int8 ProcessCommandsFrom800To899(int32);
|
|
|
|
int8 ProcessCommandsFrom900To999(int32);
|
|
|
|
int8 ProcessCommandsFrom1000To1099(int32);
|
|
|
|
int8 ProcessCommandsFrom1100To1199(int32);
|
2019-07-09 20:38:05 +00:00
|
|
|
void UpdateCompareFlag(bool);
|
2019-07-25 20:34:29 +00:00
|
|
|
int16 GetPadState(uint16, uint16);
|
|
|
|
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*);
|
2019-10-12 19:00:31 +00:00
|
|
|
void PlayerInAreaCheckCommand(int32, uint32*);
|
|
|
|
void PlayerInAngledAreaCheckCommand(int32, uint32*);
|
|
|
|
void CharInAreaCheckCommand(int32, uint32*);
|
|
|
|
void CarInAreaCheckCommand(int32, uint32*);
|
2019-07-25 20:34:29 +00:00
|
|
|
private:
|
|
|
|
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
|
|
|
|
};
|
2019-07-03 22:16:24 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
enum {
|
|
|
|
CLEANUP_UNUSED = 0,
|
|
|
|
CLEANUP_CAR,
|
|
|
|
CLEANUP_CHAR,
|
|
|
|
CLEANUP_OBJECT
|
|
|
|
};
|
|
|
|
|
|
|
|
struct CMissionCleanupEntity
|
|
|
|
{
|
|
|
|
uint8 type;
|
|
|
|
int32 id;
|
|
|
|
};
|
|
|
|
|
|
|
|
enum {
|
|
|
|
MAX_CLEANUP = 50,
|
|
|
|
MAX_UPSIDEDOWN_CAR_CHECKS = 6,
|
|
|
|
MAX_STUCK_CAR_CHECKS = 6
|
|
|
|
};
|
|
|
|
|
|
|
|
class CMissionCleanup
|
|
|
|
{
|
|
|
|
CMissionCleanupEntity m_sEntities[MAX_CLEANUP];
|
2019-07-20 13:30:11 +00:00
|
|
|
uint8 m_nCount;
|
2019-07-03 22:16:24 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
CMissionCleanup();
|
|
|
|
|
|
|
|
void Init();
|
|
|
|
CMissionCleanupEntity* FindFree();
|
|
|
|
void AddEntityToList(int32, uint8);
|
|
|
|
void RemoveEntityFromList(int32, uint8);
|
|
|
|
void Process();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct CUpsideDownCarCheckEntry
|
|
|
|
{
|
|
|
|
int32 m_nVehicleIndex;
|
|
|
|
uint32 m_nUpsideDownTimer;
|
|
|
|
};
|
|
|
|
|
|
|
|
class CUpsideDownCarCheck
|
|
|
|
{
|
|
|
|
CUpsideDownCarCheckEntry m_sCars[MAX_UPSIDEDOWN_CAR_CHECKS];
|
|
|
|
|
|
|
|
public:
|
|
|
|
void Init();
|
2019-07-06 15:06:08 +00:00
|
|
|
bool IsCarUpsideDown(int32);
|
|
|
|
void UpdateTimers();
|
|
|
|
bool AreAnyCarsUpsideDown();
|
|
|
|
void AddCarToCheck(int32);
|
|
|
|
void RemoveCarFromCheck(int32);
|
|
|
|
bool HasCarBeenUpsideDownForAWhile(int32);
|
2019-07-03 22:16:24 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct CStuckCarCheckEntry
|
|
|
|
{
|
|
|
|
int32 m_nVehicleIndex;
|
|
|
|
CVector m_vecPos;
|
2019-07-06 15:06:08 +00:00
|
|
|
int32 m_nLastCheck;
|
|
|
|
float m_fRadius;
|
2019-07-03 22:16:24 +00:00
|
|
|
uint32 m_nStuckTime;
|
|
|
|
bool m_bStuck;
|
2019-07-06 15:06:08 +00:00
|
|
|
|
|
|
|
inline void Reset();
|
2019-07-03 22:16:24 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class CStuckCarCheck
|
|
|
|
{
|
|
|
|
CStuckCarCheckEntry m_sCars[MAX_STUCK_CAR_CHECKS];
|
|
|
|
|
|
|
|
public:
|
|
|
|
void Init();
|
2019-07-06 15:06:08 +00:00
|
|
|
void Process();
|
|
|
|
void AddCarToCheck(int32, float, uint32);
|
|
|
|
void RemoveCarFromCheck(int32);
|
|
|
|
bool HasCarBeenStuckForAWhile(int32);
|
2019-07-03 22:16:24 +00:00
|
|
|
};
|
|
|
|
|
2019-07-07 16:00:02 +00:00
|
|
|
enum {
|
2019-07-09 20:38:05 +00:00
|
|
|
ARGUMENT_END = 0,
|
|
|
|
ARGUMENT_INT32,
|
2019-07-07 16:00:02 +00:00
|
|
|
ARGUMENT_GLOBALVAR,
|
|
|
|
ARGUMENT_LOCALVAR,
|
|
|
|
ARGUMENT_INT8,
|
|
|
|
ARGUMENT_INT16,
|
|
|
|
ARGUMENT_FLOAT
|
|
|
|
};
|
|
|
|
|
|
|
|
struct tCollectiveData
|
|
|
|
{
|
|
|
|
int32 index;
|
|
|
|
uint32 unk_data;
|
|
|
|
};
|
|
|
|
|
|
|
|
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 {
|
|
|
|
VAR_LOCAL = 1,
|
|
|
|
VAR_GLOBAL = 2,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum {
|
|
|
|
SIZE_MAIN_SCRIPT = 128 * 1024,
|
|
|
|
SIZE_MISSION_SCRIPT = 32 * 1024,
|
|
|
|
SIZE_SCRIPT_SPACE = SIZE_MAIN_SCRIPT + SIZE_MISSION_SCRIPT
|
|
|
|
};
|
|
|
|
|
|
|
|
enum {
|
|
|
|
MAX_NUM_SCRIPTS = 128,
|
|
|
|
MAX_NUM_CONTACTS = 16,
|
|
|
|
MAX_NUM_INTRO_TEXT_LINES = 2,
|
|
|
|
MAX_NUM_INTRO_RECTANGLES = 16,
|
|
|
|
MAX_NUM_SCRIPT_SRPITES = 16,
|
|
|
|
MAX_NUM_SCRIPT_SPHERES = 16,
|
|
|
|
MAX_NUM_COLLECTIVES = 32,
|
|
|
|
MAX_NUM_USED_OBJECTS = 200,
|
|
|
|
MAX_NUM_MISSION_SCRIPTS = 120,
|
|
|
|
MAX_NUM_BUILDING_SWAPS = 25,
|
|
|
|
MAX_NUM_INVISIBILITY_SETTINGS = 20
|
|
|
|
};
|
|
|
|
|
2019-06-12 11:46:02 +00:00
|
|
|
class CTheScripts
|
|
|
|
{
|
|
|
|
public:
|
2019-07-07 16:00:02 +00:00
|
|
|
static uint8(&ScriptSpace)[SIZE_SCRIPT_SPACE];
|
|
|
|
static CRunningScript(&ScriptsArray)[MAX_NUM_SCRIPTS];
|
|
|
|
static int32(&BaseBriefIdForContact)[MAX_NUM_CONTACTS];
|
|
|
|
static int32(&OnAMissionForContactFlag)[MAX_NUM_CONTACTS];
|
|
|
|
static CTextLine(&IntroTextLines)[MAX_NUM_INTRO_TEXT_LINES];
|
|
|
|
static CScriptRectangle(&IntroRectangles)[MAX_NUM_INTRO_RECTANGLES];
|
|
|
|
static CSprite2d(&ScriptSprites)[MAX_NUM_SCRIPT_SRPITES];
|
|
|
|
static CScriptSphere(&ScriptSphereArray)[MAX_NUM_SCRIPT_SPHERES];
|
|
|
|
static tCollectiveData(&CollectiveArray)[MAX_NUM_COLLECTIVES];
|
|
|
|
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];
|
2019-07-03 22:16:24 +00:00
|
|
|
static bool &DbgFlag;
|
|
|
|
static uint32 &OnAMissionFlag;
|
|
|
|
static CMissionCleanup &MissionCleanup;
|
|
|
|
static CStuckCarCheck &StuckCars;
|
|
|
|
static CUpsideDownCarCheck &UpsideDownCars;
|
|
|
|
static int32 &StoreVehicleIndex;
|
|
|
|
static bool &StoreVehicleWasRandom;
|
2019-07-07 16:00:02 +00:00
|
|
|
static CRunningScript *&pIdleScripts;
|
|
|
|
static CRunningScript *&pActiveScripts;
|
|
|
|
static uint32 &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 uint8 &CountdownToMakePlayerUnsafe;
|
|
|
|
static uint8 &DelayMakingPlayerUnsafeThisTime;
|
|
|
|
static uint16 &NumScriptDebugLines;
|
|
|
|
static uint16 &NumberOfIntroRectanglesThisFrame;
|
|
|
|
static uint16 &NumberOfIntroTextLinesThisFrame;
|
|
|
|
static bool &UseTextCommands;
|
2019-07-07 17:57:00 +00:00
|
|
|
static uint16 &CommandsExecuted;
|
|
|
|
static uint16 &ScriptsUpdated;
|
2019-06-20 00:31:03 +00:00
|
|
|
public:
|
2019-06-20 09:20:52 +00:00
|
|
|
static void ScriptDebugLine3D(float x1, float y1, float z1, float x2, float y2, float z2, int col, int col2);
|
2019-07-03 22:16:24 +00:00
|
|
|
static void CleanUpThisVehicle(CVehicle*);
|
|
|
|
static void CleanUpThisPed(CPed*);
|
|
|
|
static void CleanUpThisObject(CObject*);
|
2019-07-07 16:00:02 +00:00
|
|
|
static void Init();
|
2019-07-07 17:57:00 +00:00
|
|
|
static CRunningScript* StartNewScript(uint32);
|
|
|
|
static void Process();
|
|
|
|
static CRunningScript* StartTestScript();
|
|
|
|
static bool IsPlayerOnAMission();
|
2019-07-07 16:00:02 +00:00
|
|
|
|
|
|
|
static void ReadObjectNamesFromScript();
|
|
|
|
static void UpdateObjectIndices();
|
|
|
|
static void ReadMultiScriptFileOffsetsFromScript();
|
2019-07-07 17:57:00 +00:00
|
|
|
static void DrawScriptSpheres();
|
2019-07-09 20:38:05 +00:00
|
|
|
static void ClearSpaceForMissionEntity(const CVector&, CEntity*);
|
|
|
|
static void HighlightImportantArea(uint32, float, float, float, float, float);
|
|
|
|
static void DrawDebugSquare(float, float, float, float);
|
|
|
|
static void DrawDebugCube(float, float, float, float, float, float);
|
2019-10-12 19:00:31 +00:00
|
|
|
static bool IsVehicleStopped(CVehicle*);
|
2019-07-07 16:00:02 +00:00
|
|
|
|
|
|
|
static int32 Read4BytesFromScript(uint32* pIp){
|
|
|
|
int32 retval = 0;
|
|
|
|
for (int i = 0; i < 4; i++){
|
|
|
|
retval |= ScriptSpace[(*pIp)++] << (8 * i);
|
|
|
|
}
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
static int16 Read2BytesFromScript(uint32* pIp){
|
|
|
|
int16 retval = 0;
|
|
|
|
for (int i = 0; i < 2; i++){
|
|
|
|
retval |= ScriptSpace[(*pIp)++] << (8 * i);
|
|
|
|
}
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
static int8 Read1ByteFromScript(uint32* pIp){
|
|
|
|
int8 retval = 0;
|
|
|
|
for (int i = 0; i < 1; i++){
|
|
|
|
retval |= ScriptSpace[(*pIp)++] << (8 * i);
|
|
|
|
}
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
static float ReadFloatFromScript(uint32* pIp){
|
|
|
|
return Read2BytesFromScript(pIp) / 16.0f;
|
|
|
|
}
|
2019-07-25 20:34:29 +00:00
|
|
|
static void ReadTextLabelFromScript(uint32* pIp, char* buf){
|
2019-07-27 18:28:18 +00:00
|
|
|
strncpy(buf, (const char*)&ScriptSpace[*pIp], 8);
|
|
|
|
}
|
|
|
|
static wchar* GetTextByKeyFromScript(uint32* pIp) {
|
|
|
|
wchar* text = TheText.Get((const char*)&ScriptSpace[*pIp]);
|
|
|
|
*pIp += 8;
|
|
|
|
return text;
|
2019-07-25 20:34:29 +00:00
|
|
|
}
|
2019-06-12 11:46:02 +00:00
|
|
|
};
|