Simplify CreateEffectWarhead

This commit is contained in:
reaperrr
2019-03-15 03:40:49 +01:00
committed by Paul Chote
parent 78a70be0d4
commit 3735c60533
2 changed files with 28 additions and 80 deletions

View File

@@ -43,65 +43,14 @@ namespace OpenRA.Mods.Common.Warheads
[Desc("Chance of impact sound to play.")]
public readonly int ImpactSoundChance = 100;
[Desc("Consider explosion above this altitude an air explosion.",
"If that's the case, this warhead will consider the explosion position to have the 'Air' TargetType (in addition to any nearby actor's TargetTypes).")]
[Desc("Explosions above this altitude that don't impact an actor will check target validity against the 'TargetTypeAir' target types.")]
public readonly WDist AirThreshold = new WDist(128);
[Desc("Whether to consider actors in determining whether the explosion should happen. If false, only terrain will be considered.")]
public readonly bool ImpactActors = true;
[Desc("Target types to use when the warhead detonated at an altitude greater than 'AirThreshold'.")]
static readonly BitSet<TargetableType> TargetTypeAir = new BitSet<TargetableType>("Air");
public ImpactType GetImpactType(World world, CPos cell, WPos pos, Actor firedBy)
{
// Matching target actor
if (ImpactActors)
{
var targetType = GetDirectHitTargetType(world, cell, pos, firedBy, true);
if (targetType == ImpactTargetType.ValidActor)
return ImpactType.TargetHit;
if (targetType == ImpactTargetType.InvalidActor)
return ImpactType.None;
}
var dat = world.Map.DistanceAboveTerrain(pos);
if (dat > AirThreshold)
return ImpactType.Air;
return ImpactType.Ground;
}
public ImpactTargetType GetDirectHitTargetType(World world, CPos cell, WPos pos, Actor firedBy, bool checkTargetValidity = false)
{
var victims = world.FindActorsOnCircle(pos, WDist.Zero);
var invalidHit = false;
foreach (var victim in victims)
{
if (!AffectsParent && victim == firedBy)
continue;
if (!victim.Info.HasTraitInfo<IHealthInfo>())
continue;
// If the impact position is within any HitShape, we have a direct hit
var activeShapes = victim.TraitsImplementing<HitShape>().Where(Exts.IsTraitEnabled);
var directHit = activeShapes.Any(i => i.Info.Type.DistanceFromEdge(pos, victim).Length <= 0);
// If the warhead landed outside the actor's hit-shape(s), we need to skip the rest so it won't be considered an invalidHit
if (!directHit)
continue;
if (!checkTargetValidity || IsValidAgainst(victim, firedBy))
return ImpactTargetType.ValidActor;
// If we got here, it must be an invalid target
invalidHit = true;
}
// If there was at least a single direct hit, but none on valid target(s), we return InvalidActor
return invalidHit ? ImpactTargetType.InvalidActor : ImpactTargetType.NoActor;
}
[Desc("Check for direct hits against nearby actors for use in the target validity checks.")]
public readonly bool ImpactActors = true;
public override void DoImpact(Target target, Actor firedBy, IEnumerable<int> damageModifiers)
{
@@ -123,11 +72,9 @@ namespace OpenRA.Mods.Common.Warheads
var explosion = Explosions.RandomOrDefault(world.LocalRandom);
if (Image != null && explosion != null)
{
var dat = world.Map.DistanceAboveTerrain(pos);
if (ForceDisplayAtGroundLevel)
{
var dat = world.Map.DistanceAboveTerrain(pos);
pos = new WPos(pos.X, pos.Y, pos.Z - dat.Length);
}
pos -= new WVec(0, 0, dat.Length);
world.AddFrameEndTask(w => w.Add(new SpriteEffect(pos, w, Image, explosion, palette)));
}
@@ -140,23 +87,32 @@ namespace OpenRA.Mods.Common.Warheads
public bool IsValidImpact(WPos pos, Actor firedBy)
{
var world = firedBy.World;
if (ImpactActors)
{
// Check whether the explosion overlaps with an actor's hitshape
var potentialVictims = world.FindActorsOnCircle(pos, WDist.Zero);
foreach (var victim in potentialVictims)
{
if (!AffectsParent && victim == firedBy)
continue;
var activeShapes = victim.TraitsImplementing<HitShape>().Where(Exts.IsTraitEnabled);
if (!activeShapes.Any(i => i.Info.Type.DistanceFromEdge(pos, victim).Length <= 0))
continue;
if (IsValidAgainst(victim, firedBy))
return true;
}
}
var targetTile = world.Map.CellContaining(pos);
if (!world.Map.Contains(targetTile))
return false;
var impactType = GetImpactType(world, targetTile, pos, firedBy);
switch (impactType)
{
case ImpactType.TargetHit:
return true;
case ImpactType.Air:
return IsValidTarget(TargetTypeAir);
case ImpactType.Ground:
var tileInfo = world.Map.GetTerrainInfo(targetTile);
return IsValidTarget(tileInfo.TargetTypes);
default:
return false;
}
var dat = world.Map.DistanceAboveTerrain(pos);
var tileInfo = world.Map.GetTerrainInfo(targetTile);
return IsValidTarget(dat > AirThreshold ? TargetTypeAir : tileInfo.TargetTypes);
}
}
}

View File

@@ -15,14 +15,6 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Warheads
{
public enum ImpactType
{
None,
Ground,
Air,
TargetHit
}
public enum ImpactTargetType
{
NoActor,