Skip to content

Commit

Permalink
Implements NumberOfDocks and DockingOffset for BuildingTypes.
Browse files Browse the repository at this point in the history
  • Loading branch information
CCHyper committed May 1, 2022
1 parent 90024e8 commit d1f4d86
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 2 deletions.
67 changes: 67 additions & 0 deletions src/extensions/building/buildingext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "building.h"
#include "buildingtype.h"
#include "buildingtypeext.h"
#include "tibsun_inline.h"
#include "house.h"
#include "housetype.h"
#include "wwcrc.h"
Expand Down Expand Up @@ -172,6 +173,7 @@ void BuildingClassExtension::Compute_CRC(WWCRCEngine &crc) const
crc(ProduceCashTimer());
}


/**
* #issue-26
*
Expand Down Expand Up @@ -286,3 +288,68 @@ void BuildingClassExtension::Produce_Cash_AI()
}

}


/**
* Fetches the coordinate to use for docking.
*
* @author: CCHyper
*/
Coordinate BuildingClassExtension::Docking_Coord() const
{
ASSERT(ThisPtr != nullptr);
//EXT_DEBUG_TRACE("BuildingClassExtension::Docking_Coord - Name: %s (0x%08X)\n", ThisPtr->Name(), (uintptr_t)(ThisPtr));

DEBUG_WARNING("BuildingClassExtension::Docking_Coord() enter\n");

if (ThisPtr->Class->IsWeeder) {
Cell cell = ThisPtr->Get_Cell();
cell.X += 2;
cell.Y += 1;
Coordinate coord = Cell_Coord(cell, true);
coord.Z = ThisPtr->Get_Coord().Z;
return coord;
}

if (ThisPtr->Class->IsRefinery) {
Coordinate coord = ThisPtr->Center_Coord();
coord.X += CELL_LEPTON_W/2;
return coord;
}

DEBUG_WARNING("We at least got here!\n");

/**
* #issue-786
*
* Implements DockingOffset for BuildingTypes (currently limited to Helipads).
*
* @author: CCHyper
*/
BuildingTypeClassExtension *buildingtypeext = BuildingTypeClassExtensions.find(ThisPtr->Class);

DEBUG_WARNING("buildingtypeext == %p\n", buildingtypeext);

if (buildingtypeext && buildingtypeext->NumberOfDocks > 0) {

DEBUG_WARNING("Building %s has NumberOfDocks=%d, with DockingOffset0=%d,%d,%d\n",
ThisPtr->Name(),
buildingtypeext->NumberOfDocks,
buildingtypeext->DockingOffsets[0].X,
buildingtypeext->DockingOffsets[0].Y,
buildingtypeext->DockingOffsets[0].Z
);

if (ThisPtr->Class->IsHelipad) {
Coordinate coord = ThisPtr->Center_Coord();
TPoint3D<int> docking_offset = buildingtypeext->DockingOffsets[0];
coord.X += docking_offset.X;
coord.Y += docking_offset.Y;
coord.Z += docking_offset.Z;
return coord;
}

}

return ThisPtr->Docking_Coord();
}
1 change: 1 addition & 0 deletions src/extensions/building/buildingext.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class BuildingClassExtension final : public Extension<BuildingClass>
virtual void Compute_CRC(WWCRCEngine &crc) const override;

void Produce_Cash_AI();
Coordinate Docking_Coord() const;

public:
/**
Expand Down
43 changes: 43 additions & 0 deletions src/extensions/building/buildingext_hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,39 @@
#include "hooker_macros.h"


/**
* A fake class for implementing new member functions which allow
* access to the "this" pointer of the intended class.
*
* @note: This must not contain a constructor or destructor!
* @note: All functions must be prefixed with "_" to prevent accidental virtualization.
*/
class BuildingClassExt final : public BuildingClass
{
public:
Coordinate _Docking_Coord() const;
};


/**
* Reimplementation of BuildingClass::Docking_Coord.
*
* @author: CCHyper
*/
Coordinate BuildingClassExt::_Docking_Coord() const
{
DEBUG_WARNING("BuildingClassExt::_Docking_Coord()\n");
BuildingClassExtension *buildingext = BuildingClassExtensions.find(this);
if (buildingext) {
DEBUG_WARNING("calling BuildingClassExtension::Docking_Coord()\n");
return buildingext->Docking_Coord();
} else {
DEBUG_WARNING("calling BuildingClass::Docking_Coord()\n");
return BuildingClass::Docking_Coord();
}
}


/**
* #issue-26
*
Expand Down Expand Up @@ -493,4 +526,14 @@ void BuildingClassExtension_Hooks()
Patch_Jump(0x00429A96, &_BuildingClass_AI_ProduceCash_Patch);
Patch_Jump(0x0042F67D, &_BuildingClass_Captured_ProduceCash_Patch);
Patch_Jump(0x0042E179, &_BuildingClass_Grand_Opening_ProduceCash_Patch);

void ** addr = ((void **)0x006CC3A0);
DEBUG_WARNING("0x006CC3A0 before %p\n", *addr);

Patch_Dword(0x006CC3A0, Get_Func_Address(&BuildingClassExt::_Docking_Coord));

addr = ((void **)0x006CC3A0);
DEBUG_WARNING("0x006CC3A0 after %p\n", *addr);

DEBUG_WARNING("BuildingClassExt::_Docking_Coord = %p\n", Get_Func_Address(&BuildingClassExt::_Docking_Coord));
}
28 changes: 27 additions & 1 deletion src/extensions/buildingtype/buildingtypeext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ BuildingTypeClassExtension::BuildingTypeClassExtension(BuildingTypeClass *this_p
ProduceCashBudget(0),
IsStartupCashOneTime(false),
IsResetBudgetOnCapture(false),
IsEligibleForAllyBuilding(false)
IsEligibleForAllyBuilding(false),
NumberOfDocks(0),
DockingOffsets()
{
ASSERT(ThisPtr != nullptr);
//EXT_DEBUG_TRACE("BuildingTypeClassExtension constructor - Name: %s (0x%08X)\n", ThisPtr->Name(), (uintptr_t)(ThisPtr));
Expand Down Expand Up @@ -167,6 +169,8 @@ void BuildingTypeClassExtension::Compute_CRC(WWCRCEngine &crc) const
//EXT_DEBUG_TRACE("BuildingTypeClassExtension::Compute_CRC - Name: %s (0x%08X)\n", ThisPtr->Name(), (uintptr_t)(ThisPtr));

crc(IsEligibleForAllyBuilding);
crc(NumberOfDocks);
crc(DockingOffsets.Count());
}


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

char buffer[1024];

const char *ini_name = ThisPtr->Name();
const char *graphic_name = ThisPtr->Graphic_Name();

if (!ini.Is_Present(ini_name)) {
return false;
}

//if (!ArtINI.Is_Present(graphic_name)) {
// return false;
//}

/**
* The following structures have at least one docking location.
*/
if (ThisPtr->IsHelipad) {
NumberOfDocks = 1;
}

GateUpSound = ini.Get_VocType(ini_name, "GateUpSound", GateUpSound);
GateDownSound = ini.Get_VocType(ini_name, "GateDownSound", GateDownSound);

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

IsEligibleForAllyBuilding = ini.Get_Bool(ini_name, "EligibleForAllyBuilding",
ThisPtr->IsConstructionYard ? true : IsEligibleForAllyBuilding);

NumberOfDocks = ini.Get_Int(ini_name, "NumberOfDocks", NumberOfDocks);

for (int i = 0; i < NumberOfDocks; ++i) {
std::snprintf(buffer, sizeof(buffer), "DockingOffset%d", i);
TPoint3D<int> offset = ArtINI.Get_Point(graphic_name, buffer, TPoint3D<int>(0,0,0));
DockingOffsets.Add(offset);
}

return true;
}
11 changes: 11 additions & 0 deletions src/extensions/buildingtype/buildingtypeext.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

#include "extension.h"
#include "container.h"
#include "tpoint.h"


class BuildingTypeClass;
Expand Down Expand Up @@ -96,6 +97,16 @@ class BuildingTypeClassExtension final : public Extension<BuildingTypeClass>
* Is this building eligible for proximity checks by players who are its owner's allies?
*/
bool IsEligibleForAllyBuilding;

/**
* The number of available docking positions this building has.
*/
unsigned NumberOfDocks;

/**
* The offset(s) from the center of the building for each docking position.
*/
DynamicVectorClass<TPoint3D<int>> DockingOffsets;
};


Expand Down
1 change: 0 additions & 1 deletion src/extensions/ext_hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,6 @@ void Extension_Hooks()
//TagTypeClassExtension_Hooks();
//TriggerTypeClassExtension_Hooks();

TechnoClassExtension_Hooks();
UnitClassExtension_Hooks();
AircraftClassExtension_Hooks();
InfantryClassExtension_Hooks();
Expand Down

0 comments on commit d1f4d86

Please sign in to comment.