Skip to content

Commit

Permalink
Scrin Essence prefers wounded units.
Browse files Browse the repository at this point in the history
  • Loading branch information
dnqbob committed Nov 13, 2023
1 parent ce9a5d4 commit 7f975e7
Show file tree
Hide file tree
Showing 2 changed files with 154 additions and 18 deletions.
145 changes: 145 additions & 0 deletions OpenRA.Mods.Sp/Warheads/ScrinEssenceHitWarhead.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
#region Copyright & License Information
/*
* Copyright 2015- OpenRA.Mods.AS Developers (see AUTHORS)
* This file is a part of a third-party plugin for OpenRA, which is
* free software. It is made available to you under the terms of the
* GNU General Public License as published by the Free Software
* Foundation. For more information, see COPYING.
*/
#endregion

using System;
using System.Linq;
using OpenRA.GameRules;
using OpenRA.Mods.Common;
using OpenRA.Mods.Common.Traits;
using OpenRA.Mods.Common.Warheads;
using OpenRA.Primitives;
using OpenRA.Traits;

namespace OpenRA.Mods.SP.Warheads
{
public class ScrinEssenceHitWarhead : Warhead, IRulesetLoaded<WeaponInfo>
{
[WeaponReference]
[FieldLoader.Require]
[Desc("Has to be defined in weapons.yaml as well.")]
public readonly string Weapon = null;

public readonly string WeaponName = "primary";

[Desc("Target types that will not be considered first.")]
public readonly BitSet<TargetableType> SecondaryTargets = default;

[Desc("Amount of shrapnels thrown.")]
public readonly int Amount = 1;

[Desc("What diplomatic stances can be targeted by the shrapnel.")]
public readonly PlayerRelationship AimTargetStances = PlayerRelationship.Ally | PlayerRelationship.Neutral | PlayerRelationship.Enemy;

[Desc("Should the weapons be fired around the intended target or at the explosion's epicenter.")]
public readonly bool AroundTarget = false;

WeaponInfo weapon;

public void RulesetLoaded(Ruleset rules, WeaponInfo info)
{
if (!rules.Weapons.TryGetValue(Weapon.ToLowerInvariant(), out weapon))
throw new YamlException($"Weapons Ruleset does not contain an entry '{Weapon.ToLowerInvariant()}'");
}

public override void DoImpact(in Target target, WarheadArgs args)
{
var firedBy = args.SourceActor;
if (!target.IsValidFor(firedBy))
return;

var world = firedBy.World;
var map = world.Map;

var epicenter = AroundTarget && args.WeaponTarget.Type != TargetType.Invalid
? args.WeaponTarget.CenterPosition
: target.CenterPosition;

var availableTargetActors = world.FindActorsOnCircle(epicenter, weapon.Range)
.Where(x =>
{
if (!weapon.IsValidAgainst(Target.FromActor(x), firedBy.World, firedBy) || !AimTargetStances.HasRelationship(firedBy.Owner.RelationshipWith(x.Owner)))
return false;

var activeShapes = x.TraitsImplementing<HitShape>().Where(Exts.IsTraitEnabled);
if (!activeShapes.Any())
return false;

var distance = activeShapes.Min(t => t.DistanceFromEdge(x, epicenter));

if (distance < weapon.Range)
return true;

return false;
}).ToArray();

var preferedTargetActors = availableTargetActors.Where(x => !SecondaryTargets.Overlaps(x.GetEnabledTargetTypes())).Shuffle(world.SharedRandom).ToList();

var amount = 0;
for (; amount < Amount && amount < preferedTargetActors.Count; amount++)
GenerateWeapon(firedBy, preferedTargetActors[amount], epicenter, target);

if (Amount <= amount)
return;
else
amount = Amount - amount;

var otherTargetActors = availableTargetActors.Where(x => SecondaryTargets.Overlaps(x.GetEnabledTargetTypes())).Shuffle(world.SharedRandom).ToList();
for (var i = 0; i < amount && i < otherTargetActors.Count; i++)
GenerateWeapon(firedBy, otherTargetActors[i], epicenter, target);
}

void GenerateWeapon(Actor firedBy, Actor victim, WPos epicenter, in Target target)
{
var shrapnelTarget = Target.FromActor(victim);

if (shrapnelTarget.Type == TargetType.Invalid)
return;

var shrapnelFacing = (shrapnelTarget.CenterPosition - epicenter).Yaw;

// Lambdas can't use 'in' variables, so capture a copy for later
var centerPosition = target.CenterPosition;

var projectileArgs = new ProjectileArgs
{
Weapon = weapon,
Facing = shrapnelFacing,
CurrentMuzzleFacing = () => shrapnelFacing,

DamageModifiers = !firedBy.IsDead ? firedBy.TraitsImplementing<IFirepowerModifier>()
.Select(a => a.GetFirepowerModifier(WeaponName)).ToArray() : Array.Empty<int>(),

InaccuracyModifiers = Array.Empty<int>(),

RangeModifiers = Array.Empty<int>(),

Source = target.CenterPosition,
CurrentSource = () => centerPosition,
SourceActor = firedBy,
GuidedTarget = shrapnelTarget,
PassiveTarget = shrapnelTarget.CenterPosition
};

if (projectileArgs.Weapon.Projectile != null)
{
var projectile = projectileArgs.Weapon.Projectile.Create(projectileArgs);
if (projectile != null)
firedBy.World.AddFrameEndTask(w => w.Add(projectile));

if (projectileArgs.Weapon.Report != null && projectileArgs.Weapon.Report.Length > 0)
{
var pos = target.CenterPosition;
if (projectileArgs.Weapon.AudibleThroughFog || (!firedBy.World.ShroudObscures(pos) && !firedBy.World.FogObscures(pos)))
Game.Sound.Play(SoundType.World, projectileArgs.Weapon.Report, firedBy.World, pos, null, projectileArgs.Weapon.SoundVolume);
}
}
}
}
}
27 changes: 9 additions & 18 deletions mods/sp/weapons/scrweapons.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,11 @@ FloatTesla:
Warhead@1Dam: SpreadDamage
Damage: 0
InvalidTargets: Summoned
Warhead@op: FireShrapnel
Warhead@op: ScrinEssenceHit
Weapon: EssenceMissile
ImpactActors: false
Amount: 2
AimChance: 100
AllowDirectHit: true
AimTargetStances: Ally
ThrowWithoutTarget: false
SecondaryTargets: FullHealth
ValidTargets: Ground, Water, Air
InvalidTargets: Summoned
AffectsParent: true
Expand Down Expand Up @@ -1073,15 +1070,12 @@ CouncilorPlasma:
ImpactSounds: expnew14.aud
AirThreshold: 8c0
ValidTargets: Ground, Water
Warhead@op: FireShrapnel
Warhead@op: ScrinEssenceHit
Weapon: EssenceMissile
ImpactActors: true
ValidTargets: Ground, Water, Air
Amount: 1
AimChance: 100
AllowDirectHit: true
AimTargetStances: Ally
ThrowWithoutTarget: false
ValidTargets: Ground, Water
SecondaryTargets: FullHealth
AffectsParent: true
AirThreshold: 8c0

Expand Down Expand Up @@ -1232,15 +1226,12 @@ EssenceSmall:
Range: 10c0
MinRange: 1c0
Projectile: InstantExplode
Warhead@op: FireShrapnel
Warhead@op: ScrinEssenceHit
ValidTargets: Ground, Water, Air
Weapon: EssenceMissile
ImpactActors: false
Amount: 1
AimChance: 100
ThrowWithoutTarget: false
AllowDirectHit: true
AimTargetStances: Ally
ValidTargets: Ground, Water, Air
SecondaryTargets: FullHealth
AirThreshold: 8c0
AffectsParent: true

Expand All @@ -1254,7 +1245,7 @@ SpawnEssence:
Sequences: idle
Duration: 50
Palette: apolra2ialpha
Warhead@op: FireShrapnel
Warhead@op: ScrinEssenceHit
Delay: 50
AimTargetStances: Ally
AffectsParent: true
Expand Down

0 comments on commit 7f975e7

Please sign in to comment.