Move Shape from Health to new HitShape trait
Renamed Shape to Type
This commit is contained in:
@@ -296,6 +296,7 @@
|
|||||||
<Compile Include="Traits\Burns.cs" />
|
<Compile Include="Traits\Burns.cs" />
|
||||||
<Compile Include="Traits\ChangesTerrain.cs" />
|
<Compile Include="Traits\ChangesTerrain.cs" />
|
||||||
<Compile Include="Traits\Health.cs" />
|
<Compile Include="Traits\Health.cs" />
|
||||||
|
<Compile Include="Traits\HitShape.cs" />
|
||||||
<Compile Include="Traits\PowerTooltip.cs" />
|
<Compile Include="Traits\PowerTooltip.cs" />
|
||||||
<Compile Include="Traits\Render\VeteranProductionIconOverlay.cs" />
|
<Compile Include="Traits\Render\VeteranProductionIconOverlay.cs" />
|
||||||
<Compile Include="Traits\Capturable.cs" />
|
<Compile Include="Traits\Capturable.cs" />
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
using OpenRA.Effects;
|
using OpenRA.Effects;
|
||||||
using OpenRA.GameRules;
|
using OpenRA.GameRules;
|
||||||
using OpenRA.Graphics;
|
using OpenRA.Graphics;
|
||||||
@@ -302,12 +303,9 @@ namespace OpenRA.Mods.Common.Projectiles
|
|||||||
if (!info.ValidBounceBlockerStances.HasStance(victim.Owner.Stances[firedBy.Owner]))
|
if (!info.ValidBounceBlockerStances.HasStance(victim.Owner.Stances[firedBy.Owner]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var healthInfo = victim.Info.TraitInfoOrDefault<HealthInfo>();
|
|
||||||
if (healthInfo == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// If the impact position is within any actor's HitShape, we have a direct hit
|
// If the impact position is within any actor's HitShape, we have a direct hit
|
||||||
if (healthInfo.Shape.DistanceFromEdge(pos, victim).Length <= 0)
|
var activeShapes = victim.TraitsImplementing<HitShape>().Where(Exts.IsTraitEnabled);
|
||||||
|
if (activeShapes.Any(i => i.Info.Type.DistanceFromEdge(pos, victim).Length <= 0))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
readonly HealthInfo healthInfo;
|
readonly HealthInfo healthInfo;
|
||||||
readonly Lazy<BodyOrientation> coords;
|
readonly Lazy<BodyOrientation> coords;
|
||||||
|
|
||||||
|
HitShape[] shapes;
|
||||||
IBlocksProjectiles[] allBlockers;
|
IBlocksProjectiles[] allBlockers;
|
||||||
ITargetablePositions[] targetablePositions;
|
ITargetablePositions[] targetablePositions;
|
||||||
|
|
||||||
@@ -48,6 +49,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
void INotifyCreated.Created(Actor self)
|
void INotifyCreated.Created(Actor self)
|
||||||
{
|
{
|
||||||
|
shapes = self.TraitsImplementing<HitShape>().ToArray();
|
||||||
allBlockers = self.TraitsImplementing<IBlocksProjectiles>().ToArray();
|
allBlockers = self.TraitsImplementing<IBlocksProjectiles>().ToArray();
|
||||||
targetablePositions = self.TraitsImplementing<ITargetablePositions>().ToArray();
|
targetablePositions = self.TraitsImplementing<ITargetablePositions>().ToArray();
|
||||||
}
|
}
|
||||||
@@ -60,9 +62,6 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
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);
|
|
||||||
|
|
||||||
var blockers = allBlockers.Where(Exts.IsTraitEnabled).ToList();
|
var blockers = allBlockers.Where(Exts.IsTraitEnabled).ToList();
|
||||||
if (blockers.Count > 0)
|
if (blockers.Count > 0)
|
||||||
{
|
{
|
||||||
@@ -75,6 +74,10 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
TargetLineRenderable.DrawTargetMarker(wr, hc, hb);
|
TargetLineRenderable.DrawTargetMarker(wr, hc, hb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var activeShapes = shapes.Where(Exts.IsTraitEnabled);
|
||||||
|
foreach (var s in activeShapes)
|
||||||
|
s.Info.Type.DrawCombatOverlay(wr, wcr, self);
|
||||||
|
|
||||||
var tc = Color.Lime;
|
var tc = Color.Lime;
|
||||||
var enabledPositions = targetablePositions.Where(Exts.IsTraitEnabled);
|
var enabledPositions = targetablePositions.Where(Exts.IsTraitEnabled);
|
||||||
var positions = enabledPositions.SelectMany(tp => tp.TargetablePositions(self));
|
var positions = enabledPositions.SelectMany(tp => tp.TargetablePositions(self));
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
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
|
||||||
@@ -22,36 +21,6 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
[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); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
59
OpenRA.Mods.Common/Traits/HitShape.cs
Normal file
59
OpenRA.Mods.Common/Traits/HitShape.cs
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#region Copyright & License Information
|
||||||
|
/*
|
||||||
|
* Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
|
||||||
|
* This file is part of 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, either version 3 of
|
||||||
|
* the License, or (at your option) any later version. For more
|
||||||
|
* information, see COPYING.
|
||||||
|
*/
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using OpenRA.Mods.Common.HitShapes;
|
||||||
|
using OpenRA.Traits;
|
||||||
|
|
||||||
|
namespace OpenRA.Mods.Common.Traits
|
||||||
|
{
|
||||||
|
[Desc("Shape of actor for damage calculations.")]
|
||||||
|
public class HitShapeInfo : ConditionalTraitInfo
|
||||||
|
{
|
||||||
|
[FieldLoader.LoadUsing("LoadShape")]
|
||||||
|
public readonly IHitShape Type;
|
||||||
|
|
||||||
|
static object LoadShape(MiniYaml yaml)
|
||||||
|
{
|
||||||
|
IHitShape ret;
|
||||||
|
|
||||||
|
var shapeNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Type");
|
||||||
|
var shape = shapeNode != null ? shapeNode.Value.Value : string.Empty;
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(shape))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ret = Game.CreateObject<IHitShape>(shape + "Shape");
|
||||||
|
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 override object Create(ActorInitializer init) { return new HitShape(init.Self, this); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class HitShape : ConditionalTrait<HitShapeInfo>
|
||||||
|
{
|
||||||
|
public HitShape(Actor self, HitShapeInfo info)
|
||||||
|
: base(info) { }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -180,14 +180,14 @@ namespace OpenRA.Mods.Common
|
|||||||
// TODO: Investigate caching this or moving it to ActorMapInfo
|
// TODO: Investigate caching this or moving it to ActorMapInfo
|
||||||
public static WDist MinimumRequiredVictimScanRadius(Ruleset rules)
|
public static WDist MinimumRequiredVictimScanRadius(Ruleset rules)
|
||||||
{
|
{
|
||||||
return rules.Actors.SelectMany(a => a.Value.TraitInfos<HealthInfo>()).Max(h => h.Shape.OuterRadius);
|
return rules.Actors.SelectMany(a => a.Value.TraitInfos<HitShapeInfo>()).Max(h => h.Type.OuterRadius);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Investigate caching this or moving it to ActorMapInfo
|
// TODO: Investigate caching this or moving it to ActorMapInfo
|
||||||
public static WDist MinimumRequiredBlockerScanRadius(Ruleset rules)
|
public static WDist MinimumRequiredBlockerScanRadius(Ruleset rules)
|
||||||
{
|
{
|
||||||
return rules.Actors.Where(a => a.Value.HasTraitInfo<IBlocksProjectilesInfo>())
|
return rules.Actors.Where(a => a.Value.HasTraitInfo<IBlocksProjectilesInfo>())
|
||||||
.SelectMany(a => a.Value.TraitInfos<HealthInfo>()).Max(h => h.Shape.OuterRadius);
|
.SelectMany(a => a.Value.TraitInfos<HitShapeInfo>()).Max(h => h.Type.OuterRadius);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using OpenRA.GameRules;
|
using OpenRA.GameRules;
|
||||||
using OpenRA.Mods.Common.Effects;
|
using OpenRA.Mods.Common.Effects;
|
||||||
using OpenRA.Mods.Common.Traits;
|
using OpenRA.Mods.Common.Traits;
|
||||||
@@ -88,12 +89,9 @@ namespace OpenRA.Mods.Common.Warheads
|
|||||||
if (checkTargetType && !IsValidAgainst(victim, firedBy))
|
if (checkTargetType && !IsValidAgainst(victim, firedBy))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var healthInfo = victim.Info.TraitInfoOrDefault<HealthInfo>();
|
// If the impact position is within any HitShape, we have a direct hit
|
||||||
if (healthInfo == null)
|
var activeShapes = victim.TraitsImplementing<HitShape>().Where(Exts.IsTraitEnabled);
|
||||||
continue;
|
if (activeShapes.Any(i => i.Info.Type.DistanceFromEdge(pos, victim).Length <= 0))
|
||||||
|
|
||||||
// If the impact position is within any actor's HitShape, we have a direct hit
|
|
||||||
if (healthInfo.Shape.DistanceFromEdge(pos, victim).Length <= 0)
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using OpenRA.GameRules;
|
using OpenRA.GameRules;
|
||||||
using OpenRA.Mods.Common.Traits;
|
using OpenRA.Mods.Common.Traits;
|
||||||
using OpenRA.Traits;
|
using OpenRA.Traits;
|
||||||
@@ -66,11 +67,17 @@ namespace OpenRA.Mods.Common.Warheads
|
|||||||
|
|
||||||
foreach (var victim in hitActors)
|
foreach (var victim in hitActors)
|
||||||
{
|
{
|
||||||
|
// Cannot be damaged without a Health trait
|
||||||
var healthInfo = victim.Info.TraitInfoOrDefault<HealthInfo>();
|
var healthInfo = victim.Info.TraitInfoOrDefault<HealthInfo>();
|
||||||
if (healthInfo == null)
|
if (healthInfo == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var distance = healthInfo.Shape.DistanceFromEdge(pos, victim);
|
// Cannot be damaged without an active HitShape
|
||||||
|
var activeShapes = victim.TraitsImplementing<HitShape>().Where(Exts.IsTraitEnabled);
|
||||||
|
if (!activeShapes.Any())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var distance = activeShapes.Min(t => t.Info.Type.DistanceFromEdge(pos, victim));
|
||||||
var localModifiers = damageModifiers.Append(GetDamageFalloff(distance.Length));
|
var localModifiers = damageModifiers.Append(GetDamageFalloff(distance.Length));
|
||||||
|
|
||||||
DoImpact(victim, firedBy, localModifiers);
|
DoImpact(victim, firedBy, localModifiers);
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using OpenRA.Mods.Common.Traits;
|
using OpenRA.Mods.Common.Traits;
|
||||||
|
|
||||||
namespace OpenRA.Mods.Common
|
namespace OpenRA.Mods.Common
|
||||||
@@ -45,9 +46,9 @@ namespace OpenRA.Mods.Common
|
|||||||
foreach (var currActor in actorsInSquare)
|
foreach (var currActor in actorsInSquare)
|
||||||
{
|
{
|
||||||
var actorWidth = 0;
|
var actorWidth = 0;
|
||||||
var healthInfo = currActor.Info.TraitInfoOrDefault<HealthInfo>();
|
var shapes = currActor.TraitsImplementing<HitShape>().Where(Exts.IsTraitEnabled);
|
||||||
if (healthInfo != null)
|
if (shapes.Any())
|
||||||
actorWidth = healthInfo.Shape.OuterRadius.Length;
|
actorWidth = shapes.Max(h => h.Info.Type.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;
|
||||||
|
|||||||
Reference in New Issue
Block a user