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 @@ -287,6 +287,7 @@ This page lists all the individual contributions to the project by their author.
- Deploy priority filtering
- Customizable paradrop missions
- Guard range customizations
- Buildable-upon OverlayTypes
- **Morton (MortonPL)**:
- `XDrawOffset` for animations
- Shield passthrough & absorption
Expand Down
2 changes: 1 addition & 1 deletion YRpp
Submodule YRpp updated 1 files
+3 −0 HouseClass.h
41 changes: 36 additions & 5 deletions docs/Fixed-or-Improved-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ This page describes all ingame logics that are fixed or improved in Phobos witho
- Fixed `DeployToFire` not considering building placement rules for `DeploysInto` buildings and as a result not working properly with `WaterBound` buildings.
- Fixed `DeployToFire` not recalculating firer's position on land if it cannot currently deploy.
- `Arcing=true` projectile elevation inaccuracy can now be fixed by setting `Arcing.AllowElevationInaccuracy=false`.
- Wall overlays are now drawn with the custom palette defined in `Palette` in `artmd.ini` if possible.
- Setting `ReloadInTransport` to true on units with `Ammo` will allow the ammo to be reloaded according to `Reload` or `EmptyReload` timers even while the unit is inside a transport.
- It is now possible to enable `Verses` and `PercentAtMax` to be applied on negative damage by setting `ApplyModifiersOnNegativeDamage` to true on the Warhead.
- Attached animations on flying units now have their layer updated immediately after the parent unit, if on same layer they always draw above the parent.
Expand Down Expand Up @@ -146,7 +145,6 @@ This page describes all ingame logics that are fixed or improved in Phobos witho
- Units & buildings with `DecloakToFire=false` weapons now cloak while targeting & reloading.
- Units with `Sensors=true` will no longer reveal ally buildings.
- Air units are now reliably included by target scan with large range and Warhead detonation by large `CellSpread`.
- OverlayTypes now read and use `ZAdjust` if specified in their `artmd.ini` entry.
- Weapons with `AA=true` Projectile can now correctly fire at air units when both firer and target are over a bridge.
- 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.
Expand Down Expand Up @@ -221,7 +219,6 @@ This page describes all ingame logics that are fixed or improved in Phobos witho
- Fixed the bug that infantry ignored `Passengers` and `SizeLimit` when entering buildings.
- Fixed `VoiceDeploy` not played, when deployed through hot-key/command bar.
- Fixed the bug that ships can travel on elevated bridges.
- Dehardcoded 255 limit of `OverlayType`.
- Fixed an issue where airstrike flare line drawn to target at lower elevation would clip.
- Elite technos no longer scatter by default, behaviour is controlled by `SCATTER` veterancy ability now.
- Second weapon with `ElectricAssault=yes` will not unconditionally attack your building with `Overpowerable=yes`.
Expand Down Expand Up @@ -1176,9 +1173,43 @@ ProneSpeed.NoCrawls=1.5 ; floating point value, multiplier
ProneSpeed= ; floating point value, multiplier, by default, use the corresponding global value according to Crawls
```

<!--
## Overlays
-->

### Buildable-upon OverlayTypes

- It is now possible to make OverlayTypes allow buildings to be placed on them by setting `CanBeBuiltOn` to true. This still requires the tile's landtype (which is changed to overlay's land type unless OverlayType has `NoUseTileLandType=false`) to allow buildings to be placed.
- If `CanBeBuiltOn.Remove=true`, the overlay will be removed (if it is a wall owned by the player placing the building, it is sold) upon the building being placed. If this is not set to true, buildings with `Wall=true` cannot be placed on the overlay and neither does overlay with `Wall=true` allow buildings to be placed on itself regardless of other settings.

In `rulesmd.ini`:
```ini
[SOMEOVERLAY] ; OverlayType
CanBeBuiltOn=false ; boolean
CanBeBuiltOn.Remove=true ; boolean
```

### More than 255 OverlayTypes

- Game now supports more than 255 distinct OverlayTypes, up to 65535. For map file/editor support, see [Increased Overlay Limit](AI-Scripting-and-Mapping.md#increased-overlay-limit).

### Custom palette

- You can now specify custom palette for OverlayTypes in similar manner as TechnoTypes can.

In `artmd.ini`:
```ini
[SOMETERRAINTYPE] ; TerrainType
Palette= ; filename - excluding .pal extension and three-character theater-specific suffix
```

### ZAdjust

- OverlayTypes now read and use `ZAdjust`.

In `artmd.ini`:
```ini
[SOMEOVERLAY] ; OverlayType image
ZAdjust=0
```

## Particle systems

Expand Down
1 change: 1 addition & 0 deletions docs/Whats-New.md
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,7 @@ New:
- Allow jumpjet climbing ignore building height (by TaranDahl)
- Allow draw SuperWeapon timer as percentage (by NetsuNegi)
- Customize particle system of parasite logic (by NetsuNegi)
- [Buildable-upon OverlayTypes](Fixed-or-Improved-Logics.md#buildable-upon-overlaytypes) (by Starkku)

Vanilla fixes:
- Fixed sidebar not updating queued unit numbers when adding or removing units when the production is on hold (by CrimRecya)
Expand Down
48 changes: 42 additions & 6 deletions src/Ext/OverlayType/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,46 @@

OverlayTypeExt::ExtContainer OverlayTypeExt::ExtMap;

bool OverlayTypeExt::CanBeBuiltOn(int overlayTypeIndex, BuildingTypeClass* pBuildingType, bool requireToBeRemovable)
{
auto const pOverlayType = OverlayTypeClass::Array[overlayTypeIndex];
auto const pTypeExt = OverlayTypeExt::ExtMap.Find(pOverlayType);

if (!pTypeExt->CanBeBuiltOn)
return false;

if (((pBuildingType && pBuildingType->Wall) || pOverlayType->Wall) && !pTypeExt->CanBeBuiltOn_Remove)
return false;

return requireToBeRemovable ? pTypeExt->CanBeBuiltOn_Remove : true;
}

void OverlayTypeExt::RemoveOverlayFromCell(int overlayTypeIndex, CellClass* pCell, HouseClass* pSource)
{
if (overlayTypeIndex != -1 && OverlayTypeClass::Array[overlayTypeIndex]->Wall)
{
if (pSource && pCell->WallOwnerIndex == pSource->ArrayIndex)
pSource->SellWall(pCell->MapCoords, true);
else
pCell->DamageWall(-1);
}
else
{
pCell->OverlayTypeIndex = -1;
pCell->OverlayData = 0;
pCell->RecalcAttributes(-1);
}
}

// =============================
// load / save

template <typename T>
void OverlayTypeExt::ExtData::Serialize(T& Stm)
{
Stm
.Process(this->CanBeBuiltOn)
.Process(this->CanBeBuiltOn_Remove)
.Process(this->ZAdjust)
.Process(this->PaletteFile)
;
Expand All @@ -18,12 +51,15 @@ void OverlayTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI)
{
auto pThis = this->OwnerObject();

//const char* pSection = pThis->ID;
//
//if (!pINI->GetSection(pSection))
// return;
//
//INI_EX exINI(pINI);
const char* pSection = pThis->ID;

if (!pINI->GetSection(pSection))
return;

INI_EX exINI(pINI);

this->CanBeBuiltOn.Read(exINI, pSection, "CanBeBuiltOn");
this->CanBeBuiltOn_Remove.Read(exINI, pSection, "CanBeBuiltOn.Remove");

auto pArtSection = pThis->ImageFile;
INI_EX exArtINI(&CCINIClass::INI_Art);
Expand Down
7 changes: 7 additions & 0 deletions src/Ext/OverlayType/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,15 @@ class OverlayTypeExt
class ExtData final : public Extension<OverlayTypeClass>
{
public:
Valueable<bool> CanBeBuiltOn;
Valueable<bool> CanBeBuiltOn_Remove;
Valueable<int> ZAdjust;
PhobosFixedString<32u> PaletteFile;
DynamicVectorClass<ColorScheme*>* Palette; // Intentionally not serialized - rebuilt from the palette file on load.

ExtData(OverlayTypeClass* OwnerObject) : Extension<OverlayTypeClass>(OwnerObject)
, CanBeBuiltOn { false }
, CanBeBuiltOn_Remove { true }
, ZAdjust { 0 }
, PaletteFile {}
, Palette {}
Expand Down Expand Up @@ -50,4 +54,7 @@ class OverlayTypeExt

static bool LoadGlobals(PhobosStreamReader& Stm);
static bool SaveGlobals(PhobosStreamWriter& Stm);

static bool CanBeBuiltOn(int overlayTypeIndex, BuildingTypeClass* pBuildingType, bool requireToBeRemovable);
static void RemoveOverlayFromCell(int overlayTypeIndex, CellClass* pCell, HouseClass* pSource);
};
35 changes: 35 additions & 0 deletions src/Ext/OverlayType/Hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,38 @@ DEFINE_HOOK(0x47F974, CellClass_DrawOverlay_Walls, 0x5)

return SkipGameCode;
}

#pragma region CanBeBuiltOn

DEFINE_HOOK(0x47C9A7, CellClass_IsClearToBuild_Overlays, 0x5)
{
enum { ReturnFromFunction = 0x47C6D1, CheckTileLandType = 0x47C9CD };

GET(CellClass*, pThis, EDI);
GET_STACK(BuildingTypeClass*, pBuildingType, STACK_OFFSET(0x18, 0x8));

int overlayTypeIndex = pThis->OverlayTypeIndex;

if (overlayTypeIndex != -1)
{
if (OverlayTypeExt::CanBeBuiltOn(overlayTypeIndex, pBuildingType, false))
return CheckTileLandType;
}

return ReturnFromFunction;
}

DEFINE_HOOK(0x45EF11, BuildingTypeClass_FlushForPlacement_Overlays, 0x6)
{
enum { Continue = 0x45EF2C };

GET(BuildingTypeClass*, pThis, EBX);
GET(int, overlayTypeIndex, ECX);

if (OverlayTypeExt::CanBeBuiltOn(overlayTypeIndex, pThis, false))
return Continue;

return 0;
}

#pragma endregion
11 changes: 11 additions & 0 deletions src/Ext/TerrainType/Hooks.Passable.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "Body.h"
#include <Ext/OverlayType/Body.h>

constexpr bool IS_CELL_OCCUPIED(CellClass* pCell)
{
Expand Down Expand Up @@ -113,6 +114,16 @@ DEFINE_HOOK(0x5684B1, MapClass_PlaceDown_BuildableTerrain, 0x6)
TerrainTypeExt::Remove(pTerrain);
}
}

int overlayTypeIndex = pCell->OverlayTypeIndex;

if (overlayTypeIndex != -1)
{
auto const pBuildingType = static_cast<BuildingTypeClass*>(pObject->GetType());

if (OverlayTypeExt::CanBeBuiltOn(overlayTypeIndex, pBuildingType, true))
OverlayTypeExt::RemoveOverlayFromCell(overlayTypeIndex, pCell, pObject->GetOwningHouse());
}
}

return 0;
Expand Down