Add DamageTypes to Kill() and make some traits use it.

This commit is contained in:
Mustafa Alperen Seki
2018-02-03 11:07:02 +03:00
committed by reaperrr
parent b620e8107f
commit 5e7e3bb011
17 changed files with 58 additions and 22 deletions

View File

@@ -321,12 +321,12 @@ namespace OpenRA
health.InflictDamage(this, attacker, damage, false); health.InflictDamage(this, attacker, damage, false);
} }
public void Kill(Actor attacker) public void Kill(Actor attacker, HashSet<string> damageTypes = null)
{ {
if (Disposed || health == null) if (Disposed || health == null)
return; return;
health.Kill(this, attacker); health.Kill(this, attacker, damageTypes);
} }
public bool CanBeViewedByPlayer(Player player) public bool CanBeViewedByPlayer(Player player)

View File

@@ -42,7 +42,7 @@ namespace OpenRA.Traits
bool IsDead { get; } bool IsDead { get; }
void InflictDamage(Actor self, Actor attacker, Damage damage, bool ignoreModifiers); void InflictDamage(Actor self, Actor attacker, Damage damage, bool ignoreModifiers);
void Kill(Actor self, Actor attacker); void Kill(Actor self, Actor attacker, HashSet<string> damageTypes);
} }
// depends on the order of pips in WorldRenderer.cs! // depends on the order of pips in WorldRenderer.cs!

View File

@@ -10,6 +10,7 @@
#endregion #endregion
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenRA.Activities; using OpenRA.Activities;
using OpenRA.GameRules; using OpenRA.GameRules;
@@ -29,8 +30,9 @@ namespace OpenRA.Mods.Cnc.Activities
WPos to; WPos to;
int ticks; int ticks;
WAngle angle; WAngle angle;
HashSet<string> damageTypes;
public Leap(Actor self, Actor target, Armament a, WDist speed, WAngle angle) public Leap(Actor self, Actor target, Armament a, WDist speed, WAngle angle, HashSet<string> damageTypes)
{ {
var targetMobile = target.TraitOrDefault<Mobile>(); var targetMobile = target.TraitOrDefault<Mobile>();
if (targetMobile == null) if (targetMobile == null)
@@ -38,6 +40,7 @@ namespace OpenRA.Mods.Cnc.Activities
this.weapon = a.Weapon; this.weapon = a.Weapon;
this.angle = angle; this.angle = angle;
this.damageTypes = damageTypes;
mobile = self.Trait<Mobile>(); mobile = self.Trait<Mobile>();
mobile.SetLocation(mobile.FromCell, mobile.FromSubCell, targetMobile.FromCell, targetMobile.FromSubCell); mobile.SetLocation(mobile.FromCell, mobile.FromSubCell, targetMobile.FromCell, targetMobile.FromSubCell);
mobile.IsMoving = true; mobile.IsMoving = true;
@@ -67,7 +70,7 @@ namespace OpenRA.Mods.Cnc.Activities
self.World.ActorMap.GetActorsAt(mobile.ToCell, mobile.ToSubCell) self.World.ActorMap.GetActorsAt(mobile.ToCell, mobile.ToSubCell)
.Except(new[] { self }).Where(t => weapon.IsValidAgainst(t, self)) .Except(new[] { self }).Where(t => weapon.IsValidAgainst(t, self))
.Do(t => t.Kill(self)); .Do(t => t.Kill(self, damageTypes));
return NextActivity; return NextActivity;
} }

View File

@@ -25,6 +25,9 @@ namespace OpenRA.Mods.Cnc.Traits
public readonly WAngle Angle = WAngle.FromDegrees(20); public readonly WAngle Angle = WAngle.FromDegrees(20);
[Desc("Types of damage that this trait causes. Leave empty for no damage types.")]
public readonly HashSet<string> DamageTypes = new HashSet<string>();
public override object Create(ActorInitializer init) { return new AttackLeap(init.Self, this); } public override object Create(ActorInitializer init) { return new AttackLeap(init.Self, this); }
} }
@@ -51,7 +54,7 @@ namespace OpenRA.Mods.Cnc.Traits
return; return;
self.CancelActivity(); self.CancelActivity();
self.QueueActivity(new Leap(self, target.Actor, a, info.Speed, info.Angle)); self.QueueActivity(new Leap(self, target.Actor, a, info.Speed, info.Angle, info.DamageTypes));
} }
} }
} }

View File

@@ -9,6 +9,7 @@
*/ */
#endregion #endregion
using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using OpenRA.Mods.Cnc.Activities; using OpenRA.Mods.Cnc.Activities;
using OpenRA.Mods.Common.Traits; using OpenRA.Mods.Common.Traits;
@@ -22,6 +23,10 @@ namespace OpenRA.Mods.Cnc.Traits
{ {
[Desc("Should the actor die instead of being teleported?")] [Desc("Should the actor die instead of being teleported?")]
public readonly bool ExplodeInstead = false; public readonly bool ExplodeInstead = false;
[Desc("Types of damage that this trait causes to self when 'ExplodeInstead' is true. Leave empty for no damage types.")]
public readonly HashSet<string> DamageTypes = new HashSet<string>();
public readonly string ChronoshiftSound = "chrono2.aud"; public readonly string ChronoshiftSound = "chrono2.aud";
[Desc("Should the actor return to its previous location after the chronoshift wore out?")] [Desc("Should the actor return to its previous location after the chronoshift wore out?")]
@@ -95,7 +100,7 @@ namespace OpenRA.Mods.Cnc.Traits
{ {
// Damage is inflicted by the chronosphere // Damage is inflicted by the chronosphere
if (!self.Disposed) if (!self.Disposed)
self.InflictDamage(chronosphere, new Damage(int.MaxValue)); self.Kill(chronosphere, info.DamageTypes);
}); });
return true; return true;
} }

View File

@@ -53,6 +53,9 @@ namespace OpenRA.Mods.Cnc.Traits
public WeaponInfo ThumpDamageWeaponInfo { get; private set; } public WeaponInfo ThumpDamageWeaponInfo { get; private set; }
public WeaponInfo DetonationWeaponInfo { get; private set; } public WeaponInfo DetonationWeaponInfo { get; private set; }
[Desc("Types of damage that this trait causes to self while self-destructing. Leave empty for no damage types.")]
public readonly HashSet<string> DamageTypes = new HashSet<string>();
public object Create(ActorInitializer init) { return new MadTank(init.Self, this); } public object Create(ActorInitializer init) { return new MadTank(init.Self, this); }
public void RulesetLoaded(Ruleset rules, ActorInfo ai) public void RulesetLoaded(Ruleset rules, ActorInfo ai)
{ {
@@ -146,7 +149,7 @@ namespace OpenRA.Mods.Cnc.Traits
info.DetonationWeaponInfo.Impact(Target.FromPos(self.CenterPosition), self, Enumerable.Empty<int>()); info.DetonationWeaponInfo.Impact(Target.FromPos(self.CenterPosition), self, Enumerable.Empty<int>());
} }
self.Kill(self); self.Kill(self, info.DamageTypes);
}); });
} }

View File

@@ -48,7 +48,7 @@ namespace OpenRA.Mods.Cnc.Traits
if (mobile != null && !info.DetonateClasses.Overlaps(mobile.Info.Crushes)) if (mobile != null && !info.DetonateClasses.Overlaps(mobile.Info.Crushes))
return; return;
self.Kill(crusher); self.Kill(crusher, mobile != null ? mobile.Info.CrushDamageTypes : new HashSet<string>());
} }
bool ICrushable.CrushableBy(Actor self, Actor crusher, HashSet<string> crushClasses) bool ICrushable.CrushableBy(Actor self, Actor crusher, HashSet<string> crushClasses)

View File

@@ -20,6 +20,9 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Does a suicide attack where it moves next to the target when used in combination with `Explodes`.")] [Desc("Does a suicide attack where it moves next to the target when used in combination with `Explodes`.")]
class AttackSuicidesInfo : ConditionalTraitInfo, Requires<IMoveInfo> class AttackSuicidesInfo : ConditionalTraitInfo, Requires<IMoveInfo>
{ {
[Desc("Types of damage that this trait causes to self while suiciding. Leave empty for no damage types.")]
public readonly HashSet<string> DamageTypes = new HashSet<string>();
[VoiceReference] public readonly string Voice = "Action"; [VoiceReference] public readonly string Voice = "Action";
public override object Create(ActorInitializer init) { return new AttackSuicides(init.Self, this); } public override object Create(ActorInitializer init) { return new AttackSuicides(init.Self, this); }
@@ -82,10 +85,10 @@ namespace OpenRA.Mods.Common.Traits
self.QueueActivity(move.MoveToTarget(self, target)); self.QueueActivity(move.MoveToTarget(self, target));
self.QueueActivity(new CallFunc(() => self.Kill(self))); self.QueueActivity(new CallFunc(() => self.Kill(self, Info.DamageTypes)));
} }
else if (order.OrderString == "Detonate") else if (order.OrderString == "Detonate")
self.Kill(self); self.Kill(self, Info.DamageTypes);
} }
} }
} }

View File

@@ -46,6 +46,9 @@ namespace OpenRA.Mods.Common.Traits
public WeaponInfo DemolishWeaponInfo { get; private set; } public WeaponInfo DemolishWeaponInfo { get; private set; }
[Desc("Types of damage that this bridge causes to units over/in path of it while being destroyed/repaired. Leave empty for no damage types.")]
public readonly HashSet<string> DamageTypes = new HashSet<string>();
public object Create(ActorInitializer init) { return new Bridge(init.Self, this); } public object Create(ActorInitializer init) { return new Bridge(init.Self, this); }
public void RulesetLoaded(Ruleset rules, ActorInfo ai) public void RulesetLoaded(Ruleset rules, ActorInfo ai)
@@ -241,7 +244,7 @@ namespace OpenRA.Mods.Common.Traits
foreach (var c in footprint.Keys) foreach (var c in footprint.Keys)
foreach (var a in self.World.ActorMap.GetActorsAt(c)) foreach (var a in self.World.ActorMap.GetActorsAt(c))
if (a.Info.HasTraitInfo<IPositionableInfo>() && !a.Trait<IPositionable>().CanEnterCell(c)) if (a.Info.HasTraitInfo<IPositionableInfo>() && !a.Trait<IPositionable>().CanEnterCell(c))
a.Kill(self); a.Kill(self, info.DamageTypes);
} }
bool NeighbourIsDeadShore(Bridge neighbour) bool NeighbourIsDeadShore(Bridge neighbour)

View File

@@ -30,6 +30,9 @@ namespace OpenRA.Mods.Common.Traits
public WeaponInfo DemolishWeaponInfo { get; private set; } public WeaponInfo DemolishWeaponInfo { get; private set; }
[Desc("Types of damage that this bridge causes to units over/in path of it while being destroyed/repaired. Leave empty for no damage types.")]
public readonly HashSet<string> DamageTypes = new HashSet<string>();
public void RulesetLoaded(Ruleset rules, ActorInfo ai) public void RulesetLoaded(Ruleset rules, ActorInfo ai)
{ {
WeaponInfo weapon; WeaponInfo weapon;
@@ -95,7 +98,7 @@ namespace OpenRA.Mods.Common.Traits
foreach (var c in cells) foreach (var c in cells)
foreach (var a in self.World.ActorMap.GetActorsAt(c)) foreach (var a in self.World.ActorMap.GetActorsAt(c))
if (a.Info.HasTraitInfo<IPositionableInfo>() && !a.Trait<IPositionable>().CanEnterCell(c)) if (a.Info.HasTraitInfo<IPositionableInfo>() && !a.Trait<IPositionable>().CanEnterCell(c))
a.Kill(self); a.Kill(self, Info.DamageTypes);
} }
void IBridgeSegment.Repair(Actor repairer) void IBridgeSegment.Repair(Actor repairer)

View File

@@ -57,7 +57,8 @@ namespace OpenRA.Mods.Common.Traits
Game.Sound.Play(SoundType.World, Info.CrushSound, crusher.CenterPosition); Game.Sound.Play(SoundType.World, Info.CrushSound, crusher.CenterPosition);
self.Kill(crusher); var crusherMobile = crusher.TraitOrDefault<Mobile>();
self.Kill(crusher, crusherMobile != null ? crusherMobile.Info.CrushDamageTypes : new HashSet<string>());
} }
bool ICrushable.CrushableBy(Actor self, Actor crusher, HashSet<string> crushClasses) bool ICrushable.CrushableBy(Actor self, Actor crusher, HashSet<string> crushClasses)

View File

@@ -9,6 +9,7 @@
*/ */
#endregion #endregion
using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenRA.Traits; using OpenRA.Traits;
@@ -163,9 +164,12 @@ namespace OpenRA.Mods.Common.Traits
} }
} }
public void Kill(Actor self, Actor attacker) public void Kill(Actor self, Actor attacker, HashSet<string> damageTypes = null)
{ {
InflictDamage(self, attacker, new Damage(MaxHP), true); if (damageTypes == null)
damageTypes = new HashSet<string>();
InflictDamage(self, attacker, new Damage(MaxHP, damageTypes), true);
} }
void ITick.Tick(Actor self) void ITick.Tick(Actor self)

View File

@@ -9,6 +9,7 @@
*/ */
#endregion #endregion
using System.Collections.Generic;
using OpenRA.Traits; using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits namespace OpenRA.Mods.Common.Traits
@@ -21,6 +22,9 @@ namespace OpenRA.Mods.Common.Traits
[Desc("The amount of time (in ticks) before the actor dies. Two values indicate a range between which a random value is chosen.")] [Desc("The amount of time (in ticks) before the actor dies. Two values indicate a range between which a random value is chosen.")]
public readonly int[] Delay = { 0 }; public readonly int[] Delay = { 0 };
[Desc("Types of damage that this trait causes. Leave empty for no damage types.")]
public readonly HashSet<string> DamageTypes = new HashSet<string>();
[GrantedConditionReference] [GrantedConditionReference]
[Desc("The condition to grant moments before suiciding.")] [Desc("The condition to grant moments before suiciding.")]
public readonly string GrantsCondition = null; public readonly string GrantsCondition = null;
@@ -81,7 +85,7 @@ namespace OpenRA.Mods.Common.Traits
if (Info.RemoveInstead || !self.Info.HasTraitInfo<HealthInfo>()) if (Info.RemoveInstead || !self.Info.HasTraitInfo<HealthInfo>())
self.Dispose(); self.Dispose();
else else
self.Kill(self); self.Kill(self, Info.DamageTypes);
} }
} }
} }

View File

@@ -59,6 +59,9 @@ namespace OpenRA.Mods.Common.Traits
[Desc("e.g. crate, wall, infantry")] [Desc("e.g. crate, wall, infantry")]
public readonly HashSet<string> Crushes = new HashSet<string>(); public readonly HashSet<string> Crushes = new HashSet<string>();
[Desc("Types of damage that are caused while crushing. Leave empty for no damage types.")]
public readonly HashSet<string> CrushDamageTypes = new HashSet<string>();
public readonly int WaitAverage = 5; public readonly int WaitAverage = 5;
public readonly int WaitSpread = 2; public readonly int WaitSpread = 2;

View File

@@ -22,6 +22,9 @@ namespace OpenRA.Mods.Common.Traits
[Desc("If we land on invalid terrain for my actor type should we be killed?")] [Desc("If we land on invalid terrain for my actor type should we be killed?")]
public readonly bool KilledOnImpassableTerrain = true; public readonly bool KilledOnImpassableTerrain = true;
[Desc("Types of damage that this trait causes to self when 'KilledOnImpassableTerrain' is true. Leave empty for no damage types.")]
public readonly HashSet<string> DamageTypes = new HashSet<string>();
[Desc("Image where Ground/WaterCorpseSequence is looked up.")] [Desc("Image where Ground/WaterCorpseSequence is looked up.")]
public readonly string Image = "explosion"; public readonly string Image = "explosion";
@@ -101,7 +104,7 @@ namespace OpenRA.Mods.Common.Traits
if (sequence != null && palette != null) if (sequence != null && palette != null)
self.World.AddFrameEndTask(w => w.Add(new SpriteEffect(self.OccupiesSpace.CenterPosition, w, info.Image, sequence, palette))); self.World.AddFrameEndTask(w => w.Add(new SpriteEffect(self.OccupiesSpace.CenterPosition, w, info.Image, sequence, palette)));
self.Kill(self); self.Kill(self, info.DamageTypes);
} }
} }
} }

View File

@@ -219,15 +219,13 @@ namespace OpenRA.Mods.Common.Traits
break; break;
var actor = order.Target.Actor; var actor = order.Target.Actor;
var health = actor.TraitOrDefault<Health>();
var args = order.TargetString.Split(' '); var args = order.TargetString.Split(' ');
var damageTypes = new HashSet<string>(); var damageTypes = new HashSet<string>();
foreach (var damageType in args) foreach (var damageType in args)
damageTypes.Add(damageType); damageTypes.Add(damageType);
if (health != null) actor.Kill(actor, damageTypes);
health.InflictDamage(actor, actor, new Damage(health.HP, damageTypes), true);
break; break;
} }

View File

@@ -21,7 +21,7 @@ namespace OpenRA.Mods.Common.Warheads
[Desc("How much (raw) damage to deal.")] [Desc("How much (raw) damage to deal.")]
public readonly int Damage = 0; public readonly int Damage = 0;
[Desc("Types of damage that this warhead causes. Leave empty for no damage.")] [Desc("Types of damage that this warhead causes. Leave empty for no damage types.")]
public readonly HashSet<string> DamageTypes = new HashSet<string>(); public readonly HashSet<string> DamageTypes = new HashSet<string>();
[Desc("Damage percentage versus each armortype.")] [Desc("Damage percentage versus each armortype.")]