Skip to content

Commit

Permalink
feat(gamestate/server): CREATE_TRAIN(_CARRIAGE) command
Browse files Browse the repository at this point in the history
  • Loading branch information
Ehbw committed Jan 1, 2024
1 parent bab1c17 commit 0442dc6
Show file tree
Hide file tree
Showing 8 changed files with 456 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -547,18 +547,18 @@ struct CTrainGameStateDataNodeData
bool isEngine;
bool isCaboose;

bool unk12;
bool isMissionTrain;

bool direction;

bool unk14;
bool hasPassengerCarriages;

bool renderDerailed;

// 2372 {
bool unk198; //unk198
bool highPrecisionBlending; //unk224
bool hasNoThreadId; //unk199
bool allowRemovalByPopulation;
bool highPrecisionBlending;
bool shouldStopAtStations;
// }

bool forceDoorsOpen;
Expand Down Expand Up @@ -648,17 +648,6 @@ enum ePopType
POPTYPE_TOOL
};

//TODO: Probably should be moved out of fx::sync namespace
struct scrVector
{
float x;
int pad;
float y;
int pad2;
float z;
int pad3;
};

struct SyncTreeBase
{
public:
Expand Down Expand Up @@ -1124,6 +1113,9 @@ struct ScriptGuid
}
};

auto GetTrain(fx::ServerGameState* sgs, uint32_t objectId) -> fx::sync::SyncEntityPtr;
auto GetNextTrain(fx::ServerGameState* sgs, const fx::sync::SyncEntityPtr& entity) -> fx::sync::SyncEntityPtr;

struct EntityCreationState
{
// TODO: allow resending in case the target client disappears
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2627,22 +2627,23 @@ struct CTrainGameStateDataNode : GenericSerializeDataNode<CTrainGameStateDataNod

//2372 inserted a bool between isEngine and isCaboose
if (Is2372())
{
s.Serialize(data.unk198);
{
//Modified by 0x2310A8F9421EBF43
s.Serialize(data.allowRemovalByPopulation);
}

s.Serialize(data.isCaboose);
s.Serialize(data.unk12);
s.Serialize(data.isMissionTrain);
s.Serialize(data.direction);
s.Serialize(data.unk14);
s.Serialize(data.hasPassengerCarriages);
s.Serialize(data.renderDerailed);

s.Serialize(data.forceDoorsOpen);

if (Is2372())
{
//Always true on randomly spawned trains
s.Serialize(data.hasNoThreadId);
// true on randomly spawned metro trains
s.Serialize(data.shouldStopAtStations);

//Modified by 0xEC0C1D4922AF9754
s.Serialize(data.highPrecisionBlending);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -839,7 +839,8 @@ void sync::SyncCommandList::Execute(const fx::ClientSharedPtr& client)
}

#ifdef STATE_FIVE
static auto GetTrain(fx::ServerGameState* sgs, uint32_t objectId) -> fx::sync::SyncEntityPtr

auto GetTrain(fx::ServerGameState* sgs, uint32_t objectId) -> fx::sync::SyncEntityPtr
{
if (objectId != 0)
{
Expand All @@ -854,7 +855,7 @@ static auto GetTrain(fx::ServerGameState* sgs, uint32_t objectId) -> fx::sync::S
return {};
};

static auto GetNextTrain(fx::ServerGameState* sgs, const fx::sync::SyncEntityPtr& entity) -> fx::sync::SyncEntityPtr
auto GetNextTrain(fx::ServerGameState* sgs, const fx::sync::SyncEntityPtr& entity) -> fx::sync::SyncEntityPtr
{
if (auto trainState = entity->syncTree->GetTrainState())
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include <ScriptSerialization.h>
#include <MakeClientFunction.h>
#include <MakePlayerEntityFunction.h>

namespace fx
{
void DisownEntityScript(const fx::sync::SyncEntityPtr& entity);
Expand Down Expand Up @@ -1094,9 +1094,47 @@ static void Init()

fx::ScriptEngine::RegisterNativeHandler("DELETE_ENTITY", makeEntityFunction([](fx::ScriptContext& context, const fx::sync::SyncEntityPtr& entity)
{
auto resourceManager = fx::ResourceManager::GetCurrent();
auto instance = resourceManager->GetComponent<fx::ServerInstanceBaseRef>()->Get();
auto gameState = instance->GetComponent<fx::ServerGameState>();
auto resourceManager = fx::ResourceManager::GetCurrent();
auto instance = resourceManager->GetComponent<fx::ServerInstanceBaseRef>()->Get();
auto gameState = instance->GetComponent<fx::ServerGameState>();

#ifdef STATE_FIVE
// If the entity is a server-owned train, loop through all the train carriages and delete
if (entity->IsOwnedByServerScript() && entity->type == fx::sync::NetObjEntityType::Train)
{
if (auto trainState = entity->syncTree->GetTrainState())
{
auto deleteCarriages = [gameState](const fx::sync::SyncEntityPtr& engine)
{
for (auto link = GetNextTrain(gameState.GetRef(), engine); link; link = GetNextTrain(gameState.GetRef(), link))
{
if (link->handle != engine->handle)
{
gameState->DeleteEntity(link);
}
}

//Clean up the engine afterwards
gameState->DeleteEntity(engine);
};

if (trainState->isEngine)
{
deleteCarriages(entity);
return 0;
}

if (trainState->engineCarriage && trainState->engineCarriage != entity->handle)
{
if (auto engine = GetTrain(gameState.GetRef(), trainState->engineCarriage))
{
deleteCarriages(engine);
return 0;
}
}
}
}
#endif

gameState->DeleteEntity(entity);

Expand Down Expand Up @@ -1445,6 +1483,41 @@ static void Init()
auto train = entity->syncTree->GetTrainState();

return train ? train->carriageIndex : -1;
}));

fx::ScriptEngine::RegisterNativeHandler("GET_TRAIN_TRACK_ID", makeEntityFunction([](fx::ScriptContext& context, const fx::sync::SyncEntityPtr& entity)
{
auto train = entity->syncTree->GetTrainState();

return train ? train->trackId : -1;
}));

fx::ScriptEngine::RegisterNativeHandler("GET_TRAIN_CRUISE_SPEED", makeEntityFunction([](fx::ScriptContext& context, const fx::sync::SyncEntityPtr& entity)
{
auto train = entity->syncTree->GetTrainState();

return train ? float(train->cruiseSpeed) : 0;
}));

fx::ScriptEngine::RegisterNativeHandler("GET_TRAIN_CONFIG_INDEX", makeEntityFunction([](fx::ScriptContext& context, const fx::sync::SyncEntityPtr& entity)
{
auto train = entity->syncTree->GetTrainState();

return train ? train->trainConfigIndex : -1;
}));

fx::ScriptEngine::RegisterNativeHandler("GET_IS_TRAIN_RENDERED_AS_DERAILED", makeEntityFunction([](fx::ScriptContext& context, const fx::sync::SyncEntityPtr& entity)
{
auto train = entity->syncTree->GetTrainState();

return train ? train->renderDerailed : false;
}));

fx::ScriptEngine::RegisterNativeHandler("GET_TRAIN_STATE", makeEntityFunction([](fx::ScriptContext& context, const fx::sync::SyncEntityPtr& entity)
{
auto train = entity->syncTree->GetTrainState();

return train ? train->trainState : 0;
}));

fx::ScriptEngine::RegisterNativeHandler("GET_PLAYER_FAKE_WANTED_LEVEL", MakePlayerEntityFunction([](fx::ScriptContext& context, const fx::sync::SyncEntityPtr& entity)
Expand Down
Loading

0 comments on commit 0442dc6

Please sign in to comment.