Skip to content

Commit

Permalink
Veinholes and Weeders (Phobos-developers#1163)
Browse files Browse the repository at this point in the history
* Veinholes and Weeders

Prettify

Minor fixes

Rewrote tiberium pip code

Clean up some things

Removed controversial stuff

Removed leftovers, started work on docs

Docs

Requested changes

Updated docs, added named constant

Re-enabled oregath

Apply suggestions from code review

Co-authored-by: Kerbiter <[email protected]>
Added braces around nested loops

Teleporting weeders now work

* Fix after rebase

* Add changelog entries

* Fix not enough pips being displayed. Fix compiler warnings

* Fix spelling

* Change docs

* Remove duplicate string

* Update docs

* Use note syntax for compatibility notice

* Fix spelling and formatting

* Apply suggestions from code review

Co-authored-by: Kerbiter <[email protected]>

* More review suggestions

* Add links to docs

* Improve docs

* Rename constant

---------

Co-authored-by: Kerbiter <[email protected]>
  • Loading branch information
ZivDero and Metadorius authored Mar 19, 2024
1 parent 5a845b7 commit d9db475
Show file tree
Hide file tree
Showing 16 changed files with 915 additions and 29 deletions.
3 changes: 3 additions & 0 deletions CREDITS.md
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,9 @@ This page lists all the individual contributions to the project by their author.
- Flashing Technos on selecting
- **ZivDero**
- Allow giving ownership of buildings to players in Skirmish and MP using <Player @ A-H>
- 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
- **Ares developers**
- YRpp and Syringe which are used, save/load, project foundation and generally useful code from Ares
- unfinished RadTypes code
Expand Down
4 changes: 4 additions & 0 deletions Phobos.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
<ClCompile Include="src\Ext\CaptureManager\Body.cpp" />
<ClCompile Include="src\Ext\OverlayType\Body.cpp" />
<ClCompile Include="src\Ext\OverlayType\Hooks.cpp" />
<ClCompile Include="src\Ext\ParticleType\Body.cpp" />
<ClCompile Include="src\Ext\ParticleType\Hooks.cpp" />
<ClCompile Include="src\Ext\Scenario\Hooks.cpp" />
<ClCompile Include="src\Ext\Scenario\Hooks.Variables.cpp" />
<ClCompile Include="src\Ext\Sidebar\Body.cpp" />
Expand All @@ -61,6 +63,7 @@
<ClCompile Include="src\Misc\Hooks.AssignHouses.cpp" />
<ClCompile Include="src\Misc\Hooks.Gamespeed.cpp" />
<ClCompile Include="src\Misc\Hooks.Ares.cpp" />
<ClCompile Include="src\Misc\Hooks.VeinholeMonster.cpp" />
<ClCompile Include="src\Misc\PhobosToolTip.cpp" />
<ClCompile Include="src\Misc\TextInput.cpp" />
<ClCompile Include="src\New\Entity\ShieldClass.cpp" />
Expand Down Expand Up @@ -189,6 +192,7 @@
<ClInclude Include="src\Ext\Bullet\Trajectories\PhobosTrajectory.h" />
<ClInclude Include="src\Ext\Bullet\Trajectories\StraightTrajectory.h" />
<ClInclude Include="src\Ext\OverlayType\Body.h" />
<ClInclude Include="src\Ext\ParticleType\Body.h" />
<ClInclude Include="src\Ext\Sidebar\Body.h" />
<ClInclude Include="src\Ext\Anim\Body.h" />
<ClInclude Include="src\Ext\Surface\Body.h" />
Expand Down
101 changes: 100 additions & 1 deletion docs/Fixed-or-Improved-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,18 @@ In `rulesmd.ini`:
AdjustTargetCoordsOnRotation=true ; boolean
```

## Particles

### Customizable gas particle speed

- Gas particles can now drift at a custom speed.

In `rulesmd.ini`:
```ini
[GASPARTICLE] ; Particle with BehavesLike=Gas
Gas.MaxDriftSpeed=2 ; integer (TS default is 5)
```

## Projectiles

### Cluster scatter distance customization
Expand All @@ -367,7 +379,7 @@ AdjustTargetCoordsOnRotation=true ; boolean

In `rulesmd.ini`:
```ini
[SOMEPROJECTILE] ; Projectile
[SOMEPROJECTILE] ; Projectile
ClusterScatter.Min=1.0 ; float, distance in cells
ClusterScatter.Max=2.0 ; float, distance in cells
```
Expand Down Expand Up @@ -626,6 +638,8 @@ Powered.KillSpawns=false ; boolean
- `Pips.Tiberiums.Frames` can be used to list frames (zero-based) of `pips.shp` (for buildings) or `pips2.shp` (for others) used for tiberium types, in the listed order corresponding to tiberium type index. Defaults to 5 for tiberium type index 1, otherwise 2.
- `Pips.Tiberiums.EmptyFrame` can be used to set the frame for empty slots, defaults to 0.
- `Pips.Tiberiums.DisplayOrder` controls in which order the tiberium type pips are displayed, takes a list of tiberium type indices. Any tiberium type not listed will be displayed in sequential order after the listed ones.
- `Pips.Tiberiums.WeedFrame` controls which frame is displayed on Technos with `Weeder=yes`, takes a (zero-based) index of a frame in `pips.shp` (for buildings) or `pips2.shp` (for others). Defaults to 1.
- `Pips.Tiberiums.WeedEmptyFrame` can be used to set the frame for empty weed slots, defaults to 0.

In `rulesmd.ini`:
```ini
Expand All @@ -637,6 +651,8 @@ Pips.Ammo.Buildings.Size=4,2 ; X,Y, increment in pixels to next pip
Pips.Tiberiums.EmptyFrame=0 ; integer, frame of pips.shp (buildings) or pips2.shp (others) (zero-based)
Pips.Tiberiums.Frames=2,5,2,2 ; list of integers, frames of pips.shp (buildings) or pips2.shp (others) (zero-based)
Pips.Tiberiums.DisplayOrder=0,2,3,1 ; list of integers, tiberium type indices
Pips.Tiberiums.WeedEmptyFrame=0 ; integer, frame of pips.shp (buildings) or pips2.shp (others) (zero-based)
Pips.Tiberiums.WeedFrame=1 ; integer, frame of pips.shp (buildings) or pips2.shp (others) (zero-based)

[SOMETECHNO] ; TechnoType
AmmoPipFrame=13 ; integer, frame of pips2.shp (zero-based)
Expand Down Expand Up @@ -863,6 +879,89 @@ Ammo.AddOnDeploy=0 ; integer
```


## Veinholes & Weeds

### Veinholes

- Veinhole monsters now work like they used to in Tiberian Sun.
- Their core parameters are still loaded from `[General]`
- The Warhead used by veins is specified under `[CombatDamage]`. The warhead has to be properly listed under `[Warheads]` as well. The warhead has to have `Veinhole=yes` set.
- Veinholes are hardcoded to use several overlay types.
- The vein attack animation specified under `[AudioVisual]` is what deals the damage. The animation has to be properly listed under `[Animations]` as well.
- Units can be made immune to veins the same way as in Tiberian Sun.
- The monster itself is represented by the `VEINTREE` TerrainType, which has `IsVeinhole=true` set. Its strength is what determines the strength of the Veinhole.

```{note}
Everything listed below functions identically to Tiberian Sun.
Many of the tags from Tiberian Sun have been re-enabled. The values provided below are identical to those found in TS and YR rules. You can read more about them on ModENC:
[VeinholeGrowthRate](https://modenc.renegadeprojects.com/VeinholeGrowthRate), [VeinholeShrinkRate](https://modenc.renegadeprojects.com/VeinholeShrinkRate), [MaxVeinholeGrowth](https://modenc.renegadeprojects.com/MaxVeinholeGrowth), [VeinDamage](https://modenc.renegadeprojects.com/VeinDamage), [VeinholeTypeClass](https://modenc.renegadeprojects.com/VeinholeTypeClass),
[VeinholeWarhead](https://modenc.renegadeprojects.com/VeinholeWarhead), [Veinhole](https://modenc.renegadeprojects.com/Veinhole), [VeinAttack](https://modenc.renegadeprojects.com/VeinAttack), [ImmuneToVeins](https://modenc.renegadeprojects.com/ImmuneToVeins), [IsVeinhole](https://modenc.renegadeprojects.com/IsVeinhole)
```

In `rulesmd.ini`:
```ini
[General]
VeinholeGrowthRate=300 ; integer
VeinholeShrinkRate=100 ; integer
MaxVeinholeGrowth=2000 ; integer
VeinDamage=5 ; integer
VeinholeTypeClass=VEINTREE ; TerrainType

[CombatDamage]
VeinholeWarhead=VeinholeWH ; Warhead

[VeinholeWH]
Veinhole=yes

[AudioVisual]
VeinAttack=VEINATAC ; Animation

[TechnoType]
EliteAbilities=VEIN_PROOF
ImmuneToVeins=yes

[VEINTREE]
IsVeinhole=true
Strength=1000 ; integer - the strength of the Veinhole
```

```{warning}
The game expects certain overlays related to Veinholes to have certain indices, they are listed below.
```

In `rulesmd.ini`:
```ini
[OverlayTypes]
126=VEINS ; The veins (weeds)
167=VEINHOLE ; The Veinhole itself
178=VEINHOLEDUMMY ; A technical overlay
```


### Weeds & Weed Eaters

- Vehicles with `Weeder=yes` can now collect weeds. The weeds can then be deposited into a building with `Weeder=yes`.
- Weeds are not stored in a building's storage, but rather in a House's storage. The weed capacity is listed under `[General]->WeedCapacity`.
- Weeders now show the ore gathering animation. It can be customized the same way as for harvesters.
- Weeders can use the Teleport locomotor like chrono miners.

### Weed-consuming superweapons

- Superweapons can consume weeds to recharge, like the Chemical Missile special in Tiberian Sun.

```{note}
As the code for the Chemical Missile had been removed, setting `Type=ChemMissile` will not work.
```

In `rulesmd.ini`:
```ini
[SuperWeaponType]
UseWeeds=no ; boolean - should the SW use weeds to recharge?
UseWeeds.Amount= ; integer - how many? default is General->WeedCapacity
UseWeeds.StorageTimer=no ; boolean - should the counter on the sidebar display the % of weeds stored?
UseWeeds.ReadinessAnimationPercentage=0.9 ; double - when this many weeds % are stored, the SW will show it's ready on the building (open nuke/open chrono, etc.)
```

## VoxelAnims

### Customizable debris & meteor impact and warhead detonation behaviour
Expand Down
7 changes: 5 additions & 2 deletions docs/Whats-New.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# What's New

This page lists the history of changes across stable Phobos releases and also all the stuff that requires modders to change something in their mods to accomodate.
This page lists the history of changes across stable Phobos releases and also all the stuff that requires modders to change something in their mods to accommodate.

## Migrating

Expand Down Expand Up @@ -44,7 +44,7 @@ You can use the migration utility (can be found on [Phobos supplementaries repo]
- `Gravity=0` is not supported anymore as it will cause the projectile to fly backwards and be unable to hit the target which is not at the same height. Use `Straight` Trajectory instead. See [here](New-or-Enhanced-Logics.md#projectile-trajectories).
- Automatic self-destruction logic logic has been reimplemented, `Death.NoAmmo`, `Death.Countdown` and `Death.Peaceful` tags have been remade/renamed and require adjustments to function.
- `DetachedFromOwner` on weapons is deprecated. This has been replaced by `AllowDamageOnSelf` on warheads.
- Timed jump script actions now take the time measured in ingame seconds instead of frames. Divide your value by 15 to accomodate to this change.
- Timed jump script actions now take the time measured in ingame seconds instead of frames. Divide your value by 15 to accommodate to this change.
- [Placement Preview](User-Interface.md#placement-preview) logic has been adjusted, `BuildingPlacementPreview.DefaultTranslucentLevel`, `BuildingPlacementGrid.TranslucentLevel`, `PlacementPreview.Show`, `PlacementPreview.TranslucentLevel` and `ShowBuildingPlacementPreview` tags have been remade/renamed and require adjustments to function. In addition, you must explicitly enable this feature by specifying `[AudioVisual]->PlacementPreview=yes`.
- Existing script actions were renumbered, please use the migration utility to change the numbers to the correct ones.
- `DiskLaser.Radius` values were misinterpreted by a factor of 1/2π. The default radius is now 240, please multiply your customized radii by 2π.
Expand Down Expand Up @@ -362,6 +362,9 @@ New:
- Game save option when starting campaigns (by Trsdy)
- Carryall pickup voice (by Starkku)
- Option to have `Grinding.Weapon` require accumulated credits from grinding (by Starkku)
- Re-enable the Veinhole Monster and Weeds from TS (by ZivDero)
- Recreate the weed-charging of SWs like the TS Chemical Missile (by ZivDero)
- Allow to change the speed of gas particles (by ZivDero)
Vanilla fixes:
- Allow AI to repair structures built from base nodes/trigger action 125/SW delivery in single player missions (by Trsdy)
Expand Down
38 changes: 37 additions & 1 deletion src/Ext/Anim/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,42 @@ HouseClass* AnimExt::GetOwnerHouse(AnimClass* pAnim, HouseClass* pDefaultOwner)
return pTechnoOwner ? pTechnoOwner : pDefaultOwner;
}

void AnimExt::VeinAttackAI(AnimClass* pAnim)
{
CellStruct pCoordinates = pAnim->GetMapCoords();
CellClass* pCell = MapClass::Instance->GetCellAt(pCoordinates);
ObjectClass* pOccupier = pCell->FirstObject;
constexpr unsigned char fullyFlownWeedStart = 0x30; // Weeds starting from this overlay frame are fully grown
constexpr unsigned int weedOverlayIndex = 126;

if (!pOccupier || pOccupier->GetHeight() > 0 || pCell->OverlayTypeIndex != weedOverlayIndex
|| pCell->OverlayData < fullyFlownWeedStart || pCell->SlopeIndex)
{
pAnim->UnableToContinue = true;
}

if (Unsorted::CurrentFrame % 2 == 0)
{
while (pOccupier != nullptr)
{
ObjectClass* pNext = pOccupier->NextObject;
int damage = RulesClass::Instance->VeinDamage;

abstract_cast<TechnoClass*>(pOccupier);

TechnoClass* pTechno = abstract_cast<TechnoClass*>(pOccupier);

if (pTechno && !pTechno->GetTechnoType()->ImmuneToVeins && !pTechno->HasAbility(Ability::VeinProof)
&& pTechno->Health > 0 && pTechno->IsAlive && pTechno->GetHeight() <= 5)
{
pTechno->ReceiveDamage(&damage, 0, RulesExt::Global()->VeinholeWarhead, nullptr, false, false, nullptr);
}

pOccupier = pNext;
}
}
}

void AnimExt::HandleDebrisImpact(AnimTypeClass* pExpireAnim, AnimTypeClass* pWakeAnim, Iterator<AnimTypeClass*> splashAnims, HouseClass* pOwner, WarheadTypeClass* pWarhead, int nDamage,
CellClass* pCell, CoordStruct nLocation, bool heightFlag, bool isMeteor, bool warheadDetonate, bool explodeOnWater, bool splashAnimsPickRandom)
{
Expand Down Expand Up @@ -132,7 +168,7 @@ void AnimExt::HandleDebrisImpact(AnimTypeClass* pExpireAnim, AnimTypeClass* pWak
if (pWakeAnim)
pWakeAnimToUse = pWakeAnim;

if (splashAnims.size() > 0)
if (!splashAnims.empty())
{
auto nIndexR = (splashAnims.size() - 1);
auto nIndex = splashAnimsPickRandom ?
Expand Down
2 changes: 2 additions & 0 deletions src/Ext/Anim/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ class AnimExt
static bool SetAnimOwnerHouseKind(AnimClass* pAnim, HouseClass* pInvoker, HouseClass* pVictim, bool defaultToVictimOwner = true, bool defaultToInvokerOwner = false);
static HouseClass* GetOwnerHouse(AnimClass* pAnim, HouseClass* pDefaultOwner = nullptr);

static void VeinAttackAI(AnimClass* pAnim);

static void HandleDebrisImpact(AnimTypeClass* pExpireAnim, AnimTypeClass* pWakeAnim, Iterator<AnimTypeClass*> splashAnims, HouseClass* pOwner, WarheadTypeClass* pWarhead, int nDamage,
CellClass* pCell, CoordStruct nLocation, bool heightFlag, bool isMeteor, bool warheadDetonate, bool explodeOnWater, bool splashAnimsPickRandom);
};
104 changes: 104 additions & 0 deletions src/Ext/ParticleType/Body.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#include "Body.h"

ParticleTypeExt::ExtContainer ParticleTypeExt::ExtMap;

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

template <typename T>
void ParticleTypeExt::ExtData::Serialize(T& Stm)
{
Stm
.Process(this->Gas_MaxDriftSpeed)
;
}

void ParticleTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI)
{
auto pThis = this->OwnerObject();
const char* pSection = pThis->ID;

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

INI_EX exINI(pINI);

this->Gas_MaxDriftSpeed.Read(exINI, pSection, "Gas.MaxDriftSpeed");
}

void ParticleTypeExt::ExtData::LoadFromStream(PhobosStreamReader& Stm)
{
Extension<ParticleTypeClass>::LoadFromStream(Stm);
this->Serialize(Stm);
}

void ParticleTypeExt::ExtData::SaveToStream(PhobosStreamWriter& Stm)
{
Extension<ParticleTypeClass>::SaveToStream(Stm);
this->Serialize(Stm);
}

bool ParticleTypeExt::LoadGlobals(PhobosStreamReader& Stm)
{
return Stm
.Success();
}

bool ParticleTypeExt::SaveGlobals(PhobosStreamWriter& Stm)
{
return Stm
.Success();
}

// =============================
// container

ParticleTypeExt::ExtContainer::ExtContainer() : Container("ParticleTypeClass") { }
ParticleTypeExt::ExtContainer::~ExtContainer() = default;

// =============================
// container hooks

DEFINE_HOOK(0x644DBB, ParticleTypeClass_CTOR, 0x5)
{
GET(ParticleTypeClass*, pItem, ESI);

ParticleTypeExt::ExtMap.TryAllocate(pItem);

return 0;
}

DEFINE_HOOK_AGAIN(0x6457A0, ParticleTypeClass_SaveLoad_Prefix, 0x5)
DEFINE_HOOK(0x645660, ParticleTypeClass_SaveLoad_Prefix, 0x7)
{
GET_STACK(ParticleTypeClass*, pItem, 0x4);
GET_STACK(IStream*, pStm, 0x8);

ParticleTypeExt::ExtMap.PrepareStream(pItem, pStm);

return 0;
}

DEFINE_HOOK(0x64578C, ParticleTypeClass_Load_Suffix, 0x5)
{
ParticleTypeExt::ExtMap.LoadStatic();

return 0;
}

DEFINE_HOOK(0x64580A, ParticleTypeClass_Save_Suffix, 0x7)
{
ParticleTypeExt::ExtMap.SaveStatic();

return 0;
}

DEFINE_HOOK(0x6453FF, ParticleTypeClass_LoadFromINI, 0x6)
{
GET(ParticleTypeClass*, pItem, ESI);
GET_STACK(CCINIClass*, pINI, STACK_OFFSET(0xDC, 0x4));

ParticleTypeExt::ExtMap.LoadFromINI(pItem, pINI);

return 0;
}
Loading

0 comments on commit d9db475

Please sign in to comment.