Ignore damage modifiers when killing a unit via actor.Kill(). Fixes surrender desync (#460); Fixes invulnerable actors surviving in situations where they should be killed (bridge death, losing/surrender, etc).

This commit is contained in:
Paul Chote
2011-07-21 21:05:49 +12:00
parent 6ede28fdbe
commit c79f5b5365
2 changed files with 16 additions and 9 deletions

View File

@@ -70,18 +70,19 @@ namespace OpenRA.Traits
} }
} }
public void InflictDamage(Actor self, Actor attacker, int damage, WarheadInfo warhead) public void InflictDamage(Actor self, Actor attacker, int damage, WarheadInfo warhead, bool ignoreModifiers)
{ {
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 = this.DamageState; var oldState = this.DamageState;
/* apply the damage modifiers, if we have any. */ /* apply the damage modifiers, if we have any. */
var modifier = (float)self.TraitsImplementing<IDamageModifier>() var modifier = (float)self.TraitsImplementing<IDamageModifier>()
.Concat(self.Owner.PlayerActor.TraitsImplementing<IDamageModifier>()) .Concat(self.Owner.PlayerActor.TraitsImplementing<IDamageModifier>())
.Select(t => t.GetDamageModifier(attacker, warhead)).Product(); .Select(t => t.GetDamageModifier(attacker, warhead)).Product();
if (!ignoreModifiers)
damage = damage > 0 ? (int)(damage * modifier) : damage; damage = damage > 0 ? (int)(damage * modifier) : damage;
hp = Exts.Clamp(hp - damage, 0, MaxHP); hp = Exts.Clamp(hp - damage, 0, MaxHP);
var ai = new AttackInfo var ai = new AttackInfo
@@ -175,16 +176,14 @@ namespace OpenRA.Traits
{ {
var health = self.TraitOrDefault<Health>(); var health = self.TraitOrDefault<Health>();
if (health == null) return; if (health == null) return;
health.InflictDamage(self, attacker, damage, warhead); health.InflictDamage(self, attacker, damage, warhead, false);
} }
public static void Kill(this Actor self, Actor attacker) public static void Kill(this Actor self, Actor attacker)
{ {
var health = self.TraitOrDefault<Health>(); var health = self.TraitOrDefault<Health>();
if (health == null) return; if (health == null) return;
health.InflictDamage(self, attacker, health.MaxHP, null, true);
/* hack. Fix for proper */
health.InflictDamage(self, attacker, int.MaxValue, null);
} }
} }
} }

View File

@@ -34,8 +34,16 @@ namespace OpenRA.Mods.RA.Activities
if( !target.Trait<IOccupySpace>().OccupiedCells().Any( x => x.First == self.Location ) ) if( !target.Trait<IOccupySpace>().OccupiedCells().Any( x => x.First == self.Location ) )
return NextActivity; return NextActivity;
self.World.AddFrameEndTask(w => w.Add(new DelayedAction(delay, self.World.AddFrameEndTask(w => w.Add(new DelayedAction(delay, () =>
() => { if (target.IsInWorld) target.Kill(self); }))); {
// Invulnerable actors can't be demolished
var modifier = (float)target.TraitsImplementing<IDamageModifier>()
.Concat(self.Owner.PlayerActor.TraitsImplementing<IDamageModifier>())
.Select(t => t.GetDamageModifier(self, null)).Product();
if (target.IsInWorld && modifier > 0)
target.Kill(self);
})));
return NextActivity; return NextActivity;
} }
} }