Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
TRAIN_TRACK,
ROOT,
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 @@ -4179,6 +4179,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);
break;
}

default:
{
assert(0);
Expand Down Expand Up @@ -4248,10 +4268,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 @@ -498,6 +498,22 @@ void CElementRPCs::SetElementModel(CClientEntity* pSource, NetBitStreamInterface
pObject->CallEvent("onClientElementModelChange", Arguments, true);
}

break;
}
case CCLIENTBUILDING:
{
CClientBuilding* pBuilding = static_cast<CClientBuilding*>(pSource);
const unsigned short usCurrentModel = pBuilding->GetModel();
Copy link
Contributor

Choose a reason for hiding this comment

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

auto or std::uint16_t
currentModel instead of usCurrentModel?
building instead of pBuilding?


if (usCurrentModel != usModel)
Copy link
Contributor

Choose a reason for hiding this comment

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

early break?

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 ok with one break at the end of the block.

{
pBuilding->SetModel(usModel);
CLuaArguments Arguments;
Arguments.PushNumber(usCurrentModel);
Arguments.PushNumber(usModel);
pBuilding->CallEvent("onClientElementModelChange", Arguments, true);
}

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

case CCLIENTBUILDING:
{
static_cast<CClientBuilding*>(pSource)->SetUsesCollision(bEnable);
break;
}
}
}
}
Expand Down Expand Up @@ -593,6 +615,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
212 changes: 212 additions & 0 deletions Server/mods/deathmatch/logic/CBuilding.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
/*****************************************************************************
*
* 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 "CLogger.h"
#include "Utils.h"

extern CGame* g_pGame;

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

m_pBuildingManager = pBuildingManager;
m_usModel = 0xFFFF;
m_ucAlpha = 255;
m_bDoubleSided = false;
m_bCollisionsEnabled = true;
Copy link
Contributor

Choose a reason for hiding this comment

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

move to initializer list

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 looks better here and as garbage when a half of the members are in initializer list.
Base class members cannot be moved in initializer list. fyi


// 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_usModel = Copy.m_usModel;
m_ucAlpha = Copy.m_ucAlpha;
m_bDoubleSided = Copy.m_bDoubleSided;
m_vecPosition = Copy.m_vecPosition;
m_vecRotation = Copy.m_vecRotation;
m_bCollisionsEnabled = Copy.m_bCollisionsEnabled;

// 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_HighLodBuilding)
m_HighLodBuilding->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))
{
// Set the building id
m_usModel = static_cast<unsigned short>(iTemp);
}
else
{
CLogger::ErrorPrintf("Bad 'model' (%d) id specified in <building> (line %d)\n", iTemp, iLine);
return false;
}
}
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)
{
// 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