revamp of damage notifs; added Explodes
This commit is contained in:
@@ -108,12 +108,19 @@ namespace OpenRa.Game
|
|||||||
|
|
||||||
public bool IsDead { get { return Health <= 0; } }
|
public bool IsDead { get { return Health <= 0; } }
|
||||||
|
|
||||||
|
DamageState GetDamageState()
|
||||||
|
{
|
||||||
|
if (Health <= 0) return DamageState.Dead;
|
||||||
|
var halfStrength = Info.Strength * Rules.General.ConditionYellow;
|
||||||
|
return Health < halfStrength ? DamageState.Half : DamageState.Normal;
|
||||||
|
}
|
||||||
|
|
||||||
public void InflictDamage(Actor attacker, int damage, WarheadInfo warhead)
|
public void InflictDamage(Actor attacker, int damage, WarheadInfo warhead)
|
||||||
{
|
{
|
||||||
/* todo: auto-retaliate, etc */
|
|
||||||
|
|
||||||
if (IsDead) return; /* overkill! don't count extra hits as more kills! */
|
if (IsDead) return; /* overkill! don't count extra hits as more kills! */
|
||||||
|
|
||||||
|
var oldState = GetDamageState();
|
||||||
|
|
||||||
/* apply the damage modifiers, if we have any. */
|
/* apply the damage modifiers, if we have any. */
|
||||||
damage = (int)traits.WithInterface<IDamageModifier>().Aggregate(
|
damage = (int)traits.WithInterface<IDamageModifier>().Aggregate(
|
||||||
(float)damage, (a, t) => t.GetDamageModifier() * a);
|
(float)damage, (a, t) => t.GetDamageModifier() * a);
|
||||||
@@ -126,24 +133,19 @@ namespace OpenRa.Game
|
|||||||
attacker.Owner.Kills++;
|
attacker.Owner.Kills++;
|
||||||
|
|
||||||
Game.world.AddFrameEndTask(w => w.Remove(this));
|
Game.world.AddFrameEndTask(w => w.Remove(this));
|
||||||
|
|
||||||
if (Owner == Game.LocalPlayer && !traits.Contains<Building>())
|
|
||||||
Sound.Play("unitlst1.aud");
|
|
||||||
|
|
||||||
if (traits.Contains<Building>())
|
|
||||||
Sound.Play("kaboom22.aud");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var halfStrength = Info.Strength * Rules.General.ConditionYellow;
|
var newState = GetDamageState();
|
||||||
if (Health < halfStrength && (Health + damage) >= halfStrength)
|
|
||||||
{
|
|
||||||
/* we just went below half health! */
|
|
||||||
foreach (var nd in traits.WithInterface<INotifyDamage>())
|
|
||||||
nd.Damaged(this, DamageState.Half);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var ndx in traits.WithInterface<INotifyDamageEx>())
|
foreach (var nd in traits.WithInterface<INotifyDamage>())
|
||||||
ndx.Damaged(this, damage, warhead);
|
nd.Damaged(this, new AttackInfo
|
||||||
|
{
|
||||||
|
Attacker = attacker,
|
||||||
|
Damage = damage,
|
||||||
|
DamageState = newState,
|
||||||
|
DamageStateChanged = newState != oldState,
|
||||||
|
Warhead = warhead
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void QueueActivity( IActivity nextActivity )
|
public void QueueActivity( IActivity nextActivity )
|
||||||
|
|||||||
@@ -158,9 +158,11 @@
|
|||||||
<Compile Include="Traits\Activities\Follow.cs" />
|
<Compile Include="Traits\Activities\Follow.cs" />
|
||||||
<Compile Include="Traits\Activities\Turn.cs" />
|
<Compile Include="Traits\Activities\Turn.cs" />
|
||||||
<Compile Include="Traits\AttackBase.cs" />
|
<Compile Include="Traits\AttackBase.cs" />
|
||||||
|
<Compile Include="Traits\AttackInfo.cs" />
|
||||||
<Compile Include="Traits\AttackTurreted.cs" />
|
<Compile Include="Traits\AttackTurreted.cs" />
|
||||||
<Compile Include="Traits\AutoTarget.cs" />
|
<Compile Include="Traits\AutoTarget.cs" />
|
||||||
<Compile Include="Traits\Building.cs" />
|
<Compile Include="Traits\Building.cs" />
|
||||||
|
<Compile Include="Traits\Explodes.cs" />
|
||||||
<Compile Include="Traits\Harvester.cs" />
|
<Compile Include="Traits\Harvester.cs" />
|
||||||
<Compile Include="Traits\Helicopter.cs" />
|
<Compile Include="Traits\Helicopter.cs" />
|
||||||
<Compile Include="Traits\ProductionQueue.cs" />
|
<Compile Include="Traits\ProductionQueue.cs" />
|
||||||
|
|||||||
17
OpenRa.Game/Traits/AttackInfo.cs
Normal file
17
OpenRa.Game/Traits/AttackInfo.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using OpenRa.Game.GameRules;
|
||||||
|
|
||||||
|
namespace OpenRa.Game.Traits
|
||||||
|
{
|
||||||
|
class AttackInfo
|
||||||
|
{
|
||||||
|
public Actor Attacker;
|
||||||
|
public WarheadInfo Warhead;
|
||||||
|
public int Damage;
|
||||||
|
public DamageState DamageState;
|
||||||
|
public bool DamageStateChanged;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace OpenRa.Game.Traits
|
namespace OpenRa.Game.Traits
|
||||||
{
|
{
|
||||||
class Building : ITick
|
class Building : ITick, INotifyDamage
|
||||||
{
|
{
|
||||||
public readonly BuildingInfo unitInfo;
|
public readonly BuildingInfo unitInfo;
|
||||||
|
|
||||||
@@ -19,5 +19,11 @@ namespace OpenRa.Game.Traits
|
|||||||
|
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Damaged(Actor self, AttackInfo e)
|
||||||
|
{
|
||||||
|
if (e.DamageState == DamageState.Dead)
|
||||||
|
Sound.Play("kaboom22.aud");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
23
OpenRa.Game/Traits/Explodes.cs
Normal file
23
OpenRa.Game/Traits/Explodes.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using OpenRa.Game.Effects;
|
||||||
|
|
||||||
|
namespace OpenRa.Game.Traits
|
||||||
|
{
|
||||||
|
class Explodes : INotifyDamage
|
||||||
|
{
|
||||||
|
public Explodes(Actor self) {}
|
||||||
|
|
||||||
|
public void Damaged(Actor self, AttackInfo e)
|
||||||
|
{
|
||||||
|
if (self.IsDead)
|
||||||
|
{
|
||||||
|
Game.world.AddFrameEndTask(
|
||||||
|
w => w.Add(new Bullet("UnitExplode", e.Attacker.Owner, e.Attacker,
|
||||||
|
self.CenterLocation.ToInt2(), self.CenterLocation.ToInt2())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -65,9 +65,12 @@ namespace OpenRa.Game.Traits
|
|||||||
yield return Tuple.New(anim.Image, 24f * (float2)self.Location, pal);
|
yield return Tuple.New(anim.Image, 24f * (float2)self.Location, pal);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Damaged(Actor self, DamageState state)
|
public virtual void Damaged(Actor self, AttackInfo e)
|
||||||
{
|
{
|
||||||
switch( state )
|
if (!e.DamageStateChanged)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch( e.DamageState )
|
||||||
{
|
{
|
||||||
case DamageState.Normal:
|
case DamageState.Normal:
|
||||||
anim.ReplaceAnim("idle");
|
anim.ReplaceAnim("idle");
|
||||||
|
|||||||
@@ -14,9 +14,11 @@ namespace OpenRa.Game.Traits
|
|||||||
anim.PlayFacing(a, () => self.traits.Get<Turreted>().turretFacing);
|
anim.PlayFacing(a, () => self.traits.Get<Turreted>().turretFacing);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Damaged(Actor self, DamageState ds)
|
public override void Damaged(Actor self, AttackInfo e)
|
||||||
{
|
{
|
||||||
switch (ds)
|
if (!e.DamageStateChanged) return;
|
||||||
|
|
||||||
|
switch (e.DamageState)
|
||||||
{
|
{
|
||||||
case DamageState.Normal:
|
case DamageState.Normal:
|
||||||
PlayTurretAnim(self, "idle");
|
PlayTurretAnim(self, "idle");
|
||||||
|
|||||||
@@ -51,11 +51,12 @@ namespace OpenRa.Game.Traits
|
|||||||
roof.PlayThen(prefix + "build-top", () => isOpen = true);
|
roof.PlayThen(prefix + "build-top", () => isOpen = true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Damaged(Actor self, DamageState ds)
|
public override void Damaged(Actor self, AttackInfo e)
|
||||||
{
|
{
|
||||||
base.Damaged(self, ds);
|
base.Damaged(self, e);
|
||||||
|
|
||||||
switch (ds)
|
if (!e.DamageStateChanged) return;
|
||||||
|
switch (e.DamageState)
|
||||||
{
|
{
|
||||||
case DamageState.Normal:
|
case DamageState.Normal:
|
||||||
prefix = "";
|
prefix = "";
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ using OpenRa.Game.Effects;
|
|||||||
|
|
||||||
namespace OpenRa.Game.Traits
|
namespace OpenRa.Game.Traits
|
||||||
{
|
{
|
||||||
class RenderInfantry : RenderSimple, INotifyAttack, INotifyDamageEx
|
class RenderInfantry : RenderSimple, INotifyAttack, INotifyDamage
|
||||||
{
|
{
|
||||||
public RenderInfantry(Actor self)
|
public RenderInfantry(Actor self)
|
||||||
: base(self)
|
: base(self)
|
||||||
@@ -75,12 +75,10 @@ namespace OpenRa.Game.Traits
|
|||||||
yield return Util.Centered(self, anim.Image, self.CenterLocation);
|
yield return Util.Centered(self, anim.Image, self.CenterLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Damaged(Actor self, int damage, WarheadInfo warhead)
|
public void Damaged(Actor self, AttackInfo e)
|
||||||
{
|
{
|
||||||
if (self.Health <= 0)
|
if (e.DamageState == DamageState.Dead)
|
||||||
Game.world.AddFrameEndTask(w => w.Add(new Corpse(self, warhead.InfDeath)));
|
Game.world.AddFrameEndTask(w => w.Add(new Corpse(self, e.Warhead.InfDeath)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Damaged(Actor self, DamageState ds) {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ using OpenRa.Game.GameRules;
|
|||||||
|
|
||||||
namespace OpenRa.Game.Traits
|
namespace OpenRa.Game.Traits
|
||||||
{
|
{
|
||||||
class RenderUnit : RenderSimple, INotifyDamageEx
|
class RenderUnit : RenderSimple, INotifyDamage
|
||||||
{
|
{
|
||||||
public RenderUnit(Actor self)
|
public RenderUnit(Actor self)
|
||||||
: base(self)
|
: base(self)
|
||||||
@@ -33,24 +33,20 @@ namespace OpenRa.Game.Traits
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool isSmoking;
|
bool isSmoking;
|
||||||
DamageState currentDs;
|
|
||||||
Animation smoke;
|
Animation smoke;
|
||||||
|
|
||||||
public void Damaged(Actor self, DamageState ds) { currentDs = ds; }
|
public void Damaged(Actor self, AttackInfo e)
|
||||||
|
|
||||||
public void Damaged(Actor self, int damage, WarheadInfo warhead)
|
|
||||||
{
|
{
|
||||||
if (currentDs != DamageState.Half) return;
|
if (e.DamageState != DamageState.Half) return;
|
||||||
if (!isSmoking)
|
if (isSmoking) return;
|
||||||
{
|
|
||||||
isSmoking = true;
|
|
||||||
smoke.PlayThen("idle",
|
|
||||||
() => smoke.PlayThen("loop",
|
|
||||||
() => smoke.PlayBackwardsThen("end",
|
|
||||||
() => isSmoking = false)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
isSmoking = true;
|
||||||
|
smoke.PlayThen("idle",
|
||||||
|
() => smoke.PlayThen("loop",
|
||||||
|
() => smoke.PlayBackwardsThen("end",
|
||||||
|
() => isSmoking = false)));
|
||||||
|
}
|
||||||
|
|
||||||
public override void Tick(Actor self)
|
public override void Tick(Actor self)
|
||||||
{
|
{
|
||||||
base.Tick(self);
|
base.Tick(self);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ using OpenRa.Game.GameRules;
|
|||||||
namespace OpenRa.Game.Traits
|
namespace OpenRa.Game.Traits
|
||||||
{
|
{
|
||||||
// infantry prone behavior
|
// infantry prone behavior
|
||||||
class TakeCover : ITick, INotifyDamageEx, IDamageModifier, ISpeedModifier
|
class TakeCover : ITick, INotifyDamage, IDamageModifier, ISpeedModifier
|
||||||
{
|
{
|
||||||
const int defaultProneTime = 100; /* ticks, =4s */
|
const int defaultProneTime = 100; /* ticks, =4s */
|
||||||
const float proneDamage = .5f;
|
const float proneDamage = .5f;
|
||||||
@@ -19,9 +19,10 @@ namespace OpenRa.Game.Traits
|
|||||||
|
|
||||||
public TakeCover(Actor self) {}
|
public TakeCover(Actor self) {}
|
||||||
|
|
||||||
public void Damaged(Actor self, int damage, WarheadInfo warhead)
|
public void Damaged(Actor self, AttackInfo e)
|
||||||
{
|
{
|
||||||
remainingProneTime = defaultProneTime;
|
if (e.Damage > 0) /* fix to allow healing via `damage` */
|
||||||
|
remainingProneTime = defaultProneTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Tick(Actor self)
|
public void Tick(Actor self)
|
||||||
|
|||||||
@@ -8,8 +8,7 @@ namespace OpenRa.Game.Traits
|
|||||||
|
|
||||||
interface ITick { void Tick(Actor self); }
|
interface ITick { void Tick(Actor self); }
|
||||||
interface IRender { IEnumerable<Tuple<Sprite, float2, int>> Render(Actor self); }
|
interface IRender { IEnumerable<Tuple<Sprite, float2, int>> Render(Actor self); }
|
||||||
interface INotifyDamage { void Damaged(Actor self, DamageState ds); }
|
interface INotifyDamage { void Damaged(Actor self, AttackInfo e); }
|
||||||
interface INotifyDamageEx { void Damaged(Actor self, int damage, WarheadInfo warhead); }
|
|
||||||
interface INotifyBuildComplete { void BuildingComplete (Actor self); }
|
interface INotifyBuildComplete { void BuildingComplete (Actor self); }
|
||||||
interface IOrder
|
interface IOrder
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,11 +1,18 @@
|
|||||||
|
|
||||||
namespace OpenRa.Game.Traits
|
namespace OpenRa.Game.Traits
|
||||||
{
|
{
|
||||||
class Unit
|
class Unit : INotifyDamage
|
||||||
{
|
{
|
||||||
public int Facing;
|
public int Facing;
|
||||||
public int Altitude;
|
public int Altitude;
|
||||||
|
|
||||||
public Unit( Actor self ) { }
|
public Unit( Actor self ) { }
|
||||||
|
|
||||||
|
public void Damaged(Actor self, AttackInfo e)
|
||||||
|
{
|
||||||
|
if (e.DamageState == DamageState.Dead)
|
||||||
|
if (self.Owner == Game.LocalPlayer)
|
||||||
|
Sound.Play("unitlst1.aud");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,13 +21,8 @@ namespace OpenRa.Game
|
|||||||
public void AddFrameEndTask( Action<World> a ) { frameEndActions.Add( a ); }
|
public void AddFrameEndTask( Action<World> a ) { frameEndActions.Add( a ); }
|
||||||
|
|
||||||
public event Action<Actor> ActorAdded = _ => { };
|
public event Action<Actor> ActorAdded = _ => { };
|
||||||
public event Action<Actor> ActorRemoved = a =>
|
public event Action<Actor> ActorRemoved = _ => { };
|
||||||
{
|
|
||||||
a.Health = 0; /* make sure everyone sees it as dead */
|
|
||||||
foreach (var nr in a.traits.WithInterface<INotifyDamage>())
|
|
||||||
nr.Damaged(a, DamageState.Dead);
|
|
||||||
};
|
|
||||||
|
|
||||||
public void Tick()
|
public void Tick()
|
||||||
{
|
{
|
||||||
foreach (var a in actors) a.Tick();
|
foreach (var a in actors) a.Tick();
|
||||||
|
|||||||
@@ -523,6 +523,7 @@
|
|||||||
<sequence name="4w" start="0" length="10" src="h2o_exp2" />
|
<sequence name="4w" start="0" length="10" src="h2o_exp2" />
|
||||||
<sequence name="2w" start="0" length="10" src="h2o_exp3" />
|
<sequence name="2w" start="0" length="10" src="h2o_exp3" />
|
||||||
<sequence name="7" start="0" length="18" src="fball1" />
|
<sequence name="7" start="0" length="18" src="fball1" />
|
||||||
|
<sequence name="8" start="0" length="22" src="art-exp1" />
|
||||||
</unit>
|
</unit>
|
||||||
<unit name="lst">
|
<unit name="lst">
|
||||||
<sequence name="idle" start="0" length="1" />
|
<sequence name="idle" start="0" length="1" />
|
||||||
|
|||||||
17
units.ini
17
units.ini
@@ -57,7 +57,7 @@ Voice=VehicleVoice
|
|||||||
LongDesc=Regenerates Fog of War in a small area \naround the unit.\n Unarmed
|
LongDesc=Regenerates Fog of War in a small area \naround the unit.\n Unarmed
|
||||||
[ARTY]
|
[ARTY]
|
||||||
Description=Artillery
|
Description=Artillery
|
||||||
Traits=Unit, Mobile, AttackBase, RenderUnit
|
Traits=Unit, Mobile, AttackBase, RenderUnit, Explodes
|
||||||
Voice=VehicleVoice
|
Voice=VehicleVoice
|
||||||
LongDesc=Long-range artillery.\n Strong vs Infantry, Buildings\n Weak vs Tanks, Aircraft
|
LongDesc=Long-range artillery.\n Strong vs Infantry, Buildings\n Weak vs Tanks, Aircraft
|
||||||
[HARV]
|
[HARV]
|
||||||
@@ -607,10 +607,17 @@ ParaBomb
|
|||||||
DogJaw
|
DogJaw
|
||||||
Heal
|
Heal
|
||||||
SCUD
|
SCUD
|
||||||
|
UnitExplode
|
||||||
|
|
||||||
[TeslaZap]
|
[TeslaZap]
|
||||||
RenderAsTesla=true
|
RenderAsTesla=true
|
||||||
|
|
||||||
|
[UnitExplode]
|
||||||
|
Damage=500
|
||||||
|
Speed=100
|
||||||
|
Projectile=Invisible
|
||||||
|
Warhead=UnitExplodeWarhead
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -646,11 +653,19 @@ HollowPoint
|
|||||||
Super
|
Super
|
||||||
Organic
|
Organic
|
||||||
Nuke
|
Nuke
|
||||||
|
UnitExplodeWarhead
|
||||||
|
|
||||||
[HE]
|
[HE]
|
||||||
ImpactSound=kaboom25
|
ImpactSound=kaboom25
|
||||||
WaterImpactSound=splash9
|
WaterImpactSound=splash9
|
||||||
|
|
||||||
|
[UnitExplodeWarhead]
|
||||||
|
Spread=10
|
||||||
|
Verses=90%,75%,60%,25%,100%
|
||||||
|
Explosion=8
|
||||||
|
InfDeath=3
|
||||||
|
ImpactSound=kaboom15
|
||||||
|
|
||||||
[General]
|
[General]
|
||||||
OreChance=.02
|
OreChance=.02
|
||||||
LowPowerSlowdown=3
|
LowPowerSlowdown=3
|
||||||
|
|||||||
Reference in New Issue
Block a user