Merge remote-tracking branch 'origin/master' into antagonists

This commit is contained in:
Alex Noir
2017-12-03 13:10:04 +03:00
29 changed files with 359 additions and 248 deletions
@@ -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<DamageModifier> AppliedDamageModifiers;
public AttackResult(float damage, float bleeding, List<DamageModifier> appliedDamageModifiers = null)
{
this.Damage = damage;
this.Bleeding = bleeding;
this.HitArmor = hitArmor;
this.AppliedDamageModifiers = appliedDamageModifiers;
}
}
partial class Attack
{
public readonly float Range;
@@ -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));
}
}
}
@@ -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<DamageModifier> 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<WearableSprite> 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<DamageModifier>();
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<DamageModifier> appliedDamageModifiers = new List<DamageModifier>();
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)
@@ -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;
}
@@ -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<DamageModifier> damageModifiers;
private Vector2 armorSector;
[Serialize(0.0f, false)]
public float ArmorValue
public List<DamageModifier> 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<DamageModifier>();
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;
@@ -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()
@@ -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);
}
}
@@ -1873,11 +1873,6 @@ namespace Barotrauma.Networking
private void FileTransferChanged(FileSender.FileTransferOut transfer)
{
if (connectedClients.Any(c=> c.Connection == null))
{
int sdfgsdfg = 1;
}
Client recipient = connectedClients.Find(c => c.Connection == transfer.Connection);
#if CLIENT
UpdateFileTransferIndicator(recipient);
@@ -3,10 +3,7 @@
static class NetConfig
{
public const int DefaultPort = 14242;
//UpdateEntity networkevents aren't sent to clients if they're further than this from the entity
public const float UpdateEntityDistance = 2500.0f;
public const int MaxPlayers = 16;
public static string MasterServerUrl = GameMain.Config.MasterServerUrl;
@@ -20,14 +17,6 @@
//send a position update to clients (in sim units)
public const float ItemPosUpdateDistance = 2.0f;
public const float LargeCharacterUpdateInterval = 5.0f;
public const float DeleteDisconnectedTime = 10.0f;
public const float IdSendInterval = 0.2f;
public const float RerequestInterval = 0.2f;
public const int ReliableMessageBufferSize = 500;
public const int ResendAttempts = 10;
public const float DeleteDisconnectedTime = 10.0f;
}
}
@@ -57,7 +57,7 @@ namespace Barotrauma
#if DEBUG && CLIENT
if (GameMain.GameSession != null && GameMain.GameSession.Level != null && GameMain.GameSession.Submarine != null &&
!DebugConsole.IsOpen)
!DebugConsole.IsOpen && GUIComponent.KeyboardDispatcher.Subscriber == null)
{
var closestSub = Submarine.FindClosest(cam.WorldViewCenter);
if (closestSub == null) closestSub = GameMain.GameSession.Submarine;
@@ -130,7 +130,15 @@ namespace Barotrauma
DebugConsole.ThrowError("Failed to set the value of the property \"" + Name + "\" of \"" + obj + "\" to " + value + " (not a valid " + propertyInfo.PropertyType + ")", e);
return false;
}
propertyInfo.SetValue(obj, enumVal);
try
{
propertyInfo.SetValue(obj, enumVal);
}
catch (Exception e)
{
DebugConsole.ThrowError("Failed to set the value of the property \"" + Name + "\" of \"" + obj.ToString() + "\" to " + value.ToString(), e);
return false;
}
}
else
{
@@ -141,45 +149,55 @@ namespace Barotrauma
}
}
switch (typeName)
try
{
case "bool":
propertyInfo.SetValue(obj, value.ToLowerInvariant() == "true", null);
break;
case "int":
int intVal;
if (int.TryParse(value, out intVal))
{
propertyInfo.SetValue(obj, intVal, null);
}
break;
case "float":
float floatVal;
if (float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out floatVal))
{
propertyInfo.SetValue(obj, floatVal, null);
}
break;
case "string":
propertyInfo.SetValue(obj, value, null);
break;
case "vector2":
propertyInfo.SetValue(obj, XMLExtensions.ParseVector2(value));
break;
case "vector3":
propertyInfo.SetValue(obj, XMLExtensions.ParseVector3(value));
break;
case "vector4":
propertyInfo.SetValue(obj, XMLExtensions.ParseVector4(value));
break;
case "color":
propertyInfo.SetValue(obj, XMLExtensions.ParseColor(value));
break;
case "rectangle":
propertyInfo.SetValue(obj, XMLExtensions.ParseRect(value, true));
break;
switch (typeName)
{
case "bool":
propertyInfo.SetValue(obj, value.ToLowerInvariant() == "true", null);
break;
case "int":
int intVal;
if (int.TryParse(value, out intVal))
{
propertyInfo.SetValue(obj, intVal, null);
}
break;
case "float":
float floatVal;
if (float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out floatVal))
{
propertyInfo.SetValue(obj, floatVal, null);
}
break;
case "string":
propertyInfo.SetValue(obj, value, null);
break;
case "vector2":
propertyInfo.SetValue(obj, XMLExtensions.ParseVector2(value));
break;
case "vector3":
propertyInfo.SetValue(obj, XMLExtensions.ParseVector3(value));
break;
case "vector4":
propertyInfo.SetValue(obj, XMLExtensions.ParseVector4(value));
break;
case "color":
propertyInfo.SetValue(obj, XMLExtensions.ParseColor(value));
break;
case "rectangle":
propertyInfo.SetValue(obj, XMLExtensions.ParseRect(value, true));
break;
}
}
catch (Exception e)
{
DebugConsole.ThrowError("Failed to set the value of the property \"" + Name + "\" of \"" + obj.ToString() + "\" to " + value.ToString(), e);
return false;
}
return true;
}
@@ -215,42 +233,52 @@ namespace Barotrauma
}
}
if (value.GetType() == typeof(string))
try
{
switch (typeName)
if (value.GetType() == typeof(string))
{
case "string":
propertyInfo.SetValue(obj, value, null);
return true;
case "vector2":
propertyInfo.SetValue(obj, XMLExtensions.ParseVector2((string)value));
return true;
case "vector3":
propertyInfo.SetValue(obj, XMLExtensions.ParseVector3((string)value));
return true;
case "vector4":
propertyInfo.SetValue(obj, XMLExtensions.ParseVector4((string)value));
return true;
case "color":
propertyInfo.SetValue(obj, XMLExtensions.ParseColor((string)value));
return true;
case "rectangle":
propertyInfo.SetValue(obj, XMLExtensions.ParseColor((string)value));
return true;
default:
DebugConsole.ThrowError("Failed to set the value of the property \"" + Name + "\" of \"" + obj.ToString() + "\" to " + value.ToString());
DebugConsole.ThrowError("(Cannot convert a string to a " + propertyDescriptor.PropertyType.ToString() + ")");
return false;
switch (typeName)
{
case "string":
propertyInfo.SetValue(obj, value, null);
return true;
case "vector2":
propertyInfo.SetValue(obj, XMLExtensions.ParseVector2((string)value));
return true;
case "vector3":
propertyInfo.SetValue(obj, XMLExtensions.ParseVector3((string)value));
return true;
case "vector4":
propertyInfo.SetValue(obj, XMLExtensions.ParseVector4((string)value));
return true;
case "color":
propertyInfo.SetValue(obj, XMLExtensions.ParseColor((string)value));
return true;
case "rectangle":
propertyInfo.SetValue(obj, XMLExtensions.ParseRect((string)value, false));
return true;
default:
DebugConsole.ThrowError("Failed to set the value of the property \"" + Name + "\" of \"" + obj.ToString() + "\" to " + value.ToString());
DebugConsole.ThrowError("(Cannot convert a string to a " + propertyDescriptor.PropertyType.ToString() + ")");
return false;
}
}
else if (propertyDescriptor.PropertyType != value.GetType())
{
DebugConsole.ThrowError("Failed to set the value of the property \"" + Name + "\" of \"" + obj.ToString() + "\" to " + value.ToString());
DebugConsole.ThrowError("(Non-matching type, should be " + propertyDescriptor.PropertyType + " instead of " + value.GetType() + ")");
return false;
}
propertyInfo.SetValue(obj, value, null);
}
else if (propertyDescriptor.PropertyType != value.GetType())
catch (Exception e)
{
DebugConsole.ThrowError("Failed to set the value of the property \"" + Name + "\" of \"" + obj.ToString() + "\" to " + value.ToString());
DebugConsole.ThrowError("(Non-matching type, should be " + propertyDescriptor.PropertyType + " instead of " + value.GetType() + ")");
DebugConsole.ThrowError("Failed to set the value of the property \"" + Name + "\" of \"" + obj.ToString() + "\" to " + value.ToString(), e);
return false;
}
propertyInfo.SetValue(obj, value, null);
return true;
}
catch