fix desync due to bad FP in Combat.DoImpact
This commit is contained in:
@@ -176,8 +176,10 @@ namespace OpenRA
|
|||||||
var oldState = GetDamageState();
|
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(
|
var modifier = (float)traits.WithInterface<IDamageModifier>()
|
||||||
(float)damage, (a, t) => t.GetDamageModifier() * a);
|
.Select(t => t.GetDamageModifier()).Product();
|
||||||
|
|
||||||
|
damage = (int)(damage * modifier);
|
||||||
|
|
||||||
Health -= damage;
|
Health -= damage;
|
||||||
if (Health <= 0)
|
if (Health <= 0)
|
||||||
@@ -194,8 +196,8 @@ namespace OpenRA
|
|||||||
|
|
||||||
if (Health > maxHP) Health = maxHP;
|
if (Health > maxHP) Health = maxHP;
|
||||||
|
|
||||||
Log.Write("InflictDamage: {0} #{1} -> {2} #{3} raw={4} adj={5} hp={6}",
|
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);
|
attacker.Info.Name, attacker.ActorID, Info.Name, ActorID, rawDamage, damage, Health, modifier);
|
||||||
|
|
||||||
var newState = GetDamageState();
|
var newState = GetDamageState();
|
||||||
|
|
||||||
|
|||||||
@@ -81,8 +81,10 @@ namespace OpenRA
|
|||||||
args.dest, warhead.Damage, firepowerModifier, maxSpread);
|
args.dest, warhead.Damage, firepowerModifier, maxSpread);
|
||||||
|
|
||||||
foreach (var victim in hitActors)
|
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;
|
} break;
|
||||||
|
|
||||||
case DamageModel.PerCell:
|
case DamageModel.PerCell:
|
||||||
@@ -126,6 +128,20 @@ namespace OpenRA
|
|||||||
DoImpacts(args);
|
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)
|
static float GetDamageToInflict(Actor target, ProjectileArgs args, WarheadInfo warhead, float modifier)
|
||||||
{
|
{
|
||||||
// don't hit air units with splash from ground explosions, etc
|
// 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 selectable = target.Info.Traits.GetOrDefault<SelectableInfo>();
|
||||||
var radius = selectable != null ? selectable.Radius : 0;
|
var radius = selectable != null ? selectable.Radius : 0;
|
||||||
var distance = Math.Max(0, (target.CenterLocation - args.dest).Length - radius);
|
var distance = (int)Math.Max(0, (target.CenterLocation - args.dest).Length - radius);
|
||||||
var rawDamage = warhead.Damage * modifier * (float)Math.Exp(-distance / warhead.Spread);
|
var falloff = (float)GetDamageFalloff(distance / warhead.Spread);
|
||||||
var multiplier = warhead.EffectivenessAgainst(target.Info.Traits.Get<OwnedActorInfo>().Armor);
|
var rawDamage = (float)(warhead.Damage * modifier * falloff);
|
||||||
return rawDamage * multiplier;
|
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)
|
public static bool WeaponValidForTarget(WeaponInfo weapon, Actor target)
|
||||||
|
|||||||
Reference in New Issue
Block a user