From ce12b491136b4f966ce11551189e36d18c9314b6 Mon Sep 17 00:00:00 2001 From: ZivDero Date: Tue, 22 Oct 2024 17:26:55 +0300 Subject: [PATCH] Fix spawned planes being unable to land back onto their spawner --- docs/New-Features-and-Enhancements.md | 4 -- src/extensions/aircraft/aircraftext_hooks.cpp | 54 +++++++++++++++++++ 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/docs/New-Features-and-Enhancements.md b/docs/New-Features-and-Enhancements.md index 39d669d88..b96d64f11 100644 --- a/docs/New-Features-and-Enhancements.md +++ b/docs/New-Features-and-Enhancements.md @@ -239,10 +239,6 @@ HunterSeeker= ; UnitType, the unit that is this side's Hunter-Seeker. - Vinifera ports the spawn manager, responsible for AircraftType missiles and aircraft carries from Red Alert 2. -```{warning} -Aircraft carriers (i. e. spawners that spawn non-rockets) are known to have issues with Tiberian Sun aircraft, and as such may not function properly. This will be fixed in a future version of Vinifera. -``` - In `RULES.INI`: ```ini [SOMETECHNO] ; TechnoType diff --git a/src/extensions/aircraft/aircraftext_hooks.cpp b/src/extensions/aircraft/aircraftext_hooks.cpp index e4ad82d56..49368f6d8 100644 --- a/src/extensions/aircraft/aircraftext_hooks.cpp +++ b/src/extensions/aircraft/aircraftext_hooks.cpp @@ -65,6 +65,7 @@ static class AircraftClassExt final : public AircraftClass public: bool _Unlimbo(Coordinate& coord, DirType dir); bool _Enter_Idle_Mode(bool initial, bool a2); + bool _Cell_Seems_Ok(Cell& cell, bool strict) const; }; @@ -287,6 +288,58 @@ bool AircraftClassExt::_Enter_Idle_Mode(bool initial, bool a2) } +/** + * Checks to see if a cell is good to enter. + * + * @author: 06/19/1995 JLB - Created. + * ZivDero - Adjustments for Tiberian Sun. + */ +bool AircraftClassExt::_Cell_Seems_Ok(Cell& cell, bool strict) const +{ + /** + * If the cell is outisde the playable area, then it is not a valid cell to enter. + */ + if (!Map.In_Local_Radar(cell)) { + return false; + } + + /** + * Spawners and spawned objects can co-exist in cells. + */ + if (Extension::Fetch(Class)->IsSpawned) { + const TechnoClass* techno = Map[cell].Cell_Techno(); + if (techno) { + if (Extension::Fetch(techno)->SpawnManager + || Extension::Fetch(techno->Techno_Type_Class())->IsSpawned) { + return true; + } + } + } + + /** + * If we're a carryall, we can enter a potential totable unit's cell. + */ + bool can_tote = false; + if (Class->IsCarryall && Target_Legal(NavCom) && NavCom->What_Am_I() == RTTI_UNIT) + can_tote = true; + + /** + * Make sure that no other aircraft are heading to the selected location. If they + * are, then don't consider the location as valid. + */ + TARGET astarget = &Map[cell]; + for (int index = 0; index < Foots.Count(); index++) { + const FootClass* foot = Foots[index]; + if (foot && (!can_tote || foot != NavCom) && (strict || foot != this) && !foot->IsInLimbo) { + if (foot->IsDown && (Coord_Cell(foot->Coord) == cell || foot->NavCom == astarget)) { + return false; + } + } + } + + return true; +} + /** * #issue-996 @@ -586,4 +639,5 @@ void AircraftClassExtension_Hooks() Patch_Jump(0x00408940, &AircraftClassExt::_Unlimbo); Patch_Jump(0x0040B310, &AircraftClassExt::_Enter_Idle_Mode); + Patch_Jump(0x0040D260, &AircraftClassExt::_Cell_Seems_Ok); }