Skip to content

Implements NumberOfDocks and DockingOffset# for BuildingTypes. #790

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
46 changes: 46 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 @@ -178,6 +179,7 @@ void BuildingClassExtension::Compute_CRC(WWCRCEngine &crc) const
crc(ProduceCashTimer());
}


/**
* #issue-26
*
Expand Down Expand Up @@ -291,3 +293,47 @@ void BuildingClassExtension::Produce_Cash_AI()
}

}


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

Coordinate coord = This()->Center_Coord();

/**
* #issue-786
*
* Implements DockingOffset for BuildingTypes (currently limited to Helipads and Refinerys).
*
* @author: CCHyper
*/
BuildingTypeClassExtension *buildingtypeext = Extension::Fetch<BuildingTypeClassExtension>(This()->Class);

if (buildingtypeext->NumberOfDocks > 0) {

if (This()->Class->IsRefinery || This()->Class->IsWeeder) {
TPoint3D<int> docking_offset = buildingtypeext->DockingOffsets[0];
coord.X += docking_offset.X;
coord.Y += docking_offset.Y;
coord.Z += docking_offset.Z;
return coord;
}

if (This()->Class->IsHelipad) {
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 coord;
}
1 change: 1 addition & 0 deletions src/extensions/building/buildingext.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ BuildingClassExtension final : public TechnoClassExtension
virtual RTTIType What_Am_I() const override { return RTTI_BUILDING; }

void Produce_Cash_AI();
Coordinate Docking_Coord() const;

public:
/**
Expand Down
27 changes: 27 additions & 0 deletions src/extensions/building/buildingext_hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,32 @@
#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
{
BuildingClassExtension *buildingext = Extension::Fetch<BuildingClassExtension>(this);
return buildingext->Docking_Coord();
}


/**
* #issue-204
*
Expand Down Expand Up @@ -514,4 +540,5 @@ void BuildingClassExtension_Hooks()
Patch_Jump(0x0042E179, &_BuildingClass_Grand_Opening_ProduceCash_Patch);
Patch_Jump(0x004325F9, &_BuildingClass_Mission_Repair_ReloadRate_Patch);
Patch_Jump(0x0043266C, &_BuildingClass_Mission_Repair_ReloadRate_Patch);
Patch_Dword(0x006CC3A0, Get_Func_Address(&BuildingClassExt::_Docking_Coord));
}
45 changes: 44 additions & 1 deletion src/extensions/buildingtype/buildingtypeext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
******************************************************************************/
#include "buildingtypeext.h"
#include "buildingtype.h"
#include "tibsun_globals.h"
#include "tibsun_defines.h"
#include "ccini.h"
#include "wwcrc.h"
Expand All @@ -50,7 +51,9 @@ BuildingTypeClassExtension::BuildingTypeClassExtension(const BuildingTypeClass *
ProduceCashBudget(0),
IsStartupCashOneTime(false),
IsResetBudgetOnCapture(false),
IsEligibleForAllyBuilding(false)
IsEligibleForAllyBuilding(false),
NumberOfDocks(0),
DockingOffsets()
{
//if (this_ptr) EXT_DEBUG_TRACE("BuildingTypeClassExtension::BuildingTypeClassExtension - Name: %s (0x%08X)\n", Name(), (uintptr_t)(This()));

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

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


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

char buffer[1024];

const char *ini_name = Name();
const char *graphic_name = Graphic_Name();

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

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

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

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

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> default_value(0, 0, 0);

/**
* Both of these refinerys have artwork specific dock locations. As we have
* reimplemented Docking_Coord, we need to ensure the original positions
* remain unmodified.
*/
if (This()->IsWeeder) {
default_value.X += CELL_LEPTON_W * 2;
default_value.Y += CELL_LEPTON_H;

} else if (This()->IsRefinery) {
default_value.X += CELL_LEPTON_W / 2;
}

TPoint3D<int> offset = ArtINI.Get_Point(graphic_name, buffer, default_value);
DockingOffsets.Add(offset);
}

return true;
}
10 changes: 10 additions & 0 deletions src/extensions/buildingtype/buildingtypeext.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,14 @@ BuildingTypeClassExtension final : public TechnoTypeClassExtension
* 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;
};