v0.11.0.9

This commit is contained in:
Joonas Rikkonen
2020-12-09 16:34:16 +02:00
parent bbf06f0984
commit f433a7ba10
325 changed files with 13947 additions and 3652 deletions
@@ -14,27 +14,31 @@ using Microsoft.Xna.Framework.Graphics;
namespace Barotrauma
{
partial class WallSection
partial class WallSection : ISpatialEntity
{
public Rectangle rect;
public float damage;
public Gap gap;
private bool ignoreByAI;
public WallSection(Rectangle rect)
public Structure Wall { get; }
public Vector2 Position => Wall.SectionPosition(Wall.Sections.IndexOf(this));
public Vector2 WorldPosition => Wall.SectionPosition(Wall.Sections.IndexOf(this), world: true);
public Vector2 SimPosition => ConvertUnits.ToSimUnits(Position);
public Submarine Submarine => Wall.Submarine;
public Rectangle WorldRect => Submarine == null ? rect :
new Rectangle((int)(rect.X + Submarine.Position.X), (int)(rect.Y + Submarine.Position.Y), rect.Width, rect.Height);
public bool IgnoreByAI => ignoreByAI;
public WallSection(Rectangle rect, Structure wall, float damage = 0.0f)
{
System.Diagnostics.Debug.Assert(rect.Width > 0 && rect.Height > 0);
this.rect = rect;
damage = 0.0f;
this.damage = damage;
Wall = wall;
}
public WallSection(Rectangle rect, float damage)
{
System.Diagnostics.Debug.Assert(rect.Width > 0 && rect.Height > 0);
this.rect = rect;
this.damage = 0.0f;
}
public void SetIgnoreByAI(bool ignore) => ignoreByAI = ignore;
}
partial class Structure : MapEntity, IDamageable, IServerSerializable, ISerializableEntity
@@ -108,7 +112,16 @@ namespace Barotrauma
get => maxHealth ?? Prefab.Health;
set => maxHealth = value;
}
private float crushDepth;
[Serialize(Level.DefaultRealWorldCrushDepth, true)]
public float CrushDepth
{
get => crushDepth;
set => crushDepth = Math.Max(value, Level.DefaultRealWorldCrushDepth);
}
public float Health => MaxHealth;
public override bool DrawBelowWater
@@ -131,10 +144,16 @@ namespace Barotrauma
{
get
{
return Prefab.Body && !IsPlatform;
return Prefab.Body && !IsPlatform;// && HasDamage;
}
}
public bool HasDamage
{
get;
private set;
}
public StructurePrefab Prefab => prefab as StructurePrefab;
public HashSet<string> Tags
@@ -343,8 +362,8 @@ namespace Barotrauma
#endif
}
public Structure(Rectangle rectangle, StructurePrefab sp, Submarine submarine)
: base(sp, submarine)
public Structure(Rectangle rectangle, StructurePrefab sp, Submarine submarine, ushort id = Entity.NullEntityID, XElement element = null)
: base(sp, submarine, id)
{
System.Diagnostics.Debug.Assert(rectangle.Width > 0 && rectangle.Height > 0);
if (rectangle.Width == 0 || rectangle.Height == 0) { return; }
@@ -382,7 +401,6 @@ namespace Barotrauma
StairDirection = Prefab.StairDirection;
NoAITarget = Prefab.NoAITarget;
SerializableProperties = SerializableProperty.GetProperties(this);
InitProjSpecific();
@@ -399,7 +417,7 @@ namespace Barotrauma
else
{
Sections = new WallSection[1];
Sections[0] = new WallSection(rect);
Sections[0] = new WallSection(rect, this);
if (StairDirection != Direction.None)
{
@@ -408,6 +426,8 @@ namespace Barotrauma
}
}
SerializableProperties = element != null ? SerializableProperty.DeserializeProperties(this, element) : SerializableProperty.GetProperties(this);
// Only add ai targets automatically to submarine/outpost walls
if (aiTarget == null && HasBody && Tags.Contains("wall") && submarine != null && !submarine.Info.IsWreck && !NoAITarget)
{
@@ -552,7 +572,7 @@ namespace Barotrauma
//sectionRect.Height -= (int)Math.Max((rect.Y - rect.Height) - (sectionRect.Y - sectionRect.Height), 0.0f);
int xIndex = FlippedX && IsHorizontal ? (xsections - 1 - x) : x;
int yIndex = FlippedY && !IsHorizontal ? (ysections - 1 - y) : y;
Sections[xIndex + yIndex] = new WallSection(sectionRect);
Sections[xIndex + yIndex] = new WallSection(sectionRect, this);
}
else
{
@@ -560,7 +580,7 @@ namespace Barotrauma
sectionRect.Width -= (int)Math.Max(sectionRect.Right - rect.Right, 0.0f);
sectionRect.Height -= (int)Math.Max((rect.Y - rect.Height) - (sectionRect.Y - sectionRect.Height), 0.0f);
Sections[x + y] = new WallSection(sectionRect);
Sections[x + y] = new WallSection(sectionRect, this);
}
}
}
@@ -783,33 +803,36 @@ namespace Barotrauma
public void AddDamage(int sectionIndex, float damage, Character attacker = null)
{
if (!Prefab.Body || Prefab.Platform || Indestructible) return;
if (!Prefab.Body || Prefab.Platform || Indestructible ) { return; }
if (sectionIndex < 0 || sectionIndex > Sections.Length - 1) return;
if (sectionIndex < 0 || sectionIndex > Sections.Length - 1) { return; }
var section = Sections[sectionIndex];
#if CLIENT
float dmg = Math.Min(MaxHealth - section.damage, damage);
float particleAmount = MathHelper.Lerp(0, 25, MathUtils.InverseLerp(0, 100, dmg * Rand.Range(0.75f, 1.25f)));
// Special case for very low but frequent dmg like plasma cutter: 10% chance for emitting a particle
if (particleAmount < 1 && Rand.Value() < 0.10f)
if (damage > 0)
{
particleAmount = 1;
}
for (int i = 1; i <= particleAmount; i++)
{
Vector2 particlePos = new Vector2(
Rand.Range(section.rect.X, section.rect.Right),
Rand.Range(section.rect.Y - section.rect.Height, section.rect.Y));
if (Submarine != null)
float dmg = Math.Min(MaxHealth - section.damage, damage);
float particleAmount = MathHelper.Lerp(0, 25, MathUtils.InverseLerp(0, 100, dmg * Rand.Range(0.75f, 1.25f)));
// Special case for very low but frequent dmg like plasma cutter: 10% chance for emitting a particle
if (particleAmount < 1 && Rand.Value() < 0.10f)
{
particlePos += Submarine.DrawPosition;
particleAmount = 1;
}
for (int i = 1; i <= particleAmount; i++)
{
Vector2 particlePos = new Vector2(
Rand.Range(section.rect.X, section.rect.Right),
Rand.Range(section.rect.Y - section.rect.Height, section.rect.Y));
if (Submarine != null)
{
particlePos += Submarine.DrawPosition;
}
var particle = GameMain.ParticleManager.CreateParticle("shrapnel", particlePos, Rand.Vector(Rand.Range(1.0f, 50.0f)));
if (particle == null) break;
}
var particle = GameMain.ParticleManager.CreateParticle("shrapnel", particlePos, Rand.Vector(Rand.Range(1.0f, 50.0f)));
if (particle == null) break;
}
#endif
if (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer)
@@ -895,15 +918,12 @@ namespace Barotrauma
}
return sectionPos;
}
}
}
public AttackResult AddDamage(Character attacker, Vector2 worldPosition, Attack attack, float deltaTime, bool playSound = false)
{
if (Submarine != null && Submarine.GodMode) return new AttackResult(0.0f, null);
if (!Prefab.Body || Prefab.Platform || Indestructible) return new AttackResult(0.0f, null);
if (Submarine != null && Submarine.GodMode) { return new AttackResult(0.0f, null); }
if (!Prefab.Body || Prefab.Platform || Indestructible) { return new AttackResult(0.0f, null); }
Vector2 transformedPos = worldPosition;
if (Submarine != null) transformedPos -= Submarine.Position;
@@ -921,26 +941,24 @@ namespace Barotrauma
GameMain.ParticleManager.CreateParticle("dustcloud", SectionPosition(i), 0.0f, 0.0f);
#endif
}
}
}
#if CLIENT
if (playSound)
if (playSound && damageAmount > 0)
{
SoundPlayer.PlayDamageSound(attack.StructureSoundType, damageAmount, worldPosition, tags: Tags);
}
#endif
return new AttackResult(damageAmount, null);
}
private void SetDamage(int sectionIndex, float damage, Character attacker = null, bool createNetworkEvent = true)
public void SetDamage(int sectionIndex, float damage, Character attacker = null, bool createNetworkEvent = true)
{
if (Submarine != null && Submarine.GodMode || Indestructible) { return; }
if (!Prefab.Body) { return; }
if (!MathUtils.IsValid(damage)) { return; }
damage = MathHelper.Clamp(damage, 0.0f, MaxHealth - Prefab.MinHealth);
#if SERVER
if (GameMain.Server != null && createNetworkEvent && damage != Sections[sectionIndex].damage)
{
@@ -1054,13 +1072,14 @@ namespace Barotrauma
}
float gapOpen = (damage / MaxHealth - LeakThreshold) * (1.0f / (1.0f - LeakThreshold));
Sections[sectionIndex].gap.Open = gapOpen;
Sections[sectionIndex].gap.Open = gapOpen;
}
float damageDiff = damage - Sections[sectionIndex].damage;
bool hadHole = SectionBodyDisabled(sectionIndex);
Sections[sectionIndex].damage = MathHelper.Clamp(damage, 0.0f, MaxHealth);
HasDamage = Sections.Any(s => s.damage > 0.0f);
if (attacker != null && damageDiff != 0.0f)
{
OnHealthChangedProjSpecific(attacker, damageDiff);
@@ -1077,7 +1096,7 @@ namespace Barotrauma
bool hasHole = SectionBodyDisabled(sectionIndex);
if (hadHole == hasHole) return;
if (hadHole == hasHole) { return; }
UpdateSections();
}
@@ -1259,7 +1278,7 @@ namespace Barotrauma
}
}
public static Structure Load(XElement element, Submarine submarine)
public static Structure Load(XElement element, Submarine submarine, IdRemap idRemap)
{
string name = element.Attribute("name").Value;
string identifier = element.GetAttributeString("identifier", "");
@@ -1272,14 +1291,10 @@ namespace Barotrauma
}
Rectangle rect = element.GetAttributeRect("rect", Rectangle.Empty);
Structure s = new Structure(rect, prefab, submarine)
Structure s = new Structure(rect, prefab, submarine, idRemap.GetOffsetId(element), element)
{
Submarine = submarine,
ID = (ushort)int.Parse(element.Attribute("ID").Value)
};
s.OriginalID = s.ID;
SerializableProperty.DeserializeProperties(s, element);
if (submarine?.Info.GameVersion != null)
{