From c8a511a76d1dda84a4e8485e784b11684eb7b2dd Mon Sep 17 00:00:00 2001 From: Fly-Star <100747645+a851903106@users.noreply.github.com> Date: Sun, 2 Nov 2025 12:27:02 +0800 Subject: [PATCH 1/2] SHP turret vehicles support the use of `*tur.shp` files --- CREDITS.md | 1 + docs/Whats-New.md | 1 + src/Ext/TechnoType/Body.cpp | 2 ++ src/Ext/TechnoType/Body.h | 4 ++++ src/Ext/TechnoType/Hooks.cpp | 27 +++++++++++++++++++++++++++ src/Ext/Unit/Hooks.DrawIt.cpp | 27 ++++++++++++++++++++++++++- 6 files changed, 61 insertions(+), 1 deletion(-) diff --git a/CREDITS.md b/CREDITS.md index 5a508b272e..718d6bfd5e 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -396,6 +396,7 @@ This page lists all the individual contributions to the project by their author. - Fast access structure - Iron Curtain/Custom Tint Support for SHP Turreted Vehicles - Reactivate unused trigger events 2, 53, and 54 + - SHP turret vehicles support the use of `*tur.shp` files - **NetsuNegi**: - Forbidding parallel AI queues by type - Jumpjet crash speed fix when crashing onto building diff --git a/docs/Whats-New.md b/docs/Whats-New.md index ce89f81c75..ff96aff918 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -457,6 +457,7 @@ New: - Fast access structure (by FlyStar) - Toggle off laser trail and shake effects (by Ollerus) - [Dehardcode the `ZAdjust` of warhead anim](Fixed-or-Improved-Logics.md#dehardcode-the-zadjust-of-warhead-anim) (by TaranDahl) +- SHP turret vehicles support the use of `*tur.shp` files (by FlyStar) Vanilla fixes: - Fixed sidebar not updating queued unit numbers when adding or removing units when the production is on hold (by CrimRecya) diff --git a/src/Ext/TechnoType/Body.cpp b/src/Ext/TechnoType/Body.cpp index cf59f3baac..51af1838b4 100644 --- a/src/Ext/TechnoType/Body.cpp +++ b/src/Ext/TechnoType/Body.cpp @@ -1658,6 +1658,8 @@ void TechnoTypeExt::ExtData::Serialize(T& Stm) .Process(this->InfantryAutoDeploy) .Process(this->TurretResponse) + + .Process(this->TurretShape) ; } void TechnoTypeExt::ExtData::LoadFromStream(PhobosStreamReader& Stm) diff --git a/src/Ext/TechnoType/Body.h b/src/Ext/TechnoType/Body.h index efe25a53e1..22aacfa2a7 100644 --- a/src/Ext/TechnoType/Body.h +++ b/src/Ext/TechnoType/Body.h @@ -434,6 +434,8 @@ class TechnoTypeExt Nullable TurretResponse; + SHPStruct* TurretShape; + ExtData(TechnoTypeClass* OwnerObject) : Extension(OwnerObject) , HealthBar_Hide { false } , HealthBar_HidePips { false } @@ -818,6 +820,8 @@ class TechnoTypeExt , InfantryAutoDeploy {} , TurretResponse {} + + , TurretShape { nullptr } { } virtual ~ExtData() = default; diff --git a/src/Ext/TechnoType/Hooks.cpp b/src/Ext/TechnoType/Hooks.cpp index d873c710ac..866ae9e55a 100644 --- a/src/Ext/TechnoType/Hooks.cpp +++ b/src/Ext/TechnoType/Hooks.cpp @@ -128,3 +128,30 @@ DEFINE_HOOK(0x71464A, TechnoTypeClass_ReadINI_Speed, 0x7) return SkipGameCode; } + +DEFINE_HOOK(0x747A2E, UnitTypeClass_ReadINI_TurretShape, 0x6) +{ + GET(UnitTypeClass*, pType, EDI); + + if (!pType->Voxel && pType->Turret) + { + char nameBuffer[0x19]; + char Buffer[260]; + const auto pArtSection = pType->ImageFile; + + if (Phobos::Config::ArtImageSwap && + CCINIClass::INI_Art.ReadString(pArtSection, "Image", 0, nameBuffer, 0x19) != 0) + { + _snprintf_s(Buffer, sizeof(Buffer), "%sTUR.SHP", nameBuffer); + } + else + { + _snprintf_s(Buffer, sizeof(Buffer), "%sTUR.SHP", pArtSection); + } + + if (const auto pShape = FileSystem::LoadSHPFile(Buffer)) + TechnoTypeExt::ExtMap.Find(pType)->TurretShape = pShape; + } + + return 0; +} diff --git a/src/Ext/Unit/Hooks.DrawIt.cpp b/src/Ext/Unit/Hooks.DrawIt.cpp index b2c44ed79e..53d6649278 100644 --- a/src/Ext/Unit/Hooks.DrawIt.cpp +++ b/src/Ext/Unit/Hooks.DrawIt.cpp @@ -29,8 +29,14 @@ DEFINE_HOOK(0x73C7AC, UnitClass_DrawAsSHP_DrawTurret_TintFix, 0x6) pThis->Draw_A_SHP(pShape, bodyFrameIdx, &location, &bounds, 0, 256, zAdjust, zGradient, 0, extraLight, 0, 0, 0, 0, 0, 0); + const auto pTurretShape = TechnoTypeExt::ExtMap.Find(pType)->TurretShape; + const int StartFrame = pTurretShape ? 0 : (pType->WalkFrames * pType->Facings); + + if (pTurretShape) + pShape = pTurretShape; + const auto secondaryDir = pThis->SecondaryFacing.Current(); - const int frameIdx = secondaryDir.GetFacing<32>(4) + pType->WalkFrames * pType->Facings; + const int frameIdx = secondaryDir.GetFacing<32>(4) + StartFrame; const auto primaryDir = pThis->PrimaryFacing.Current(); const double bodyRad = primaryDir.GetRadian<32>(); @@ -50,3 +56,22 @@ DEFINE_HOOK(0x73C7AC, UnitClass_DrawAsSHP_DrawTurret_TintFix, 0x6) Game::bDrawShadow = originalDrawShadow; return SkipDrawCode; } + +DEFINE_HOOK(0x73CCF4, UnitClass_DrawSHP_FacingsB_TurretShape, 0xA) +{ + enum { SkipGameCode = 0x73CD06 }; + + GET(UnitClass*, pThis, EBP); + GET(UnitTypeClass*, pType, ECX); + + const auto pTurretShape = TechnoTypeExt::ExtMap.Find(pType)->TurretShape; + const int StartFrame = pTurretShape ? 0 : (pType->WalkFrames * pType->Facings); + const int frameIdx = pThis->SecondaryFacing.Current().GetFacing<32>(4) + StartFrame; + + if (pTurretShape) + R->EDI(pTurretShape); + + R->ECX(pThis); + R->EAX(frameIdx); + return 0x73CD06; +} From 0604167757a34859f22c1cfc206489431f335c12 Mon Sep 17 00:00:00 2001 From: Fly-Star <100747645+a851903106@users.noreply.github.com> Date: Sun, 16 Nov 2025 21:17:26 +0800 Subject: [PATCH 2/2] Update New-or-Enhanced-Logics.md --- docs/New-or-Enhanced-Logics.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index d04603a742..39cdc03fa0 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -2094,6 +2094,13 @@ WaterImage.ConditionRed= ; VehicleType entry Note that the VehicleTypes had to be defined under [VehicleTypes] and use same image type (SHP/VXL) for vanilla/damaged states. ``` +### Independent SHP Vehicle Turret Files + +- SHP turret vehicles support the use of `*tur.shp` files. + - If the SHP vehicle has a Shape file named `* tur.shp` when drawing the turret, the start frame becomes 0; Otherwise, it is still `WalkFrames * Facings`. + - If you want to split the existing shape file in two, you only need to separate the 32-frame image of the turret and the corresponding 32-frame shadow from the source file and combine them into a new shape file. + - When the turrets of carrier-based vehicles need to be replaced, dividing them into two files can reduce troublesome steps. + ### Jumpjet Tilts While Moving ![image](_static/images/jumpjet-tilt.gif)