Skip to content

Commit 7727cb6

Browse files
committed
Implements NumberOfDocks and DockingOffset for BuildingTypes.
1 parent 90024e8 commit 7727cb6

File tree

5 files changed

+125
-1
lines changed

5 files changed

+125
-1
lines changed

src/extensions/building/buildingext.cpp

+54
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "building.h"
3030
#include "buildingtype.h"
3131
#include "buildingtypeext.h"
32+
#include "tibsun_inline.h"
3233
#include "house.h"
3334
#include "housetype.h"
3435
#include "wwcrc.h"
@@ -172,6 +173,7 @@ void BuildingClassExtension::Compute_CRC(WWCRCEngine &crc) const
172173
crc(ProduceCashTimer());
173174
}
174175

176+
175177
/**
176178
* #issue-26
177179
*
@@ -286,3 +288,55 @@ void BuildingClassExtension::Produce_Cash_AI()
286288
}
287289

288290
}
291+
292+
293+
/**
294+
* Fetches the coordinate to use for docking.
295+
*
296+
* @author: CCHyper
297+
*/
298+
Coordinate BuildingClassExtension::Docking_Coord() const
299+
{
300+
ASSERT(ThisPtr != nullptr);
301+
//EXT_DEBUG_TRACE("BuildingClassExtension::Docking_Coord - Name: %s (0x%08X)\n", ThisPtr->Name(), (uintptr_t)(ThisPtr));
302+
303+
if (ThisPtr->Class->IsWeeder) {
304+
Cell cell = ThisPtr->Get_Cell();
305+
cell.X += 2;
306+
cell.Y += 1;
307+
Coordinate coord = Cell_Coord(cell, true);
308+
coord.Z = ThisPtr->Get_Coord().Z;
309+
return coord;
310+
}
311+
312+
if (ThisPtr->Class->IsRefinery) {
313+
Coordinate coord = ThisPtr->Center_Coord();
314+
coord.X += CELL_LEPTON_W/2;
315+
return coord;
316+
}
317+
318+
/**
319+
* #issue-786
320+
*
321+
* Implements initial DockingOffsets support for Helipads and Service bays.
322+
*
323+
* @author: CCHyper
324+
*/
325+
BuildingTypeClassExtension *buildingtypeext = BuildingTypeClassExtensions.find(ThisPtr->Class);
326+
327+
if (buildingtypeext && buildingtypeext->NumberOfDocks > 0) {
328+
329+
TPoint3D<int> docking_offset_1 = buildingtypeext->DockingOffsets[0];
330+
331+
if (ThisPtr->Class->IsHelipad) {
332+
Coordinate coord = ThisPtr->Center_Coord();
333+
coord.X += docking_offset_1.X;
334+
coord.Y += docking_offset_1.Y;
335+
coord.Z += docking_offset_1.Z;
336+
return coord;
337+
}
338+
339+
}
340+
341+
return ThisPtr->Docking_Coord();
342+
}

src/extensions/building/buildingext.h

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class BuildingClassExtension final : public Extension<BuildingClass>
5353
virtual void Compute_CRC(WWCRCEngine &crc) const override;
5454

5555
void Produce_Cash_AI();
56+
Coordinate Docking_Coord() const;
5657

5758
public:
5859
/**

src/extensions/building/buildingext_hooks.cpp

+32
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,36 @@
5555
#include "hooker_macros.h"
5656

5757

58+
/**
59+
* A fake class for implementing new member functions which allow
60+
* access to the "this" pointer of the intended class.
61+
*
62+
* @note: This must not contain a constructor or destructor!
63+
* @note: All functions must be prefixed with "_" to prevent accidental virtualization.
64+
*/
65+
class BuildingClassExt final : public BuildingClass
66+
{
67+
public:
68+
Coordinate _Docking_Coord() const;
69+
};
70+
71+
72+
/**
73+
* Reimplementation of BuildingClass::Docking_Coord.
74+
*
75+
* @author: CCHyper
76+
*/
77+
Coordinate BuildingClassExt::_Docking_Coord() const
78+
{
79+
BuildingClassExtension *buildingext = BuildingClassExtensions.find(this);
80+
if (buildingext) {
81+
return buildingext->Docking_Coord();
82+
} else {
83+
return BuildingClass::Docking_Coord();
84+
}
85+
}
86+
87+
5888
/**
5989
* #issue-26
6090
*
@@ -493,4 +523,6 @@ void BuildingClassExtension_Hooks()
493523
Patch_Jump(0x00429A96, &_BuildingClass_AI_ProduceCash_Patch);
494524
Patch_Jump(0x0042F67D, &_BuildingClass_Captured_ProduceCash_Patch);
495525
Patch_Jump(0x0042E179, &_BuildingClass_Grand_Opening_ProduceCash_Patch);
526+
527+
Change_Virtual_Address(0x006CC3A0, Get_Func_Address(&BuildingClassExt::_Docking_Coord));
496528
}

src/extensions/buildingtype/buildingtypeext.cpp

+27-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ BuildingTypeClassExtension::BuildingTypeClassExtension(BuildingTypeClass *this_p
5454
ProduceCashBudget(0),
5555
IsStartupCashOneTime(false),
5656
IsResetBudgetOnCapture(false),
57-
IsEligibleForAllyBuilding(false)
57+
IsEligibleForAllyBuilding(false),
58+
NumberOfDocks(0),
59+
DockingOffsets()
5860
{
5961
ASSERT(ThisPtr != nullptr);
6062
//EXT_DEBUG_TRACE("BuildingTypeClassExtension constructor - Name: %s (0x%08X)\n", ThisPtr->Name(), (uintptr_t)(ThisPtr));
@@ -167,6 +169,8 @@ void BuildingTypeClassExtension::Compute_CRC(WWCRCEngine &crc) const
167169
//EXT_DEBUG_TRACE("BuildingTypeClassExtension::Compute_CRC - Name: %s (0x%08X)\n", ThisPtr->Name(), (uintptr_t)(ThisPtr));
168170

169171
crc(IsEligibleForAllyBuilding);
172+
crc(NumberOfDocks);
173+
crc(DockingOffsets.Count());
170174
}
171175

172176

@@ -181,12 +185,26 @@ bool BuildingTypeClassExtension::Read_INI(CCINIClass &ini)
181185
//EXT_DEBUG_TRACE("BuildingTypeClassExtension::Read_INI - Name: %s (0x%08X)\n", ThisPtr->Name(), (uintptr_t)(ThisPtr));
182186
EXT_DEBUG_WARNING("BuildingTypeClassExtension::Read_INI - Name: %s (0x%08X)\n", ThisPtr->Name(), (uintptr_t)(ThisPtr));
183187

188+
char buffer[1024];
189+
184190
const char *ini_name = ThisPtr->Name();
191+
const char *graphic_name = ThisPtr->Graphic_Name();
185192

186193
if (!ini.Is_Present(ini_name)) {
187194
return false;
188195
}
189196

197+
//if (!ArtINI.Is_Present(graphic_name)) {
198+
// return false;
199+
//}
200+
201+
/**
202+
* The following structures have at least one docking location.
203+
*/
204+
if (ThisPtr->IsHelipad) {
205+
NumberOfDocks = 1;
206+
}
207+
190208
GateUpSound = ini.Get_VocType(ini_name, "GateUpSound", GateUpSound);
191209
GateDownSound = ini.Get_VocType(ini_name, "GateDownSound", GateDownSound);
192210

@@ -199,6 +217,14 @@ bool BuildingTypeClassExtension::Read_INI(CCINIClass &ini)
199217

200218
IsEligibleForAllyBuilding = ini.Get_Bool(ini_name, "EligibleForAllyBuilding",
201219
ThisPtr->IsConstructionYard ? true : IsEligibleForAllyBuilding);
220+
221+
NumberOfDocks = ini.Get_Int(ini_name, "NumberOfDocks", NumberOfDocks);
222+
223+
for (int i = 0; i < NumberOfDocks; ++i) {
224+
std::snprintf(buffer, sizeof(buffer), "DockingOffset%d", i);
225+
TPoint3D<int> offset = ArtINI.Get_Point(graphic_name, buffer, TPoint3D<int>(0,0,0));
226+
DockingOffsets.Add(offset);
227+
}
202228

203229
return true;
204230
}

src/extensions/buildingtype/buildingtypeext.h

+11
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
#include "extension.h"
3131
#include "container.h"
32+
#include "tpoint.h"
3233

3334

3435
class BuildingTypeClass;
@@ -96,6 +97,16 @@ class BuildingTypeClassExtension final : public Extension<BuildingTypeClass>
9697
* Is this building eligible for proximity checks by players who are its owner's allies?
9798
*/
9899
bool IsEligibleForAllyBuilding;
100+
101+
/**
102+
* The number of available docking positions this building has.
103+
*/
104+
unsigned NumberOfDocks;
105+
106+
/**
107+
* The offset(s) from the center of the building for each docking position.
108+
*/
109+
DynamicVectorClass<TPoint3D<int>> DockingOffsets;
99110
};
100111

101112

0 commit comments

Comments
 (0)