Revert Simplify CreateEffectWarhead

Reverts #16312.
This commit is contained in:
reaperrr
2019-06-30 14:31:30 +02:00
committed by abcdefg30
parent 2912bff850
commit 1c03fb9e51
2 changed files with 80 additions and 28 deletions

View File

@@ -43,14 +43,65 @@ namespace OpenRA.Mods.Common.Warheads
[Desc("Chance of impact sound to play.")]
public readonly int ImpactSoundChance = 100;
[Desc("Explosions above this altitude that don't impact an actor will check target validity against the 'TargetTypeAir' target types.")]
[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).")]
public readonly WDist AirThreshold = new WDist(128);
[Desc("Target types to use when the warhead detonated at an altitude greater than 'AirThreshold'.")]
[Desc("Whether to consider actors in determining whether the explosion should happen. If false, only terrain will be considered.")]
public readonly bool ImpactActors = true;
static readonly BitSet<TargetableType> TargetTypeAir = new BitSet<TargetableType>("Air");
[Desc("Check for direct hits against nearby actors for use in the target validity checks.")]
public readonly bool ImpactActors = true;
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;
}
public override void DoImpact(Target target, Actor firedBy, IEnumerable<int> damageModifiers)
{
@@ -72,9 +123,11 @@ namespace OpenRA.Mods.Common.Warheads
var explosion = Explosions.RandomOrDefault(world.LocalRandom);
if (Image != null && explosion != null)
{
var dat = world.Map.DistanceAboveTerrain(pos);
if (ForceDisplayAtGroundLevel)
pos -= new WVec(0, 0, dat.Length);
{
var dat = world.Map.DistanceAboveTerrain(pos);
pos = new WPos(pos.X, pos.Y, pos.Z - dat.Length);
}
world.AddFrameEndTask(w => w.Add(new SpriteEffect(pos, w, Image, explosion, palette)));
}
@@ -87,32 +140,23 @@ 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 dat = world.Map.DistanceAboveTerrain(pos);
var tileInfo = world.Map.GetTerrainInfo(targetTile);
return IsValidTarget(dat > AirThreshold ? TargetTypeAir : tileInfo.TargetTypes);
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;
}
}
}
}

View File

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