Skip to content

Commit 1856cb7

Browse files
committed
Implements NumberOfDocks and DockingOffset for BuildingTypes.
1 parent 850f118 commit 1856cb7

File tree

5 files changed

+128
-1
lines changed

5 files changed

+128
-1
lines changed

src/extensions/building/buildingext.cpp

+46
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"
@@ -178,6 +179,7 @@ void BuildingClassExtension::Compute_CRC(WWCRCEngine &crc) const
178179
crc(ProduceCashTimer());
179180
}
180181

182+
181183
/**
182184
* #issue-26
183185
*
@@ -291,3 +293,47 @@ void BuildingClassExtension::Produce_Cash_AI()
291293
}
292294

293295
}
296+
297+
298+
/**
299+
* Fetches the coordinate to use for docking.
300+
*
301+
* @author: CCHyper
302+
*/
303+
Coordinate BuildingClassExtension::Docking_Coord() const
304+
{
305+
//EXT_DEBUG_TRACE("BuildingClassExtension::Docking_Coord - Name: %s (0x%08X)\n", Name(), (uintptr_t)(This()));
306+
307+
Coordinate coord = This()->Center_Coord();
308+
309+
/**
310+
* #issue-786
311+
*
312+
* Implements DockingOffset for BuildingTypes (currently limited to Helipads and Refinerys).
313+
*
314+
* @author: CCHyper
315+
*/
316+
BuildingTypeClassExtension *buildingtypeext = Extension::Fetch<BuildingTypeClassExtension>(This()->Class);
317+
318+
if (buildingtypeext->NumberOfDocks > 0) {
319+
320+
if (This()->Class->IsRefinery || This()->Class->IsWeeder) {
321+
TPoint3D<int> docking_offset = buildingtypeext->DockingOffsets[0];
322+
coord.X += docking_offset.X;
323+
coord.Y += docking_offset.Y;
324+
coord.Z += docking_offset.Z;
325+
return coord;
326+
}
327+
328+
if (This()->Class->IsHelipad) {
329+
TPoint3D<int> docking_offset = buildingtypeext->DockingOffsets[0];
330+
coord.X += docking_offset.X;
331+
coord.Y += docking_offset.Y;
332+
coord.Z += docking_offset.Z;
333+
return coord;
334+
}
335+
336+
}
337+
338+
return coord;
339+
}

src/extensions/building/buildingext.h

+1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ BuildingClassExtension final : public TechnoClassExtension
6666
virtual RTTIType What_Am_I() const override { return RTTI_BUILDING; }
6767

6868
void Produce_Cash_AI();
69+
Coordinate Docking_Coord() const;
6970

7071
public:
7172
/**

src/extensions/building/buildingext_hooks.cpp

+27
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,32 @@
5656
#include "hooker_macros.h"
5757

5858

59+
/**
60+
* A fake class for implementing new member functions which allow
61+
* access to the "this" pointer of the intended class.
62+
*
63+
* @note: This must not contain a constructor or destructor!
64+
* @note: All functions must be prefixed with "_" to prevent accidental virtualization.
65+
*/
66+
class BuildingClassExt final : public BuildingClass
67+
{
68+
public:
69+
Coordinate _Docking_Coord() const;
70+
};
71+
72+
73+
/**
74+
* Reimplementation of BuildingClass::Docking_Coord.
75+
*
76+
* @author: CCHyper
77+
*/
78+
Coordinate BuildingClassExt::_Docking_Coord() const
79+
{
80+
BuildingClassExtension *buildingext = Extension::Fetch<BuildingClassExtension>(this);
81+
return buildingext->Docking_Coord();
82+
}
83+
84+
5985
/**
6086
* #issue-26
6187
*
@@ -481,4 +507,5 @@ void BuildingClassExtension_Hooks()
481507
Patch_Jump(0x00429A96, &_BuildingClass_AI_ProduceCash_Patch);
482508
Patch_Jump(0x0042F67D, &_BuildingClass_Captured_ProduceCash_Patch);
483509
Patch_Jump(0x0042E179, &_BuildingClass_Grand_Opening_ProduceCash_Patch);
510+
Patch_Dword(0x006CC3A0, Get_Func_Address(&BuildingClassExt::_Docking_Coord));
484511
}

src/extensions/buildingtype/buildingtypeext.cpp

+44-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
******************************************************************************/
2828
#include "buildingtypeext.h"
2929
#include "buildingtype.h"
30+
#include "tibsun_globals.h"
3031
#include "tibsun_defines.h"
3132
#include "ccini.h"
3233
#include "wwcrc.h"
@@ -50,7 +51,9 @@ BuildingTypeClassExtension::BuildingTypeClassExtension(const BuildingTypeClass *
5051
ProduceCashBudget(0),
5152
IsStartupCashOneTime(false),
5253
IsResetBudgetOnCapture(false),
53-
IsEligibleForAllyBuilding(false)
54+
IsEligibleForAllyBuilding(false),
55+
NumberOfDocks(0),
56+
DockingOffsets()
5457
{
5558
//if (this_ptr) EXT_DEBUG_TRACE("BuildingTypeClassExtension::BuildingTypeClassExtension - Name: %s (0x%08X)\n", Name(), (uintptr_t)(This()));
5659

@@ -174,6 +177,8 @@ void BuildingTypeClassExtension::Compute_CRC(WWCRCEngine &crc) const
174177
//EXT_DEBUG_TRACE("BuildingTypeClassExtension::Compute_CRC - Name: %s (0x%08X)\n", Name(), (uintptr_t)(This()));
175178

176179
crc(IsEligibleForAllyBuilding);
180+
crc(NumberOfDocks);
181+
crc(DockingOffsets.Count());
177182
}
178183

179184

@@ -190,7 +195,14 @@ bool BuildingTypeClassExtension::Read_INI(CCINIClass &ini)
190195
return false;
191196
}
192197

198+
char buffer[1024];
199+
193200
const char *ini_name = Name();
201+
const char *graphic_name = Graphic_Name();
202+
203+
//if (!ArtINI.Is_Present(graphic_name)) {
204+
// return false;
205+
//}
194206

195207
GateUpSound = ini.Get_VocType(ini_name, "GateUpSound", GateUpSound);
196208
GateDownSound = ini.Get_VocType(ini_name, "GateDownSound", GateDownSound);
@@ -204,6 +216,37 @@ bool BuildingTypeClassExtension::Read_INI(CCINIClass &ini)
204216

205217
IsEligibleForAllyBuilding = ini.Get_Bool(ini_name, "EligibleForAllyBuilding",
206218
This()->IsConstructionYard ? true : IsEligibleForAllyBuilding);
219+
220+
/**
221+
* The following structures must have at least one docking location.
222+
*/
223+
if (This()->IsHelipad || This()->IsRefinery || This()->IsWeeder) {
224+
NumberOfDocks = 1;
225+
}
226+
227+
NumberOfDocks = ini.Get_Int(ini_name, "NumberOfDocks", NumberOfDocks);
228+
229+
for (int i = 0; i < NumberOfDocks; ++i) {
230+
std::snprintf(buffer, sizeof(buffer), "DockingOffset%d", i);
231+
232+
TPoint3D<int> default_value(0, 0, 0);
233+
234+
/**
235+
* Both of these refinerys have artwork specific dock locations. As we have
236+
* reimplemented Docking_Coord, we need to ensure the original positions
237+
* remain unmodified.
238+
*/
239+
if (This()->IsWeeder) {
240+
default_value.X += CELL_LEPTON_W * 2;
241+
default_value.Y += CELL_LEPTON_H;
242+
243+
} else if (This()->IsRefinery) {
244+
default_value.X += CELL_LEPTON_W / 2;
245+
}
246+
247+
TPoint3D<int> offset = ArtINI.Get_Point(graphic_name, buffer, default_value);
248+
DockingOffsets.Add(offset);
249+
}
207250

208251
return true;
209252
}

src/extensions/buildingtype/buildingtypeext.h

+10
Original file line numberDiff line numberDiff line change
@@ -106,4 +106,14 @@ BuildingTypeClassExtension final : public TechnoTypeClassExtension
106106
* Is this building eligible for proximity checks by players who are its owner's allies?
107107
*/
108108
bool IsEligibleForAllyBuilding;
109+
110+
/**
111+
* The number of available docking positions this building has.
112+
*/
113+
unsigned NumberOfDocks;
114+
115+
/**
116+
* The offset(s) from the center of the building for each docking position.
117+
*/
118+
DynamicVectorClass<TPoint3D<int>> DockingOffsets;
109119
};

0 commit comments

Comments
 (0)