Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add createBuilding for server #3897

Draft
wants to merge 16 commits into
base: master
Choose a base branch
from
Draft
6 changes: 5 additions & 1 deletion Client/mods/deathmatch/logic/CClientGame.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,12 @@ class CClientGame
SCRIPTFILE,
WATER,
WEAPON,
POINTLIGHTS,
_DATABASE_CONNECTION, // server only
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not DATABASE_CONNECTION?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because it's server only and unexpected on the client.

TRAIN_TRACK,
ROOT,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ROOT?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Synced with the server.

UNKNOWN,
BUILDING,
POINTLIGHTS,
};

enum
Expand Down
36 changes: 32 additions & 4 deletions Client/mods/deathmatch/logic/CPacketHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4218,6 +4218,26 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream)
break;
}

case CClientGame::BUILDING:
{
std::uint16_t modelId;
SRotationRadiansSync rotationRadians(false);

// Read out the position, rotation, object ID
bitStream.Read(&position);
bitStream.Read(&rotationRadians);
bitStream.ReadCompressed(modelId);

if (!CClientBuildingManager::IsValidModel(modelId))
modelId = 1700;

bitStream.Read(LowLodObjectID);
CClientBuilding* pBuilding = new CClientBuilding(g_pClientGame->m_pManager, EntityID, modelId, position.data.vecPosition, rotationRadians.data.vecRotation, ucInterior);

pBuilding->SetUsesCollision(bCollisonsEnabled);
TheNormalnij marked this conversation as resolved.
Show resolved Hide resolved
break;
}

default:
{
assert(0);
Expand Down Expand Up @@ -4287,10 +4307,18 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream)

if (TempLowLodObjectID != INVALID_ELEMENT_ID)
{
CClientObject* pTempObject = DynamicCast<CClientObject>(pTempEntity);
CClientObject* pLowLodObject = DynamicCast<CClientObject>(CElementIDs::GetElement(TempLowLodObjectID));
if (pTempObject)
pTempObject->SetLowLodObject(pLowLodObject);
if (CClientObject* pTempObject = DynamicCast<CClientObject>(pTempEntity))
{
CClientObject* pLowLodObject = DynamicCast<CClientObject>(CElementIDs::GetElement(TempLowLodObjectID));
if (pTempObject)
pTempObject->SetLowLodObject(pLowLodObject);
}
else if (CClientBuilding* pTempObject = DynamicCast<CClientBuilding>(pTempEntity))
{
CClientBuilding* pLowLod = DynamicCast<CClientBuilding>(CElementIDs::GetElement(TempLowLodObjectID));
if (pTempObject)
pTempObject->SetLowLodBuilding(pLowLod);
}
}

delete pEntityStuff;
Expand Down
29 changes: 29 additions & 0 deletions Client/mods/deathmatch/logic/rpc/CElementRPCs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,22 @@ void CElementRPCs::SetElementModel(CClientEntity* pSource, NetBitStreamInterface
pObject->CallEvent("onClientElementModelChange", Arguments, true);
}

break;
}
case CCLIENTBUILDING:
{
CClientBuilding* building = static_cast<CClientBuilding*>(pSource);
const auto currentModel = building->GetModel();

if (currentModel != usModel)
{
building->SetModel(usModel);
CLuaArguments Arguments;
Arguments.PushNumber(currentModel);
Arguments.PushNumber(usModel);
building->CallEvent("onClientElementModelChange", Arguments, true);
}

break;
}
}
Expand Down Expand Up @@ -543,6 +559,12 @@ void CElementRPCs::SetElementCollisionsEnabled(CClientEntity* pSource, NetBitStr
pObject->SetCollisionEnabled(bEnable);
break;
}

case CCLIENTBUILDING:
{
static_cast<CClientBuilding*>(pSource)->SetUsesCollision(bEnable);
break;
}
}
}
}
Expand Down Expand Up @@ -594,6 +616,13 @@ void CElementRPCs::SetLowLodElement(CClientEntity* pSource, NetBitStreamInterfac
pObject->SetLowLodObject(pLowLodObject);
break;
}
case CCLIENTBUILDING:
{
CClientBuilding* pLowLodBuilding = DynamicCast<CClientBuilding>(CElementIDs::GetElement(LowLodObjectID));
CClientBuilding* pBuilding = static_cast<CClientBuilding*>(pSource);
pBuilding->SetLowLodBuilding(pLowLodBuilding);
break;
}
}
}
}
Expand Down
214 changes: 214 additions & 0 deletions Server/mods/deathmatch/logic/CBuilding.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
/*****************************************************************************
*
* PROJECT: Multi Theft Auto v1.0
* LICENSE: See LICENSE in the top level directory
* FILE: mods/deathmatch/logic/CBuilding.cpp
* PURPOSE: Object entity class
*
* Multi Theft Auto is available from http://www.multitheftauto.com/
*
*****************************************************************************/

#include "StdInc.h"
#include "CBuilding.h"
#include "CBuildingManager.h"
#include "CLogger.h"
#include "Utils.h"

extern CGame* g_pGame;

CBuilding::CBuilding(CElement* pParent, CBuildingManager* pBuildingManager) : CElement(pParent)
{
// Init
m_iType = CElement::BUILDING;
SetTypeName("buidling");

m_pBuildingManager = pBuildingManager;
m_model = 0xFFFF;
m_alpha = 255;
m_bDoubleSided = false;
m_bCollisionsEnabled = true;
m_pLowLodBuilding = nullptr;
m_pHighLodBuilding = nullptr;

// Add us to the manager's list
pBuildingManager->AddToList(this);
}

CBuilding::CBuilding(const CBuilding& Copy) : CElement(Copy.m_pParent), m_pLowLodBuilding(Copy.m_pLowLodBuilding)
{
// Init
m_iType = CElement::BUILDING;
SetTypeName("buidling");

m_pBuildingManager = Copy.m_pBuildingManager;
m_model = Copy.m_model;
m_alpha = Copy.m_alpha;
m_bDoubleSided = Copy.m_bDoubleSided;
m_vecPosition = Copy.m_vecPosition;
m_vecRotation = Copy.m_vecRotation;
m_bCollisionsEnabled = Copy.m_bCollisionsEnabled;
m_pHighLodBuilding = nullptr;

// Add us to the manager's list
m_pBuildingManager->AddToList(this);
UpdateSpatialData();
}

CBuilding::~CBuilding()
{
// Unlink us from manager
Unlink();
}

CElement* CBuilding::Clone(bool* bAddEntity, CResource* pResource)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ignored?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These params are ignored, why?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a CEntity interface method

{
return new CBuilding(*this);
}

void CBuilding::Unlink()
{
// Remove us from the manager's list
m_pBuildingManager->RemoveFromList(this);

// Remove LowLod refs in others
SetLowLodBuilding(nullptr);

if (m_pHighLodBuilding)
m_pHighLodBuilding->SetLowLodBuilding(nullptr);
}

bool CBuilding::ReadSpecialData(const int iLine)
{
// Grab the "posX" data
if (!GetCustomDataFloat("posX", m_vecPosition.fX, true))
{
CLogger::ErrorPrintf("Bad/missing 'posX' attribute in <building> (line %d)\n", iLine);
return false;
}

// Grab the "posY" data
if (!GetCustomDataFloat("posY", m_vecPosition.fY, true))
{
CLogger::ErrorPrintf("Bad/missing 'posY' attribute in <building> (line %d)\n", iLine);
return false;
}

// Grab the "posZ" data
if (!GetCustomDataFloat("posZ", m_vecPosition.fZ, true))
{
CLogger::ErrorPrintf("Bad/missing 'posZ' attribute in <building> (line %d)\n", iLine);
return false;
}

// Grab the "rotX", "rotY" and "rotZ" data
GetCustomDataFloat("rotX", m_vecRotation.fX, true);
GetCustomDataFloat("rotY", m_vecRotation.fY, true);
GetCustomDataFloat("rotZ", m_vecRotation.fZ, true);
// We store radians, but load degrees
ConvertDegreesToRadians(m_vecRotation);

// Grab the "model" data
int iTemp;
if (GetCustomDataInt("model", iTemp, true))
{
// Valid id?
if (!CBuildingManager::IsValidModel(iTemp))
{
CLogger::ErrorPrintf("Bad 'model' (%d) id specified in <building> (line %d)\n", iTemp, iLine);
return false;
}

// Set the building id
m_model = static_cast<unsigned short>(iTemp);
}
else
{
CLogger::ErrorPrintf("Bad/missing 'model' attribute in <building> (line %d)\n", iLine);
return false;
}

if (GetCustomDataInt("interior", iTemp, true))
m_ucInterior = static_cast<unsigned char>(iTemp);

if (!GetCustomDataBool("collisions", m_bCollisionsEnabled, true))
m_bCollisionsEnabled = true;

return true;
}

void CBuilding::GetMatrix(CMatrix& matrix)
{
matrix.vPos = GetPosition();
CVector vecRotation;
GetRotation(vecRotation);

// Do extra calculation to change rotation order if it will make a difference
if (vecRotation.fX != 0 && vecRotation.fY != 0)
{
ConvertRadiansToDegreesNoWrap(vecRotation);
vecRotation = ConvertEulerRotationOrder(vecRotation, EULER_ZXY, EULER_ZYX);
ConvertDegreesToRadiansNoWrap(vecRotation);
}
matrix.SetRotation(vecRotation);
}

void CBuilding::SetMatrix(const CMatrix& matrix)
{
// Set position and rotation from matrix
SetPosition(matrix.vPos);
CVector vecRotation = matrix.GetRotation();
SetRotation(vecRotation);
}

const CVector& CBuilding::GetPosition()
{
return m_vecPosition;
}

void CBuilding::SetPosition(const CVector& vecPosition)
{
// Different position?
if (m_vecPosition != vecPosition)
{
// Update our vectors
m_vecPosition = vecPosition;
UpdateSpatialData();
}
}

void CBuilding::GetRotation(CVector& vecRotation)
{
vecRotation = m_vecRotation;
}

void CBuilding::SetRotation(const CVector& vecRotation)
{
m_vecRotation = vecRotation;
}

bool CBuilding::SetLowLodBuilding(CBuilding* pNewLowLodBuilding) noexcept
{
// Set or clear?
if (!pNewLowLodBuilding)
{
if (m_pLowLodBuilding)
{
m_pLowLodBuilding->SetHighLodObject(nullptr);
m_pLowLodBuilding = nullptr;
}
m_pLowLodBuilding = nullptr;
return true;
}
else
{
// Remove any previous link
SetLowLodBuilding(nullptr);

// Make new link
m_pLowLodBuilding = pNewLowLodBuilding;
pNewLowLodBuilding->SetHighLodObject(this);
return true;
}
}

Loading
Loading