Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CREDITS.md
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,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
Expand Down
7 changes: 7 additions & 0 deletions docs/New-or-Enhanced-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -2111,6 +2111,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)
Expand Down
1 change: 1 addition & 0 deletions docs/Whats-New.md
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,7 @@ New:
- [Interceptor target scan delay customization](New-or-Enhanced-Logics.md#projectile-interception-logic) (by Starkku)
- Allow deploy controlled MCV (by NetsuNegi)
- Customize if cloning need power (by NetsuNegi)
- 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)
Expand Down
2 changes: 2 additions & 0 deletions src/Ext/TechnoType/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1668,6 +1668,8 @@ void TechnoTypeExt::ExtData::Serialize(T& Stm)
.Process(this->InfantryAutoDeploy)

.Process(this->TurretResponse)

.Process(this->TurretShape)
;
}
void TechnoTypeExt::ExtData::LoadFromStream(PhobosStreamReader& Stm)
Expand Down
4 changes: 4 additions & 0 deletions src/Ext/TechnoType/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,8 @@ class TechnoTypeExt

Nullable<bool> TurretResponse;

SHPStruct* TurretShape;

ExtData(TechnoTypeClass* OwnerObject) : Extension<TechnoTypeClass>(OwnerObject)
, HealthBar_Hide { false }
, HealthBar_HidePips { false }
Expand Down Expand Up @@ -826,6 +828,8 @@ class TechnoTypeExt
, InfantryAutoDeploy {}

, TurretResponse {}

, TurretShape { nullptr }
{ }

virtual ~ExtData() = default;
Expand Down
27 changes: 27 additions & 0 deletions src/Ext/TechnoType/Hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
27 changes: 26 additions & 1 deletion src/Ext/Unit/Hooks.DrawIt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>();
Expand All @@ -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;
}