Skip to content

[Vanilla Fix] Fix BalloonHover incorrectly considering ground factors when pathfinding #1661

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 17 commits 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
1 change: 1 addition & 0 deletions CREDITS.md
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,7 @@ This page lists all the individual contributions to the project by their author.
- Make harvesters do addtional scan after unload
- Customize the scatter caused by aircraft attack mission
- Customize whether `Crater=yes` animation would destroy tiberium
- Fix BalloonHover incorrectly considering ground factors when pathfinding
- **tyuah8**:
- Drive/Jumpjet/Ship/Teleport locomotor did not power on when it is un-piggybacked bugfix
- Destroyed unit leaves sensors bugfix
Expand Down
1 change: 1 addition & 0 deletions docs/Fixed-or-Improved-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ This page describes all ingame logics that are fixed or improved in Phobos witho
- Infantry support `IsGattling=yes`.
- Fixed the issue that the widespread damage caused by detonation on the bridge/ground cannot affect objects on the ground/bridge who are in the opposite case.
- Fixed the bug that `DamageSelf` and `AllowDamageOnSelf` are ineffective on airforce.
- Fixed the bug where technos with `BalloonHover=yes` incorrectly considered ground factors when setting the destination and distributing moving commands. If you don't want this anyway, use `[General]->BalloonHoverPathingFix=false` to disable this fix.

## Fixes / interactions with other extensions

Expand Down
1 change: 1 addition & 0 deletions docs/Whats-New.md
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@ Vanilla fixes:
- Second weapon with `ElectricAssault=yes` will not unconditionally attack your building with `Overpowerable=yes` (by FlyStar)
- Fixed the issue that the widespread damage caused by detonation on the bridge/ground cannot affect objects on the ground/bridge who are in the opposite case (by CrimRecya)
- Fixed the bug that `DamageSelf` and `AllowDamageOnSelf` are ineffective on airforce (by NetsuNegi)
- Fix BalloonHover incorrectly considering ground factors when pathfinding (by TaranDahl)

Phobos fixes:
- Fixed the bug that `AllowAirstrike=no` cannot completely prevent air strikes from being launched against it (by NetsuNegi)
Expand Down
5 changes: 5 additions & 0 deletions src/Ext/Rules/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,9 @@ void RulesExt::ExtData::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI)

this->AnimCraterDestroyTiberium.Read(exINI, GameStrings::General, "AnimCraterDestroyTiberium");

this->BalloonHoverPathingFix.Read(exINI, GameStrings::General, "BalloonHoverPathingFix");
Phobos::Optimizations::DisableBalloonHoverPathingFix = !this->BalloonHoverPathingFix;

// Section AITargetTypes
int itemsCount = pINI->GetKeyCount("AITargetTypes");
for (int i = 0; i < itemsCount; ++i)
Expand Down Expand Up @@ -501,6 +504,7 @@ void RulesExt::ExtData::Serialize(T& Stm)
.Process(this->DamagedSpeed)
.Process(this->HarvesterScanAfterUnload)
.Process(this->AnimCraterDestroyTiberium)
.Process(this->BalloonHoverPathingFix)
;
}

Expand All @@ -510,6 +514,7 @@ void RulesExt::ExtData::LoadFromStream(PhobosStreamReader& Stm)
this->Serialize(Stm);

this->ReplaceVoxelLightSources();
Phobos::Optimizations::DisableBalloonHoverPathingFix = !this->BalloonHoverPathingFix;
}

void RulesExt::ExtData::SaveToStream(PhobosStreamWriter& Stm)
Expand Down
4 changes: 4 additions & 0 deletions src/Ext/Rules/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,8 @@ class RulesExt

Valueable<bool> AnimCraterDestroyTiberium;

Valueable<bool> BalloonHoverPathingFix;

ExtData(RulesClass* OwnerObject) : Extension<RulesClass>(OwnerObject)
, Storage_TiberiumIndex { -1 }
, HarvesterDumpAmount { 0.0f }
Expand Down Expand Up @@ -401,6 +403,8 @@ class RulesExt
, HarvesterScanAfterUnload { false }

, AnimCraterDestroyTiberium { true }

, BalloonHoverPathingFix { false }
{ }

virtual ~ExtData() = default;
Expand Down
73 changes: 73 additions & 0 deletions src/Misc/Hooks.BugFixes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2196,3 +2196,76 @@ DEFINE_HOOK(0x489E47, DamageArea_RockerItemsFix2, 0x6)
}

#pragma region


#pragma region BalloonHoverPathingFix

DEFINE_HOOK(0x64D592, Game_PreProcessMegaMissionList_CheckForTargetCrdRecal1, 0x6)
{
enum { SkipTargetCrdRecal = 0x64D598 };
GET(TechnoClass*, pTechno, EBP);
return pTechno->GetTechnoType()->BalloonHover ? SkipTargetCrdRecal : 0;
}

DEFINE_HOOK(0x64D575, Game_PreProcessMegaMissionList_CheckForTargetCrdRecal2, 0x6)
{
enum { SkipTargetCrdRecal = 0x64D598 };
GET(TechnoClass*, pTechno, EBP);
return pTechno->GetTechnoType()->BalloonHover ? SkipTargetCrdRecal : 0;
}

DEFINE_HOOK(0x64D5C5, Game_PreProcessMegaMissionList_CheckForTargetCrdRecal3, 0x6)
{
enum { SkipTargetCrdRecal = 0x64D659 };
GET(TechnoClass*, pTechno, EBP);
return pTechno->GetTechnoType()->BalloonHover ? SkipTargetCrdRecal : 0;
}

DEFINE_HOOK(0x51BFA2, InfantryClass_IsCellOccupied_Start, 0x6)
{
enum { MoveOK = 0x51C02D };
GET(InfantryClass*, pThis, EBP);
return pThis->Type->BalloonHover && pThis->IsInAir() ? MoveOK : 0;
}

DEFINE_HOOK(0x73F0A7, UnitClass_IsCellOccupied_Start, 0x9)
{
enum { MoveOK = 0x73F23F };
GET(UnitClass*, pThis, ECX);
return pThis->Type->BalloonHover && pThis->IsInAir() ? MoveOK : 0;
}

namespace ApproachTargetContext
{
bool IsBalloonHover = false;
}

DEFINE_HOOK(0x4D5690, FootClass_ApproachTarget_SetContext, 0x6)
{
GET(FootClass*, pThis, ECX);
ApproachTargetContext::IsBalloonHover = pThis->GetTechnoType()->BalloonHover;
return 0;
}

DEFINE_HOOK_AGAIN(0x4D5A42, FootClass_ApproachTarget_ResetContext, 0x5);
DEFINE_HOOK_AGAIN(0x4D5AB5, FootClass_ApproachTarget_ResetContext, 0x5);
DEFINE_HOOK_AGAIN(0x4D68DE, FootClass_ApproachTarget_ResetContext, 0x5);
DEFINE_HOOK_AGAIN(0x4D6A8B, FootClass_ApproachTarget_ResetContext, 0x5);
DEFINE_HOOK(0x4D5744, FootClass_ApproachTarget_ResetContext, 0x5)
{
ApproachTargetContext::IsBalloonHover = false;
return 0;
}

DEFINE_HOOK(0x4834A0, CellClass_IsClearToMove_Start, 0x5)
{
if (ApproachTargetContext::IsBalloonHover)
{
R->AL(true);
return 0x483605;
}

return 0;
}

#pragma endregion
12 changes: 12 additions & 0 deletions src/Phobos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ bool Phobos::DisplayDamageNumbers = false;
bool Phobos::IsLoadingSaveGame = false;

bool Phobos::Optimizations::Applied = false;
bool Phobos::Optimizations::DisableBalloonHoverPathingFix = false;
bool Phobos::Optimizations::DisableRadDamageOnBuildings = true;
bool Phobos::Optimizations::DisableSyncLogging = false;

Expand Down Expand Up @@ -269,6 +270,17 @@ void Phobos::ApplyOptimizations()
if (Phobos::Optimizations::DisableRadDamageOnBuildings)
Patch::Apply_RAW(0x43FB23, { 0x53, 0x55, 0x56, 0x8B, 0xF1 });

// Disable BalloonHover path finding fix
if (Phobos::Optimizations::DisableBalloonHoverPathingFix)
{
Patch::Apply_RAW(0x64D592, { 0x0F, 0x8F, 0xB8, 0x00, 0x00, 0x00 });
Patch::Apply_RAW(0x64D575, { 0x0F, 0x8F, 0xD5, 0x00, 0x00, 0x00 });
Patch::Apply_RAW(0x64D5C5, { 0x8A, 0x44, 0x24, 0x13, 0x84, 0xC0 });
Patch::Apply_RAW(0x51BFA2, { 0x85, 0x99, 0x40, 0x01, 0x00, 0x00 });
Patch::Apply_RAW(0x73F0A7, { 0x8B, 0xD9, 0x8B, 0x8C, 0x24, 0x88, 0x00, 0x00, 0x00 });
Patch::Apply_RAW(0x4D5690, { 0x55, 0x8B, 0xEC, 0x83, 0xE4, 0xF8 });
}

if (SessionClass::IsMultiplayer())
{
// Disable MainLoop_SaveGame
Expand Down
1 change: 1 addition & 0 deletions src/Phobos.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ class Phobos
{
public:
static bool Applied;
static bool DisableBalloonHoverPathingFix;
static bool DisableRadDamageOnBuildings;
static bool DisableSyncLogging;
};
Expand Down