From ff494bce8c86b250558aabd53bd5f4c6a50ead64 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Sat, 10 Aug 2024 20:55:17 +0800 Subject: [PATCH 01/21] Core --- CREDITS.md | 4 +++ docs/Fixed-or-Improved-Logics.md | 1 + docs/Whats-New.md | 1 + src/Ext/Building/Body.cpp | 52 +++++++++++++++++++++++++++++++- src/Ext/Building/Body.h | 1 + src/Ext/Building/Hooks.cpp | 12 ++++++++ 6 files changed, 70 insertions(+), 1 deletion(-) diff --git a/CREDITS.md b/CREDITS.md index 37d143fdb4..19a2cf164c 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -343,6 +343,10 @@ This page lists all the individual contributions to the project by their author. - Re-enable the Veinhole Monster and Weeds from TS - Recreate the weed-charging of SWs like the TS Chemical Missile - Allow to change the speed of gas particles +- **CrimRecya** + - Units will not always stuck in the factory +- **TaranDahl** + - Units are now unable to kick out from a factory that is in construction process - **handama** - AI script action to jump back to previous script - **Ares developers** - YRpp and Syringe which are used, save/load, project foundation and generally useful code from Ares diff --git a/docs/Fixed-or-Improved-Logics.md b/docs/Fixed-or-Improved-Logics.md index 67c0652549..1daa99f2e5 100644 --- a/docs/Fixed-or-Improved-Logics.md +++ b/docs/Fixed-or-Improved-Logics.md @@ -162,6 +162,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. If the unit is not able to kick out from the factory, the unit will be removed and the cost will be given back to its house. ## Fixes / interactions with other extensions diff --git a/docs/Whats-New.md b/docs/Whats-New.md index db6d18be34..546b612c81 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -505,6 +505,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) Phobos fixes: - Fixed a few errors of calling for superweapon launch by `LaunchSW` or building infiltration (by Trsdy) diff --git a/src/Ext/Building/Body.cpp b/src/Ext/Building/Body.cpp index 5f52d26ab3..f597358703 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,56 @@ bool BuildingExt::ExtData::HandleInfiltrate(HouseClass* pInfiltratorHouse,int mo return true; } +void BuildingExt::ExtData::KickOutStuckUnits() +{ + if (Unsorted::CurrentFrame % 15) + return; + + BuildingClass* const pThis = this->OwnerObject(); + + if (pThis->GetCurrentMission() == Mission::Unload) + return; + + BuildingTypeClass* const pType = pThis->Type; + + if (pType->Factory != AbstractType::UnitType) + return; + + CellStruct cell = CellClass::Coord2Cell(pThis->GetCenterCoords()); + + if (CellClass* const pCell = MapClass::Instance->GetCellAt(cell)) + { + for (ObjectClass* pObject = pCell->FirstObject; pObject; pObject = pObject->NextObject) + { + if (pObject->WhatAmI() == AbstractType::Unit) + { + UnitClass* const pUnit = static_cast(pObject); + + if (pUnit->Destination || pUnit->GetHeight() || pThis->Owner != pUnit->Owner) + continue; + + if (pUnit->unknown_int_120 > 0 && (Unsorted::CurrentFrame - pUnit->unknown_int_120) > 120) // Unable to kick out + { + if (HouseClass* const pOwner = pUnit->Owner) + pOwner->GiveMoney(pUnit->Type->GetActualCost(pOwner)); + + pUnit->KillPassengers(nullptr); + pUnit->Stun(); + pUnit->Limbo(); + pUnit->UnInit(); + continue; + } + + pUnit->unknown_int_120 = Unsorted::CurrentFrame; + pThis->SendCommand(RadioCommand::RequestLink, pUnit); + pThis->SendCommand(RadioCommand::RequestTether, pUnit); + pThis->QueueMission(Mission::Unload, false); + break; + } + } + } +} + // ============================= // load / save diff --git a/src/Ext/Building/Body.h b/src/Ext/Building/Body.h index 33d13c1a5f..dffd3c3699 100644 --- a/src/Ext/Building/Body.h +++ b/src/Ext/Building/Body.h @@ -55,6 +55,7 @@ class BuildingExt bool HasSuperWeapon(int index, bool withUpgrades) const; bool HandleInfiltrate(HouseClass* pInfiltratorHouse , int moneybefore); void UpdatePrimaryFactoryAI(); + void KickOutStuckUnits(); virtual ~ExtData() = default; // virtual void LoadFromINIFile(CCINIClass* pINI) override; diff --git a/src/Ext/Building/Hooks.cpp b/src/Ext/Building/Hooks.cpp index 1b14db540f..147128649b 100644 --- a/src/Ext/Building/Hooks.cpp +++ b/src/Ext/Building/Hooks.cpp @@ -27,6 +27,7 @@ DEFINE_HOOK(0x43FE69, BuildingClass_AI, 0xA) pExt->DisplayIncomeString(); pExt->ApplyPoweredKillSpawns(); + pExt->KickOutStuckUnits(); return 0; } @@ -324,6 +325,17 @@ DEFINE_HOOK(0x443CCA, BuildingClass_KickOutUnit_AircraftType_Phobos, 0xA) return 0; } +DEFINE_HOOK(0x4444A0, BuildingClass_KickOutUnit_NoKickOutInConstruction, 0x7) +{ + enum { OfCourse = 0x444565, NoChance = 0x4444B3}; + + GET(BuildingClass* const, pThis, ESI); + + const Mission mission = pThis->GetCurrentMission(); + + return (mission == Mission::Unload || mission == Mission::Construction) ? NoChance : OfCourse; +} + // Ares didn't have something like 0x7397E4 in its UnitDelivery code DEFINE_HOOK(0x44FBBF, CreateBuildingFromINIFile_AfterCTOR_BeforeUnlimbo, 0x8) { From ff9257b63f35fc61bbce4d3ff5802113f7956fb6 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Sat, 10 Aug 2024 21:20:06 +0800 Subject: [PATCH 02/21] Co-Author MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: 航味麻酱 <93972760+tarandahl@users.noreply.github.com> --- src/Ext/Building/Hooks.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Ext/Building/Hooks.cpp b/src/Ext/Building/Hooks.cpp index 147128649b..5210bc5320 100644 --- a/src/Ext/Building/Hooks.cpp +++ b/src/Ext/Building/Hooks.cpp @@ -325,6 +325,7 @@ DEFINE_HOOK(0x443CCA, BuildingClass_KickOutUnit_AircraftType_Phobos, 0xA) return 0; } +// Should not kick out units if the factory building is in construction process DEFINE_HOOK(0x4444A0, BuildingClass_KickOutUnit_NoKickOutInConstruction, 0x7) { enum { OfCourse = 0x444565, NoChance = 0x4444B3}; From b734ec66d7a3a05abcb269bf343118180ecf5cef Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Sat, 10 Aug 2024 21:51:39 +0800 Subject: [PATCH 03/21] Fix --- src/Ext/Building/Body.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Ext/Building/Body.cpp b/src/Ext/Building/Body.cpp index f597358703..b7ca2947f9 100644 --- a/src/Ext/Building/Body.cpp +++ b/src/Ext/Building/Body.cpp @@ -362,13 +362,20 @@ void BuildingExt::ExtData::KickOutStuckUnits() if (CellClass* const pCell = MapClass::Instance->GetCellAt(cell)) { + TechnoClass* const pTechno = pCell->FindTechnoNearestTo(Point2D::Empty, false); + for (ObjectClass* pObject = pCell->FirstObject; pObject; pObject = pObject->NextObject) { if (pObject->WhatAmI() == AbstractType::Unit) { UnitClass* const pUnit = static_cast(pObject); - if (pUnit->Destination || pUnit->GetHeight() || pThis->Owner != pUnit->Owner) + if (pUnit->Destination || pThis->Owner != pUnit->Owner) + continue; + + const int height = pUnit->GetHeight(); + + if (height < 0 || height > 208) continue; if (pUnit->unknown_int_120 > 0 && (Unsorted::CurrentFrame - pUnit->unknown_int_120) > 120) // Unable to kick out From 115b33ce32f13ed7df1bf7f4cd3639f599ad93bf Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Sat, 10 Aug 2024 21:52:57 +0800 Subject: [PATCH 04/21] Delete useless --- src/Ext/Building/Body.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Ext/Building/Body.cpp b/src/Ext/Building/Body.cpp index b7ca2947f9..856e4656d4 100644 --- a/src/Ext/Building/Body.cpp +++ b/src/Ext/Building/Body.cpp @@ -362,8 +362,6 @@ void BuildingExt::ExtData::KickOutStuckUnits() if (CellClass* const pCell = MapClass::Instance->GetCellAt(cell)) { - TechnoClass* const pTechno = pCell->FindTechnoNearestTo(Point2D::Empty, false); - for (ObjectClass* pObject = pCell->FirstObject; pObject; pObject = pObject->NextObject) { if (pObject->WhatAmI() == AbstractType::Unit) From e3e7cb33de7385fae88aa64bcb0f5cf7231c30fd Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Sun, 11 Aug 2024 17:18:47 +0800 Subject: [PATCH 05/21] Fix --- src/Ext/Building/Body.cpp | 36 ++++-------------------------------- src/Ext/Building/Body.h | 2 +- src/Ext/Building/Hooks.cpp | 12 +++++++++++- 3 files changed, 16 insertions(+), 34 deletions(-) diff --git a/src/Ext/Building/Body.cpp b/src/Ext/Building/Body.cpp index 856e4656d4..88375a3425 100644 --- a/src/Ext/Building/Body.cpp +++ b/src/Ext/Building/Body.cpp @@ -343,24 +343,9 @@ bool BuildingExt::ExtData::HandleInfiltrate(HouseClass* pInfiltratorHouse,int mo return true; } -void BuildingExt::ExtData::KickOutStuckUnits() +void BuildingExt::KickOutStuckUnits(BuildingClass* pThis) { - if (Unsorted::CurrentFrame % 15) - return; - - BuildingClass* const pThis = this->OwnerObject(); - - if (pThis->GetCurrentMission() == Mission::Unload) - return; - - BuildingTypeClass* const pType = pThis->Type; - - if (pType->Factory != AbstractType::UnitType) - return; - - CellStruct cell = CellClass::Coord2Cell(pThis->GetCenterCoords()); - - if (CellClass* const pCell = MapClass::Instance->GetCellAt(cell)) + if (CellClass* const pCell = MapClass::Instance->GetCellAt(pThis->GetCenterCoords())) { for (ObjectClass* pObject = pCell->FirstObject; pObject; pObject = pObject->NextObject) { @@ -368,7 +353,7 @@ void BuildingExt::ExtData::KickOutStuckUnits() { UnitClass* const pUnit = static_cast(pObject); - if (pUnit->Destination || pThis->Owner != pUnit->Owner) + if (pThis->Owner != pUnit->Owner) continue; const int height = pUnit->GetHeight(); @@ -376,23 +361,10 @@ void BuildingExt::ExtData::KickOutStuckUnits() if (height < 0 || height > 208) continue; - if (pUnit->unknown_int_120 > 0 && (Unsorted::CurrentFrame - pUnit->unknown_int_120) > 120) // Unable to kick out - { - if (HouseClass* const pOwner = pUnit->Owner) - pOwner->GiveMoney(pUnit->Type->GetActualCost(pOwner)); - - pUnit->KillPassengers(nullptr); - pUnit->Stun(); - pUnit->Limbo(); - pUnit->UnInit(); - continue; - } - - pUnit->unknown_int_120 = Unsorted::CurrentFrame; pThis->SendCommand(RadioCommand::RequestLink, pUnit); pThis->SendCommand(RadioCommand::RequestTether, pUnit); pThis->QueueMission(Mission::Unload, false); - break; + break; // one after another } } } diff --git a/src/Ext/Building/Body.h b/src/Ext/Building/Body.h index dffd3c3699..b343cec7ac 100644 --- a/src/Ext/Building/Body.h +++ b/src/Ext/Building/Body.h @@ -55,7 +55,6 @@ class BuildingExt bool HasSuperWeapon(int index, bool withUpgrades) const; bool HandleInfiltrate(HouseClass* pInfiltratorHouse , int moneybefore); void UpdatePrimaryFactoryAI(); - void KickOutStuckUnits(); virtual ~ExtData() = default; // virtual void LoadFromINIFile(CCINIClass* pINI) override; @@ -105,4 +104,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 5210bc5320..99e2da84da 100644 --- a/src/Ext/Building/Hooks.cpp +++ b/src/Ext/Building/Hooks.cpp @@ -27,7 +27,6 @@ DEFINE_HOOK(0x43FE69, BuildingClass_AI, 0xA) pExt->DisplayIncomeString(); pExt->ApplyPoweredKillSpawns(); - pExt->KickOutStuckUnits(); return 0; } @@ -325,6 +324,17 @@ 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) && pThis->GetCurrentMission() == Mission::Guard && pThis->Type->Factory == AbstractType::UnitType) + BuildingExt::KickOutStuckUnits(pThis); + + return 0; +} + // Should not kick out units if the factory building is in construction process DEFINE_HOOK(0x4444A0, BuildingClass_KickOutUnit_NoKickOutInConstruction, 0x7) { From c0a95ba2787afbd71e473d0b122402fb7280bd33 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Sun, 11 Aug 2024 19:01:49 +0800 Subject: [PATCH 06/21] Check WeaponsFactory --- src/Ext/Building/Hooks.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Ext/Building/Hooks.cpp b/src/Ext/Building/Hooks.cpp index 99e2da84da..a29004577b 100644 --- a/src/Ext/Building/Hooks.cpp +++ b/src/Ext/Building/Hooks.cpp @@ -329,8 +329,13 @@ DEFINE_HOOK(0x450248, BuildingClass_UpdateFactory_KickOutStuckUnits, 0x6) { GET(BuildingClass*, pThis, ESI); - if (!(Unsorted::CurrentFrame % 15) && pThis->GetCurrentMission() == Mission::Guard && pThis->Type->Factory == AbstractType::UnitType) - BuildingExt::KickOutStuckUnits(pThis); + if (!(Unsorted::CurrentFrame % 15) && pThis->GetCurrentMission() == Mission::Guard) + { + BuildingTypeClass* const pType = pThis->Type; + + if (pType->Factory == AbstractType::UnitType && pType->WeaponsFactory) + BuildingExt::KickOutStuckUnits(pThis); + } return 0; } From f14899547d8f7f589966cfff0d9b22b158118c6a Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Mon, 12 Aug 2024 13:24:54 +0800 Subject: [PATCH 07/21] CellHeight --- src/Ext/Building/Body.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ext/Building/Body.cpp b/src/Ext/Building/Body.cpp index 88375a3425..e41dde2a60 100644 --- a/src/Ext/Building/Body.cpp +++ b/src/Ext/Building/Body.cpp @@ -358,7 +358,7 @@ void BuildingExt::KickOutStuckUnits(BuildingClass* pThis) const int height = pUnit->GetHeight(); - if (height < 0 || height > 208) + if (height < 0 || height > Unsorted::CellHeight) continue; pThis->SendCommand(RadioCommand::RequestLink, pUnit); From cf7663a55b3d42a588cac8af3b1416ffd437f96b Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Tue, 13 Aug 2024 21:36:08 +0800 Subject: [PATCH 08/21] Fix --- src/Ext/Building/Body.cpp | 41 ++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/src/Ext/Building/Body.cpp b/src/Ext/Building/Body.cpp index e41dde2a60..234b9a2f29 100644 --- a/src/Ext/Building/Body.cpp +++ b/src/Ext/Building/Body.cpp @@ -345,26 +345,41 @@ bool BuildingExt::ExtData::HandleInfiltrate(HouseClass* pInfiltratorHouse,int mo void BuildingExt::KickOutStuckUnits(BuildingClass* pThis) { - if (CellClass* const pCell = MapClass::Instance->GetCellAt(pThis->GetCenterCoords())) + BuildingTypeClass* const pType = pThis->Type; + const CellStruct foundation { pType->GetFoundationWidth(), pType->GetFoundationHeight(false) }; + const CellStruct topLeft = pThis->GetMapCoords() + CellStruct { 1, 1 }; + const CellStruct bottomRight = topLeft + foundation - CellStruct { 1, 1 }; + + for (short curX = topLeft.X; curX < bottomRight.X; ++curX) { - for (ObjectClass* pObject = pCell->FirstObject; pObject; pObject = pObject->NextObject) + for (short curY = topLeft.Y; curY < bottomRight.Y; ++curY) { - if (pObject->WhatAmI() == AbstractType::Unit) + if (CellClass* const pCell = MapClass::Instance->GetCellAt(CellStruct{ curX, curY })) { - UnitClass* const pUnit = static_cast(pObject); + for (ObjectClass* pObject = pCell->FirstObject; pObject; pObject = pObject->NextObject) + { + if (pObject->WhatAmI() == AbstractType::Unit) + { + UnitClass* const pUnit = static_cast(pObject); - if (pThis->Owner != pUnit->Owner) - continue; + if (pThis->Owner != pUnit->Owner) + continue; - const int height = pUnit->GetHeight(); + const int height = pUnit->GetHeight(); - if (height < 0 || height > Unsorted::CellHeight) - continue; + if (height < 0 || height > Unsorted::CellHeight) + continue; - pThis->SendCommand(RadioCommand::RequestLink, pUnit); - pThis->SendCommand(RadioCommand::RequestTether, pUnit); - pThis->QueueMission(Mission::Unload, false); - break; // one after another + if (!pThis->ContainsLink(pUnit)) + { + pThis->SendCommand(RadioCommand::RequestLink, pUnit); + pThis->SendCommand(RadioCommand::RequestTether, pUnit); + } + + pThis->QueueMission(Mission::Unload, false); + break; // one after another + } + } } } } From 8a77a94d6f4fa61081465f6aa9782809eeb7b14b Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Tue, 13 Aug 2024 21:53:21 +0800 Subject: [PATCH 09/21] Fix --- src/Ext/Building/Body.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/Ext/Building/Body.cpp b/src/Ext/Building/Body.cpp index 234b9a2f29..3599fbd3bd 100644 --- a/src/Ext/Building/Body.cpp +++ b/src/Ext/Building/Body.cpp @@ -370,12 +370,6 @@ void BuildingExt::KickOutStuckUnits(BuildingClass* pThis) if (height < 0 || height > Unsorted::CellHeight) continue; - if (!pThis->ContainsLink(pUnit)) - { - pThis->SendCommand(RadioCommand::RequestLink, pUnit); - pThis->SendCommand(RadioCommand::RequestTether, pUnit); - } - pThis->QueueMission(Mission::Unload, false); break; // one after another } From fff3d9a3c4e09382fd68680ed3e7346fc1f90c93 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Tue, 13 Aug 2024 22:11:15 +0800 Subject: [PATCH 10/21] Fix --- src/Ext/Building/Body.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Ext/Building/Body.cpp b/src/Ext/Building/Body.cpp index 3599fbd3bd..c3084fd820 100644 --- a/src/Ext/Building/Body.cpp +++ b/src/Ext/Building/Body.cpp @@ -370,7 +370,8 @@ void BuildingExt::KickOutStuckUnits(BuildingClass* pThis) if (height < 0 || height > Unsorted::CellHeight) continue; - pThis->QueueMission(Mission::Unload, false); + pUnit->Limbo(); + pUnit->Unlimbo(CellClass::Cell2Coord(CellStruct{ curX, ++curY }), DirType::East); break; // one after another } } From 204fb75b70ba83517a3c59082d15fe50f9482625 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Tue, 13 Aug 2024 22:25:03 +0800 Subject: [PATCH 11/21] Fix --- src/Ext/Building/Body.cpp | 35 +++++++++++++---------------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/src/Ext/Building/Body.cpp b/src/Ext/Building/Body.cpp index c3084fd820..c9faacd316 100644 --- a/src/Ext/Building/Body.cpp +++ b/src/Ext/Building/Body.cpp @@ -345,36 +345,27 @@ bool BuildingExt::ExtData::HandleInfiltrate(HouseClass* pInfiltratorHouse,int mo void BuildingExt::KickOutStuckUnits(BuildingClass* pThis) { - BuildingTypeClass* const pType = pThis->Type; - const CellStruct foundation { pType->GetFoundationWidth(), pType->GetFoundationHeight(false) }; - const CellStruct topLeft = pThis->GetMapCoords() + CellStruct { 1, 1 }; - const CellStruct bottomRight = topLeft + foundation - CellStruct { 1, 1 }; + const CellStruct cell = pThis->GetMapCoords(); - for (short curX = topLeft.X; curX < bottomRight.X; ++curX) + if (CellClass* const pCell = MapClass::Instance->GetCellAt(cell)) { - for (short curY = topLeft.Y; curY < bottomRight.Y; ++curY) + for (ObjectClass* pObject = pCell->FirstObject; pObject; pObject = pObject->NextObject) { - if (CellClass* const pCell = MapClass::Instance->GetCellAt(CellStruct{ curX, curY })) + if (pObject->WhatAmI() == AbstractType::Unit) { - for (ObjectClass* pObject = pCell->FirstObject; pObject; pObject = pObject->NextObject) - { - if (pObject->WhatAmI() == AbstractType::Unit) - { - UnitClass* const pUnit = static_cast(pObject); + UnitClass* const pUnit = static_cast(pObject); - if (pThis->Owner != pUnit->Owner) - continue; + if (pThis->Owner != pUnit->Owner) + continue; - const int height = pUnit->GetHeight(); + const int height = pUnit->GetHeight(); - if (height < 0 || height > Unsorted::CellHeight) - continue; + if (height < 0 || height > Unsorted::CellHeight) + continue; - pUnit->Limbo(); - pUnit->Unlimbo(CellClass::Cell2Coord(CellStruct{ curX, ++curY }), DirType::East); - break; // one after another - } - } + pUnit->Limbo(); + pUnit->Unlimbo(CellClass::Cell2Coord(CellStruct{ static_cast(cell.X + 2), cell.Y }), DirType::East); + break; // one after another } } } From af52bf96484e975d87a3d03f0435ef2c7ca47266 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Tue, 13 Aug 2024 23:52:20 +0800 Subject: [PATCH 12/21] Fix --- src/Ext/Building/Body.cpp | 42 +++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/src/Ext/Building/Body.cpp b/src/Ext/Building/Body.cpp index c9faacd316..0a84ba1935 100644 --- a/src/Ext/Building/Body.cpp +++ b/src/Ext/Building/Body.cpp @@ -345,27 +345,43 @@ bool BuildingExt::ExtData::HandleInfiltrate(HouseClass* pInfiltratorHouse,int mo void BuildingExt::KickOutStuckUnits(BuildingClass* pThis) { - const CellStruct cell = pThis->GetMapCoords(); + if (pThis->GetNthLink()) + { + pThis->QueueMission(Mission::Unload, false); + return; + } - if (CellClass* const pCell = MapClass::Instance->GetCellAt(cell)) + BuildingTypeClass* const pType = pThis->Type; + const CellStruct foundation { pType->GetFoundationWidth(), pType->GetFoundationHeight(false) }; + const CellStruct topLeft = pThis->GetMapCoords() + CellStruct { 1, 1 }; + const CellStruct bottomRight = topLeft + foundation - CellStruct { 1, 1 }; + + for (short curX = topLeft.X; curX < bottomRight.X; ++curX) { - for (ObjectClass* pObject = pCell->FirstObject; pObject; pObject = pObject->NextObject) + for (short curY = topLeft.Y; curY < bottomRight.Y; ++curY) { - if (pObject->WhatAmI() == AbstractType::Unit) + if (CellClass* const pCell = MapClass::Instance->GetCellAt(CellStruct{ curX, curY })) { - UnitClass* const pUnit = static_cast(pObject); + for (ObjectClass* pObject = pCell->FirstObject; pObject; pObject = pObject->NextObject) + { + if (pObject->WhatAmI() == AbstractType::Unit) + { + UnitClass* const pUnit = static_cast(pObject); - if (pThis->Owner != pUnit->Owner) - continue; + if (pThis->Owner != pUnit->Owner) + continue; - const int height = pUnit->GetHeight(); + const int height = pUnit->GetHeight(); - if (height < 0 || height > Unsorted::CellHeight) - continue; + if (height < 0 || height > Unsorted::CellHeight) + continue; - pUnit->Limbo(); - pUnit->Unlimbo(CellClass::Cell2Coord(CellStruct{ static_cast(cell.X + 2), cell.Y }), DirType::East); - break; // one after another + pThis->SendCommand(RadioCommand::RequestLink, pUnit); + pThis->SendCommand(RadioCommand::RequestTether, pUnit); + pThis->QueueMission(Mission::Unload, false); + break; // one after another + } + } } } } From d0d498cf5c308e454b11ea49dbcae4c297b3fdf5 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Tue, 13 Aug 2024 23:57:56 +0800 Subject: [PATCH 13/21] Fix --- src/Ext/Building/Body.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/Ext/Building/Body.cpp b/src/Ext/Building/Body.cpp index 0a84ba1935..4485c17b27 100644 --- a/src/Ext/Building/Body.cpp +++ b/src/Ext/Building/Body.cpp @@ -376,9 +376,20 @@ void BuildingExt::KickOutStuckUnits(BuildingClass* pThis) if (height < 0 || height > Unsorted::CellHeight) continue; - pThis->SendCommand(RadioCommand::RequestLink, pUnit); - pThis->SendCommand(RadioCommand::RequestTether, pUnit); - pThis->QueueMission(Mission::Unload, false); + pUnit->Limbo(); + + if (!pUnit->Unlimbo(CellClass::Cell2Coord(CellStruct{ bottomRight.X, curY }), DirType::East)) + { + if (HouseClass* const pOwner = pUnit->Owner) + pOwner->GiveMoney(pUnit->Type->GetActualCost(pOwner)); + + pUnit->KillPassengers(nullptr); + pUnit->Stun(); + pUnit->Limbo(); + pUnit->UnInit(); + continue; + } + break; // one after another } } From a613113795f6b28e827f4b5e0c6e997f5f5ec36c Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Wed, 14 Aug 2024 00:03:08 +0800 Subject: [PATCH 14/21] Fix --- src/Ext/Building/Body.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ext/Building/Body.cpp b/src/Ext/Building/Body.cpp index 4485c17b27..ef9f5689ee 100644 --- a/src/Ext/Building/Body.cpp +++ b/src/Ext/Building/Body.cpp @@ -354,7 +354,7 @@ void BuildingExt::KickOutStuckUnits(BuildingClass* pThis) BuildingTypeClass* const pType = pThis->Type; const CellStruct foundation { pType->GetFoundationWidth(), pType->GetFoundationHeight(false) }; const CellStruct topLeft = pThis->GetMapCoords() + CellStruct { 1, 1 }; - const CellStruct bottomRight = topLeft + foundation - CellStruct { 1, 1 }; + const CellStruct bottomRight = topLeft + foundation - CellStruct { 2, 2 }; for (short curX = topLeft.X; curX < bottomRight.X; ++curX) { From ef912532435e15f8fdc8f8b01cc7ebe522543f7e Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Wed, 14 Aug 2024 00:29:44 +0800 Subject: [PATCH 15/21] Fix --- src/Ext/Building/Body.cpp | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/src/Ext/Building/Body.cpp b/src/Ext/Building/Body.cpp index ef9f5689ee..2262970237 100644 --- a/src/Ext/Building/Body.cpp +++ b/src/Ext/Building/Body.cpp @@ -376,20 +376,11 @@ void BuildingExt::KickOutStuckUnits(BuildingClass* pThis) if (height < 0 || height > Unsorted::CellHeight) continue; - pUnit->Limbo(); - - if (!pUnit->Unlimbo(CellClass::Cell2Coord(CellStruct{ bottomRight.X, curY }), DirType::East)) - { - if (HouseClass* const pOwner = pUnit->Owner) - pOwner->GiveMoney(pUnit->Type->GetActualCost(pOwner)); - - pUnit->KillPassengers(nullptr); - pUnit->Stun(); - pUnit->Limbo(); - pUnit->UnInit(); - continue; - } + if (TeamClass* const pTeam = pUnit->Team) + pTeam->LiberateMember(pUnit); + pThis->SendCommand(RadioCommand::RequestLink, pUnit); + pThis->QueueMission(Mission::Unload, false); break; // one after another } } From e64c545df872d4d247dafa430198be7f36562ae5 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Wed, 14 Aug 2024 00:54:06 +0800 Subject: [PATCH 16/21] Fix --- src/Ext/Building/Body.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/Ext/Building/Body.cpp b/src/Ext/Building/Body.cpp index 2262970237..3ef7266600 100644 --- a/src/Ext/Building/Body.cpp +++ b/src/Ext/Building/Body.cpp @@ -345,10 +345,18 @@ bool BuildingExt::ExtData::HandleInfiltrate(HouseClass* pInfiltratorHouse,int mo void BuildingExt::KickOutStuckUnits(BuildingClass* pThis) { - if (pThis->GetNthLink()) + if (TechnoClass* const pTechno = pThis->GetNthLink()) { - pThis->QueueMission(Mission::Unload, false); - return; + if (UnitClass* const pUnit = abstract_cast(pTechno)) + { + if (TeamClass* const pTeam = pUnit->Team) + pTeam->LiberateMember(pUnit); + + pUnit->SetDestination(nullptr, false); + pUnit->ForceMission(Mission::Guard); + pThis->QueueMission(Mission::Unload, false); + return; + } } BuildingTypeClass* const pType = pThis->Type; @@ -379,6 +387,8 @@ void BuildingExt::KickOutStuckUnits(BuildingClass* pThis) if (TeamClass* const pTeam = pUnit->Team) pTeam->LiberateMember(pUnit); + pUnit->SetDestination(nullptr, false); + pUnit->ForceMission(Mission::Guard); pThis->SendCommand(RadioCommand::RequestLink, pUnit); pThis->QueueMission(Mission::Unload, false); break; // one after another From cad816852bf3b7bde7f448cd6dfe8132a21da170 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Wed, 14 Aug 2024 18:08:21 +0800 Subject: [PATCH 17/21] Fix --- src/Ext/Building/Body.cpp | 25 ++++++++++++++----------- src/Ext/Building/Hooks.cpp | 4 ++-- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/Ext/Building/Body.cpp b/src/Ext/Building/Body.cpp index 3ef7266600..35e4f77110 100644 --- a/src/Ext/Building/Body.cpp +++ b/src/Ext/Building/Body.cpp @@ -349,16 +349,21 @@ void BuildingExt::KickOutStuckUnits(BuildingClass* pThis) { if (UnitClass* const pUnit = abstract_cast(pTechno)) { - if (TeamClass* const pTeam = pUnit->Team) - pTeam->LiberateMember(pUnit); + if (pUnit->CurrentMission != Mission::Enter) + { + if (TeamClass* const pTeam = pUnit->Team) + pTeam->LiberateMember(pUnit); - pUnit->SetDestination(nullptr, false); - pUnit->ForceMission(Mission::Guard); - pThis->QueueMission(Mission::Unload, false); - return; + pUnit->SetDestination(nullptr, false); + pUnit->ForceMission(Mission::Guard); + pThis->QueueMission(Mission::Unload, false); + return; // one after another + } } } +// CoordStruct buffer = CoordStruct::Empty; +// CellClass* const pCell = MapClass::Instance->GetCellAt(*pThis->GetExitCoords(&buffer, 0)); BuildingTypeClass* const pType = pThis->Type; const CellStruct foundation { pType->GetFoundationWidth(), pType->GetFoundationHeight(false) }; const CellStruct topLeft = pThis->GetMapCoords() + CellStruct { 1, 1 }; @@ -372,11 +377,9 @@ void BuildingExt::KickOutStuckUnits(BuildingClass* pThis) { for (ObjectClass* pObject = pCell->FirstObject; pObject; pObject = pObject->NextObject) { - if (pObject->WhatAmI() == AbstractType::Unit) + if (UnitClass* const pUnit = abstract_cast(pObject)) { - UnitClass* const pUnit = static_cast(pObject); - - if (pThis->Owner != pUnit->Owner) + if (pThis->Owner != pUnit->Owner || pUnit->CurrentMission == Mission::Enter) continue; const int height = pUnit->GetHeight(); @@ -391,7 +394,7 @@ void BuildingExt::KickOutStuckUnits(BuildingClass* pThis) pUnit->ForceMission(Mission::Guard); pThis->SendCommand(RadioCommand::RequestLink, pUnit); pThis->QueueMission(Mission::Unload, false); - break; // one after another + return; // one after another } } } diff --git a/src/Ext/Building/Hooks.cpp b/src/Ext/Building/Hooks.cpp index a29004577b..a224467957 100644 --- a/src/Ext/Building/Hooks.cpp +++ b/src/Ext/Building/Hooks.cpp @@ -329,11 +329,11 @@ DEFINE_HOOK(0x450248, BuildingClass_UpdateFactory_KickOutStuckUnits, 0x6) { GET(BuildingClass*, pThis, ESI); - if (!(Unsorted::CurrentFrame % 15) && pThis->GetCurrentMission() == Mission::Guard) + if (!(Unsorted::CurrentFrame % 15) && pThis->CurrentMission == Mission::Guard) { BuildingTypeClass* const pType = pThis->Type; - if (pType->Factory == AbstractType::UnitType && pType->WeaponsFactory) + if (pType->Factory == AbstractType::UnitType && pType->WeaponsFactory && !pType->Naval) BuildingExt::KickOutStuckUnits(pThis); } From 010a3471057797ba7dc68d2f311b70205e7329b2 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Sun, 25 Aug 2024 00:30:05 +0800 Subject: [PATCH 18/21] Add conditions --- src/Ext/Building/Hooks.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/Ext/Building/Hooks.cpp b/src/Ext/Building/Hooks.cpp index a224467957..c397cc245e 100644 --- a/src/Ext/Building/Hooks.cpp +++ b/src/Ext/Building/Hooks.cpp @@ -329,27 +329,32 @@ DEFINE_HOOK(0x450248, BuildingClass_UpdateFactory_KickOutStuckUnits, 0x6) { GET(BuildingClass*, pThis, ESI); - if (!(Unsorted::CurrentFrame % 15) && pThis->CurrentMission == Mission::Guard) + if (!(Unsorted::CurrentFrame % 15)) { BuildingTypeClass* const pType = pThis->Type; - if (pType->Factory == AbstractType::UnitType && pType->WeaponsFactory && !pType->Naval) - BuildingExt::KickOutStuckUnits(pThis); + 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, 0x7) +DEFINE_HOOK(0x4444A0, BuildingClass_KickOutUnit_NoKickOutInConstruction, 0xA) { - enum { OfCourse = 0x444565, NoChance = 0x4444B3}; + enum { ThisIsOK = 0x444565, ThisIsNotOK = 0x4444B3}; GET(BuildingClass* const, pThis, ESI); const Mission mission = pThis->GetCurrentMission(); - return (mission == Mission::Unload || mission == Mission::Construction) ? NoChance : OfCourse; + return (mission == Mission::Unload || mission == Mission::Construction) ? ThisIsNotOK : ThisIsOK; } // Ares didn't have something like 0x7397E4 in its UnitDelivery code From 000095bdaf6076e4978add597f1bec2705b76f28 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Sun, 25 Aug 2024 00:32:29 +0800 Subject: [PATCH 19/21] Fix a bug that units kicked out from the factory building inside will still get stuck at the door --- src/Ext/Building/Body.cpp | 52 ++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 31 deletions(-) diff --git a/src/Ext/Building/Body.cpp b/src/Ext/Building/Body.cpp index 35e4f77110..83d2233021 100644 --- a/src/Ext/Building/Body.cpp +++ b/src/Ext/Building/Body.cpp @@ -349,54 +349,44 @@ void BuildingExt::KickOutStuckUnits(BuildingClass* pThis) { if (UnitClass* const pUnit = abstract_cast(pTechno)) { - if (pUnit->CurrentMission != Mission::Enter) + if (!pUnit->unknown_bool_418 && pUnit->GetCurrentSpeed() <= 0) { if (TeamClass* const pTeam = pUnit->Team) pTeam->LiberateMember(pUnit); - pUnit->SetDestination(nullptr, false); - pUnit->ForceMission(Mission::Guard); - pThis->QueueMission(Mission::Unload, false); + if (pThis->CurrentMission == Mission::Guard) + pThis->QueueMission(Mission::Unload, false); + else + pThis->SendCommand(RadioCommand::NotifyUnlink, pUnit); + + pUnit->QueueMission(Mission::Guard, false); return; // one after another } } } -// CoordStruct buffer = CoordStruct::Empty; -// CellClass* const pCell = MapClass::Instance->GetCellAt(*pThis->GetExitCoords(&buffer, 0)); - BuildingTypeClass* const pType = pThis->Type; - const CellStruct foundation { pType->GetFoundationWidth(), pType->GetFoundationHeight(false) }; - const CellStruct topLeft = pThis->GetMapCoords() + CellStruct { 1, 1 }; - const CellStruct bottomRight = topLeft + foundation - CellStruct { 2, 2 }; + CoordStruct buffer = CoordStruct::Empty; - for (short curX = topLeft.X; curX < bottomRight.X; ++curX) + if (CellClass* const pCell = MapClass::Instance->GetCellAt(*pThis->GetExitCoords(&buffer, 0))) { - for (short curY = topLeft.Y; curY < bottomRight.Y; ++curY) + for (ObjectClass* pObject = pCell->FirstObject; pObject; pObject = pObject->NextObject) { - if (CellClass* const pCell = MapClass::Instance->GetCellAt(CellStruct{ curX, curY })) + if (UnitClass* const pUnit = abstract_cast(pObject)) { - for (ObjectClass* pObject = pCell->FirstObject; pObject; pObject = pObject->NextObject) - { - if (UnitClass* const pUnit = abstract_cast(pObject)) - { - if (pThis->Owner != pUnit->Owner || pUnit->CurrentMission == Mission::Enter) - continue; + if (pThis->Owner != pUnit->Owner || pUnit->unknown_bool_418) + continue; - const int height = pUnit->GetHeight(); + const int height = pUnit->GetHeight(); - if (height < 0 || height > Unsorted::CellHeight) - continue; + if (height < 0 || height > Unsorted::CellHeight) + continue; - if (TeamClass* const pTeam = pUnit->Team) - pTeam->LiberateMember(pUnit); + if (TeamClass* const pTeam = pUnit->Team) + pTeam->LiberateMember(pUnit); - pUnit->SetDestination(nullptr, false); - pUnit->ForceMission(Mission::Guard); - pThis->SendCommand(RadioCommand::RequestLink, pUnit); - pThis->QueueMission(Mission::Unload, false); - return; // one after another - } - } + pThis->SendCommand(RadioCommand::RequestLink, pUnit); + pThis->QueueMission(Mission::Unload, false); + return; // one after another } } } From 6796f90374ad5f971a6ad097398697cb7a356909 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Sun, 25 Aug 2024 13:45:05 +0800 Subject: [PATCH 20/21] Fix an issue that caused a delay in kicking out --- src/Ext/Building/Body.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Ext/Building/Body.cpp b/src/Ext/Building/Body.cpp index 83d2233021..cb9111e428 100644 --- a/src/Ext/Building/Body.cpp +++ b/src/Ext/Building/Body.cpp @@ -354,11 +354,7 @@ void BuildingExt::KickOutStuckUnits(BuildingClass* pThis) if (TeamClass* const pTeam = pUnit->Team) pTeam->LiberateMember(pUnit); - if (pThis->CurrentMission == Mission::Guard) - pThis->QueueMission(Mission::Unload, false); - else - pThis->SendCommand(RadioCommand::NotifyUnlink, pUnit); - + pThis->SendCommand(RadioCommand::NotifyUnlink, pUnit); pUnit->QueueMission(Mission::Guard, false); return; // one after another } From ddbaac7062c26bee33fd50be145ede325d958e54 Mon Sep 17 00:00:00 2001 From: CrimRecya <335958461@qq.com> Date: Wed, 18 Sep 2024 23:20:55 +0800 Subject: [PATCH 21/21] Update Fixed-or-Improved-Logics.md --- docs/Fixed-or-Improved-Logics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Fixed-or-Improved-Logics.md b/docs/Fixed-or-Improved-Logics.md index 2907778b4a..f31339236d 100644 --- a/docs/Fixed-or-Improved-Logics.md +++ b/docs/Fixed-or-Improved-Logics.md @@ -161,7 +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. If the unit is not able to kick out from the factory, the unit will be removed and the cost will be given back to its house. +- 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.