diff --git a/CREDITS.md b/CREDITS.md index c8555f9fa..beb38f460 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -355,6 +355,9 @@ This page lists all the individual contributions to the project by their author. - Allow to change the speed of gas particles - **CrimRecya** - Fix `LimboKill` not working reliably + - Units will not always stuck in the factory +- **TaranDahl** + - Units are now unable to kick out from a factory that is in construction process - **Ollerus** - Build limit group enhancement - Customizable rocker amplitude diff --git a/docs/Fixed-or-Improved-Logics.md b/docs/Fixed-or-Improved-Logics.md index f5f3cabe2..f31339236 100644 --- a/docs/Fixed-or-Improved-Logics.md +++ b/docs/Fixed-or-Improved-Logics.md @@ -161,6 +161,7 @@ This page describes all ingame logics that are fixed or improved in Phobos witho - OverlayTypes now read and use `ZAdjust` if specified in their `artmd.ini` entry. - Setting `[AudioVisual]` -> `ColorAddUse8BitRGB` to true makes game treat values from `[ColorAdd]` as 8-bit RGB (0-255) instead of RGB565 (0-31 for red & blue, 0-63 for green). This works for `LaserTargetColor`, `IronCurtainColor`, `BerserkColor` and `ForceShieldColor`. - Weapons with `AA=true` Projectile can now correctly fire at air units when both firer and target are over a bridge. +- Units are now unable to kick out from a factory that is in construction process, and will not always stuck in the factory. - Fixed disguised units not using the correct palette if target has custom palette. - Building upgrades now consistently use building's `PowerUpN` animation settings corresponding to the upgrade's `PowersUpToLevel` where possible. - Subterranean units are no longer allowed to perform deploy functions like firing weapons or `IsSimpleDeployer` while burrowed or burrowing, they will instead emerge first like they do for transport unloading. diff --git a/docs/Whats-New.md b/docs/Whats-New.md index dd8bb1a74..e236638e5 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -519,6 +519,7 @@ Vanilla fixes: - Units with `Sensors=true` will no longer reveal ally buildings (by Starkku) - Air units are now reliably included by target scan with large range and Warhead detonation by large `CellSpread` (by Starkku) - Weapons with `AA=true` Projectile can now correctly fire at air units when both firer and target are over a bridge (by Starkku) +- Units are now unable to kick out from a factory that is in construction process, and will not always stuck in the factory (by CrimRecya & TaranDahl) - Fixed disguised units not using the correct palette if target has custom palette (by NetsuNegi) - Building upgrades now consistently use building's `PowerUpN` animation settings corresponding to the upgrade's `PowersUpToLevel` where possible (by Starkku) - Subterranean units are no longer allowed to perform deploy functions like firing weapons or `IsSimpleDeployer` while burrowed or burrowing, they will instead emerge first like they do for transport unloading (by Starkku) diff --git a/src/Ext/Building/Body.cpp b/src/Ext/Building/Body.cpp index 4b785fb18..3799961c0 100644 --- a/src/Ext/Building/Body.cpp +++ b/src/Ext/Building/Body.cpp @@ -334,7 +334,7 @@ bool BuildingExt::ExtData::HandleInfiltrate(HouseClass* pInfiltratorHouse,int mo int idx = this->TypeExtData->SpyEffect_VictimSuperWeapon; if (idx >= 0) launchTheSWHere(pVictimHouse->Supers.Items[idx], pVictimHouse); - + idx = this->TypeExtData->SpyEffect_InfiltratorSuperWeapon; if (idx >= 0) launchTheSWHere(pInfiltratorHouse->Supers.Items[idx], pInfiltratorHouse); @@ -343,6 +343,51 @@ bool BuildingExt::ExtData::HandleInfiltrate(HouseClass* pInfiltratorHouse,int mo return true; } +void BuildingExt::KickOutStuckUnits(BuildingClass* pThis) +{ + if (TechnoClass* const pTechno = pThis->GetNthLink()) + { + if (UnitClass* const pUnit = abstract_cast(pTechno)) + { + if (!pUnit->unknown_bool_418 && pUnit->GetCurrentSpeed() <= 0) + { + if (TeamClass* const pTeam = pUnit->Team) + pTeam->LiberateMember(pUnit); + + pThis->SendCommand(RadioCommand::NotifyUnlink, pUnit); + pUnit->QueueMission(Mission::Guard, false); + return; // one after another + } + } + } + + CoordStruct buffer = CoordStruct::Empty; + + if (CellClass* const pCell = MapClass::Instance->GetCellAt(*pThis->GetExitCoords(&buffer, 0))) + { + for (ObjectClass* pObject = pCell->FirstObject; pObject; pObject = pObject->NextObject) + { + if (UnitClass* const pUnit = abstract_cast(pObject)) + { + if (pThis->Owner != pUnit->Owner || pUnit->unknown_bool_418) + continue; + + const int height = pUnit->GetHeight(); + + if (height < 0 || height > Unsorted::CellHeight) + continue; + + if (TeamClass* const pTeam = pUnit->Team) + pTeam->LiberateMember(pUnit); + + pThis->SendCommand(RadioCommand::RequestLink, pUnit); + pThis->QueueMission(Mission::Unload, false); + return; // one after another + } + } + } +} + // ============================= // load / save diff --git a/src/Ext/Building/Body.h b/src/Ext/Building/Body.h index 9b0b947dd..5ca5b1bbe 100644 --- a/src/Ext/Building/Body.h +++ b/src/Ext/Building/Body.h @@ -106,4 +106,5 @@ class BuildingExt static bool CanGrindTechno(BuildingClass* pBuilding, TechnoClass* pTechno); static bool DoGrindingExtras(BuildingClass* pBuilding, TechnoClass* pTechno, int refund); static bool CanUndeployOnSell(BuildingClass* pThis); + static void KickOutStuckUnits(BuildingClass* pThis); }; diff --git a/src/Ext/Building/Hooks.cpp b/src/Ext/Building/Hooks.cpp index e8612abe9..410ca8766 100644 --- a/src/Ext/Building/Hooks.cpp +++ b/src/Ext/Building/Hooks.cpp @@ -365,6 +365,39 @@ DEFINE_HOOK(0x443CCA, BuildingClass_KickOutUnit_AircraftType_Phobos, 0xA) return 0; } +// Kick out stuck units when the factory building is not busy +DEFINE_HOOK(0x450248, BuildingClass_UpdateFactory_KickOutStuckUnits, 0x6) +{ + GET(BuildingClass*, pThis, ESI); + + if (!(Unsorted::CurrentFrame % 15)) + { + BuildingTypeClass* const pType = pThis->Type; + + if (pType->Factory == AbstractType::UnitType && pType->WeaponsFactory && !pType->Naval && pThis->QueuedMission != Mission::Unload) + { + const Mission mission = pThis->CurrentMission; + + if (mission == Mission::Guard || (mission == Mission::Unload && pThis->MissionStatus == 1)) + BuildingExt::KickOutStuckUnits(pThis); + } + } + + return 0; +} + +// Should not kick out units if the factory building is in construction process +DEFINE_HOOK(0x4444A0, BuildingClass_KickOutUnit_NoKickOutInConstruction, 0xA) +{ + enum { ThisIsOK = 0x444565, ThisIsNotOK = 0x4444B3}; + + GET(BuildingClass* const, pThis, ESI); + + const Mission mission = pThis->GetCurrentMission(); + + return (mission == Mission::Unload || mission == Mission::Construction) ? ThisIsNotOK : ThisIsOK; +} + // Ares didn't have something like 0x7397E4 in its UnitDelivery code DEFINE_HOOK(0x44FBBF, CreateBuildingFromINIFile_AfterCTOR_BeforeUnlimbo, 0x8) {