stable CScriptPaths

This commit is contained in:
majestic 2020-08-19 11:11:19 -07:00
parent 895055a3d1
commit 03c90b7c40
6 changed files with 250 additions and 11 deletions

View File

@ -39,6 +39,7 @@
#include "Text.h"
#include "Camera.h"
#include "Radar.h"
#include "Fluff.h"
uint8 CReplay::Mode;
CAddressInReplayBuffer CReplay::Record;
@ -229,7 +230,7 @@ void CReplay::EnableReplays(void)
void PlayReplayFromHD(void);
void CReplay::Update(void)
{
if (CCutsceneMgr::IsCutsceneProcessing() || CTimer::GetIsPaused())
if (CCutsceneMgr::IsCutsceneProcessing() || CTimer::GetIsPaused() || CScriptPaths::IsOneActive())
return;
switch (Mode){
case MODE_RECORD:
@ -1175,6 +1176,7 @@ void CReplay::StoreStuffInMem(void)
if (ped)
StoreDetailedPedAnimation(ped, &pPedAnims[i]);
}
CScriptPaths::Save_ForReplay();
}
void CReplay::RestoreStuffFromMem(void)
@ -1351,6 +1353,7 @@ void CReplay::RestoreStuffFromMem(void)
}
delete[] pPedAnims;
pPedAnims = nil;
CScriptPaths::Load_ForReplay();
DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND);
DMAudio.SetRadioInCar(OldRadioStation);
DMAudio.ChangeMusicMode(MUSICMODE_GAME);

View File

@ -82,6 +82,7 @@
#include "main.h"
#include "Ropes.h"
#include "MBlur.h"
#include "Fluff.h"
#ifdef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
#include <stdarg.h>
#endif
@ -12046,36 +12047,42 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
//case COMMAND_IS_PLAYER_STANDING_ON_A_VEHICLE:
//case COMMAND_IS_PLAYER_FOOT_DOWN:
//case COMMAND_IS_CHAR_FOOT_DOWN:
case COMMAND_INITIALISE_OBJECT_PATH:
// TODO(MIAMI): script path
case COMMAND_INITIALISE_OBJECT_PATH: {
CollectParameters(&m_nIp, 2);
debug("INITALISE_OBJECT_PATH not yet implemented, skipping\n");
ScriptParams[0] = 0;
int32 counter = 0;
while (counter < 3 && CScriptPaths::aArray[counter].m_state != SCRIPT_PATH_DISABLED) {
counter++;
}
CScriptPaths::aArray[counter].InitialiseOne(ScriptParams[0], *(float*)&ScriptParams[1]);
ScriptParams[0] = counter;
StoreParameters(&m_nIp, 1);
return 0;
}
case COMMAND_START_OBJECT_ON_PATH:
{
CollectParameters(&m_nIp, 2);
debug("START_OBJECT_ON_PATH not yet implemented, skipping\n");
CObject *pObj = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
assert(pObj);
CScriptPaths::aArray[ScriptParams[1]].SetObjectToControl(pObj);
return 0;
}
case COMMAND_SET_OBJECT_PATH_SPEED:
{
CollectParameters(&m_nIp, 2);
debug("SET_OBJECT_PATH_SPEED not yet implemented, skipping\n");
CScriptPaths::aArray[ScriptParams[0]].m_fSpeed = *(float*)&ScriptParams[1];
return 0;
}
case COMMAND_SET_OBJECT_PATH_POSITION:
{
CollectParameters(&m_nIp, 2);
debug("SET_OBJECT_PATH_POSITION not yet implemented, skipping\n");
CScriptPaths::aArray[ScriptParams[0]].m_fPosition = *(float*)&ScriptParams[1];
return 0;
}
//case COMMAND_GET_OBJECT_DISTANCE_ALONG_PATH:
case COMMAND_CLEAR_OBJECT_PATH:
{
CollectParameters(&m_nIp, 1);
debug("CLEAR_OBJECT_PATH not yet implemented, skipping\n");
CScriptPaths::aArray[ScriptParams[0]].Clear();
return 0;
}
case COMMAND_HELI_GOTO_COORDS:

View File

@ -333,6 +333,7 @@ bool CGame::Initialise(const char* datFile)
CDebug::DebugInitTextBuffer();
ThePaths.Init();
ThePaths.AllocatePathFindInfoMem(4500);
CScriptPaths::Init();
CWeather::Init();
CCullZones::Init();
COcclusion::Init();
@ -463,6 +464,7 @@ bool CGame::ShutDown(void)
CReplay::FinishPlayback();
CPlane::Shutdown();
CTrain::Shutdown();
CScriptPaths::Shutdown();
CSpecialFX::Shutdown();
#ifndef PS2
CGarages::Shutdown();
@ -577,6 +579,7 @@ void CGame::ReInitGameObjectVariables(void)
CSpecialFX::Init();
CRopes::Init();
CWaterCannons::Init();
CScriptPaths::Init();
CParticle::ReloadConfig();
#ifdef PS2_MENU
@ -719,6 +722,7 @@ void CGame::Process(void)
CWeather::Update();
CTheScripts::Process();
CCollision::Update();
CScriptPaths::Update();
CTrain::UpdateTrains();
CPlane::UpdatePlanes();
CHeli::UpdateHelis();

View File

@ -1521,3 +1521,196 @@ CEscalators::Shutdown(void) {
}
NumEscalators = 0;
}
CScriptPath CScriptPaths::aArray[3];
void CScriptPath::FindCoorsFromDistanceOnPath(float t, float *pX, float *pY, float *pZ)
{
int32 i;
for (i = 0; m_pNode[i + 1].t < t; i++)
if (i == m_numNodes - 1) {
// don't go beyond last node
*pX = m_pNode[m_numNodes - 1].p.x;
*pY = m_pNode[m_numNodes - 1].p.y;
*pZ = m_pNode[m_numNodes - 1].p.z;
return;
}
float f = (t - m_pNode[i].t) / (m_pNode[i + 1].t - m_pNode[i].t);
*pX = (1.0f - f)*m_pNode[i].p.x + f*m_pNode[i + 1].p.x;
*pY = (1.0f - f)*m_pNode[i].p.y + f*m_pNode[i + 1].p.y;
*pZ = (1.0f - f)*m_pNode[i].p.z + f*m_pNode[i + 1].p.z;
}
void CScriptPath::Update(void) {
if (m_state != SCRIPT_PATH_ACTIVE)
return;
m_fPosition += m_fSpeed * CTimer::GetTimeStepInSeconds();
m_fPosition = clamp(m_fPosition, 0.0f, m_fTotalLength);
if (m_pObjects[0] || m_pObjects[1] || m_pObjects[2] || m_pObjects[3]
|| m_pObjects[4] || m_pObjects[5]) {
float t1, t2;
CVector pos1, pos2;
t1 = Max(m_fPosition - m_fObjectLength / 2.0f, 0.0f);
FindCoorsFromDistanceOnPath(t1, &pos1.x, &pos1.y, &pos1.z);
t2 = Min(m_fPosition + m_fObjectLength / 2.0f, m_fTotalLength);
FindCoorsFromDistanceOnPath(t2, &pos2.x, &pos2.y, &pos2.z);
CVector newForward, newUp(0.0f, 0.0f, 1.0f), newRight;
newForward = pos2 - pos1;
newForward.Normalise();
newRight = CrossProduct(newForward, newUp);
newRight.Normalise();
newUp = CrossProduct(newRight, newForward);
for (int i = 0; i < 6; i++) {
if (m_pObjects[i]) {
CMatrix prevMat(m_pObjects[i]->GetMatrix());
CVector prevPosition = m_pObjects[i]->GetPosition();
m_pObjects[i]->SetPosition((pos1 + pos2) / 2.0f);
m_pObjects[i]->GetRight() = newRight;
m_pObjects[i]->GetUp() = newUp;
m_pObjects[i]->GetForward() = newForward;
m_pObjects[i]->GetMatrix().UpdateRW();
m_pObjects[i]->UpdateRwFrame();
if (!m_pObjects[i]->bIsBIGBuilding && prevPosition != m_pObjects[i]->GetPosition())
m_pObjects[i]->RemoveAndAdd();
m_pObjects[i]->GetMatrix().UpdateRW();
m_pObjects[i]->UpdateRwFrame();
m_pObjects[i]->m_vecMoveSpeed = (m_pObjects[i]->GetPosition() - prevMat.GetPosition()) / CTimer::GetTimeStep();
float deltaAngle = m_pObjects[i]->GetForward().Heading() - prevMat.GetForward().Heading();
while (deltaAngle < (float)PI) deltaAngle += (float)TWOPI;
while (deltaAngle > (float)PI) deltaAngle -= (float)TWOPI;
float zTurnSpeed = deltaAngle / CTimer::GetTimeStep();
m_pObjects[i]->m_vecTurnSpeed = CVector(0.0f, 0.0f, zTurnSpeed);
m_pObjects[i]->m_vecMoveFriction = CVector(0.0f, 0.0f, 0.0f);
m_pObjects[i]->m_vecTurnFriction = CVector(0.0f, 0.0f, 0.0f);
}
}
}
}
void CScriptPath::Clear(void) {
if (m_pNode)
delete m_pNode;
m_pNode = nil;
m_numNodes = 0;
for (int i = 0; i < 6; i++)
m_pObjects[i] = nil;
m_state = SCRIPT_PATH_DISABLED;
}
void CScriptPath::InitialiseOne(int32 numNodes, float width) {
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_state = SCRIPT_PATH_INITIALIZED;
}
void CScriptPath::SetObjectToControl(CObject *pObj) {
int32 i = 0;
while (i < 6 && m_pObjects[i])
i++;
m_pObjects[i] = pObj;
pObj->RegisterReference((CEntity**)&m_pObjects[i]);
pObj->m_phy_flagA08 = false;
m_state = SCRIPT_PATH_ACTIVE;
}
void CScriptPaths::Init(void) {
for (int i = 0; i < 3; i++)
aArray[i].Clear();
}
void CScriptPaths::Shutdown(void) {
for (int i = 0; i < 3; i++)
aArray[i].Clear();
}
void CScriptPaths::Update(void) {
for (int i = 0; i < 3; i++)
aArray[i].Update();
}
bool CScriptPaths::IsOneActive(void) {
for (int i = 0; i < 3; i++)
if (aArray[i].m_state == SCRIPT_PATH_ACTIVE && aArray[i].m_fSpeed != 0.0f)
return true;
return false;
}
void CScriptPaths::Load(uint8 *buf, uint32 size) {
INITSAVEBUF
for (int32 i = 0; i < 3; i++)
aArray[i].Clear();
for (int32 i = 0; i < 3; i++) {
aArray[i] = ReadSaveBuf<CScriptPath>(buf);
for (int32 j = 0; j < 6; j++) {
CScriptPath *pPath = &aArray[i];
if (pPath->m_pObjects[j] != nil) {
pPath->m_pObjects[j] = CPools::GetObjectPool()->GetSlot((uintptr)pPath->m_pObjects[j] - 1);
pPath->m_pObjects[j]->m_phy_flagA08 = false;
}
}
aArray[i].m_pNode = new CPlaneNode[aArray[i].m_numNodes];
for (int32 j = 0; j < aArray[i].m_numNodes; j++) {
aArray[i].m_pNode[j] = ReadSaveBuf<CPlaneNode>(buf);
}
}
VALIDATESAVEBUF(size)
}
void CScriptPaths::Save(uint8 *buf, uint32 *size) {
*size = sizeof(aArray);
INITSAVEBUF
for (int32 i = 0; i < 3; i++) {
CScriptPath *pPath = WriteSaveBuf(buf, aArray[i]);
for (int32 j = 0; j < 6; j++) {
if (pPath->m_pObjects[j] != nil)
pPath->m_pObjects[j] = (CObject*)(CPools::GetObjectPool()->GetJustIndex(pPath->m_pObjects[j]) + 1);
}
for (int32 j = 0; j < aArray[i].m_numNodes; j++) {
WriteSaveBuf(buf, aArray[i].m_pNode[j]);
*size += sizeof(aArray[i].m_pNode[j]);
}
}
VALIDATESAVEBUF(*size);
}
CObject* g_pScriptPathObjects[18];
void CScriptPaths::Load_ForReplay(void) {
for (int i = 0; i < 3; i++) {
for (int32 j = 0; j < 6; j++) {
aArray[i].m_pObjects[j] = g_pScriptPathObjects[6 * i + j];
}
}
}
void CScriptPaths::Save_ForReplay(void) {
for (int i = 0; i < 3; i++) {
for (int32 j = 0; j < 6; j++) {
g_pScriptPathObjects[6 * i + j] = aArray[i].m_pObjects[j];
}
}
}

View File

@ -2,17 +2,45 @@
#include "common.h"
#include "Vector.h"
#include "Object.h"
#include "Plane.h"
enum {
SCRIPT_PATH_DISABLED = 0,
SCRIPT_PATH_INITIALIZED,
SCRIPT_PATH_ACTIVE
};
// TODO
class CScriptPath
{
public:
int32 m_numNodes;
CPlaneNode *m_pNode;
float m_fTotalLength;
float m_fSpeed;
float m_fPosition;
float m_fObjectLength;
int32 m_state;
CObject *m_pObjects[6];
void Clear(void);
void Update(void);
void InitialiseOne(int32 numNodes, float width);
void FindCoorsFromDistanceOnPath(float t, float *pX, float *pY, float *pZ);
void SetObjectToControl(CObject *pObj);
};
// TODO
class CScriptPaths
{
public:
static CScriptPath aArray[3];
static void Init(void);
static void Shutdown(void);
static void Update(void);
static bool IsOneActive(void);
static void Save(uint8 *buf, uint32 *size);
static void Load(uint8 *buf, uint32 size);
static void Save_ForReplay();
static void Load_ForReplay();
};
class CPlaneTrail

View File

@ -38,6 +38,7 @@
#include "World.h"
#include "Zones.h"
#include "Timecycle.h"
#include "Fluff.h"
#define BLOCK_COUNT 20
#define SIZE_OF_SIMPLEVARS 0xD4
@ -226,6 +227,7 @@ GenericSave(int file)
WriteSaveDataBlock(CTheCarGenerators::SaveAllCarGenerators);
WriteSaveDataBlock(CParticleObject::SaveParticle);
WriteSaveDataBlock(cAudioScriptObject::SaveAllAudioScriptObjects);
WriteSaveDataBlock(CScriptPaths::Save);
WriteSaveDataBlock(CWorld::Players[CWorld::PlayerInFocus].SavePlayerInfo);
WriteSaveDataBlock(CStats::SaveStats);
WriteSaveDataBlock(CSetPieces::Save);
@ -377,6 +379,8 @@ GenericLoad()
LoadSaveDataBlock();
ReadDataFromBlock("Loading AudioScript Objects \n", cAudioScriptObject::LoadAllAudioScriptObjects);
LoadSaveDataBlock();
ReadDataFromBlock("Loading ScriptPaths \n", CScriptPaths::Load);
LoadSaveDataBlock();
ReadDataFromBlock("Loading Player Info \n", CWorld::Players[CWorld::PlayerInFocus].LoadPlayerInfo);
LoadSaveDataBlock();
ReadDataFromBlock("Loading Stats \n", CStats::LoadStats);