diff --git a/Barotrauma/BarotraumaShared/BarotraumaShared.projitems b/Barotrauma/BarotraumaShared/BarotraumaShared.projitems index d7f24d232..b2beaca84 100644 --- a/Barotrauma/BarotraumaShared/BarotraumaShared.projitems +++ b/Barotrauma/BarotraumaShared/BarotraumaShared.projitems @@ -1356,6 +1356,7 @@ + diff --git a/Barotrauma/BarotraumaShared/Content/Characters/Carrier/carrier.xml b/Barotrauma/BarotraumaShared/Content/Characters/Carrier/carrier.xml index 99d366bd0..ec69f90e3 100644 --- a/Barotrauma/BarotraumaShared/Content/Characters/Carrier/carrier.xml +++ b/Barotrauma/BarotraumaShared/Content/Characters/Carrier/carrier.xml @@ -24,12 +24,15 @@ - + + + + diff --git a/Barotrauma/BarotraumaShared/Content/Characters/Crawler/crawler.xml b/Barotrauma/BarotraumaShared/Content/Characters/Crawler/crawler.xml index 7972a2cc5..631ee917a 100644 --- a/Barotrauma/BarotraumaShared/Content/Characters/Crawler/crawler.xml +++ b/Barotrauma/BarotraumaShared/Content/Characters/Crawler/crawler.xml @@ -30,17 +30,20 @@ - + + - 0 + + - + + diff --git a/Barotrauma/BarotraumaShared/Content/Characters/Mantis/mantis.xml b/Barotrauma/BarotraumaShared/Content/Characters/Mantis/mantis.xml index d3038cf53..b6f0d3057 100644 --- a/Barotrauma/BarotraumaShared/Content/Characters/Mantis/mantis.xml +++ b/Barotrauma/BarotraumaShared/Content/Characters/Mantis/mantis.xml @@ -33,25 +33,28 @@ - + + - + + - + + - + - - + + diff --git a/Barotrauma/BarotraumaShared/Content/Characters/Moloch/moloch.xml b/Barotrauma/BarotraumaShared/Content/Characters/Moloch/moloch.xml index 6fe19a384..aa8e40274 100644 --- a/Barotrauma/BarotraumaShared/Content/Characters/Moloch/moloch.xml +++ b/Barotrauma/BarotraumaShared/Content/Characters/Moloch/moloch.xml @@ -19,9 +19,10 @@ - + + diff --git a/Barotrauma/BarotraumaShared/Content/Characters/Watcher/watcher.xml b/Barotrauma/BarotraumaShared/Content/Characters/Watcher/watcher.xml index 7ba3c6a56..d89840630 100644 --- a/Barotrauma/BarotraumaShared/Content/Characters/Watcher/watcher.xml +++ b/Barotrauma/BarotraumaShared/Content/Characters/Watcher/watcher.xml @@ -25,9 +25,10 @@ - + + diff --git a/Barotrauma/BarotraumaShared/Content/Items/Diving/divinggear.xml b/Barotrauma/BarotraumaShared/Content/Items/Diving/divinggear.xml index a35919b7e..cbd95c95d 100644 --- a/Barotrauma/BarotraumaShared/Content/Items/Diving/divinggear.xml +++ b/Barotrauma/BarotraumaShared/Content/Items/Diving/divinggear.xml @@ -63,8 +63,7 @@ @@ -73,7 +72,7 @@ - + @@ -142,7 +141,6 @@ - diff --git a/Barotrauma/BarotraumaShared/Content/Items/Jobgear/engigear.xml b/Barotrauma/BarotraumaShared/Content/Items/Jobgear/engigear.xml index a4281f7e1..6856a3bdf 100644 --- a/Barotrauma/BarotraumaShared/Content/Items/Jobgear/engigear.xml +++ b/Barotrauma/BarotraumaShared/Content/Items/Jobgear/engigear.xml @@ -1,8 +1,7 @@  @@ -19,7 +18,10 @@ - + + + + @@ -48,6 +50,9 @@ + + + diff --git a/Barotrauma/BarotraumaShared/Content/Items/Jobgear/securitygear.xml b/Barotrauma/BarotraumaShared/Content/Items/Jobgear/securitygear.xml index 804017f10..438f7cc0c 100644 --- a/Barotrauma/BarotraumaShared/Content/Items/Jobgear/securitygear.xml +++ b/Barotrauma/BarotraumaShared/Content/Items/Jobgear/securitygear.xml @@ -10,17 +10,18 @@ - + + + + - @@ -34,6 +35,8 @@ + + diff --git a/Barotrauma/BarotraumaShared/Content/Items/Weapons/railgun.xml b/Barotrauma/BarotraumaShared/Content/Items/Weapons/railgun.xml index 4480fe655..969b6213c 100644 --- a/Barotrauma/BarotraumaShared/Content/Items/Weapons/railgun.xml +++ b/Barotrauma/BarotraumaShared/Content/Items/Weapons/railgun.xml @@ -72,8 +72,7 @@ @@ -103,8 +102,7 @@ diff --git a/Barotrauma/BarotraumaShared/Source/Characters/Attack.cs b/Barotrauma/BarotraumaShared/Source/Characters/Attack.cs index 64081f55e..3ea9aa97e 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/Attack.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/Attack.cs @@ -11,24 +11,32 @@ namespace Barotrauma Damage, Bloodloss, Pressure, Suffocation, Drowning, Burn, Husk, Disconnected } - public enum DamageType { None, Blunt, Slash, Burn } + [Flags] + public enum DamageType + { + None = 0, + Blunt = 1, + Slash = 2, + Burn = 4, + Any = Blunt | Slash | Burn + } struct AttackResult { public readonly float Damage; public readonly float Bleeding; - - public readonly bool HitArmor; - public AttackResult(float damage, float bleeding, bool hitArmor=false) + public readonly List AppliedDamageModifiers; + + public AttackResult(float damage, float bleeding, List appliedDamageModifiers = null) { this.Damage = damage; this.Bleeding = bleeding; - this.HitArmor = hitArmor; + this.AppliedDamageModifiers = appliedDamageModifiers; } } - + partial class Attack { public readonly float Range; diff --git a/Barotrauma/BarotraumaShared/Source/Characters/DamageModifier.cs b/Barotrauma/BarotraumaShared/Source/Characters/DamageModifier.cs new file mode 100644 index 000000000..e97d57971 --- /dev/null +++ b/Barotrauma/BarotraumaShared/Source/Characters/DamageModifier.cs @@ -0,0 +1,66 @@ +using Microsoft.Xna.Framework; +using System.Xml.Linq; + +namespace Barotrauma +{ + class DamageModifier + { + [Serialize(DamageType.None, false)] + public DamageType DamageType + { + get; + private set; + } + + [Serialize(1.0f, false)] + public float DamageMultiplier + { + get; + private set; + } + + [Serialize(1.0f, false)] + public float BleedingMultiplier + { + get; + private set; + } + + [Serialize("0.0,360", false)] + public Vector2 ArmorSector + { + get; + private set; + } + + [Serialize(true, false)] + public bool IsArmor + { + get; + private set; + } + + [Serialize(true, false)] + public bool DeflectProjectiles + { + get; + private set; + } + + +#if CLIENT + [Serialize(DamageSoundType.None, false)] + public DamageSoundType DamageSoundType + { + get; + private set; + } +#endif + + public DamageModifier(XElement element) + { + SerializableProperty.DeserializeProperties(this, element); + ArmorSector = new Vector2(MathHelper.ToRadians(ArmorSector.X), MathHelper.ToRadians(ArmorSector.Y)); + } + } +} diff --git a/Barotrauma/BarotraumaShared/Source/Characters/Limb.cs b/Barotrauma/BarotraumaShared/Source/Characters/Limb.cs index 48c33837d..cc3ce8e8d 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/Limb.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/Limb.cs @@ -72,10 +72,7 @@ namespace Barotrauma private bool isSevered; private float severedFadeOutTimer; - - private readonly Vector2 armorSector; - private readonly float armorValue; - + public Vector2? MouthPos; //a timer for delaying when a hitsound/attacksound can be played again @@ -91,6 +88,8 @@ namespace Barotrauma private Vector2 animTargetPos; private float scale; + + private List damageModifiers; public float AttackTimer; @@ -179,7 +178,7 @@ namespace Barotrauma public float Burnt { get { return burnt; } - set { burnt = MathHelper.Clamp(value,0.0f,100.0f); } + protected set { burnt = MathHelper.Clamp(value, 0.0f, 100.0f); } } public List WearingItems @@ -255,15 +254,7 @@ namespace Barotrauma GameMain.World.AddJoint(pullJoint); steerForce = element.GetAttributeFloat("steerforce", 0.0f); - - //maxHealth = Math.Max(ToolBox.GetAttributeFloat(element, "health", 100.0f),1.0f); - - armorSector = element.GetAttributeVector2("armorsector", Vector2.Zero); - armorSector.X = MathHelper.ToRadians(armorSector.X); - armorSector.Y = MathHelper.ToRadians(armorSector.Y); - - armorValue = Math.Max(element.GetAttributeFloat("armor", 0.0f), 0.0f); - + if (element.Attribute("mouthpos") != null) { MouthPos = ConvertUnits.ToSimUnits(element.GetAttributeVector2("mouthpos", Vector2.Zero)); @@ -272,6 +263,8 @@ namespace Barotrauma body.BodyType = BodyType.Dynamic; body.FarseerBody.AngularDamping = LimbAngularDamping; + damageModifiers = new List(); + foreach (XElement subElement in element.Elements()) { switch (subElement.Name.ToString().ToLowerInvariant()) @@ -322,6 +315,9 @@ namespace Barotrauma case "attack": attack = new Attack(subElement); break; + case "damagemodifier": + damageModifiers.Add(new DamageModifier(subElement)); + break; } } @@ -344,46 +340,51 @@ namespace Barotrauma public AttackResult AddDamage(Vector2 position, DamageType damageType, float amount, float bleedingAmount, bool playSound) { - bool hitArmor = false; - float totalArmorValue = 0.0f; + List appliedDamageModifiers = new List(); - if (armorValue > 0.0f && SectorHit(armorSector, position)) + foreach (DamageModifier damageModifier in damageModifiers) { - hitArmor = true; - totalArmorValue += armorValue; + if (damageModifier.DamageType.HasFlag(damageType) && SectorHit(damageModifier.ArmorSector, position)) + { + appliedDamageModifiers.Add(damageModifier); + } } - + foreach (WearableSprite wearable in wearingItems) { - if (wearable.WearableComponent.ArmorValue > 0.0f && - SectorHit(wearable.WearableComponent.ArmorSectorLimits, position)) + foreach (DamageModifier damageModifier in wearable.WearableComponent.DamageModifiers) { - hitArmor = true; - totalArmorValue += wearable.WearableComponent.ArmorValue; + if (damageModifier.DamageType.HasFlag(damageType) && SectorHit(damageModifier.ArmorSector, position)) + { + appliedDamageModifiers.Add(damageModifier); + } } - } + } - if (hitArmor) + foreach (DamageModifier damageModifier in appliedDamageModifiers) { - totalArmorValue = Math.Max(totalArmorValue, 0.0f); - - amount = Math.Max(0.0f, amount - totalArmorValue); - bleedingAmount = Math.Max(0.0f, bleedingAmount - totalArmorValue); + amount *= damageModifier.DamageMultiplier; + bleedingAmount *= damageModifier.BleedingMultiplier; } #if CLIENT if (playSound) { DamageSoundType damageSoundType = (damageType == DamageType.Blunt) ? DamageSoundType.LimbBlunt : DamageSoundType.LimbSlash; - if (hitArmor) - { - damageSoundType = DamageSoundType.LimbArmor; - } + foreach (DamageModifier damageModifier in appliedDamageModifiers) + { + if (damageModifier.DamageSoundType != DamageSoundType.None) + { + damageSoundType = damageModifier.DamageSoundType; + break; + } + } + SoundPlayer.PlayDamageSound(damageSoundType, amount, position); } - float bloodParticleAmount = hitArmor || bleedingAmount <= 0.0f ? 0 : (int)Math.Min(amount / 5, 10); + float bloodParticleAmount = bleedingAmount <= 0.0f ? 0 : (int)Math.Min(amount / 5, 10); float bloodParticleSize = MathHelper.Clamp(amount / 50.0f, 0.1f, 1.0f); for (int i = 0; i < bloodParticleAmount; i++) @@ -402,9 +403,14 @@ namespace Barotrauma #endif + if (damageType == DamageType.Burn) + { + Burnt += amount * 10.0f; + } + damage += Math.Max(amount,bleedingAmount) / character.MaxHealth * 100.0f; - return new AttackResult(amount, bleedingAmount, hitArmor); + return new AttackResult(amount, bleedingAmount, appliedDamageModifiers); } public bool SectorHit(Vector2 armorSector, Vector2 simPosition) diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Projectile.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Projectile.cs index 56373779e..569a34735 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Projectile.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Projectile.cs @@ -5,6 +5,7 @@ using FarseerPhysics.Dynamics.Joints; using Microsoft.Xna.Framework; using System; using System.Collections.Generic; +using System.Linq; using System.Xml.Linq; namespace Barotrauma.Items.Components @@ -255,7 +256,8 @@ namespace Barotrauma.Items.Components target.Body.ApplyLinearImpulse(item.body.LinearVelocity * item.body.Mass); - if (attackResult.HitArmor) + if (attackResult.AppliedDamageModifiers != null && + attackResult.AppliedDamageModifiers.Any(dm => dm.DeflectProjectiles)) { item.body.LinearVelocity *= 0.1f; } diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Wearable.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Wearable.cs index 941753833..9bfd51af6 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Wearable.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Wearable.cs @@ -1,5 +1,6 @@ using Microsoft.Xna.Framework; using System; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Xml.Linq; @@ -27,79 +28,62 @@ namespace Barotrauma.Items.Components class Wearable : Pickable { - WearableSprite[] wearableSprites; - LimbType[] limbType; - Limb[] limb; + private WearableSprite[] wearableSprites; + private LimbType[] limbType; + private Limb[] limb; - private float armorValue; + private List damageModifiers; - private Vector2 armorSector; - - [Serialize(0.0f, false)] - public float ArmorValue + public List DamageModifiers { - get { return armorValue; } - set { armorValue = MathHelper.Clamp(value, 0.0f, 100.0f); } + get { return damageModifiers; } } - - [Serialize("0.0,360.0", false)] - public Vector2 ArmorSector - { - get { return armorSector; } - set - { - armorSector.X = MathHelper.ToRadians(value.X); - armorSector.Y = MathHelper.ToRadians(value.Y); - } - } - - public Vector2 ArmorSectorLimits - { - get { return armorSector; } - } - + public Wearable (Item item, XElement element) : base(item, element) { this.item = item; - var sprites = element.Elements().Where(x => x.Name.ToString() == "sprite").ToList(); - int spriteCount = sprites.Count; + damageModifiers = new List(); + + int spriteCount = element.Elements().Count(x => x.Name.ToString() == "sprite"); wearableSprites = new WearableSprite[spriteCount]; limbType = new LimbType[spriteCount]; limb = new Limb[spriteCount]; int i = 0; - foreach (XElement subElement in sprites) + foreach (XElement subElement in element.Elements()) { - //Rectangle sourceRect = new Rectangle( - // ToolBox.GetAttributeInt(subElement, "sourcex", 1), - // ToolBox.GetAttributeInt(subElement, "sourcey", 1), - // ToolBox.GetAttributeInt(subElement, "sourcewidth", 1), - // ToolBox.GetAttributeInt(subElement, "sourceheight", 1)); - - if (subElement.Attribute("texture") == null) + switch (subElement.Name.ToString().ToLower()) { - DebugConsole.ThrowError("Item \"" + item.Name + "\" doesn't have a texture specified!"); - return; + case "sprite": + if (subElement.Attribute("texture") == null) + { + DebugConsole.ThrowError("Item \"" + item.Name + "\" doesn't have a texture specified!"); + return; + } + + string spritePath = subElement.Attribute("texture").Value; + spritePath = Path.GetDirectoryName(item.Prefab.ConfigFile) + "/" + spritePath; + + var sprite = new Sprite(subElement, "", spritePath); + wearableSprites[i] = new WearableSprite(this, sprite, + subElement.GetAttributeBool("hidelimb", false), + subElement.GetAttributeBool("inheritlimbdepth", true), + (LimbType)Enum.Parse(typeof(LimbType), subElement.GetAttributeString("depthlimb", "None"), true)); + + limbType[i] = (LimbType)Enum.Parse(typeof(LimbType), + subElement.GetAttributeString("limb", "Head"), true); + + i++; + break; + case "damagemodifier": + damageModifiers.Add(new DamageModifier(subElement)); + break; } - - string spritePath = subElement.Attribute("texture").Value; - spritePath = Path.GetDirectoryName( item.Prefab.ConfigFile)+"/"+spritePath; - - var sprite = new Sprite(subElement, "", spritePath); - wearableSprites[i] = new WearableSprite(this, sprite, - subElement.GetAttributeBool("hidelimb", false), - subElement.GetAttributeBool("inheritlimbdepth", true), - (LimbType)Enum.Parse(typeof(LimbType), subElement.GetAttributeString("depthlimb", "None"), true)); - - limbType[i] = (LimbType)Enum.Parse(typeof(LimbType), - subElement.GetAttributeString("limb", "Head"), true); - - i++; } } - + public override void Equip(Character character) { picker = character; @@ -107,15 +91,7 @@ namespace Barotrauma.Items.Components { Limb equipLimb = character.AnimController.GetLimb(limbType[i]); if (equipLimb == null) continue; - - //something is already on the limb -> unequip it - //if (equipLimb.WearingItem != null && equipLimb.WearingItem != this) - //{ - // equipLimb.WearingItem.Unequip(character); - //} - - //sprite[i].Depth = equipLimb.sprite.Depth - 0.001f; - + item.body.Enabled = false; IsActive = true; @@ -143,20 +119,9 @@ namespace Barotrauma.Items.Components Limb equipLimb = character.AnimController.GetLimb(limbType[i]); if (equipLimb == null) continue; - //foreach (WearableSprite wearable in equipLimb.WearingItems) - //{ - // if (wearable != wearableSprites[i]) continue; + equipLimb.WearingItems.RemoveAll(w => w != null && w == wearableSprites[i]); - // equipLimb.WearingItems.Remove(wearableSprites[i]); - //} - - equipLimb.WearingItems.RemoveAll(w=> w!=null && w==wearableSprites[i]); - - //if (equipLimb.WearingItem != this) continue; - limb[i] = null; - //equipLimb.WearingItem = null; - //equipLimb.WearingItemSprite = null; } IsActive = false; diff --git a/Barotrauma/BarotraumaShared/Source/Items/Item.cs b/Barotrauma/BarotraumaShared/Source/Items/Item.cs index 92c3ddad5..e4282a895 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Item.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Item.cs @@ -761,7 +761,7 @@ namespace Barotrauma float damageAmount = attack.GetStructureDamage(deltaTime); Condition -= damageAmount; - return new AttackResult(damageAmount, 0.0f, false); + return new AttackResult(damageAmount, 0.0f, null); } private bool IsInWater() diff --git a/Barotrauma/BarotraumaShared/Source/Map/FireSource.cs b/Barotrauma/BarotraumaShared/Source/Map/FireSource.cs index 8f44317e0..bfa7eb231 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/FireSource.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/FireSource.cs @@ -205,8 +205,6 @@ namespace Barotrauma float dmg = (float)Math.Sqrt(size.X) * deltaTime / c.AnimController.Limbs.Length; foreach (Limb limb in c.AnimController.Limbs) { - if (limb.WearingItems.Find(w => w != null && w.WearableComponent.Item.FireProof) != null) continue; - limb.Burnt += dmg * 10.0f; c.AddDamage(limb.SimPosition, DamageType.Burn, dmg, 0, 0, false); } }