Skip to content

Commit

Permalink
Implements TransformsInto for UnitTypes.
Browse files Browse the repository at this point in the history
  • Loading branch information
Rampastring committed Feb 10, 2023
1 parent 850f118 commit a6f7676
Show file tree
Hide file tree
Showing 5 changed files with 471 additions and 2 deletions.
117 changes: 117 additions & 0 deletions src/extensions/house/houseext_hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,12 @@
#include "house.h"
#include "housetype.h"
#include "technotype.h"
#include "buildingtype.h"
#include "techno.h"
#include "factory.h"
#include "super.h"
#include "unittypeext.h"
#include "extension.h"
#include "fatal.h"
#include "debughandler.h"
#include "asserthandler.h"
Expand Down Expand Up @@ -154,6 +159,116 @@ DECLARE_PATCH(_HouseClass_Can_Build_BuildCheat_Patch)
}


/**
* #issue-715
*
* Gets the number of queued objects when determining whether a cameo
* should be disabled.
*
* Author: Rampastring
*/
int _HouseClass_ShouldDisableCameo_Get_Queued_Count(FactoryClass* factory, TechnoTypeClass* technotype)
{
int count = factory->Total_Queued(*technotype);
TechnoClass* factoryobject = factory->Get_Object();

if (factoryobject == nullptr || count == 0) {
return 0;
}

/**
* Check that the factory is trying to create the object that the player is trying to queue
* If not, we don't need to mess with the count
*/
if (factoryobject->Techno_Type_Class() != technotype) {
return count;
}

/**
* #issue-715
*
* If the object can transform into another object through our special logic,
* then check that doing so doesn't allow circumventing build limits
*/
if (technotype->What_Am_I() == RTTI_UNITTYPE) {
UnitTypeClass* unittype = reinterpret_cast<UnitTypeClass*>(technotype);
UnitTypeClassExtension* unittypeext = Extension::Fetch<UnitTypeClassExtension>(unittype);

if (unittype->DeploysInto == nullptr && unittypeext->TransformsInto != nullptr) {
count += factory->House->UQuantity.Count_Of((UnitType)(unittypeext->TransformsInto->Get_Heap_ID()));
}
}

return count;
}


/**
* #issue-715
*
* Updates the build limit logic with unit queuing to
* take our unit transformation logic into account.
*/
DECLARE_PATCH(_HouseClass_ShouldDisableCameo_BuildLimit_Fix)
{
GET_REGISTER_STATIC(FactoryClass*, factory, ecx);
GET_REGISTER_STATIC(TechnoTypeClass*, technotype, esi);
static int queuedcount;

queuedcount = _HouseClass_ShouldDisableCameo_Get_Queued_Count(factory, technotype);

_asm { mov eax, [queuedcount] }
JMP_REG(ecx, 0x004CB77D);
}


/**
* #issue-715
*
* Take vehicles that can transform into other vehicles into acccount when
* determining whether a build limit has been met/exceeded.
* Otherwise these kinds of units could be used to bypass build limits
* (build a limited vehicle, transform it, now you can build another vehicle).
*
* Author: Rampastring
*/
DECLARE_PATCH(_HouseClass_Can_Build_BuildLimit_Handle_Vehicle_Transform)
{
GET_REGISTER_STATIC(UnitTypeClass*, unittype, edi);
GET_REGISTER_STATIC(HouseClass*, house, ebp);
static UnitTypeClassExtension* unittypeext;
static int objectcount;

unittypeext = Extension::Fetch<UnitTypeClassExtension>(unittype);

/**
* Stolen bytes / code.
*/
objectcount = house->UQuantity.Count_Of((UnitType)unittype->Get_Heap_ID());

/**
* Check whether this unit can deploy into a building.
* If it can, increment the object count by the number of buildings.
*/
if (unittype->DeploysInto != nullptr) {
objectcount += house->BQuantity.Count_Of((BuildingType)unittype->DeploysInto->Get_Heap_ID());
}
else if (unittypeext->TransformsInto != nullptr) {

/**
* This unit can transform into another unit, increment the object count
* by the number of transformed units.
*/
objectcount += house->UQuantity.Count_Of((UnitType)(unittypeext->TransformsInto->Get_Heap_ID()));
}

_asm { mov esi, objectcount }

continue_function:
JMP(0x004BC1B9);
}


/**
* Main function for patching the hooks.
*/
Expand All @@ -166,4 +281,6 @@ void HouseClassExtension_Hooks()

Patch_Jump(0x004BBD26, &_HouseClass_Can_Build_BuildCheat_Patch);
Patch_Jump(0x004BD30B, &_HouseClass_Super_Weapon_Handler_InstantRecharge_Patch);
Patch_Jump(0x004CB777, &_HouseClass_ShouldDisableCameo_BuildLimit_Fix);
Patch_Jump(0x004BC187, _HouseClass_Can_Build_BuildLimit_Handle_Vehicle_Transform);
}
53 changes: 53 additions & 0 deletions src/extensions/techno/technoext_hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
#include "infantry.h"
#include "infantrytype.h"
#include "infantrytypeext.h"
#include "unittype.h"
#include "unittypeext.h"
#include "voc.h"
#include "vinifera_util.h"
#include "extension.h"
Expand Down Expand Up @@ -684,6 +686,56 @@ DECLARE_PATCH(_TechnoClass_Null_House_Warning_Patch)
}


/**
* #issue-356
*
* Enables the deploy keyboard command to work for units that
* transform into a different unit on deploy.
*
* @author: Rampastring
*/
DECLARE_PATCH(_TechnoClass_2A0_Is_Allowed_To_Deploy_Unit_Transform_Patch)
{
GET_REGISTER_STATIC(UnitTypeClass*, unittype, eax);
static UnitTypeClassExtension* unittypeext;

/**
* Stolen bytes/code.
*/
if (unittype->DeploysInto != nullptr) {
goto has_deploy_ability;

} else if (unittype->MaxPassengers > 0) {
goto has_deploy_ability;

} else if (unittype->IsMobileEMP) {
goto has_deploy_ability;
}

unittypeext = Extension::Fetch<UnitTypeClassExtension>(unittype);

if (unittypeext->TransformsInto != nullptr) {
goto has_deploy_ability;
}

/**
* The unit has no ability that allows it to deploy / unload.
* Mark that and continue function after the check.
*/
has_no_deploy_ability:
_asm { mov eax, unittype }
JMP_REG(ecx, 0x006320E0);

/**
* The unit has some kind of an ability that allows it to deploy / unload.
* Continue function after the check.
*/
has_deploy_ability:
_asm { mov eax, unittype }
JMP_REG(ecx, 0x006320E5);
}


/**
* Main function for patching the hooks.
*/
Expand All @@ -703,4 +755,5 @@ void TechnoClassExtension_Hooks()
Patch_Jump(0x00630390, &_TechnoClass_Fire_At_Suicide_Patch);
Patch_Jump(0x00631223, &_TechnoClass_Fire_At_Electric_Bolt_Patch);
Patch_Jump(0x00636F09, &_TechnoClass_Is_Allowed_To_Retaliate_Can_Retaliate_Patch);
Patch_Jump(0x006320C2, &_TechnoClass_2A0_Is_Allowed_To_Deploy_Unit_Transform_Patch);
}

0 comments on commit a6f7676

Please sign in to comment.