Skip to content

Commit

Permalink
Add initial server awareness for custom train tracks (#1715)
Browse files Browse the repository at this point in the history
This **fully backwards compatible** pull request contains initial support for the train track element and the ability to change between default train tracks. This is the first in a series of pull requests that intends to pick apart the `feature/custom-train-tracks` branch in #250, so that it can be confidently reviewed and merged without worrying about bugs too much.

You can get default track elements using the below documentation. This documentation is currently only accurate server-side. Client-side it will just return the same number you provide, as clients do not yet have a concept of track elements.

```lua
-- OOP: TrainTrack.getDefaultTrack(trackID)
train-track getDefaultTrack(number trackID)

-- trackID: the ID of the default track, one of `0`, `1`, `2`, `3`.
```

And then set (or get) the track of a train using the following functions:

```lua
-- OOP: v:setTrack(t)
bool setTrainTrack(vehicle v, train-track t)

-- OOP: v:getTrack(v)
train-track getTrainTrack(vehicle v)
```

I have tested sync with one and two players, and track and position _syncing_ seems to work great. The only client changes this PR brings is exposing existing client to the Lua API (a partial revert of 89b5620 / #1713).


The client-side `setTrainTrack` function is not protected, and can run on server trains. This is consistent with the behaviour of `setTrainPosition`, `setTrainDirection` and `setTrainSpeed`.


Finally, since this code is based on the original `feature/custom-train-tracks` branch:

Co-authored-by: Jusonex <jusonex96@gmail.com>
Co-authored-by: Cazomino05 <Cazomino05@gmail.com>
Co-authored-by: "sebasdevelopment@gmx.com" <sebasdevelopment@gmx.com>
  • Loading branch information
4 people committed Oct 16, 2020
1 parent fced208 commit c610ff3
Show file tree
Hide file tree
Showing 21 changed files with 843 additions and 25 deletions.
51 changes: 40 additions & 11 deletions Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ void CLuaVehicleDefs::LoadFunctions()
{"isTrainDerailable", IsTrainDerailable},
{"getTrainDirection", GetTrainDirection},
{"getTrainSpeed", GetTrainSpeed},
{"getTrainTrack", ArgumentParser<GetTrainTrack>},
{"getTrainPosition", GetTrainPosition},
{"isTrainChainEngine", IsTrainChainEngine},
{"getVehicleGravity", GetVehicleGravity},
Expand Down Expand Up @@ -116,6 +117,7 @@ void CLuaVehicleDefs::LoadFunctions()
{"setTrainDerailable", SetTrainDerailable},
{"setTrainDirection", SetTrainDirection},
{"setTrainSpeed", SetTrainSpeed},
{"setTrainTrack", ArgumentParser<SetTrainTrack>},
{"setTrainPosition", SetTrainPosition},
{"setVehicleTaxiLightOn", SetVehicleTaxiLightOn},
{"setVehicleGravity", SetVehicleGravity},
Expand All @@ -129,7 +131,7 @@ void CLuaVehicleDefs::LoadFunctions()
{"setVehicleComponentScale", SetVehicleComponentScale},
{"resetVehicleComponentPosition", ResetVehicleComponentPosition},
{"resetVehicleComponentRotation", ResetVehicleComponentRotation},
{"resetVehicleComponentScale", ResetVehicleComponentScale },
{"resetVehicleComponentScale", ResetVehicleComponentScale},
{"setVehicleComponentVisible", SetVehicleComponentVisible},
{"setVehicleNitroActivated", SetVehicleNitroActivated},
{"setVehicleNitroCount", SetVehicleNitroCount},
Expand All @@ -138,7 +140,7 @@ void CLuaVehicleDefs::LoadFunctions()
{"setHeliBladeCollisionsEnabled", SetHeliBladeCollisionsEnabled},
{"setVehicleWindowOpen", SetVehicleWindowOpen},
{"setVehicleModelExhaustFumesPosition", SetVehicleModelExhaustFumesPosition},
{"setVehicleModelDummyPosition", SetVehicleModelDummyPosition },
{"setVehicleModelDummyPosition", SetVehicleModelDummyPosition},
{"setVehicleWheelScale", ArgumentParser<SetVehicleWheelScale>},
{"setVehicleModelWheelSize", ArgumentParser<SetVehicleModelWheelSize>},
};
Expand Down Expand Up @@ -175,6 +177,7 @@ void CLuaVehicleDefs::AddClass(lua_State* luaVM)
lua_classfunction(luaVM, "getNitroLevel", "getVehicleNitroLevel");
lua_classfunction(luaVM, "getDirection", "getTrainDirection");
lua_classfunction(luaVM, "getTrainSpeed", "getTrainSpeed");
lua_classfunction(luaVM, "getTrack", "getTrainTrack");
lua_classfunction(luaVM, "getTrainPosition", "getTrainPosition");
lua_classfunction(luaVM, "getName", "getVehicleName");
lua_classfunction(luaVM, "getVehicleType", "getVehicleType");
Expand Down Expand Up @@ -257,6 +260,7 @@ void CLuaVehicleDefs::AddClass(lua_State* luaVM)
lua_classfunction(luaVM, "setNitroLevel", "setVehicleNitroLevel");
lua_classfunction(luaVM, "setDirection", "setTrainDirection");
lua_classfunction(luaVM, "setTrainSpeed", "setTrainSpeed");
lua_classfunction(luaVM, "setTrack", "setTrainTrack");
lua_classfunction(luaVM, "setTrainPosition", "setTrainPosition");
lua_classfunction(luaVM, "setDerailable", "setTrainDerailable");
lua_classfunction(luaVM, "setDerailed", "setTrainDerailed");
Expand Down Expand Up @@ -312,6 +316,7 @@ void CLuaVehicleDefs::AddClass(lua_State* luaVM)
lua_classvariable(luaVM, "towedByVehicle", NULL, "getVehicleTowedByVehicle");
lua_classvariable(luaVM, "direction", "setTrainDirection", "getTrainDirection");
lua_classvariable(luaVM, "trainSpeed", "setTrainSpeed", "getTrainSpeed");
lua_classvariable(luaVM, "track", "setTrainTrack", "getTrainTrack");
lua_classvariable(luaVM, "trainPosition", "setTrainPosition", "getTrainPosition");
lua_classvariable(luaVM, "derailable", "setTrainDerailable", "isTrainDerailable");
lua_classvariable(luaVM, "derailed", "setTrainDerailed", "isTrainDerailed");
Expand Down Expand Up @@ -1362,6 +1367,16 @@ int CLuaVehicleDefs::GetTrainSpeed(lua_State* luaVM)
return 1;
}

std::variant<uchar, bool> CLuaVehicleDefs::GetTrainTrack(CClientVehicle* pVehicle)
{
if (pVehicle->GetVehicleType() != CLIENTVEHICLE_TRAIN)
return false;
else if (pVehicle->IsDerailed())
return false;

return pVehicle->GetTrainTrack();
}

int CLuaVehicleDefs::GetTrainPosition(lua_State* luaVM)
{
CClientVehicle* pVehicle = NULL;
Expand Down Expand Up @@ -2306,6 +2321,22 @@ int CLuaVehicleDefs::SetTrainSpeed(lua_State* luaVM)
return 1;
}

bool CLuaVehicleDefs::SetTrainTrack(CClientVehicle* pVehicle, uchar ucTrack)
{
if (ucTrack > 3)
throw new std::invalid_argument("Invalid track number range (0-3)");

if (pVehicle->GetVehicleType() != CLIENTVEHICLE_TRAIN)
return false;
else if (pVehicle->IsDerailed())
{
return false;
}

pVehicle->SetTrainTrack(ucTrack);
return true;
}

int CLuaVehicleDefs::SetTrainPosition(lua_State* luaVM)
{
CClientVehicle* pVehicle = NULL;
Expand Down Expand Up @@ -3206,7 +3237,6 @@ int CLuaVehicleDefs::OOP_GetVehicleComponentPosition(lua_State* luaVM)
lua_pushvector(luaVM, vecPosition);
return 1;
}

}
}
else
Expand Down Expand Up @@ -3333,7 +3363,7 @@ int CLuaVehicleDefs::SetVehicleComponentScale(lua_State* luaVM)
argStream.ReadVector3D(vecScale);
argStream.ReadEnumString(inputBase, EComponentBase::PARENT);

if(!argStream.HasErrors())
if (!argStream.HasErrors())
{
pVehicle->SetComponentScale(strComponent, vecScale, inputBase);
lua_pushboolean(luaVM, true);
Expand All @@ -3358,10 +3388,10 @@ int CLuaVehicleDefs::GetVehicleComponentScale(lua_State* luaVM)
argStream.ReadString(strComponent);
argStream.ReadEnumString(outputBase, EComponentBase::PARENT);

if(!argStream.HasErrors())
if (!argStream.HasErrors())
{
CVector vecScale;
if(pVehicle->GetComponentScale(strComponent, vecScale, outputBase))
if (pVehicle->GetComponentScale(strComponent, vecScale, outputBase))
{
lua_pushnumber(luaVM, vecScale.fX);
lua_pushnumber(luaVM, vecScale.fY);
Expand All @@ -3388,10 +3418,10 @@ int CLuaVehicleDefs::OOP_GetVehicleComponentScale(lua_State* luaVM)
argStream.ReadString(strComponent);
argStream.ReadEnumString(outputBase, EComponentBase::PARENT);

if(!argStream.HasErrors())
if (!argStream.HasErrors())
{
CVector vecScale;
if(pVehicle->GetComponentScale(strComponent, vecScale, outputBase))
if (pVehicle->GetComponentScale(strComponent, vecScale, outputBase))
{
lua_pushvector(luaVM, vecScale);
return 1;
Expand Down Expand Up @@ -3458,9 +3488,9 @@ int CLuaVehicleDefs::ResetVehicleComponentScale(lua_State* luaVM)
argStream.ReadUserData(pVehicle);
argStream.ReadString(strComponent);

if(!argStream.HasErrors())
if (!argStream.HasErrors())
{
if(pVehicle->ResetComponentScale(strComponent))
if (pVehicle->ResetComponentScale(strComponent))
{
lua_pushboolean(luaVM, true);
return 1;
Expand Down Expand Up @@ -4009,7 +4039,6 @@ int CLuaVehicleDefs::OOP_GetVehicleModelExhaustFumesPosition(lua_State* luaVM)
return 1;
}


float CLuaVehicleDefs::GetVehicleWheelScale(CClientVehicle* const pVehicle)
{
return pVehicle->GetWheelScale();
Expand Down
2 changes: 2 additions & 0 deletions Client/mods/deathmatch/logic/luadefs/CLuaVehicleDefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class CLuaVehicleDefs : public CLuaDefs
LUA_DECLARE(IsTrainDerailable);
LUA_DECLARE(GetTrainDirection);
LUA_DECLARE(GetTrainSpeed);
static std::variant<uchar, bool> GetTrainTrack(CClientVehicle* pVehicle);
LUA_DECLARE(GetTrainPosition);
LUA_DECLARE(IsTrainChainEngine);
LUA_DECLARE_OOP(GetVehicleGravity);
Expand Down Expand Up @@ -119,6 +120,7 @@ class CLuaVehicleDefs : public CLuaDefs
LUA_DECLARE(SetTrainDerailable);
LUA_DECLARE(SetTrainDirection);
LUA_DECLARE(SetTrainSpeed);
static bool SetTrainTrack(CClientVehicle* pVehicle, uchar ucTrack);
LUA_DECLARE(SetTrainPosition);
LUA_DECLARE(SetVehicleGravity);
LUA_DECLARE(SetVehicleHeadLightColor);
Expand Down
2 changes: 2 additions & 0 deletions Server/mods/deathmatch/StdInc.h
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,8 @@ struct SAclRequest;
#include "CTextDisplay.h"
#include "CTextItem.h"
#include "CTickRateSettings.h"
#include "CTrainTrack.h"
#include "CTrainTrackManager.h"
#include "CUnoccupiedVehicleSync.h"
#include "CVehicle.h"
#include "CVehicleColorManager.h"
Expand Down
1 change: 1 addition & 0 deletions Server/mods/deathmatch/logic/CElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ class CElement
WATER,
WEAPON,
DATABASE_CONNECTION,
TRAIN_TRACK,
ROOT,
UNKNOWN,
};
Expand Down
2 changes: 2 additions & 0 deletions Server/mods/deathmatch/logic/CGame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,8 @@ bool CGame::Start(int iArgumentCount, char* szArguments[])

m_pCustomWeaponManager = new CCustomWeaponManager();

m_pTrainTrackManager = std::make_shared<CTrainTrackManager>();

// Parse the commandline
if (!m_CommandLineParser.Parse(iArgumentCount, szArguments))
{
Expand Down
6 changes: 5 additions & 1 deletion Server/mods/deathmatch/logic/CGame.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ class CVehicleManager;
class CZoneNames;
class CLanBroadcast;
class CWaterManager;

class CTrainTrackManager;
class CWeaponStatManager;
class CBuildingRemovalManager;

Expand Down Expand Up @@ -253,6 +253,8 @@ class CGame
CMasterServerAnnouncer* GetMasterServerAnnouncer() { return m_pMasterServerAnnouncer; }
SharedUtil::CAsyncTaskScheduler* GetAsyncTaskScheduler() { return m_pAsyncTaskScheduler; }

std::shared_ptr<CTrainTrackManager> GetTrainTrackManager() { return m_pTrainTrackManager; }

void JoinPlayer(CPlayer& Player);
void InitialDataStream(CPlayer& Player);
void QuitPlayer(CPlayer& Player, CClient::eQuitReasons Reason = CClient::QUIT_QUIT, bool bSayInConsole = true, const char* szKickReason = "None",
Expand Down Expand Up @@ -554,6 +556,8 @@ class CGame
CWeaponStatManager* m_pWeaponStatsManager;
CBuildingRemovalManager* m_pBuildingRemovalManager;

std::shared_ptr<CTrainTrackManager> m_pTrainTrackManager;

CCustomWeaponManager* m_pCustomWeaponManager;
CFunctionUseLogger* m_pFunctionUseLogger;

Expand Down
58 changes: 58 additions & 0 deletions Server/mods/deathmatch/logic/CTrainTrack.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*****************************************************************************
*
* PROJECT: Multi Theft Auto
* LICENSE: See LICENSE in the top level directory
*
* Multi Theft Auto is available from http://www.multitheftauto.com/
*
*****************************************************************************/

#include "StdInc.h"

CTrainTrack::CTrainTrack(CTrainTrackManager* pManager, const std::vector<STrackNode>& nodes, bool linkLastNodes, CElement* pParent, uchar defaultTrackId)
: CElement(pParent), m_pManager(pManager)
{
m_iType = CElement::TRAIN_TRACK;
SetTypeName("train-track");

m_LinkLastNodes = linkLastNodes;
m_Nodes = nodes;
m_DefaultTrackId = defaultTrackId;
}

CTrainTrack::~CTrainTrack()
{
// Remove all vehicles from the track
CVehicleManager* pVehicleManager = g_pGame->GetVehicleManager();
for (auto pVehicle : pVehicleManager->GetVehicles())
{
if (pVehicle->GetTrainTrack() != this)
continue;

pVehicle->SetTrainTrack(nullptr);
pVehicle->SetDerailed(true);
}

// Unreference train track
m_pManager->DestroyTrainTrack(this);
}

bool CTrainTrack::SetTrackNodePosition(uint nodeIndex, const CVector& position)
{
if (nodeIndex >= m_Nodes.size())
return false;

auto& node = m_Nodes[nodeIndex];
node.position = position;
return true;
}

bool CTrainTrack::GetTrackNodePosition(uint nodeIndex, CVector& position)
{
if (nodeIndex >= m_Nodes.size())
return false;

auto& node = m_Nodes[nodeIndex];
position = node.position;
return true;
}
59 changes: 59 additions & 0 deletions Server/mods/deathmatch/logic/CTrainTrack.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*****************************************************************************
*
* PROJECT: Multi Theft Auto
* LICENSE: See LICENSE in the top level directory
*
* Multi Theft Auto is available from http://www.multitheftauto.com/
*
*****************************************************************************/

#pragma once
class CTrainTrackManager;

struct STrackNode
{
CVector position;
float railDistance;

STrackNode(std::int16_t x, std::int16_t y, std::int16_t z, std::uint16_t distance)
{
position.fX = 8.0f * x;
position.fY = 8.0f * y;
position.fZ = 8.0f * z;
railDistance = 3.0f * distance; // TODO(Jusonex, feature/custom-train-tracks/9063a3dc080): Remove distance
}

STrackNode(const CVector& pos) : position(pos) {}
STrackNode() {}
};

class CTrainTrack : public CElement
{
public:
CTrainTrack(CTrainTrackManager* pManager, const std::vector<STrackNode>& nodes, bool linkLastNodes, CElement* pParent, uchar defaultTrackId = 0xFF);
// TODO: Add move constructor
virtual ~CTrainTrack();

bool SetTrackNodePosition(uint nodeIndex, const CVector& position);
bool GetTrackNodePosition(uint nodeIndex, CVector& position);

inline const std::vector<STrackNode>& GetNodes() const { return m_Nodes; }
inline std::size_t GetNumberOfNodes() const { return m_Nodes.size(); }

inline void SetLastNodesLinked(bool link) { m_LinkLastNodes = link; }
inline bool GetLastNodesLinked() { return m_LinkLastNodes; }

inline bool IsDefault() { return m_DefaultTrackId != 0xFF; }
inline uchar GetDefaultTrackId() { return m_DefaultTrackId; }

virtual void Unlink() override {}
bool ReadSpecialData(const int iLine) override { return false; }

private:
CTrainTrackManager* m_pManager;

std::vector<STrackNode> m_Nodes;
bool m_LinkLastNodes;
bool m_Default;
uchar m_DefaultTrackId;
};
Loading

0 comments on commit c610ff3

Please sign in to comment.