Skip to content

Commit

Permalink
[Minor] [Ares Fix] Ares academy fix (#1456)
Browse files Browse the repository at this point in the history
Bug Description:
This is a fix to the Ares bug: Academy feature doesn't apply to the
initial payload of vehicles built off a War Factory. Curiously, Academy
applies to the initial payloads of vehicles under any other
circumstances, even when built off a Naval Shipyard.

Cause:
It is "Unsorted::IKnowWhatImDoing" prevented the
"HouseExt::ApplyAcademy" from taking effect.

Fix:
The fix is simple, when Ares is supposed to have initialized the initial
payload, and Academy is prevented from taking any effect, temporarily
turn off "Unsorted::IKnowWhatImDoing", invoke "HouseExt::ApplyAcademy",
then turn on "Unsorted::IKnowWhatImDoing" again.

---------

Co-authored-by: Kerbiter <crabiter@vivaldi.net>
  • Loading branch information
Aephiex and Metadorius authored Dec 20, 2024
1 parent f0791ed commit 5ac6ce5
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 0 deletions.
1 change: 1 addition & 0 deletions CREDITS.md
Original file line number Diff line number Diff line change
Expand Up @@ -408,3 +408,4 @@ This page lists all the individual contributions to the project by their author.
- **Damfoos** - extensive and thorough testing
- **Dmitry Volkov** - extensive and thorough testing
- **Rise of the East community** - extensive playtesting of in-dev features
- **Aephiex** - fixed Ares academy not working on the initial payloads of vehicles built from a war factory
1 change: 1 addition & 0 deletions docs/Fixed-or-Improved-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ This page describes all ingame logics that are fixed or improved in Phobos witho
- Fixed an issue introduced by Ares that caused `Grinding=true` building `ActiveAnim` to be incorrectly restored while `SpecialAnim` was playing and the building was sold, erased or destroyed.
- Fixed Ares' Abductor weapon leaves permanent placement stats when abducting moving vehicles.
- Suppressed Ares' swizzle warning when parsing `Tags` and `TaskForces` (typically begin with `[Developer fatal]Pointer 00000000 declared change to both`).
- Fixed Academy *(Ares feature)* not working on the initial payloads *(Ares feature)* of vehicles built from a war factory.

## Aircraft

Expand Down
1 change: 1 addition & 0 deletions docs/Whats-New.md
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,7 @@ Fixes / interactions with other extensions:
- Appended Ares' `SW.Shots` usage to extended tooltips (by Trsdy)
- Fixed Ares' Abductor weapon leaves permanent placement stats when abducting moving vehicles (by Trsdy)
- Suppressed Ares' swizzle warning when parsing `Tags` and `TaskForces` (by Trsdy)
- Fixed Academy *(Ares feature)* not working on the initial payloads *(Ares feature)* of vehicles built from a war factory. (by Aephiex)
</details>
### 0.3.0.1
Expand Down
53 changes: 53 additions & 0 deletions src/Misc/Hooks.BugFixes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <Utilities/Macro.h>
#include <Utilities/Debug.h>
#include <Utilities/TemplateDef.h>
#include <Utilities/AresFunctions.h>

/*
Allow usage of TileSet of 255 and above without making NE-SW broken bridges unrepairable
Expand Down Expand Up @@ -1089,3 +1090,55 @@ size_t __fastcall HexStr2Int_replacement(const char* str)
}
DEFINE_JUMP(CALL, 0x6E8305, GET_OFFSET(HexStr2Int_replacement)); // TaskForce
DEFINE_JUMP(CALL, 0x6E5FA6, GET_OFFSET(HexStr2Int_replacement)); // TagType

// This is the inline function to get the academy type that a techno enjoys.
inline static const AbstractType GetAresAcademyType(TechnoClass* pTechno)
{
if (pTechno->WhatAmI() == AbstractType::Unit)
{
if (pTechno->GetTechnoType()->ConsideredAircraft)
return AbstractType::Aircraft;
else if (pTechno->GetTechnoType()->Organic)
return AbstractType::Infantry;
else
return AbstractType::Unit;
}
else if (pTechno->WhatAmI() == AbstractType::Infantry
|| pTechno->WhatAmI() == AbstractType::Aircraft
|| pTechno->WhatAmI() == AbstractType::Building)
{
return pTechno->WhatAmI();
}
return AbstractType::None;
}

// This is a fix to the Ares bug: Academy feature doesn't apply to the initial payload of vehicles built off a War Factory.
// Curiously, Academy applies to the initial payloads of vehicles under any other circumstances, even when built off a Naval Shipyard.
// It is "Unsorted::IKnowWhatImDoing" prevented the "HouseExt::ApplyAcademy" from taking effect.
// The fix is simple, when Ares is supposed to have initialized the initial payload, and Academy is prevented from taking any effect,
// temporarily turn off "Unsorted::IKnowWhatImDoing", invoke "HouseExt::ApplyAcademy", then turn on "Unsorted::IKnowWhatImDoing" again.
DEFINE_HOOK(0x4D71A0, FootClass_Put_InitialPayload_AfterAres, 0x6)
{
GET(FootClass* const, pThis, ESI);

if (AresFunctions::ApplyAcademy && Unsorted::IKnowWhatImDoing)
{
if (pThis && !pThis->InLimbo && pThis->IsOnMap && pThis->WhatAmI() == AbstractType::Unit
&& pThis->GetTechnoType()->Passengers > 0
&& pThis->Passengers.NumPassengers > 0)
{
for (auto pNext = pThis->Passengers.FirstPassenger; pNext; pNext = abstract_cast<FootClass*>(pNext->NextObject))
{
auto abstractType = GetAresAcademyType(pNext);
if (abstractType != AbstractType::None)
{
--Unsorted::IKnowWhatImDoing;
AresFunctions::ApplyAcademy(AresFunctions::HouseExtMap_Find(pNext->Owner), pNext, abstractType);
++Unsorted::IKnowWhatImDoing;
}
}
}
}

return 0;
}
16 changes: 16 additions & 0 deletions src/Utilities/AresAddressInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@

decltype(AresFunctions::ConvertTypeTo) AresFunctions::ConvertTypeTo = nullptr;
decltype(AresFunctions::SpawnSurvivors) AresFunctions::SpawnSurvivors = nullptr;
decltype(AresFunctions::ApplyAcademy) AresFunctions::ApplyAcademy = nullptr;
std::function<AresSWTypeExtData* (SuperWeaponTypeClass*)> AresFunctions::SWTypeExtMap_Find;
std::function<AresHouseExtData* (HouseClass*)> AresFunctions::HouseExtMap_Find;

void* AresFunctions::_SWTypeExtMap = nullptr;
decltype(AresFunctions::_SWTypeExtMapFind) AresFunctions::_SWTypeExtMapFind = nullptr;
void* AresFunctions::_HouseExtMap = nullptr;
decltype(AresFunctions::_HouseExtMapFind) AresFunctions::_HouseExtMapFind = nullptr;

void Apply_Ares3_0_Patches();
void Apply_Ares3_0p1_Patches();
Expand All @@ -24,10 +28,16 @@ void AresFunctions::InitAres3_0()
else
NOTE_ARES_FUN(SpawnSurvivors, 0x464C0);

NOTE_ARES_FUN(ApplyAcademy, 0x020750);

NOTE_ARES_FUN(_SWTypeExtMapFind, 0x57C70);
NOTE_ARES_FUN(_SWTypeExtMap, 0xC1C54);
SWTypeExtMap_Find = [](SuperWeaponTypeClass* swt) { return _SWTypeExtMapFind(_SWTypeExtMap, swt); };

NOTE_ARES_FUN(_HouseExtMapFind, 0x57C70);
NOTE_ARES_FUN(_HouseExtMap, 0xC1AA8);
HouseExtMap_Find = [](HouseClass* houseClass) { return _HouseExtMapFind(_HouseExtMap, houseClass); };

#ifndef USING_MULTIFINITE_SYRINGE
Apply_Ares3_0_Patches();
#endif
Expand All @@ -44,10 +54,16 @@ void AresFunctions::InitAres3_0p1()
else
NOTE_ARES_FUN(SpawnSurvivors, 0x47030);

NOTE_ARES_FUN(ApplyAcademy, 0x0211D0);

NOTE_ARES_FUN(_SWTypeExtMapFind, 0x58900);
NOTE_ARES_FUN(_SWTypeExtMap, 0xC2C50);
SWTypeExtMap_Find = [](SuperWeaponTypeClass* swt) { return _SWTypeExtMapFind(_SWTypeExtMap, swt); };

NOTE_ARES_FUN(_HouseExtMapFind, 0x589A0);
NOTE_ARES_FUN(_HouseExtMap, 0xC2B08);
HouseExtMap_Find = [](HouseClass* houseClass) { return _HouseExtMapFind(_HouseExtMap, houseClass); };

#ifndef USING_MULTIFINITE_SYRINGE
Apply_Ares3_0p1_Patches();
#endif
Expand Down
9 changes: 9 additions & 0 deletions src/Utilities/AresFunctions.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once
#include <functional>
#include <GeneralDefinitions.h>
class TechnoClass;
class TechnoTypeClass;
class FootClass;
Expand All @@ -24,12 +25,20 @@ class AresFunctions
static bool(__stdcall* ConvertTypeTo)(TechnoClass* pFoot, TechnoTypeClass* pConvertTo);

static void(__stdcall* SpawnSurvivors)(FootClass* pThis, TechnoClass* pKiller, bool Select, bool IgnoreDefenses);

static void(__thiscall* ApplyAcademy)(void*, TechnoClass* pTechno, AbstractType considerAs);

static std::function<AresSWTypeExtData* (SuperWeaponTypeClass*)> SWTypeExtMap_Find;

static std::function<AresHouseExtData* (HouseClass*)> HouseExtMap_Find;

private:
static constexpr bool _maybe = false;

static constexpr bool AresWasWrongAboutSpawnSurvivors = _maybe;

static void* _SWTypeExtMap;
static void* _HouseExtMap;
static AresSWTypeExtData* (__thiscall* _SWTypeExtMapFind)(void*, SuperWeaponTypeClass*);
static AresHouseExtData* (__thiscall* _HouseExtMapFind)(void*, HouseClass*);
};

0 comments on commit 5ac6ce5

Please sign in to comment.