Integrated HitShapes

Integrated hit shapes with field loader and warhead calculations.
This commit is contained in:
Huw Pascoe
2015-10-29 16:58:07 +00:00
parent 5ef6d86f66
commit a8299221db
6 changed files with 40 additions and 15 deletions

View File

@@ -44,7 +44,7 @@ namespace OpenRA.Mods.Common.Lint
if (!warhead.ValidTargets.Overlaps(targetable)) if (!warhead.ValidTargets.Overlaps(targetable))
continue; continue;
if (healthTraits.Where(x => x.Radius.Length > warhead.TargetExtraSearchRadius.Length).Any()) if (healthTraits.Where(x => x.Shape.OuterRadius.Length > warhead.TargetExtraSearchRadius.Length).Any())
emitError("Actor type `{0}` has a health radius exceeding the victim scan radius of a warhead on `{1}`!" emitError("Actor type `{0}` has a health radius exceeding the victim scan radius of a warhead on `{1}`!"
.F(actorInfo.Key, weaponInfo.Key)); .F(actorInfo.Key, weaponInfo.Key));
} }

View File

@@ -12,7 +12,6 @@ using System;
using System.Drawing; using System.Drawing;
using OpenRA.Graphics; using OpenRA.Graphics;
using OpenRA.Mods.Common.Effects; using OpenRA.Mods.Common.Effects;
using OpenRA.Mods.Common.Graphics;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits namespace OpenRA.Mods.Common.Traits
@@ -48,13 +47,12 @@ namespace OpenRA.Mods.Common.Traits
if (devMode == null || !devMode.ShowCombatGeometry) if (devMode == null || !devMode.ShowCombatGeometry)
return; return;
if (healthInfo != null)
RangeCircleRenderable.DrawRangeCircle(wr, self.CenterPosition, healthInfo.Radius,
1, Color.Red, 0, Color.Red);
var wcr = Game.Renderer.WorldRgbaColorRenderer; var wcr = Game.Renderer.WorldRgbaColorRenderer;
var iz = 1 / wr.Viewport.Zoom; var iz = 1 / wr.Viewport.Zoom;
if (healthInfo != null)
healthInfo.Shape.DrawCombatOverlay(wr, wcr, self);
if (blockInfo != null) if (blockInfo != null)
{ {
var hc = Color.Orange; var hc = Color.Orange;

View File

@@ -8,7 +8,9 @@
*/ */
#endregion #endregion
using System;
using System.Linq; using System.Linq;
using OpenRA.Mods.Common.HitShapes;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits namespace OpenRA.Mods.Common.Traits
@@ -17,13 +19,39 @@ namespace OpenRA.Mods.Common.Traits
{ {
[Desc("HitPoints")] [Desc("HitPoints")]
public readonly int HP = 0; public readonly int HP = 0;
[Desc("Physical size of the unit used for damage calculations. Impacts within this radius apply full damage.")]
public readonly WDist Radius = new WDist(426);
[Desc("Trigger interfaces such as AnnounceOnKill?")] [Desc("Trigger interfaces such as AnnounceOnKill?")]
public readonly bool NotifyAppliedDamage = true; public readonly bool NotifyAppliedDamage = true;
[FieldLoader.LoadUsing("LoadShape")]
public readonly IHitShape Shape;
static object LoadShape(MiniYaml yaml)
{
IHitShape ret;
var shapeNode = yaml.Nodes.Find(n => n.Key == "Shape");
var shape = shapeNode != null ? shapeNode.Value.Value : string.Empty;
if (!string.IsNullOrEmpty(shape))
{
ret = Game.CreateObject<IHitShape>(shape + "Shape");
try
{
FieldLoader.Load(ret, shapeNode.Value);
}
catch (YamlException e)
{
throw new YamlException("HitShape {0}: {1}".F(shape, e.Message));
}
}
else
ret = new CircleShape();
ret.Initialize();
return ret;
}
public virtual object Create(ActorInitializer init) { return new Health(init, this); } public virtual object Create(ActorInitializer init) { return new Health(init, this); }
} }

View File

@@ -78,7 +78,7 @@ namespace OpenRA.Mods.Common.Warheads
continue; continue;
// If the impact position is within any actor's health radius, we have a direct hit // If the impact position is within any actor's health radius, we have a direct hit
if ((unit.CenterPosition - pos).LengthSquared <= healthInfo.Radius.LengthSquared) if ((unit.CenterPosition - pos).LengthSquared <= healthInfo.Shape.OuterRadius.LengthSquared)
return true; return true;
} }

View File

@@ -66,9 +66,8 @@ namespace OpenRA.Mods.Common.Warheads
if (healthInfo == null) if (healthInfo == null)
continue; continue;
var localModifiers = damageModifiers; var distance = healthInfo.Shape.DistanceFromEdge(pos, victim);
var distance = Math.Max(0, (victim.CenterPosition - pos).Length - healthInfo.Radius.Length); var localModifiers = damageModifiers.Append(GetDamageFalloff(distance.Length));
localModifiers = localModifiers.Append(GetDamageFalloff(distance));
DoImpact(victim, firedBy, localModifiers); DoImpact(victim, firedBy, localModifiers);
} }

View File

@@ -46,7 +46,7 @@ namespace OpenRA.Mods.Common
var actorWidth = 0; var actorWidth = 0;
var healthInfo = currActor.Info.TraitInfoOrDefault<HealthInfo>(); var healthInfo = currActor.Info.TraitInfoOrDefault<HealthInfo>();
if (healthInfo != null) if (healthInfo != null)
actorWidth = healthInfo.Radius.Length; actorWidth = healthInfo.Shape.OuterRadius.Length;
var projection = MinimumPointLineProjection(lineStart, lineEnd, currActor.CenterPosition); var projection = MinimumPointLineProjection(lineStart, lineEnd, currActor.CenterPosition);
var distance = (currActor.CenterPosition - projection).HorizontalLength; var distance = (currActor.CenterPosition - projection).HorizontalLength;