Skip to content

Commit

Permalink
Adds specific case for buildings with IsNavalYard when the AI is sear…
Browse files Browse the repository at this point in the history
…ching for a suitable building location.
  • Loading branch information
CCHyper committed May 3, 2022
1 parent ac5c82e commit 3af0745
Showing 1 changed file with 80 additions and 0 deletions.
80 changes: 80 additions & 0 deletions src/extensions/house/houseext_hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@
#include "housetype.h"
#include "technotype.h"
#include "super.h"
#include "building.h"
#include "buildingtype.h"
#include "buildingtypeext.h"
#include "rules.h"
#include "rulesext.h"
#include "iomap.h"
#include "fatal.h"
#include "debughandler.h"
#include "asserthandler.h"
Expand All @@ -41,6 +47,76 @@
#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 HouseClassExt final : public HouseClass
{
public:
Cell _Find_Build_Location(BuildingTypeClass *buildingtype, int (__fastcall *callback)(int, Cell &, int, int), int a3 = -1);
};


/**
* #issue-531
*
* Interception of Find_Build_Location. This allows us to find a suitable building
* location for the specific buildings, such as the Naval Yard.
*
* @author: CCHyper
*/
Cell HouseClassExt::_Find_Build_Location(BuildingTypeClass *buildingtype, int (__fastcall *callback)(int, Cell &, int, int), int a3)
{
/**
* Find the type class extension instance.
*/
BuildingTypeClassExtension *buildingtypeext = BuildingTypeClassExtensions.find(buildingtype);
if (buildingtypeext && buildingtypeext->IsNavalYard) {

if (RulesExtension) {

BuildingTypeClass *desired_navalyard = Get_First_Ownable(RulesExtension->BuildNavalYard);
ASSERT_PRINT(desired_navalyard != nullptr, "Failed to find a ownable building in BuildNavalYard list!");

int navalyard_width = desired_navalyard->Width() + 2;
int navalyard_height = desired_navalyard->Height() + 2;

Cell found_cell = Map.Nearby_Location(Coord_Cell(Center), SPEED_FOOT, -1, MZONE_NORMAL, 0, navalyard_width, navalyard_height);
if (found_cell) {

if (ConstructionYards.Count() > 0) {
BuildingClass *conyard = ConstructionYards.Fetch_Head();
if (conyard) {

Coordinate conyard_coord = conyard->Center_Coord();
Coordinate found_coord = Map[found_cell].Center_Coord();

if (Distance(conyard_coord, found_coord) > Cell_To_Lepton(RulesExtension->AINavalYardAdjacency)) {
return Cell(0,0);
}

}

}

}

return found_cell;
}

}

/**
* Call the original function to find a location for land buildings.
*/
return HouseClass::Find_Build_Location(buildingtype, callback, a3);
}


/**
* Patch for InstantSuperRechargeCommandClass
*
Expand Down Expand Up @@ -167,4 +243,8 @@ void HouseClassExtension_Hooks()

Patch_Jump(0x004BBD26, &_HouseClass_Can_Build_BuildCheat_Patch);
Patch_Jump(0x004BD30B, &_HouseClass_Super_Weapon_Handler_InstantRecharge_Patch);

Patch_Call(0x0042D460, &HouseClassExt::_Find_Build_Location);
Patch_Call(0x0042D53C, &HouseClassExt::_Find_Build_Location);
Patch_Call(0x004C8104, &HouseClassExt::_Find_Build_Location);
}

0 comments on commit 3af0745

Please sign in to comment.