fix desync due to bad FP in Combat.DoImpact

This commit is contained in:
Chris Forbes
2010-04-30 19:42:02 +12:00
parent a22aa7ccb8
commit 36fc025a86
2 changed files with 33 additions and 10 deletions

View File

@@ -176,8 +176,10 @@ namespace OpenRA
var oldState = GetDamageState();
/* apply the damage modifiers, if we have any. */
damage = (int)traits.WithInterface<IDamageModifier>().Aggregate(
(float)damage, (a, t) => t.GetDamageModifier() * a);
var modifier = (float)traits.WithInterface<IDamageModifier>()
.Select(t => t.GetDamageModifier()).Product();
damage = (int)(damage * modifier);
Health -= damage;
if (Health <= 0)
@@ -194,8 +196,8 @@ namespace OpenRA
if (Health > maxHP) Health = maxHP;
Log.Write("InflictDamage: {0} #{1} -> {2} #{3} raw={4} adj={5} hp={6}",
attacker.Info.Name, attacker.ActorID, Info.Name, ActorID, rawDamage, damage, Health);
Log.Write("InflictDamage: {0} #{1} -> {2} #{3} raw={4} adj={5} hp={6} mod={7}",
attacker.Info.Name, attacker.ActorID, Info.Name, ActorID, rawDamage, damage, Health, modifier);
var newState = GetDamageState();

View File

@@ -81,8 +81,10 @@ namespace OpenRA
args.dest, warhead.Damage, firepowerModifier, maxSpread);
foreach (var victim in hitActors)
victim.InflictDamage(args.firedBy,
(int)GetDamageToInflict(victim, args, warhead, firepowerModifier), warhead);
{
var damage = (int)GetDamageToInflict(victim, args, warhead, firepowerModifier);
victim.InflictDamage(args.firedBy, damage, warhead);
}
} break;
case DamageModel.PerCell:
@@ -126,6 +128,20 @@ namespace OpenRA
DoImpacts(args);
}
static readonly float[] falloff =
{
1f, 0.3678795f, 0.1353353f, 0.04978707f,
0.01831564f, 0.006737947f, 0.002478752f, 0.000911882f
};
static float GetDamageFalloff(float x)
{
var u = (int)x;
if (u >= falloff.Length - 1) return 0;
var t = x - u;
return (falloff[u] * (1 - t)) + (falloff[u + 1] * t);
}
static float GetDamageToInflict(Actor target, ProjectileArgs args, WarheadInfo warhead, float modifier)
{
// don't hit air units with splash from ground explosions, etc
@@ -133,10 +149,15 @@ namespace OpenRA
var selectable = target.Info.Traits.GetOrDefault<SelectableInfo>();
var radius = selectable != null ? selectable.Radius : 0;
var distance = Math.Max(0, (target.CenterLocation - args.dest).Length - radius);
var rawDamage = warhead.Damage * modifier * (float)Math.Exp(-distance / warhead.Spread);
var multiplier = warhead.EffectivenessAgainst(target.Info.Traits.Get<OwnedActorInfo>().Armor);
return rawDamage * multiplier;
var distance = (int)Math.Max(0, (target.CenterLocation - args.dest).Length - radius);
var falloff = (float)GetDamageFalloff(distance / warhead.Spread);
var rawDamage = (float)(warhead.Damage * modifier * falloff);
var multiplier = (float)warhead.EffectivenessAgainst(target.Info.Traits.Get<OwnedActorInfo>().Armor);
Log.Write("GetDamageToInflict {0} #{1} r={2} dist={3} falloff={4} raw={5} mul={6}",
target.Info.Name, target.ActorID, radius, distance, falloff, rawDamage, multiplier);
return (float)(rawDamage * multiplier);
}
public static bool WeaponValidForTarget(WeaponInfo weapon, Actor target)