Skip to content

Commit 60a5181

Browse files
authored
[Minor] Extended ExtendedAircraftMissions (#1654)
- Aircraft will now be able to use waypoints. - When a `guard` command (`[G]` by default) is issued, the aircraft will search for targets around the current location and return immediately when target is not found, target is destroyed or ammos are depleted. - If the target is destroyed but ammos are not depleted yet, it will also return because the aircraft's command is one-time. - When an `attack move` command (`[Ctrl]+[Shift]`) is issued, the aircraft will move towards the destination and search for nearby targets on the route for attack. Once ammo is depleted or the destination is reached, it will return. - If the automatically selected target is destroyed but ammo is not depleted yet during the process, the aircraft will continue flying to the destination. - In addition, the actions of aircraft are also changed. - `ExtendedAircraftMissions.SmoothMoving` controls whether the aircraft will return to the airport when the distance to the destination is less than half of `SlowdownDistance` or its turning radius. - `ExtendedAircraftMissions.EarlyDescend` controls whether the aircraft not have to fly directly above the airport before starting to descend when the distance between the aircraft and the landing point is less than `SlowdownDistance` (also work for aircraft spawned by aircraft carriers). - `ExtendedAircraftMissions.RearApproach` controls whether the aircraft should start landing at the airport from the opposite direction of `LandingDir`. In `rulesmd.ini`: ```ini [General] ExtendedAircraftMissions=false ; boolean [SOMEAIRCRAFT] ; AircraftType ExtendedAircraftMissions.SmoothMoving= ; boolean, default to [General] -> ExtendedAircraftMissions ExtendedAircraftMissions.EarlyDescend= ; boolean, default to [General] -> ExtendedAircraftMissions ExtendedAircraftMissions.RearApproach= ; boolean, default to [General] -> ExtendedAircraftMissions ``` --- ![landing](https://github.com/user-attachments/assets/859012d5-4131-4708-b539-cefb1f62da37)
1 parent 02f017a commit 60a5181

File tree

5 files changed

+215
-34
lines changed

5 files changed

+215
-34
lines changed

docs/Fixed-or-Improved-Logics.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,16 +275,24 @@ FiringForceScatter=true ; boolean
275275
### Extended Aircraft Missions
276276

277277
- Aircraft will now be able to use waypoints.
278-
- Aircraft can fly at a certain speed as much as possible, when the distance to the destination is less than half of `SlowdownDistance` or 8 cell distances divided by `ROT`, it will return to the airport. And now aircraft not have to fly directly above the airport before starting to descend.
279278
- When a `guard` command (`[G]` by default) is issued, the aircraft will search for targets around the current location and return immediately when target is not found, target is destroyed or ammos are depleted.
280279
- If the target is destroyed but ammos are not depleted yet, it will also return because the aircraft's command is one-time.
281280
- When an `attack move` command (`[Ctrl]+[Shift]`) is issued, the aircraft will move towards the destination and search for nearby targets on the route for attack. Once ammo is depleted or the destination is reached, it will return.
282281
- If the automatically selected target is destroyed but ammo is not depleted yet during the process, the aircraft will continue flying to the destination.
282+
- In addition, the actions of aircraft are also changed.
283+
- `ExtendedAircraftMissions.SmoothMoving` controls whether the aircraft will return to the airport when the distance to the destination is less than half of `SlowdownDistance` or its turning radius.
284+
- `ExtendedAircraftMissions.EarlyDescend` controls whether the aircraft not have to fly directly above the airport before starting to descend when the distance between the aircraft and the landing point is less than `SlowdownDistance` (also work for aircraft spawned by aircraft carriers).
285+
- `ExtendedAircraftMissions.RearApproach` controls whether the aircraft should start landing at the airport from the opposite direction of `LandingDir`.
283286

284287
In `rulesmd.ini`:
285288
```ini
286289
[General]
287-
ExtendedAircraftMissions=false ; boolean
290+
ExtendedAircraftMissions=false ; boolean
291+
292+
[SOMEAIRCRAFT] ; AircraftType
293+
ExtendedAircraftMissions.SmoothMoving= ; boolean, default to [General] -> ExtendedAircraftMissions
294+
ExtendedAircraftMissions.EarlyDescend= ; boolean, default to [General] -> ExtendedAircraftMissions
295+
ExtendedAircraftMissions.RearApproach= ; boolean, default to [General] -> ExtendedAircraftMissions
288296
```
289297

290298
### Fixed spawn distance & spawn height for airstrike / SpyPlane aircraft

src/Ext/Aircraft/Hooks.cpp

Lines changed: 185 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -298,21 +298,27 @@ DEFINE_HOOK(0x414C0B, AircraftClass_ChronoSparkleDelay, 0x5)
298298

299299
DEFINE_HOOK(0x4CF31C, FlyLocomotionClass_FlightUpdate_LandingDir, 0x9)
300300
{
301-
enum { SkipGameCode = 0x4CF351 };
301+
enum { SkipGameCode = 0x4CF3D0, SetSecondaryFacing = 0x4CF351 };
302302

303-
GET(FootClass**, pLinkedToPtr, ESI);
303+
GET(FootClass** const, pFootPtr, ESI);
304+
GET_STACK(IFlyControl* const, iFly, STACK_OFFSET(0x48, -0x38));
304305
REF_STACK(unsigned int, dir, STACK_OFFSET(0x48, 0x8));
305306

306-
auto const pLinkedTo = *pLinkedToPtr;
307+
const auto pFoot = *pFootPtr;
307308
dir = 0;
308309

309-
if (pLinkedTo->CurrentMission == Mission::Enter || pLinkedTo->GetMapCoords() == CellClass::Coord2Cell(pLinkedTo->Locomotor->Destination()))
310-
{
311-
if (auto const pAircraft = abstract_cast<AircraftClass*, true>(pLinkedTo))
312-
dir = DirStruct(AircraftExt::GetLandingDir(pAircraft)).Raw;
313-
}
310+
if (!iFly)
311+
return SetSecondaryFacing;
314312

315-
return SkipGameCode;
313+
if (iFly->Is_Locked())
314+
return SkipGameCode;
315+
316+
if (const auto pAircraft = abstract_cast<AircraftClass*, true>(pFoot))
317+
dir = DirStruct(AircraftExt::GetLandingDir(pAircraft)).Raw;
318+
else
319+
dir = (iFly->Landing_Direction() << 13);
320+
321+
return SetSecondaryFacing;
316322
}
317323

318324
namespace SeparateAircraftTemp
@@ -329,11 +335,10 @@ DEFINE_HOOK(0x446F57, BuildingClass_GrandOpening_PoseDir_SetContext, 0x6)
329335
return 0;
330336
}
331337

332-
DirType _fastcall AircraftClass_PoseDir_Wrapper(AircraftClass* pThis)
338+
DirType __fastcall AircraftClass_PoseDir_Wrapper(AircraftClass* pThis)
333339
{
334340
return AircraftExt::GetLandingDir(pThis, SeparateAircraftTemp::pBuilding);
335341
}
336-
337342
DEFINE_FUNCTION_JUMP(CALL, 0x446F67, AircraftClass_PoseDir_Wrapper); // BuildingClass_GrandOpening
338343

339344
DEFINE_HOOK(0x443FC7, BuildingClass_ExitObject_PoseDir1, 0x8)
@@ -352,7 +357,10 @@ DEFINE_HOOK(0x44402E, BuildingClass_ExitObject_PoseDir2, 0x5)
352357
GET(AircraftClass*, pAircraft, EBP);
353358

354359
auto dir = DirStruct(AircraftExt::GetLandingDir(pAircraft, pThis));
355-
// pAircraft->PrimaryFacing.SetCurrent(dir);
360+
361+
if (RulesExt::Global()->ExtendedAircraftMissions)
362+
pAircraft->PrimaryFacing.SetCurrent(dir);
363+
356364
pAircraft->SecondaryFacing.SetCurrent(dir);
357365

358366
return 0;
@@ -399,23 +407,31 @@ DEFINE_HOOK(0x416A0A, AircraftClass_Mission_Move_SmoothMoving, 0x5)
399407
GET(AircraftClass* const, pThis, ESI);
400408
GET(CoordStruct* const, pCoords, EAX);
401409

402-
if (!RulesExt::Global()->ExtendedAircraftMissions)
410+
if (pThis->Team || pThis->Airstrike || pThis->Spawned)
403411
return 0;
404412

405413
const auto pType = pThis->Type;
406414

407-
if (!pType->AirportBound || pThis->Team || pThis->Airstrike || pThis->Spawned)
415+
if (!pType->AirportBound)
416+
return 0;
417+
418+
const auto extendedMissions = RulesExt::Global()->ExtendedAircraftMissions;
419+
420+
if (!TechnoTypeExt::ExtMap.Find(pType)->ExtendedAircraftMissions_SmoothMoving.Get(extendedMissions))
408421
return 0;
409422

410423
const int distance = Game::F2I(Point2D { pCoords->X, pCoords->Y }.DistanceFrom(Point2D { pThis->Location.X, pThis->Location.Y }));
411424

412425
// When the horizontal distance between the aircraft and its destination is greater than half of its deceleration distance
413426
// or its turning radius, continue to move forward, otherwise return to airbase or execute the next planning waypoint
414-
if (distance > std::max((pType->SlowdownDistance >> 1), (2048 / pType->ROT)))
427+
const auto rotRadian = std::abs(pThis->PrimaryFacing.ROT.Raw * (Math::TwoPi / 65536)); // GetRadian<65536>() is an incorrect method
428+
const auto turningRadius = rotRadian > 1e-10 ? static_cast<int>(pType->Speed / rotRadian) : 0;
429+
430+
if (distance > std::max((pType->SlowdownDistance / 2), turningRadius))
415431
return (R->Origin() == 0x4168C7 ? ContinueMoving1 : ContinueMoving2);
416432

417433
// Try next planning waypoint first, then return to air base if it does not exist or cannot be taken
418-
if (!pThis->TryNextPlanningTokenNode())
434+
if (!extendedMissions || !pThis->TryNextPlanningTokenNode())
419435
pThis->EnterIdleMode(false, true);
420436

421437
return EnterIdleAndReturn;
@@ -436,14 +452,142 @@ DEFINE_HOOK(0x4DDD66, FootClass_IsLandZoneClear_ReplaceHardcode, 0x6) // To avoi
436452
return SkipGameCode;
437453
}
438454

439-
DEFINE_HOOK(0x4CF408, FlyLocomotionClass_FlightUpdate_SetFlightLevel, 0x6) // Make aircraft not have to fly directly above the airport before starting to descend
455+
DEFINE_HOOK(0x4CF190, FlyLocomotionClass_FlightUpdate_SetPrimaryFacing, 0x6) // Make aircraft not to fly directly to the airport before starting to land
440456
{
441-
enum { SkipGameCode = 0x4CF40E };
457+
enum { SkipGameCode = 0x4CF29A };
458+
459+
GET(IFlyControl* const, iFly, EAX);
460+
461+
if (!iFly || !iFly->Is_Locked())
462+
{
463+
GET(FootClass** const, pFootPtr, ESI);
464+
GET(const int, distance, EBX);
465+
466+
const auto pFoot = *pFootPtr;
467+
const auto pAircraft = abstract_cast<AircraftClass*, true>(pFoot);
468+
469+
// Rewrite vanilla implement
470+
if (!pAircraft || !TechnoTypeExt::ExtMap.Find(pAircraft->Type)->ExtendedAircraftMissions_RearApproach.Get(RulesExt::Global()->ExtendedAircraftMissions))
471+
{
472+
REF_STACK(const CoordStruct, destination, STACK_OFFSET(0x48, 0x8));
473+
474+
const auto footCoords = pFoot->GetCoords();
475+
const auto desired = DirStruct(Math::atan2(footCoords.Y - destination.Y, destination.X - footCoords.X));
476+
477+
if (!iFly || !iFly->Is_Strafe() || distance > 768 // I don't know why it's 3 cells' length, but its vanilla, keep it
478+
|| std::abs(static_cast<short>(static_cast<short>(desired.Raw) - static_cast<short>(pFoot->PrimaryFacing.Current().Raw))) >= 8192)
479+
{
480+
pFoot->PrimaryFacing.SetDesired(desired);
481+
}
482+
}
483+
else
484+
{
485+
// No const because it also need to be used by SecondaryFacing
486+
REF_STACK(CoordStruct, destination, STACK_OFFSET(0x48, 0x8));
487+
488+
const auto footCoords = pAircraft->GetCoords();
489+
const auto landingDir = DirStruct(AircraftExt::GetLandingDir(pAircraft));
490+
491+
// Try to land from the rear
492+
if (pAircraft->Destination && (pAircraft->DockNowHeadingTo == pAircraft->Destination || pAircraft->SpawnOwner == pAircraft->Destination))
493+
{
494+
const auto pType = pAircraft->Type;
442495

443-
GET(FlyLocomotionClass* const, pThis, EBP);
444-
GET(TechnoTypeClass* const, pType, EAX);
496+
// Like smooth moving
497+
const auto rotRadian = std::abs(pAircraft->PrimaryFacing.ROT.Raw * (Math::TwoPi / 65536));
498+
const auto turningRadius = rotRadian > 1e-10 ? static_cast<int>(pType->Speed / rotRadian) : 0;
499+
500+
// diameter = 2 * radius
501+
const auto cellCounts = Math::max((pType->SlowdownDistance / 256), (turningRadius / 128));
502+
503+
// The direction of the airport
504+
const auto currentDir = DirStruct(Math::atan2(footCoords.Y - destination.Y, destination.X - footCoords.X));
505+
506+
// Included angle's raw
507+
const auto difference = static_cast<short>(static_cast<short>(currentDir.Raw) - static_cast<short>(landingDir.Raw));
508+
509+
// Land from this direction of the airport
510+
const auto landingFace = landingDir.GetFacing<8>(4);
511+
auto cellOffset = Unsorted::AdjacentCoord[landingFace];
512+
513+
// When the direction is opposite, moving to the side first, then automatically shorten based on the current distance
514+
if (std::abs(difference) >= 12288) // 12288 -> 3/16 * 65536 (1/8 < 3/16 < 1/4, so the landing can begin at the appropriate location)
515+
cellOffset = (cellOffset + Unsorted::AdjacentCoord[((difference > 0) ? (landingFace + 2) : (landingFace - 2)) & 7]) * cellCounts;
516+
else // 724 -> 512√2
517+
cellOffset *= Math::min(cellCounts, ((landingFace & 1) ? (distance / 724) : (distance / 512)));
518+
519+
// On the way back, increase the offset value of the destination so that it looks like a real airplane
520+
destination.X += cellOffset.X;
521+
destination.Y += cellOffset.Y;
522+
}
523+
524+
if (footCoords.Y != destination.Y && footCoords.X != destination.X)
525+
pAircraft->PrimaryFacing.SetDesired(DirStruct(Math::atan2(footCoords.Y - destination.Y, destination.X - footCoords.X)));
526+
else
527+
pAircraft->PrimaryFacing.SetDesired(landingDir);
528+
}
529+
}
530+
531+
return SkipGameCode;
532+
}
533+
534+
DEFINE_HOOK(0x4CF3D0, FlyLocomotionClass_FlightUpdate_SetFlightLevel, 0x7) // Make aircraft not have to fly directly above the airport before starting to descend
535+
{
536+
GET(FootClass** const, pFootPtr, ESI);
537+
538+
const auto pAircraft = abstract_cast<AircraftClass*, true>(*pFootPtr);
539+
540+
if (!pAircraft)
541+
return 0;
542+
543+
const auto pType = pAircraft->Type;
544+
545+
// Ares hook
546+
if (pType->HunterSeeker)
547+
return 0;
548+
549+
if (!TechnoTypeExt::ExtMap.Find(pType)->ExtendedAircraftMissions_EarlyDescend.Get(RulesExt::Global()->ExtendedAircraftMissions))
550+
return 0;
551+
552+
enum { SkipGameCode = 0x4CF4D2 };
553+
554+
GET_STACK(FlyLocomotionClass* const, pThis, STACK_OFFSET(0x48, -0x28));
555+
GET(const int, distance, EBX);
556+
557+
// Restore skipped code
558+
R->EBP(pThis);
559+
560+
// Same as vanilla
561+
if (pThis->IsElevating && distance < 768)
562+
{
563+
// Fast descent
564+
const auto floorHeight = MapClass::Instance.GetCellFloorHeight(pThis->MovingDestination);
565+
pThis->FlightLevel = pThis->MovingDestination.Z - floorHeight;
566+
567+
// Bug fix
568+
if (MapClass::Instance.GetCellAt(pAircraft->Location)->ContainsBridge() && pThis->FlightLevel >= CellClass::BridgeHeight)
569+
pThis->FlightLevel -= CellClass::BridgeHeight;
570+
571+
return SkipGameCode;
572+
}
573+
574+
const auto flightLevel = pType->GetFlightLevel();
575+
576+
// Check returning actions
577+
if (distance < pType->SlowdownDistance && pAircraft->Destination
578+
&& (pAircraft->DockNowHeadingTo == pAircraft->Destination || pAircraft->SpawnOwner == pAircraft->Destination))
579+
{
580+
// Slow descent
581+
const auto floorHeight = MapClass::Instance.GetCellFloorHeight(pThis->MovingDestination);
582+
const auto destinationHeight = pThis->MovingDestination.Z - floorHeight + 1;
583+
pThis->FlightLevel = static_cast<int>((flightLevel - destinationHeight) * (static_cast<double>(distance) / pType->SlowdownDistance)) + destinationHeight;
584+
}
585+
else
586+
{
587+
// Horizontal flight
588+
pThis->FlightLevel = flightLevel;
589+
}
445590

446-
R->ECX(RulesExt::Global()->ExtendedAircraftMissions && pThis->LinkedTo->CurrentMission == Mission::Enter || pType->IsDropship);
447591
return SkipGameCode;
448592
}
449593

@@ -461,13 +605,26 @@ DEFINE_HOOK(0x41A96C, AircraftClass_Mission_AreaGuard, 0x6)
461605

462606
if (pThis->TargetAndEstimateDamage(coords, ThreatType::Area))
463607
pThis->QueueMission(Mission::Attack, false);
608+
else if (pThis->Destination && pThis->Destination != pThis->DockNowHeadingTo)
609+
pThis->EnterIdleMode(false, true);
464610

465611
return SkipGameCode;
466612
}
467613

468614
return 0;
469615
}
470616

617+
// Sleep: return to airbase if in incorrect sleep status
618+
int __fastcall AircraftClass_Mission_Sleep(AircraftClass* pThis)
619+
{
620+
if (!pThis->Destination || pThis->Destination == pThis->DockNowHeadingTo)
621+
return 450; // Vanilla MissionClass_Mission_Sleep value
622+
623+
pThis->EnterIdleMode(false, true);
624+
return 1;
625+
}
626+
DEFINE_FUNCTION_JUMP(VTABLE, 0x7E24A8, AircraftClass_Mission_Sleep)
627+
471628
// AttackMove: return when no ammo or arrived destination
472629
bool __fastcall AircraftTypeClass_CanAttackMove(AircraftTypeClass* pThis)
473630
{
@@ -582,12 +739,9 @@ DEFINE_HOOK(0x4C7403, EventClass_Execute_AircraftAreaGuard, 0x6)
582739

583740
GET(TechnoClass* const, pTechno, EDI);
584741

585-
if (RulesExt::Global()->ExtendedAircraftMissions && pTechno->WhatAmI() == AbstractType::Aircraft)
742+
if (RulesExt::Global()->ExtendedAircraftMissions
743+
&& pTechno->WhatAmI() == AbstractType::Aircraft)
586744
{
587-
// If we're on dock reloading but have ammo, untether from dock and try to scan for targets.
588-
if (pTechno->CurrentMission == Mission::Sleep && pTechno->Ammo)
589-
pTechno->SendToEachLink(RadioCommand::NotifyUnlink);
590-
591745
// Skip assigning destination / target here.
592746
return SkipGameCode;
593747
}
@@ -603,9 +757,12 @@ DEFINE_HOOK(0x4C72F2, EventClass_Execute_AircraftAreaGuard_Untether, 0x6)
603757
GET(EventClass* const, pThis, ESI);
604758
GET(TechnoClass* const, pTechno, EDI);
605759

606-
if (RulesExt::Global()->ExtendedAircraftMissions && pTechno->WhatAmI() == AbstractType::Aircraft
607-
&& pThis->MegaMission.Mission == (char)Mission::Area_Guard)
760+
if (RulesExt::Global()->ExtendedAircraftMissions
761+
&& pTechno->WhatAmI() == AbstractType::Aircraft
762+
&& pThis->MegaMission.Mission == (char)Mission::Area_Guard
763+
&& (pTechno->CurrentMission != Mission::Sleep || !pTechno->Ammo))
608764
{
765+
// If we're on dock reloading but have ammo, untether from dock and try to scan for targets.
609766
return SkipGameCode;
610767
}
611768

src/Ext/TechnoType/Body.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -638,12 +638,16 @@ void TechnoTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI)
638638
this->Overload_ParticleSys.Read(exINI, pSection, "Overload.ParticleSys");
639639
this->Overload_ParticleSysCount.Read(exINI, pSection, "Overload.ParticleSysCount");
640640

641-
this->FallingDownDamage.Read(exINI, pSection, "FallingDownDamage");
642-
this->FallingDownDamage_Water.Read(exINI, pSection, "FallingDownDamage.Water");
643-
644641
this->Harvester_CanGuardArea.Read(exINI, pSection, "Harvester.CanGuardArea");
645642
this->HarvesterScanAfterUnload.Read(exINI, pSection, "HarvesterScanAfterUnload");
646643

644+
this->ExtendedAircraftMissions_SmoothMoving.Read(exINI, pSection, "ExtendedAircraftMissions.SmoothMoving");
645+
this->ExtendedAircraftMissions_EarlyDescend.Read(exINI, pSection, "ExtendedAircraftMissions.EarlyDescend");
646+
this->ExtendedAircraftMissions_RearApproach.Read(exINI, pSection, "ExtendedAircraftMissions.RearApproach");
647+
648+
this->FallingDownDamage.Read(exINI, pSection, "FallingDownDamage");
649+
this->FallingDownDamage_Water.Read(exINI, pSection, "FallingDownDamage.Water");
650+
647651
this->FiringForceScatter.Read(exINI, pSection, "FiringForceScatter");
648652

649653
// Ares 0.2
@@ -1215,6 +1219,10 @@ void TechnoTypeExt::ExtData::Serialize(T& Stm)
12151219
.Process(this->Harvester_CanGuardArea)
12161220
.Process(this->HarvesterScanAfterUnload)
12171221

1222+
.Process(this->ExtendedAircraftMissions_SmoothMoving)
1223+
.Process(this->ExtendedAircraftMissions_EarlyDescend)
1224+
.Process(this->ExtendedAircraftMissions_RearApproach)
1225+
12181226
.Process(this->FallingDownDamage)
12191227
.Process(this->FallingDownDamage_Water)
12201228

src/Ext/TechnoType/Body.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,10 @@ class TechnoTypeExt
359359
Valueable<bool> Harvester_CanGuardArea;
360360
Nullable<bool> HarvesterScanAfterUnload;
361361

362+
Nullable<bool> ExtendedAircraftMissions_SmoothMoving;
363+
Nullable<bool> ExtendedAircraftMissions_EarlyDescend;
364+
Nullable<bool> ExtendedAircraftMissions_RearApproach;
365+
362366
Valueable<double> FallingDownDamage;
363367
Nullable<double> FallingDownDamage_Water;
364368

@@ -678,6 +682,10 @@ class TechnoTypeExt
678682
, Harvester_CanGuardArea { false }
679683
, HarvesterScanAfterUnload {}
680684

685+
, ExtendedAircraftMissions_SmoothMoving {}
686+
, ExtendedAircraftMissions_EarlyDescend {}
687+
, ExtendedAircraftMissions_RearApproach {}
688+
681689
, FallingDownDamage { 1.0 }
682690
, FallingDownDamage_Water {}
683691

src/Misc/Hooks.BugFixes.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1153,7 +1153,7 @@ DEFINE_HOOK(0x73ED66, UnitClass_Mission_Harvest_PathfindingFix, 0x5)
11531153

11541154
#pragma region StopEventFix
11551155

1156-
DEFINE_JUMP(LJMP, 0x4C756B, 0x4C757D); // Skip cell under bridge check
1156+
DEFINE_JUMP(LJMP, 0x4C752A, 0x4C757D); // Skip cell under bridge check
11571157

11581158
DEFINE_HOOK(0x4C75DA, EventClass_RespondToEvent_Stop, 0x6)
11591159
{

0 commit comments

Comments
 (0)