-
-
Notifications
You must be signed in to change notification settings - Fork 111
[Highly Customized] Optimize aircrafts actions #1366
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
Changes from all commits
218fa3b
a2d91cb
6157437
d855e1d
05c8cc5
a59956b
5d8f4d9
6481cc1
77847a6
ce00c49
e35eac3
d28d175
8943f30
96c5482
3f27ca2
2b5dd08
4e1d14c
a9635b5
283f0a9
245b52d
9c07122
1249ec7
5a631ec
71d4545
48f5129
acee930
3f72785
4cfe4d8
723463b
02dd0bd
11d8147
5118bc0
14dbf03
841cb51
d553698
5028b7b
445b1ac
a452dcc
17325e2
a1c2169
6f94f86
4175056
5ea6f11
464cca9
d1542fb
d4a4250
396f982
c3cf57f
92b2d8c
f15b1b8
5a7fb09
9b188f5
7670926
83376da
d7f98de
5f508b8
673927b
becf4a6
6d91e3a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
+1 −1 | BuildingClass.h | |
+3 −2 | BuildingTypeClass.h | |
+2 −1 | BulletClass.h | |
+12 −15 | DisplayClass.h | |
+10 −9 | FootClass.h | |
+1 −1 | MissionClass.h | |
+1 −1 | PowerClass.h | |
+3 −0 | README.md | |
+3 −0 | SidebarClass.h | |
+19 −20 | TechnoClass.h | |
+7 −8 | WWMouseClass.h |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -318,6 +318,179 @@ DEFINE_HOOK(0x415EEE, AircraftClass_Fire_KickOutPassengers, 0x6) | |
return SkipKickOutPassengers; | ||
} | ||
|
||
// Aircraft mission hard code are all disposable that no ammo, target died or arrived destination all will call the aircraft return airbase | ||
#pragma region ExtendedAircraftMissions | ||
|
||
// Waypoint: enable and smooth moving action | ||
bool __fastcall AircraftTypeClass_CanUseWaypoint(AircraftTypeClass* pThis) | ||
{ | ||
return RulesExt::Global()->ExtendedAircraftMissions.Get(); | ||
} | ||
DEFINE_JUMP(VTABLE, 0x7E2908, GET_OFFSET(AircraftTypeClass_CanUseWaypoint)) | ||
|
||
// KickOut: skip useless tether | ||
DEFINE_JUMP(LJMP, 0x444021, 0x44402E) | ||
|
||
// Move: smooth the planning paths and returning route | ||
DEFINE_HOOK_AGAIN(0x4168C7, AircraftClass_Mission_Move_SmoothMoving, 0x5) | ||
DEFINE_HOOK(0x416A0A, AircraftClass_Mission_Move_SmoothMoving, 0x5) | ||
{ | ||
enum { EnterIdleAndReturn = 0x416AC0, ContinueMoving1 = 0x416908, ContinueMoving2 = 0x416A47 }; | ||
|
||
GET(AircraftClass* const, pThis, ESI); | ||
GET(CoordStruct* const, pCoords, EAX); | ||
|
||
if (!RulesExt::Global()->ExtendedAircraftMissions) | ||
return 0; | ||
|
||
const auto pType = pThis->Type; | ||
|
||
if (!pType->AirportBound || pThis->Team || pThis->Airstrike || pThis->Spawned) | ||
return 0; | ||
|
||
const int distance = Game::F2I(Point2D { pCoords->X, pCoords->Y }.DistanceFrom(Point2D { pThis->Location.X, pThis->Location.Y })); | ||
|
||
// When the horizontal distance between the aircraft and its destination is greater than half of its deceleration distance | ||
// or its turning radius, continue to move forward, otherwise return to airbase or execute the next planning path | ||
if (distance > std::max((pType->SlowdownDistance >> 1), (2048 / pType->ROT))) | ||
return (R->Origin() == 0x4168C7 ? ContinueMoving1 : ContinueMoving2); | ||
|
||
pThis->EnterIdleMode(false, true); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For example an easy but nasty way to "avoid" this is to add remaining waypoints check before enteridlemode. But it's probably not correct. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Normally |
||
|
||
return EnterIdleAndReturn; | ||
} | ||
|
||
// AreaGuard: return when no ammo or first target died | ||
DEFINE_HOOK_AGAIN(0x41A982, AircraftClass_Mission_AreaGuard, 0x6) | ||
DEFINE_HOOK(0x41A96C, AircraftClass_Mission_AreaGuard, 0x6) | ||
{ | ||
enum { SkipGameCode = 0x41A97A }; | ||
|
||
GET(AircraftClass* const, pThis, ESI); | ||
|
||
if (RulesExt::Global()->ExtendedAircraftMissions && !pThis->Team && pThis->Ammo && pThis->IsArmed()) | ||
{ | ||
auto coords = pThis->GetCoords(); | ||
|
||
if (pThis->TargetAndEstimateDamage(coords, ThreatType::Area)) | ||
{ | ||
pThis->QueueMission(Mission::Attack, false); | ||
return SkipGameCode; | ||
} | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
// AttackMove: return when no ammo or arrived destination | ||
bool __fastcall AircraftTypeClass_CanAttackMove(AircraftTypeClass* pThis) | ||
{ | ||
return RulesExt::Global()->ExtendedAircraftMissions.Get(); | ||
} | ||
DEFINE_JUMP(VTABLE, 0x7E290C, GET_OFFSET(AircraftTypeClass_CanAttackMove)) | ||
|
||
DEFINE_HOOK(0x6FA68B, TechnoClass_Update_AttackMovePaused, 0xA) // To make aircrafts not search for targets while resting at the airport, this is designed to adapt to loop waypoint | ||
{ | ||
enum { SkipGameCode = 0x6FA6F5 }; | ||
|
||
GET(TechnoClass* const, pThis, ESI); | ||
|
||
const bool skip = RulesExt::Global()->ExtendedAircraftMissions | ||
&& pThis->WhatAmI() == AbstractType::Aircraft | ||
&& (!pThis->Ammo || !pThis->IsInAir()); | ||
|
||
return skip ? SkipGameCode : 0; | ||
} | ||
|
||
DEFINE_HOOK(0x4DF3BA, FootClass_UpdateAttackMove_AircraftHoldAttackMoveTarget1, 0x6) // When it have MegaDestination | ||
{ | ||
enum { LoseTarget = 0x4DF3D3, HoldTarget = 0x4DF4AB }; | ||
|
||
GET(FootClass* const, pThis, ESI); | ||
|
||
// The aircraft is constantly moving, which may cause its target to constantly enter and leave its range, so it is fixed to hold the target. | ||
if (RulesExt::Global()->ExtendedAircraftMissions && pThis->WhatAmI() == AbstractType::Aircraft) | ||
return HoldTarget; | ||
|
||
return pThis->InAuxiliarySearchRange(pThis->Target) ? HoldTarget : LoseTarget; | ||
} | ||
|
||
DEFINE_HOOK(0x4DF42A, FootClass_UpdateAttackMove_AircraftHoldAttackMoveTarget2, 0x6) // When it have MegaTarget | ||
{ | ||
enum { ContinueCheck = 0x4DF462, HoldTarget = 0x4DF4AB }; | ||
|
||
GET(FootClass* const, pThis, ESI); | ||
|
||
// Although if the target selected by CS is an object rather than cell. | ||
return (RulesExt::Global()->ExtendedAircraftMissions && pThis->WhatAmI() == AbstractType::Aircraft) ? HoldTarget : ContinueCheck; | ||
} | ||
|
||
DEFINE_HOOK(0x418CD1, AircraftClass_Mission_Attack_ContinueFlyToDestination, 0x6) | ||
{ | ||
enum { Continue = 0x418C43, Return = 0x418CE8 }; | ||
|
||
GET(AircraftClass* const, pThis, ESI); | ||
|
||
if (!pThis->Target) | ||
{ | ||
if (!RulesExt::Global()->ExtendedAircraftMissions || !pThis->MegaMissionIsAttackMove() || !pThis->MegaDestination) | ||
return Continue; | ||
|
||
pThis->SetDestination(pThis->MegaDestination, false); | ||
pThis->QueueMission(Mission::Move, true); | ||
pThis->HaveAttackMoveTarget = false; | ||
} | ||
else | ||
{ | ||
pThis->MissionStatus = 1; | ||
} | ||
|
||
R->EAX(1); | ||
return Return; | ||
} | ||
|
||
// Idle: clear the target if no ammo | ||
DEFINE_HOOK(0x414D4D, AircraftClass_Update_ClearTargetIfNoAmmo, 0x6) | ||
Metadorius marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
enum { ClearTarget = 0x414D3F }; | ||
|
||
GET(AircraftClass* const, pThis, ESI); | ||
|
||
if (RulesExt::Global()->ExtendedAircraftMissions && !pThis->Ammo && !pThis->Airstrike && !pThis->Spawned) | ||
{ | ||
if (!SessionClass::IsCampaign()) // To avoid AI's aircrafts team repeatedly attempting to attack the target when no ammo | ||
{ | ||
if (const auto pTeam = pThis->Team) | ||
pTeam->LiberateMember(pThis); | ||
} | ||
|
||
return ClearTarget; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
// Stop: clear the mega mission and return to airbase immediately | ||
// (StopEventFix's DEFINE_HOOK(0x4C75DA, EventClass_RespondToEvent_Stop, 0x6) in Hooks.BugFixes.cpp) | ||
|
||
// GreatestThreat: for all the mission that should let the aircraft auto select a target | ||
AbstractClass* __fastcall AircraftClass_GreatestThreat(AircraftClass* pThis, void* _, ThreatType threatType, CoordStruct* pSelectCoords, bool onlyTargetHouseEnemy) | ||
{ | ||
if (RulesExt::Global()->ExtendedAircraftMissions) | ||
{ | ||
if (const auto pPrimaryWeapon = pThis->GetWeapon(0)->WeaponType) | ||
threatType |= pPrimaryWeapon->AllowedThreats(); | ||
|
||
if (const auto pSecondaryWeapon = pThis->GetWeapon(1)->WeaponType) | ||
threatType |= pSecondaryWeapon->AllowedThreats(); | ||
} | ||
|
||
return pThis->FootClass::GreatestThreat(threatType, pSelectCoords, onlyTargetHouseEnemy); | ||
} | ||
DEFINE_JUMP(VTABLE, 0x7E2668, GET_OFFSET(AircraftClass_GreatestThreat)) | ||
|
||
#pragma endregion | ||
|
||
static __forceinline bool CheckSpyPlaneCameraCount(AircraftClass* pThis) | ||
{ | ||
auto const pExt = TechnoExt::ExtMap.Find(pThis); | ||
|
Uh oh!
There was an error while loading. Please reload this page.