Skip to content

Commit 6e22129

Browse files
authored
Add createBuilding for server (PR #3897)
1 parent a0c2e41 commit 6e22129

25 files changed

+739
-82
lines changed

Client/mods/deathmatch/logic/CClientBuildingManager.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,11 @@ class CClientBuildingManager
4040

4141
private:
4242
bool DoPoolResize(size_t newCapacity);
43-
void AddToList(CClientBuilding* pBuilding) { m_List.push_back(pBuilding); }
43+
void AddToList(CClientBuilding* pBuilding)
44+
{
45+
ResizePoolIfNeeds();
46+
m_List.push_back(pBuilding);
47+
}
4448
void RemoveFromList(CClientBuilding* pBuilding);
4549

4650
std::list<CClientBuilding*> m_List;

Client/mods/deathmatch/logic/CClientGame.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,12 @@ class CClientGame
129129
SCRIPTFILE,
130130
WATER,
131131
WEAPON,
132-
POINTLIGHTS,
132+
_DATABASE_CONNECTION, // server only
133+
TRAIN_TRACK,
134+
ROOT,
133135
UNKNOWN,
136+
BUILDING,
137+
POINTLIGHTS,
134138
};
135139

136140
enum

Client/mods/deathmatch/logic/CPacketHandler.cpp

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4219,6 +4219,26 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream)
42194219
break;
42204220
}
42214221

4222+
case CClientGame::BUILDING:
4223+
{
4224+
std::uint16_t modelId;
4225+
SRotationRadiansSync rotationRadians(false);
4226+
4227+
// Read out the position, rotation, object ID
4228+
bitStream.Read(&position);
4229+
bitStream.Read(&rotationRadians);
4230+
bitStream.ReadCompressed(modelId);
4231+
4232+
if (!CClientBuildingManager::IsValidModel(modelId))
4233+
modelId = 1700;
4234+
4235+
bitStream.Read(LowLodObjectID);
4236+
CClientBuilding* pBuilding = new CClientBuilding(g_pClientGame->m_pManager, EntityID, modelId, position.data.vecPosition, rotationRadians.data.vecRotation, ucInterior);
4237+
4238+
pBuilding->SetUsesCollision(bCollisonsEnabled);
4239+
break;
4240+
}
4241+
42224242
default:
42234243
{
42244244
assert(0);
@@ -4288,10 +4308,18 @@ void CPacketHandler::Packet_EntityAdd(NetBitStreamInterface& bitStream)
42884308

42894309
if (TempLowLodObjectID != INVALID_ELEMENT_ID)
42904310
{
4291-
CClientObject* pTempObject = DynamicCast<CClientObject>(pTempEntity);
4292-
CClientObject* pLowLodObject = DynamicCast<CClientObject>(CElementIDs::GetElement(TempLowLodObjectID));
4293-
if (pTempObject)
4294-
pTempObject->SetLowLodObject(pLowLodObject);
4311+
if (CClientObject* pTempObject = DynamicCast<CClientObject>(pTempEntity))
4312+
{
4313+
CClientObject* pLowLodObject = DynamicCast<CClientObject>(CElementIDs::GetElement(TempLowLodObjectID));
4314+
if (pTempObject)
4315+
pTempObject->SetLowLodObject(pLowLodObject);
4316+
}
4317+
else if (CClientBuilding* pTempObject = DynamicCast<CClientBuilding>(pTempEntity))
4318+
{
4319+
CClientBuilding* pLowLod = DynamicCast<CClientBuilding>(CElementIDs::GetElement(TempLowLodObjectID));
4320+
if (pTempObject)
4321+
pTempObject->SetLowLodBuilding(pLowLod);
4322+
}
42954323
}
42964324

42974325
delete pEntityStuff;

Client/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,6 @@ CClientBuilding* CLuaBuildingDefs::CreateBuilding(lua_State* const luaVM, std::u
5353
else
5454
rot.emplace(CVector(0, 0, 0));
5555

56-
m_pBuildingManager->ResizePoolIfNeeds();
57-
5856
CClientBuilding* pBuilding = new CClientBuilding(m_pManager, INVALID_ELEMENT_ID, modelId, pos, rot.value() , interior.value_or(0));
5957

6058
CClientEntity* pRoot = pResource->GetResourceDynamicEntity();

Client/mods/deathmatch/logic/rpc/CElementRPCs.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,22 @@ void CElementRPCs::SetElementModel(CClientEntity* pSource, NetBitStreamInterface
499499
pObject->CallEvent("onClientElementModelChange", Arguments, true);
500500
}
501501

502+
break;
503+
}
504+
case CCLIENTBUILDING:
505+
{
506+
CClientBuilding* building = static_cast<CClientBuilding*>(pSource);
507+
const auto currentModel = building->GetModel();
508+
509+
if (currentModel != usModel)
510+
{
511+
building->SetModel(usModel);
512+
CLuaArguments Arguments;
513+
Arguments.PushNumber(currentModel);
514+
Arguments.PushNumber(usModel);
515+
building->CallEvent("onClientElementModelChange", Arguments, true);
516+
}
517+
502518
break;
503519
}
504520
}
@@ -543,6 +559,12 @@ void CElementRPCs::SetElementCollisionsEnabled(CClientEntity* pSource, NetBitStr
543559
pObject->SetCollisionEnabled(bEnable);
544560
break;
545561
}
562+
563+
case CCLIENTBUILDING:
564+
{
565+
static_cast<CClientBuilding*>(pSource)->SetUsesCollision(bEnable);
566+
break;
567+
}
546568
}
547569
}
548570
}
@@ -594,6 +616,13 @@ void CElementRPCs::SetLowLodElement(CClientEntity* pSource, NetBitStreamInterfac
594616
pObject->SetLowLodObject(pLowLodObject);
595617
break;
596618
}
619+
case CCLIENTBUILDING:
620+
{
621+
CClientBuilding* pLowLodBuilding = DynamicCast<CClientBuilding>(CElementIDs::GetElement(LowLodObjectID));
622+
CClientBuilding* pBuilding = static_cast<CClientBuilding*>(pSource);
623+
pBuilding->SetLowLodBuilding(pLowLodBuilding);
624+
break;
625+
}
597626
}
598627
}
599628
}
Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
/*****************************************************************************
2+
*
3+
* PROJECT: Multi Theft Auto v1.0
4+
* LICENSE: See LICENSE in the top level directory
5+
* FILE: mods/deathmatch/logic/CBuilding.cpp
6+
* PURPOSE: Object entity class
7+
*
8+
* Multi Theft Auto is available from http://www.multitheftauto.com/
9+
*
10+
*****************************************************************************/
11+
12+
#include "StdInc.h"
13+
#include "CBuilding.h"
14+
#include "CBuildingManager.h"
15+
#include "CLogger.h"
16+
#include "Utils.h"
17+
18+
extern CGame* g_pGame;
19+
20+
CBuilding::CBuilding(CElement* pParent, CBuildingManager* pBuildingManager) : CElement(pParent)
21+
{
22+
// Init
23+
m_iType = CElement::BUILDING;
24+
SetTypeName("buidling");
25+
26+
m_pBuildingManager = pBuildingManager;
27+
m_model = 0xFFFF;
28+
m_bDoubleSided = false;
29+
m_bCollisionsEnabled = true;
30+
m_pLowLodBuilding = nullptr;
31+
m_pHighLodBuilding = nullptr;
32+
33+
// Add us to the manager's list
34+
pBuildingManager->AddToList(this);
35+
}
36+
37+
CBuilding::CBuilding(const CBuilding& Copy) : CElement(Copy.m_pParent), m_pLowLodBuilding(Copy.m_pLowLodBuilding)
38+
{
39+
// Init
40+
m_iType = CElement::BUILDING;
41+
SetTypeName("buidling");
42+
43+
m_pBuildingManager = Copy.m_pBuildingManager;
44+
m_model = Copy.m_model;
45+
m_bDoubleSided = Copy.m_bDoubleSided;
46+
m_vecPosition = Copy.m_vecPosition;
47+
m_vecRotation = Copy.m_vecRotation;
48+
m_bCollisionsEnabled = Copy.m_bCollisionsEnabled;
49+
m_pHighLodBuilding = nullptr;
50+
51+
// Add us to the manager's list
52+
m_pBuildingManager->AddToList(this);
53+
UpdateSpatialData();
54+
}
55+
56+
CBuilding::~CBuilding()
57+
{
58+
// Unlink us from manager
59+
Unlink();
60+
}
61+
62+
CElement* CBuilding::Clone(bool* bAddEntity, CResource* pResource)
63+
{
64+
return new CBuilding(*this);
65+
}
66+
67+
void CBuilding::Unlink()
68+
{
69+
// Remove us from the manager's list
70+
m_pBuildingManager->RemoveFromList(this);
71+
72+
// Remove LowLod refs in others
73+
SetLowLodBuilding(nullptr);
74+
75+
if (m_pHighLodBuilding)
76+
m_pHighLodBuilding->SetLowLodBuilding(nullptr);
77+
}
78+
79+
bool CBuilding::ReadSpecialData(const int iLine)
80+
{
81+
// Grab the "posX" data
82+
if (!GetCustomDataFloat("posX", m_vecPosition.fX, true))
83+
{
84+
CLogger::ErrorPrintf("Bad/missing 'posX' attribute in <building> (line %d)\n", iLine);
85+
return false;
86+
}
87+
88+
// Grab the "posY" data
89+
if (!GetCustomDataFloat("posY", m_vecPosition.fY, true))
90+
{
91+
CLogger::ErrorPrintf("Bad/missing 'posY' attribute in <building> (line %d)\n", iLine);
92+
return false;
93+
}
94+
95+
// Grab the "posZ" data
96+
if (!GetCustomDataFloat("posZ", m_vecPosition.fZ, true))
97+
{
98+
CLogger::ErrorPrintf("Bad/missing 'posZ' attribute in <building> (line %d)\n", iLine);
99+
return false;
100+
}
101+
102+
// Grab the "rotX", "rotY" and "rotZ" data
103+
GetCustomDataFloat("rotX", m_vecRotation.fX, true);
104+
GetCustomDataFloat("rotY", m_vecRotation.fY, true);
105+
GetCustomDataFloat("rotZ", m_vecRotation.fZ, true);
106+
// We store radians, but load degrees
107+
ConvertDegreesToRadians(m_vecRotation);
108+
109+
// Grab the "model" data
110+
int iTemp;
111+
if (GetCustomDataInt("model", iTemp, true))
112+
{
113+
// Valid id?
114+
if (!CBuildingManager::IsValidModel(iTemp))
115+
{
116+
CLogger::ErrorPrintf("Bad 'model' (%d) id specified in <building> (line %d)\n", iTemp, iLine);
117+
return false;
118+
}
119+
120+
// Set the building id
121+
m_model = static_cast<unsigned short>(iTemp);
122+
}
123+
else
124+
{
125+
CLogger::ErrorPrintf("Bad/missing 'model' attribute in <building> (line %d)\n", iLine);
126+
return false;
127+
}
128+
129+
if (GetCustomDataInt("interior", iTemp, true))
130+
m_ucInterior = static_cast<unsigned char>(iTemp);
131+
132+
if (!GetCustomDataBool("collisions", m_bCollisionsEnabled, true))
133+
m_bCollisionsEnabled = true;
134+
135+
return true;
136+
}
137+
138+
void CBuilding::GetMatrix(CMatrix& matrix)
139+
{
140+
matrix.vPos = GetPosition();
141+
CVector vecRotation;
142+
GetRotation(vecRotation);
143+
144+
// Do extra calculation to change rotation order if it will make a difference
145+
if (vecRotation.fX != 0 && vecRotation.fY != 0)
146+
{
147+
ConvertRadiansToDegreesNoWrap(vecRotation);
148+
vecRotation = ConvertEulerRotationOrder(vecRotation, EULER_ZXY, EULER_ZYX);
149+
ConvertDegreesToRadiansNoWrap(vecRotation);
150+
}
151+
matrix.SetRotation(vecRotation);
152+
}
153+
154+
void CBuilding::SetMatrix(const CMatrix& matrix)
155+
{
156+
// Set position and rotation from matrix
157+
SetPosition(matrix.vPos);
158+
CVector vecRotation = matrix.GetRotation();
159+
SetRotation(vecRotation);
160+
}
161+
162+
const CVector& CBuilding::GetPosition()
163+
{
164+
return m_vecPosition;
165+
}
166+
167+
void CBuilding::SetPosition(const CVector& vecPosition)
168+
{
169+
// Different position?
170+
if (m_vecPosition != vecPosition)
171+
{
172+
// Update our vectors
173+
m_vecPosition = vecPosition;
174+
UpdateSpatialData();
175+
}
176+
}
177+
178+
void CBuilding::GetRotation(CVector& vecRotation)
179+
{
180+
vecRotation = m_vecRotation;
181+
}
182+
183+
void CBuilding::SetRotation(const CVector& vecRotation)
184+
{
185+
m_vecRotation = vecRotation;
186+
}
187+
188+
bool CBuilding::SetLowLodBuilding(CBuilding* pNewLowLodBuilding) noexcept
189+
{
190+
// Set or clear?
191+
if (!pNewLowLodBuilding)
192+
{
193+
if (m_pLowLodBuilding)
194+
{
195+
m_pLowLodBuilding->SetHighLodObject(nullptr);
196+
m_pLowLodBuilding = nullptr;
197+
}
198+
m_pLowLodBuilding = nullptr;
199+
return true;
200+
}
201+
else
202+
{
203+
// Remove any previous link
204+
SetLowLodBuilding(nullptr);
205+
206+
// Make new link
207+
m_pLowLodBuilding = pNewLowLodBuilding;
208+
pNewLowLodBuilding->SetHighLodObject(this);
209+
return true;
210+
}
211+
}
212+

0 commit comments

Comments
 (0)