diff --git a/CREDITS.md b/CREDITS.md index da4121daac..c19a52a688 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -221,6 +221,7 @@ This page lists all the individual contributions to the project by their author. - Fire particle rotation coordinate adjust toggle - `AmbientDamage` warhead & main target ignore customization - Projectile return weapon + - Aircraft landing / docking direction - **Morton (MortonPL)**: - `XDrawOffset` for animations - Shield passthrough & absorption diff --git a/docs/Fixed-or-Improved-Logics.md b/docs/Fixed-or-Improved-Logics.md index a592bec4bb..466b3ce6bf 100644 --- a/docs/Fixed-or-Improved-Logics.md +++ b/docs/Fixed-or-Improved-Logics.md @@ -145,6 +145,7 @@ This page describes all ingame logics that are fixed or improved in Phobos witho - Fixed `AmbientDamage` when used with `IsRailgun=yes` being cut off by elevation changes. - Fixed railgun and fire particles being cut off by elevation changes. - Fixed teleport units' (for example CLEG) frozen-still timer being cleared after load game. +- Aircraft docking on buildings now respect `[AudioVisual]`->`PoseDir` as the default setting and do not always land facing north or in case of pre-placed buildings, the building's direction. ## Fixes / interactions with other extensions @@ -165,6 +166,17 @@ SpawnDistanceFromTarget= ; floating point value, distance in cells SpawnHeight= ; integer, height in leptons ``` +### Landing direction + +- By default aircraft land facing the direction specified by `[AudioVisual]`->`PoseDir`. This can now be customized per AircraftType via `LandingDir`, defaults to `[AudioVisual]`->`PoseDir`. If the building the aircraft is docking to has [aircraft docking direction](#aircraft-docking-direction) set, that setting takes priority over this. + - Negative values are allowed as a special case for `AirportBound=false` aircraft which makes them land facing their current direction. + +In `rulesmd.ini`: +```ini +[SOMEAIRCRAFT] ; AircraftType +LandingDir= ; Direction type (integers from 0-255). Accepts negative values as a special case. +``` + ## Animations ### Animation weapon and damage settings @@ -239,6 +251,16 @@ HideIfNoOre.Threshold=0 ; integer, minimal ore growth stage ## Buildings +### Aircraft docking direction + +- It is now possible to customize the landing direction for docking aircraft via `AircraftDockingDir` on the dock building. This overrides the aircraft's own [landing direction](#landing-direction) setting and defaults to `[AudioVisual]` -> `PoseDir`. + +In `rulesmd.ini`: +```ini +[SOMEBUILDING] ; BuildingType +AircraftDockingDir= ; Direction type (integers from 0-255) +``` + ### Airstrike target eligibility - By default whether or not a building can be targeted by airstrikes depends on value of `CanC4`, which also affects other things. This can now be changed independently by setting `AllowAirstrike`. If not set, defaults to value of `CanC4`. diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index c798c02969..35e76a1be1 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -266,7 +266,7 @@ CreateUnit= ; VehicleType CreateUnit.Owner=Victim ; Owner house kind, Invoker/Killer/Victim/Civilian/Special/Neutral/Random CreateUnit.RemapAnim=false ; boolean CreateUnit.Mission=Guard ; MissionType -CreateUnit.Facing=0 ; integer, facings in range of 0-255 +CreateUnit.Facing=0 ; Direction type (integers from 0-255) CreateUnit.RandomFacing=true ; boolean CreateUnit.InheritFacings=false ; boolean CreateUnit.InheritTurretFacings=false ; boolean diff --git a/docs/Whats-New.md b/docs/Whats-New.md index 52978445c7..e4645c9626 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -357,6 +357,7 @@ New: - `AmbientDamage` warhead & main target ignore customization (by Starkku) - Flashing Technos on selecting (by Fryone) - Projectile return weapon (by Starkku) +- Allow customizing aircraft landing direction per aircraft or per dock (by Starkku) Vanilla fixes: - Allow AI to repair structures built from base nodes/trigger action 125/SW delivery in single player missions (by Trsdy) @@ -410,6 +411,7 @@ Vanilla fixes: - Fixed `AmbientDamage` when used with `IsRailgun=yes` being cut off by elevation changes (by Starkku) - Fixed railgun and fire particles being cut off by elevation changes (by Starkku) - Fixed teleport units' frozen-still timer being reset after load game (by Trsdy) +- Aircraft docking on buildings now respect `[AudioVisual]`->`PoseDir` as the default setting and do not always land facing north or in case of pre-placed buildings, the building's direction (by Starkku) Phobos fixes: - Fixed a few errors of calling for superweapon launch by `LaunchSW` or building infiltration (by Trsdy) diff --git a/src/Ext/Aircraft/Body.cpp b/src/Ext/Aircraft/Body.cpp index 286b5d0deb..f1262fb3c5 100644 --- a/src/Ext/Aircraft/Body.cpp +++ b/src/Ext/Aircraft/Body.cpp @@ -1,4 +1,8 @@ #include "Body.h" + +#include + +#include #include #include @@ -50,3 +54,43 @@ bool AircraftExt::PlaceReinforcementAircraft(AircraftClass* pThis, CellStruct ed return result; } + +DirType AircraftExt::GetLandingDir(AircraftClass* pThis, BuildingClass* pDock) +{ + auto const poseDir = static_cast(RulesClass::Instance->PoseDir); + + if (!pThis) + return poseDir; + + bool isAirportBound = true; + + if (pDock || pThis->HasAnyLink()) + { + auto pBuilding = pDock; + + if (!pDock) + pBuilding = abstract_cast(pThis->GetNthLink(0)); + + if (pBuilding) + { + auto const pBuildingTypeExt = BuildingTypeExt::ExtMap.Find(pBuilding->Type); + + if (pBuildingTypeExt->AircraftDockingDir.isset()) + return pBuildingTypeExt->AircraftDockingDir.Get(); + } + } + else if (!pThis->Type->AirportBound) + { + isAirportBound = false; + } + + int landingDir = TechnoTypeExt::ExtMap.Find(pThis->GetTechnoType())->LandingDir.Get((int)poseDir); + + if (isAirportBound) + return static_cast(Math::clamp(landingDir, 0, 255)); + else if (landingDir < 0) + return pThis->PrimaryFacing.Current().GetDir(); + + return poseDir; +} + diff --git a/src/Ext/Aircraft/Body.h b/src/Ext/Aircraft/Body.h index bfca1435c4..f4c536b8bf 100644 --- a/src/Ext/Aircraft/Body.h +++ b/src/Ext/Aircraft/Body.h @@ -8,5 +8,6 @@ class AircraftExt public: static void FireBurst(AircraftClass* pThis, AbstractClass* pTarget, int shotNumber); static bool PlaceReinforcementAircraft(AircraftClass* pThis, CellStruct edgeCell); + static DirType GetLandingDir(AircraftClass* pThis, BuildingClass* pDock = nullptr); }; diff --git a/src/Ext/Aircraft/Hooks.cpp b/src/Ext/Aircraft/Hooks.cpp index ae6ddbf70e..8cc650d879 100644 --- a/src/Ext/Aircraft/Hooks.cpp +++ b/src/Ext/Aircraft/Hooks.cpp @@ -1,8 +1,11 @@ #include -#include +#include + + #include #include #include +#include DEFINE_HOOK(0x417FF1, AircraftClass_Mission_Attack_StrafeShots, 0x6) { @@ -107,3 +110,49 @@ DEFINE_HOOK(0x414C0B, AircraftClass_ChronoSparkleDelay, 0x5) R->ECX(RulesExt::Global()->ChronoSparkleDisplayDelay); return 0x414C10; } + + +#pragma region LandingDir + +DEFINE_HOOK(0x4CF31C, FlyLocomotionClass_FlightUpdate_LandingDir, 0x9) +{ + enum { SkipGameCode = 0x4CF351 }; + + GET(FootClass**, pLinkedToPtr, ESI); + REF_STACK(unsigned int, dir, STACK_OFFSET(0x48, 0x8)); + + auto const pLinkedTo = *pLinkedToPtr; + dir = 0; + + if (pLinkedTo->CurrentMission == Mission::Enter || pLinkedTo->GetMapCoords() == CellClass::Coord2Cell(pLinkedTo->Locomotor->Destination())) + { + if (auto const pAircraft = abstract_cast(pLinkedTo)) + dir = DirStruct(AircraftExt::GetLandingDir(pAircraft)).Raw; + } + + return SkipGameCode; +} + +DEFINE_HOOK(0x446F6C, BuildingClass_GrandOpening_PoseDir, 0x9) +{ + GET(BuildingClass*, pThis, EBP); + GET(AircraftClass*, pAircraft, ESI); + + R->EAX(AircraftExt::GetLandingDir(pAircraft, pThis)); + + return 0; +} + +DEFINE_HOOK_AGAIN(0x443FEF, BuildingClass_ExitObject_PoseDir, 0xA) +DEFINE_HOOK(0x443FC7, BuildingClass_ExitObject_PoseDir, 0x8) +{ + GET(BuildingClass*, pThis, ESI); + GET(AircraftClass*, pAircraft, EBP); + + R->EAX(AircraftExt::GetLandingDir(pAircraft, pThis)); + + return 0; +} + +#pragma endregion + diff --git a/src/Ext/BuildingType/Body.cpp b/src/Ext/BuildingType/Body.cpp index 3c4236b313..68ca76f47a 100644 --- a/src/Ext/BuildingType/Body.cpp +++ b/src/Ext/BuildingType/Body.cpp @@ -147,6 +147,8 @@ void BuildingTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) this->ConsideredVehicle.Read(exINI, pSection, "ConsideredVehicle"); this->SellBuildupLength.Read(exINI, pSection, "SellBuildupLength"); + this->AircraftDockingDir.Read(exINI, pSection, "AircraftDockingDir"); + // Ares tag this->SpyEffect_Custom.Read(exINI, pSection, "SpyEffect.Custom"); if (SuperWeaponTypeClass::Array->Count > 0) @@ -234,6 +236,7 @@ void BuildingTypeExt::ExtData::Serialize(T& Stm) .Process(this->ConsideredVehicle) .Process(this->ZShapePointMove_OnBuildup) .Process(this->SellBuildupLength) + .Process(this->AircraftDockingDir) ; } diff --git a/src/Ext/BuildingType/Body.h b/src/Ext/BuildingType/Body.h index beba93e1c3..b99f11e638 100644 --- a/src/Ext/BuildingType/Body.h +++ b/src/Ext/BuildingType/Body.h @@ -61,6 +61,8 @@ class BuildingTypeExt Valueable ZShapePointMove_OnBuildup; Valueable SellBuildupLength; + Nullable AircraftDockingDir; + ExtData(BuildingTypeClass* OwnerObject) : Extension(OwnerObject) , PowersUp_Owner { AffectedHouse::Owner } , PowersUp_Buildings {} @@ -96,6 +98,7 @@ class BuildingTypeExt , ConsideredVehicle {} , ZShapePointMove_OnBuildup { false } , SellBuildupLength { 23 } + , AircraftDockingDir {} { } // Ares 0.A functions diff --git a/src/Ext/TechnoType/Body.cpp b/src/Ext/TechnoType/Body.cpp index 5c5a8e9f23..4785b96757 100644 --- a/src/Ext/TechnoType/Body.cpp +++ b/src/Ext/TechnoType/Body.cpp @@ -272,6 +272,7 @@ void TechnoTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) this->SpawnDistanceFromTarget.Read(exINI, pSection, "SpawnDistanceFromTarget"); this->SpawnHeight.Read(exINI, pSection, "SpawnHeight"); + this->LandingDir.Read(exINI, pSection, "LandingDir"); // Ares 0.2 this->RadarJamRadius.Read(exINI, pSection, "RadarJamRadius"); @@ -569,6 +570,7 @@ void TechnoTypeExt::ExtData::Serialize(T& Stm) .Process(this->SpawnDistanceFromTarget) .Process(this->SpawnHeight) + .Process(this->LandingDir) ; } void TechnoTypeExt::ExtData::LoadFromStream(PhobosStreamReader& Stm) diff --git a/src/Ext/TechnoType/Body.h b/src/Ext/TechnoType/Body.h index dd57056cf6..2b9b5a2cee 100644 --- a/src/Ext/TechnoType/Body.h +++ b/src/Ext/TechnoType/Body.h @@ -181,6 +181,7 @@ class TechnoTypeExt Nullable SpawnDistanceFromTarget; Nullable SpawnHeight; + Nullable LandingDir; struct LaserTrailDataEntry { @@ -359,6 +360,7 @@ class TechnoTypeExt , SpawnDistanceFromTarget {} , SpawnHeight {} + , LandingDir {} { } virtual ~ExtData() = default;