Skip to content

Commit c41d279

Browse files
committed
Fix subterranean harvester pathfinding
1 parent 02da3f9 commit c41d279

8 files changed

+136
-17
lines changed

Phobos.vcxproj

+1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
<ClCompile Include="src\Ext\TEvent\Body.cpp" />
6464
<ClCompile Include="src\Ext\Trigger\Hooks.cpp" />
6565
<ClCompile Include="src\Ext\Unit\Hooks.Crushing.cpp" />
66+
<ClCompile Include="src\Ext\Unit\Hooks.Harvester.cpp" />
6667
<ClCompile Include="src\Locomotion\TestLocomotionClass.cpp" />
6768
<ClCompile Include="src\Misc\Hooks.Gamespeed.cpp" />
6869
<ClCompile Include="src\Misc\Hooks.Ares.cpp" />

docs/Fixed-or-Improved-Logics.md

+1
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ This page describes all ingame logics that are fixed or improved in Phobos witho
190190
- Allowed `AuxBuilding` to count building upgrades.
191191
- Fix the bug that parasite will vanish if it missed its target when its previous cell is occupied.
192192
- Prevent the units with locomotors that cause problems from entering the tank bunker.
193+
- Fixed `MovementZone=Subterannean` harvesters being unable to find docks if in area enclosed by water, cliffs etc.
193194

194195
## Fixes / interactions with other extensions
195196

docs/Whats-New.md

+1
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,7 @@ Vanilla fixes:
330330
- Aircraft will now behave as expected according to it's `MovementZone` and `SpeedType` when moving onto different surfaces. In particular, this fixes erratic behavior when vanilla aircraft is ordered to move onto water surface and instead the movement order changes to a shore nearby (by CrimRecya)
331331
- Fix the bug that parasite will vanish if it missed its target when its previous cell is occupied (by 航味麻酱)
332332
- Prevent the units with locomotors that cause problems from entering the tank bunker (by TaranDahl)
333+
- Fixed `MovementZone=Subterannean` harvesters being unable to find docks if in area enclosed by water, cliffs etc.
333334

334335
Phobos fixes:
335336
- Type conversion on Warheads and Superweapons will no longer recursively convert units if applicable conversion pairs are listed, and only first applicable pair takes effect (by Starkku)

src/Ext/Techno/Body.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,8 @@ void TechnoExt::ExtData::Serialize(T& Stm)
485485
.Process(this->LaserTrails)
486486
.Process(this->AttachedEffects)
487487
.Process(this->AE)
488+
.Process(this->SubterraneanHarvFreshFromFactory)
489+
.Process(this->SubterraneanHarvRallyDest)
488490
.Process(this->ReceiveDamage)
489491
.Process(this->PassengerDeletionTimer)
490492
.Process(this->CurrentShieldType)

src/Ext/Techno/Body.h

+4
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ class TechnoExt
2828
std::vector<LaserTrailClass> LaserTrails;
2929
std::vector<std::unique_ptr<AttachEffectClass>> AttachedEffects;
3030
AttachEffectTechnoProperties AE;
31+
bool SubterraneanHarvFreshFromFactory;
32+
AbstractClass* SubterraneanHarvRallyDest;
3133
bool ReceiveDamage;
3234
bool LastKillWasTeamTarget;
3335
CDTimerClass PassengerDeletionTimer;
@@ -66,6 +68,8 @@ class TechnoExt
6668
, LaserTrails {}
6769
, AttachedEffects {}
6870
, AE {}
71+
, SubterraneanHarvFreshFromFactory { false }
72+
, SubterraneanHarvRallyDest { nullptr }
6973
, ReceiveDamage { false }
7074
, LastKillWasTeamTarget { false }
7175
, PassengerDeletionTimer {}

src/Ext/Techno/Hooks.Misc.cpp

+32
Original file line numberDiff line numberDiff line change
@@ -455,4 +455,36 @@ DEFINE_HOOK(0x70FB73, FootClass_IsBunkerableNow_Dehardcode, 0x6)
455455
auto const pTypeExt = TechnoTypeExt::ExtMap.Find(pType);
456456
return pTypeExt->BunkerableAnyway ? CanEnter : 0;
457457
}
458+
458459
#pragma endregion
460+
461+
// issue #112 Make FireOnce=yes work on other TechnoTypes
462+
// Author: Starkku
463+
DEFINE_HOOK(0x4C7512, EventClass_Execute_StopCommand, 0x6)
464+
{
465+
GET(TechnoClass* const, pThis, ESI);
466+
467+
auto const pUnit = abstract_cast<UnitClass*>(pThis);
468+
469+
if (pUnit)
470+
{
471+
// Reset target for deploy weapons.
472+
if (pUnit->CurrentMission == Mission::Unload && pUnit->Type->DeployFire && !pUnit->Type->IsSimpleDeployer)
473+
{
474+
pUnit->SetTarget(nullptr);
475+
pThis->QueueMission(Mission::Guard, true);
476+
}
477+
478+
auto const pType = pUnit->Type;
479+
480+
// Reset subterranean harvester rally point info.
481+
if ((pType->Harvester || pType->Weeder) && pType->MovementZone == MovementZone::Subterrannean)
482+
{
483+
auto const pExt = TechnoExt::ExtMap.Find(pUnit);
484+
pExt->SubterraneanHarvFreshFromFactory = false;
485+
pExt->SubterraneanHarvRallyDest = nullptr;
486+
}
487+
}
488+
489+
return 0;
490+
}

src/Ext/Unit/Hooks.DeployFire.cpp

+1-17
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,7 @@
33
#include <Ext/Techno/Body.h>
44
#include <Utilities/Macro.h>
55

6-
// issue #112 Make FireOnce=yes work on other TechnoTypes
7-
// Author: Starkku
8-
DEFINE_HOOK(0x4C7512, EventClass_Execute_StopUnitDeployFire, 0x6)
9-
{
10-
GET(TechnoClass* const, pThis, ESI);
11-
12-
auto const pUnit = abstract_cast<UnitClass*>(pThis);
13-
if (pUnit && pUnit->CurrentMission == Mission::Unload && pUnit->Type->DeployFire && !pUnit->Type->IsSimpleDeployer)
14-
{
15-
pUnit->SetTarget(nullptr);
16-
pThis->QueueMission(Mission::Guard, true);
17-
}
18-
19-
return 0;
20-
}
21-
22-
DEFINE_HOOK(0x4C77E4, EventClass_Execute_UnitDeployFire, 0x6)
6+
DEFINE_HOOK(0x4C77E4, EventClass_Execute_DeployCommand, 0x6)
237
{
248
enum { DoNotExecute = 0x4C8109 };
259

src/Ext/Unit/Hooks.Harvester.cpp

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#include <Ext/Techno/Body.h>
2+
3+
// Hooks that allow harvesters / weeders to work correctly with MovementZone=Subterannean (sic) - Starkku
4+
#pragma region SubterraneanHarvesters
5+
6+
// Allow scanning for docks in all map zones.
7+
DEFINE_HOOK(0x4DEFC6, FootClass_FindDock_SubterraneanHarvester, 0x5)
8+
{
9+
GET(TechnoTypeClass*, pTechnoType, EAX);
10+
11+
if (auto const pUnitType = abstract_cast<UnitTypeClass*>(pTechnoType))
12+
{
13+
if ((pUnitType->Harvester || pUnitType->Weeder) && pUnitType->MovementZone == MovementZone::Subterrannean)
14+
R->ECX(MovementZone::Fly);
15+
}
16+
17+
return 0;
18+
}
19+
20+
// Allow scanning for ore in all map zones.
21+
DEFINE_HOOK(0x4DCF86, FootClass_FindTiberium_SubterraneanHarvester, 0x5)
22+
{
23+
enum { SkipGameCode = 0x4DCF9B };
24+
25+
GET(MovementZone, mZone, ECX);
26+
27+
if (mZone == MovementZone::Subterrannean)
28+
R->ECX(MovementZone::Fly);
29+
30+
return 0;
31+
}
32+
33+
// Allow scanning for weeds in all map zones.
34+
DEFINE_HOOK(0x4DDB23, FootClass_FindWeeds_SubterraneanHarvester, 0x5)
35+
{
36+
enum { SkipGameCode = 0x4DCF9B };
37+
38+
GET(MovementZone, mZone, EAX);
39+
40+
if (mZone == MovementZone::Subterrannean)
41+
R->EAX(MovementZone::Fly);
42+
43+
return 0;
44+
}
45+
46+
// Set rally point.
47+
DEFINE_HOOK(0x44459A, BuildingClass_ExitObject_SubterraneanHarvester, 0x5)
48+
{
49+
GET(TechnoClass*, pThis, EDI);
50+
51+
if (auto const pUnit = abstract_cast<UnitClass*>(pThis))
52+
{
53+
auto const pType = pUnit->Type;
54+
55+
if ((pType->Harvester || pType->Weeder) && pType->MovementZone == MovementZone::Subterrannean)
56+
{
57+
auto const pExt = TechnoExt::ExtMap.Find(pUnit);
58+
pExt->SubterraneanHarvFreshFromFactory = true;
59+
pExt->SubterraneanHarvRallyDest = pUnit->ArchiveTarget;
60+
}
61+
}
62+
63+
return 0;
64+
}
65+
66+
// Handle rally point once idle.
67+
DEFINE_HOOK(0x7389B1, UnitClass_EnterIdleMode_SubterraneanHarvester, 0x6)
68+
{
69+
enum { ReturnFromFunction = 0x738D21 };
70+
71+
GET(UnitClass*, pThis, ESI);
72+
73+
auto const pExt = TechnoExt::ExtMap.Find(pThis);
74+
75+
if (pExt->SubterraneanHarvFreshFromFactory)
76+
{
77+
pThis->SetArchiveTarget(nullptr);
78+
pThis->ClearNavQueue();
79+
80+
if (pThis->Destination && pExt->SubterraneanHarvRallyDest && pThis->Destination != pExt->SubterraneanHarvRallyDest && pThis->DistanceFrom(pThis->Destination) > Unsorted::LeptonsPerCell)
81+
pThis->SetDestination(pExt->SubterraneanHarvRallyDest, false);
82+
else
83+
pThis->SetDestination(nullptr, false);
84+
85+
pExt->SubterraneanHarvFreshFromFactory = false;
86+
pExt->SubterraneanHarvRallyDest = nullptr;
87+
88+
return ReturnFromFunction;
89+
}
90+
91+
return 0;
92+
}
93+
94+
#pragma endregion

0 commit comments

Comments
 (0)