diff --git a/src/Ext/Building/Body.cpp b/src/Ext/Building/Body.cpp index 79757c55eb..7348eab758 100644 --- a/src/Ext/Building/Body.cpp +++ b/src/Ext/Building/Body.cpp @@ -357,7 +357,7 @@ void BuildingExt::KickOutStuckUnits(BuildingClass* pThis) { if (const auto pUnit = abstract_cast(pThis->GetNthLink())) { - if (!pUnit->IsTether && pUnit->GetCurrentSpeed() <= 0) + if (pUnit->Locomotor->Destination() == CoordStruct::Empty) { if (const auto pTeam = pUnit->Team) pTeam->LiberateMember(pUnit); @@ -369,19 +369,22 @@ void BuildingExt::KickOutStuckUnits(BuildingClass* pThis) } auto buffer = CoordStruct::Empty; - auto pCell = MapClass::Instance.GetCellAt(*pThis->GetExitCoords(&buffer, 0)); - const auto pOwner = pThis->Owner; - int i = 0; + pThis->GetExitCoords(&buffer, 0); + + auto cell = CellClass::Coord2Cell(buffer); + + const auto pType = pThis->Type; + const short start = static_cast(pThis->Location.X / Unsorted::LeptonsPerCell + pType->GetFoundationWidth() - 2); // door + const short end = cell.X; // exit + auto pCell = MapClass::Instance.GetCellAt(cell); while (true) { for (auto pObject = pCell->FirstObject; pObject; pObject = pObject->NextObject) { - if (pObject->WhatAmI() == AbstractType::Unit) + if (const auto pUnit = abstract_cast(pObject)) { - const auto pUnit = static_cast(pObject); - - if (pOwner != pUnit->Owner || pUnit->IsTether) + if (pThis->Owner != pUnit->Owner || pUnit->Locomotor->Destination() != CoordStruct::Empty) continue; const auto height = pUnit->GetHeight(); @@ -398,11 +401,10 @@ void BuildingExt::KickOutStuckUnits(BuildingClass* pThis) } } - if (++i >= 2) + if (--cell.X < end) return; // no stuck - // Continue checking towards the bottom right corner - pCell = pCell->GetNeighbourCell(FacingType::East); + pCell = MapClass::Instance.GetCellAt(cell); } } diff --git a/src/Ext/Building/Hooks.cpp b/src/Ext/Building/Hooks.cpp index 82d9372d04..23d9755f03 100644 --- a/src/Ext/Building/Hooks.cpp +++ b/src/Ext/Building/Hooks.cpp @@ -220,7 +220,7 @@ DEFINE_HOOK(0x450248, BuildingClass_UpdateFactory_KickOutStuckUnits, 0x6) { const auto mission = pThis->CurrentMission; - if (mission == Mission::Guard && !pThis->InLimbo || mission == Mission::Unload && pThis->MissionStatus == 1) // Unloading but stuck + if (mission == Mission::Guard && !pThis->InLimbo || mission == Mission::Unload && pThis->MissionStatus == 3) // Unloading but stuck BuildingExt::KickOutStuckUnits(pThis); } } diff --git a/src/Ext/BuildingType/Hooks.cpp b/src/Ext/BuildingType/Hooks.cpp index a04001c576..3a61cdbf04 100644 --- a/src/Ext/BuildingType/Hooks.cpp +++ b/src/Ext/BuildingType/Hooks.cpp @@ -75,7 +75,7 @@ DEFINE_HOOK(0x6D528A, TacticalClass_DrawPlacement_PlacementPreview, 0x6) const auto pBuilding = specific_cast(DisplayClass::Instance.CurrentBuilding); const auto pType = pBuilding ? pBuilding->Type : nullptr; - const auto pTypeExt = BuildingTypeExt::ExtMap.Find(pType); + const auto pTypeExt = BuildingTypeExt::ExtMap.TryFind(pType); const bool isShow = pTypeExt && pTypeExt->PlacementPreview; if (isShow) @@ -404,3 +404,28 @@ DEFINE_HOOK(0x44E85F, BuildingClass_Power_DamageFactor, 0x7) return Handled; } + +#pragma region WeaponFactoryPath + +DEFINE_HOOK(0x73F5A7, UnitClass_IsCellOccupied_UnlimboDirection, 0x8) +{ + enum { NextObject = 0x73FA87, ContinueCheck = 0x73F5AF }; + + GET(const bool, notPassable, EAX); + + if (notPassable) + return ContinueCheck; + + GET(BuildingClass* const, pBuilding, ESI); + + const auto pType = pBuilding->Type; + + if (!pType->WeaponsFactory) + return NextObject; + + GET(CellClass* const, pCell, EDI); + + return pCell->MapCoords.Y == pType->FoundationOutside[10].Y ? NextObject : ContinueCheck; +} + +#pragma endregion