(5a377a8ee) Unstable v0.9.1000.0
This commit is contained in:
@@ -30,9 +30,9 @@ namespace Barotrauma
|
||||
|
||||
public float EmpStrength { get; set; }
|
||||
|
||||
public Explosion(float range, float force, float damage, float structureDamage, float empStrength = 0.0f)
|
||||
public Explosion(float range, float force, float damage, float structureDamage, float itemDamage, float empStrength = 0.0f)
|
||||
{
|
||||
attack = new Attack(damage, 0.0f, 0.0f, structureDamage, range)
|
||||
attack = new Attack(damage, 0.0f, 0.0f, structureDamage, itemDamage, range)
|
||||
{
|
||||
SeverLimbsProbability = 1.0f
|
||||
};
|
||||
@@ -157,42 +157,47 @@ namespace Barotrauma
|
||||
|
||||
if (GameMain.NetworkMember == null || !GameMain.NetworkMember.IsClient)
|
||||
{
|
||||
if (flames)
|
||||
foreach (Item item in Item.ItemList)
|
||||
{
|
||||
foreach (Item item in Item.ItemList)
|
||||
if (item.Condition <= 0.0f) { continue; }
|
||||
if (Vector2.Distance(item.WorldPosition, worldPosition) > attack.Range * 0.5f) { continue; }
|
||||
if (flames && !item.FireProof)
|
||||
{
|
||||
if (item.CurrentHull != hull || item.FireProof || item.Condition <= 0.0f) { continue; }
|
||||
|
||||
//don't apply OnFire effects if the item is inside a fireproof container
|
||||
//(or if it's inside a container that's inside a fireproof container, etc)
|
||||
Item container = item.Container;
|
||||
bool fireProof = false;
|
||||
while (container != null)
|
||||
{
|
||||
if (container.FireProof) { fireProof = true; break; }
|
||||
if (container.FireProof)
|
||||
{
|
||||
fireProof = true;
|
||||
break;
|
||||
}
|
||||
container = container.Container;
|
||||
}
|
||||
|
||||
if (fireProof || Vector2.Distance(item.WorldPosition, worldPosition) > attack.Range * 0.5f) { continue; }
|
||||
|
||||
item.ApplyStatusEffects(ActionType.OnFire, 1.0f);
|
||||
if (item.Condition <= 0.0f && GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
|
||||
if (!fireProof)
|
||||
{
|
||||
GameMain.NetworkMember.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.ApplyStatusEffect, ActionType.OnFire });
|
||||
item.ApplyStatusEffects(ActionType.OnFire, 1.0f);
|
||||
if (item.Condition <= 0.0f && GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
|
||||
{
|
||||
GameMain.NetworkMember.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.ApplyStatusEffect, ActionType.OnFire });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (item.Prefab.DamagedByExplosions && !item.Indestructible)
|
||||
if (item.Prefab.DamagedByExplosions && !item.Indestructible)
|
||||
{
|
||||
float limbRadius = item.body == null ? 0.0f : item.body.GetMaxExtent();
|
||||
float dist = Vector2.Distance(item.WorldPosition, worldPosition);
|
||||
dist = Math.Max(0.0f, dist - ConvertUnits.ToDisplayUnits(limbRadius));
|
||||
if (dist > attack.Range)
|
||||
{
|
||||
float limbRadius = item.body == null ? 0.0f : item.body.GetMaxExtent();
|
||||
float dist = Vector2.Distance(item.WorldPosition, worldPosition);
|
||||
dist = Math.Max(0.0f, dist - ConvertUnits.ToDisplayUnits(limbRadius));
|
||||
|
||||
if (dist > attack.Range) { continue; }
|
||||
|
||||
float distFactor = 1.0f - dist / attack.Range;
|
||||
float damageAmount = attack.GetItemDamage(1.0f);
|
||||
item.Condition -= damageAmount * distFactor;
|
||||
continue;
|
||||
}
|
||||
float distFactor = 1.0f - dist / attack.Range;
|
||||
float damageAmount = attack.GetItemDamage(1.0f) * item.Prefab.ExplosionDamageMultiplier;
|
||||
item.Condition -= damageAmount * distFactor;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -200,10 +205,9 @@ namespace Barotrauma
|
||||
|
||||
partial void ExplodeProjSpecific(Vector2 worldPosition, Hull hull);
|
||||
|
||||
|
||||
public static void DamageCharacters(Vector2 worldPosition, Attack attack, float force, Entity damageSource, Character attacker)
|
||||
{
|
||||
if (attack.Range <= 0.0f) return;
|
||||
if (attack.Range <= 0.0f) { return; }
|
||||
|
||||
//long range for the broad distance check, because large characters may still be in range even if their collider isn't
|
||||
float broadRange = Math.Max(attack.Range * 10.0f, 10000.0f);
|
||||
@@ -220,19 +224,20 @@ namespace Barotrauma
|
||||
Vector2 explosionPos = worldPosition;
|
||||
if (c.Submarine != null) { explosionPos -= c.Submarine.Position; }
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
Hull hull = Hull.FindHull(explosionPos, null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
explosionPos = ConvertUnits.ToSimUnits(explosionPos);
|
||||
|
||||
Dictionary<Limb, float> distFactors = new Dictionary<Limb, float>();
|
||||
Dictionary<Limb, float> damages = new Dictionary<Limb, float>();
|
||||
foreach (Limb limb in c.AnimController.Limbs)
|
||||
{
|
||||
float dist = Vector2.Distance(limb.WorldPosition, worldPosition);
|
||||
|
||||
//calculate distance from the "outer surface" of the physics body
|
||||
//doesn't take the rotation of the limb into account, but should be accurate enough for this purpose
|
||||
float limbRadius = Math.Max(Math.Max(limb.body.width * 0.5f, limb.body.height * 0.5f), limb.body.radius);
|
||||
float limbRadius = limb.body.GetMaxExtent();
|
||||
dist = Math.Max(0.0f, dist - ConvertUnits.ToDisplayUnits(limbRadius));
|
||||
|
||||
if (dist > attack.Range) { continue; }
|
||||
@@ -240,14 +245,18 @@ namespace Barotrauma
|
||||
float distFactor = 1.0f - dist / attack.Range;
|
||||
|
||||
//solid obstacles between the explosion and the limb reduce the effect of the explosion by 90%
|
||||
if (Submarine.CheckVisibility(limb.SimPosition, explosionPos) != null) distFactor *= 0.1f;
|
||||
if (Submarine.CheckVisibility(limb.SimPosition, explosionPos) != null)
|
||||
{
|
||||
distFactor *= 0.1f;
|
||||
}
|
||||
|
||||
distFactors.Add(limb, distFactor);
|
||||
|
||||
List<Affliction> modifiedAfflictions = new List<Affliction>();
|
||||
int limbCount = c.AnimController.Limbs.Count(l => !l.IsSevered && !l.ignoreCollisions);
|
||||
foreach (Affliction affliction in attack.Afflictions.Keys)
|
||||
{
|
||||
modifiedAfflictions.Add(affliction.CreateMultiplied(distFactor / c.AnimController.Limbs.Length));
|
||||
modifiedAfflictions.Add(affliction.CreateMultiplied(distFactor / limbCount));
|
||||
}
|
||||
c.LastDamageSource = damageSource;
|
||||
if (attacker == null)
|
||||
@@ -255,14 +264,18 @@ namespace Barotrauma
|
||||
if (damageSource is Item item)
|
||||
{
|
||||
attacker = item.GetComponent<Projectile>()?.User;
|
||||
if (attacker == null) attacker = item.GetComponent<MeleeWeapon>()?.User;
|
||||
if (attacker == null)
|
||||
{
|
||||
attacker = item.GetComponent<MeleeWeapon>()?.User;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//use a position slightly from the limb's position towards the explosion
|
||||
//ensures that the attack hits the correct limb and that the direction of the hit can be determined correctly in the AddDamage methods
|
||||
Vector2 hitPos = limb.WorldPosition + (worldPosition - limb.WorldPosition) / dist * 0.01f;
|
||||
c.AddDamage(hitPos, modifiedAfflictions, attack.Stun * distFactor, false, attacker: attacker);
|
||||
AttackResult attackResult = c.AddDamage(hitPos, modifiedAfflictions, attack.Stun * distFactor, false, attacker: attacker);
|
||||
damages.Add(limb, attackResult.Damage);
|
||||
|
||||
if (attack.StatusEffects != null && attack.StatusEffects.Any())
|
||||
{
|
||||
@@ -287,14 +300,19 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
//sever joints
|
||||
if (c.IsDead && attack.SeverLimbsProbability > 0.0f)
|
||||
if (attack.SeverLimbsProbability > 0.0f)
|
||||
{
|
||||
foreach (Limb limb in c.AnimController.Limbs)
|
||||
{
|
||||
if (!distFactors.ContainsKey(limb)) { continue; }
|
||||
if (Rand.Range(0.0f, 1.0f) < attack.SeverLimbsProbability * distFactors[limb])
|
||||
if (limb.character.Removed || limb.Removed) { continue; }
|
||||
if (limb.IsSevered) { continue; }
|
||||
if (!c.IsDead && !limb.CanBeSeveredAlive) { continue; }
|
||||
if (distFactors.TryGetValue(limb, out float distFactor))
|
||||
{
|
||||
c.TrySeverLimbJoints(limb, 1.0f);
|
||||
if (damages.TryGetValue(limb, out float damage))
|
||||
{
|
||||
c.TrySeverLimbJoints(limb, attack.SeverLimbsProbability * distFactor, damage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user