2f107db...5202af9
This commit is contained in:
@@ -119,33 +119,35 @@ namespace Barotrauma
|
||||
if (force == 0.0f && attack.Stun == 0.0f && attack.GetTotalDamage(false) == 0.0f) return;
|
||||
|
||||
DamageCharacters(worldPosition, attack, force, damageSource);
|
||||
|
||||
if (flames && GameMain.Client == null)
|
||||
|
||||
if (GameMain.NetworkMember == null || !GameMain.NetworkMember.IsClient)
|
||||
{
|
||||
foreach (Item item in Item.ItemList)
|
||||
if (flames)
|
||||
{
|
||||
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;
|
||||
while (container != null)
|
||||
foreach (Item item in Item.ItemList)
|
||||
{
|
||||
if (container.FireProof) return;
|
||||
container = container.Container;
|
||||
}
|
||||
if (item.CurrentHull != hull || item.FireProof || item.Condition <= 0.0f) continue;
|
||||
|
||||
if (Vector2.Distance(item.WorldPosition, worldPosition) > attack.Range * 0.1f) 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;
|
||||
while (container != null)
|
||||
{
|
||||
if (container.FireProof) return;
|
||||
container = container.Container;
|
||||
}
|
||||
|
||||
item.ApplyStatusEffects(ActionType.OnFire, 1.0f);
|
||||
if (Vector2.Distance(item.WorldPosition, worldPosition) > attack.Range * 0.1f) continue;
|
||||
|
||||
if (item.Condition <= 0.0f && GameMain.Server != null)
|
||||
{
|
||||
GameMain.Server.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 });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
partial void ExplodeProjSpecific(Vector2 worldPosition, Hull hull);
|
||||
|
||||
@@ -74,7 +74,9 @@ namespace Barotrauma
|
||||
hull = Hull.FindHull(worldPosition, spawningHull);
|
||||
if (hull == null || worldPosition.Y < hull.WorldSurface) return;
|
||||
|
||||
#if CLIENT
|
||||
if (!isNetworkMessage && GameMain.Client != null) return;
|
||||
#endif
|
||||
|
||||
hull.AddFireSource(this);
|
||||
|
||||
@@ -174,7 +176,9 @@ namespace Barotrauma
|
||||
|
||||
UpdateProjSpecific(growModifier);
|
||||
|
||||
#if CLIENT
|
||||
if (GameMain.Client != null) return;
|
||||
#endif
|
||||
|
||||
if (size.X < 1.0f) Remove();
|
||||
}
|
||||
@@ -230,7 +234,10 @@ namespace Barotrauma
|
||||
|
||||
private void DamageItems(float deltaTime)
|
||||
{
|
||||
if (size.X <= 0.0f || GameMain.Client != null) return;
|
||||
if (size.X <= 0.0f) return;
|
||||
#if CLIENT
|
||||
if (GameMain.Client != null) return;
|
||||
#endif
|
||||
|
||||
foreach (Item item in Item.ItemList)
|
||||
{
|
||||
@@ -250,9 +257,9 @@ namespace Barotrauma
|
||||
if (item.Position.Y < position.Y - size.Y || item.Position.Y > hull.Rect.Y) continue;
|
||||
|
||||
item.ApplyStatusEffects(ActionType.OnFire, deltaTime);
|
||||
if (item.Condition <= 0.0f && GameMain.Server != null)
|
||||
if (item.Condition <= 0.0f && GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
|
||||
{
|
||||
GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.ApplyStatusEffect, ActionType.OnFire });
|
||||
GameMain.NetworkMember.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.ApplyStatusEffect, ActionType.OnFire });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -285,7 +292,9 @@ namespace Barotrauma
|
||||
//evaporate some of the water
|
||||
hull.WaterVolume -= extinguishAmount;
|
||||
|
||||
#if CLIENT
|
||||
if (GameMain.Client != null) return;
|
||||
#endif
|
||||
|
||||
if (size.X < 1.0f) Remove();
|
||||
}
|
||||
@@ -312,7 +321,9 @@ namespace Barotrauma
|
||||
|
||||
hull.WaterVolume -= extinguishAmount;
|
||||
|
||||
#if CLIENT
|
||||
if (GameMain.Client != null) return;
|
||||
#endif
|
||||
|
||||
if (size.X < 1.0f) Remove();
|
||||
}
|
||||
|
||||
@@ -49,16 +49,13 @@ namespace Barotrauma
|
||||
private bool update;
|
||||
|
||||
public bool Visible = true;
|
||||
|
||||
float[] waveY; //displacement from the surface of the water
|
||||
float[] waveVel; //velocity of the point
|
||||
|
||||
float[] leftDelta;
|
||||
float[] rightDelta;
|
||||
private float[] waveY; //displacement from the surface of the water
|
||||
private float[] waveVel; //velocity of the point
|
||||
|
||||
private float lastSentVolume, lastSentOxygen;
|
||||
private float sendUpdateTimer;
|
||||
|
||||
private float[] leftDelta;
|
||||
private float[] rightDelta;
|
||||
|
||||
public List<Gap> ConnectedGaps;
|
||||
|
||||
public override string Name
|
||||
@@ -407,7 +404,10 @@ namespace Barotrauma
|
||||
{
|
||||
FireSources.Add(fireSource);
|
||||
|
||||
if (GameMain.Server != null && !IdFreed) GameMain.Server.CreateEntityEvent(this);
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer && !IdFreed)
|
||||
{
|
||||
GameMain.NetworkMember.CreateEntityEvent(this);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
@@ -421,24 +421,6 @@ namespace Barotrauma
|
||||
aiTarget.SightRange = Submarine == null ? 0.0f : Math.Max(Submarine.Velocity.Length() * 500.0f, 500.0f);
|
||||
aiTarget.SoundRange -= deltaTime * 1000.0f;
|
||||
|
||||
//update client hulls if the amount of water has changed by >10%
|
||||
//or if oxygen percentage has changed by 5%
|
||||
if (Math.Abs(lastSentVolume - waterVolume) > Volume * 0.1f ||
|
||||
Math.Abs(lastSentOxygen - OxygenPercentage) > 5f)
|
||||
{
|
||||
if (GameMain.Server != null && !IdFreed)
|
||||
{
|
||||
sendUpdateTimer -= deltaTime;
|
||||
if (sendUpdateTimer < 0.0f)
|
||||
{
|
||||
GameMain.Server.CreateEntityEvent(this);
|
||||
lastSentVolume = waterVolume;
|
||||
lastSentOxygen = OxygenPercentage;
|
||||
sendUpdateTimer = NetworkUpdateInterval;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!update)
|
||||
{
|
||||
lethalPressure = 0.0f;
|
||||
@@ -597,9 +579,9 @@ namespace Barotrauma
|
||||
{
|
||||
FireSources.Remove(fire);
|
||||
|
||||
if (GameMain.Server != null && !Removed && !IdFreed)
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer && !Removed && !IdFreed)
|
||||
{
|
||||
GameMain.Server.CreateEntityEvent(this);
|
||||
GameMain.NetworkMember.CreateEntityEvent(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -632,15 +614,18 @@ namespace Barotrauma
|
||||
/// Approximate distance from this hull to the target hull, moving through open gaps without passing through walls.
|
||||
/// Uses a greedy algo and may not use the most optimal path. Returns float.MaxValue if no path is found.
|
||||
/// </summary>
|
||||
public float GetApproximateDistance(Hull target, float maxDistance)
|
||||
public float GetApproximateDistance(Vector2 startPos, Vector2 endPos, Hull targetHull, float maxDistance)
|
||||
{
|
||||
return GetApproximateHullDistance(new HashSet<Hull>(), target, 0.0f, maxDistance);
|
||||
return GetApproximateHullDistance(startPos, endPos, new HashSet<Hull>(), targetHull, 0.0f, maxDistance);
|
||||
}
|
||||
|
||||
private float GetApproximateHullDistance(HashSet<Hull> connectedHulls, Hull target, float distance, float maxDistance)
|
||||
private float GetApproximateHullDistance(Vector2 startPos, Vector2 endPos, HashSet<Hull> connectedHulls, Hull target, float distance, float maxDistance)
|
||||
{
|
||||
if (distance >= maxDistance) return float.MaxValue;
|
||||
if (this == target) return distance;
|
||||
if (this == target)
|
||||
{
|
||||
return distance + Vector2.Distance(startPos, endPos);
|
||||
}
|
||||
|
||||
connectedHulls.Add(this);
|
||||
|
||||
@@ -663,7 +648,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (g.linkedTo[i] is Hull hull && !connectedHulls.Contains(hull))
|
||||
{
|
||||
float dist = hull.GetApproximateHullDistance(connectedHulls, target, distance + Vector2.Distance(g.Position, this.Position), maxDistance);
|
||||
float dist = hull.GetApproximateHullDistance(g.Position, endPos, connectedHulls, target, distance + Vector2.Distance(startPos, g.Position), maxDistance);
|
||||
if (dist < float.MaxValue) return dist;
|
||||
}
|
||||
}
|
||||
@@ -847,78 +832,6 @@ namespace Barotrauma
|
||||
return TextManager.Get("Sub" + roomPos.ToString());
|
||||
}
|
||||
|
||||
public void ServerWrite(NetBuffer message, Client c, object[] extraData = null)
|
||||
{
|
||||
message.WriteRangedSingle(MathHelper.Clamp(waterVolume / Volume, 0.0f, 1.5f), 0.0f, 1.5f, 8);
|
||||
message.WriteRangedSingle(MathHelper.Clamp(OxygenPercentage, 0.0f, 100.0f), 0.0f, 100.0f, 8);
|
||||
|
||||
message.Write(FireSources.Count > 0);
|
||||
if (FireSources.Count > 0)
|
||||
{
|
||||
message.WriteRangedInteger(0, 16, Math.Min(FireSources.Count, 16));
|
||||
for (int i = 0; i < Math.Min(FireSources.Count, 16); i++)
|
||||
{
|
||||
var fireSource = FireSources[i];
|
||||
Vector2 normalizedPos = new Vector2(
|
||||
(fireSource.Position.X - rect.X) / rect.Width,
|
||||
(fireSource.Position.Y - (rect.Y - rect.Height)) / rect.Height);
|
||||
|
||||
message.WriteRangedSingle(MathHelper.Clamp(normalizedPos.X, 0.0f, 1.0f), 0.0f, 1.0f, 8);
|
||||
message.WriteRangedSingle(MathHelper.Clamp(normalizedPos.Y, 0.0f, 1.0f), 0.0f, 1.0f, 8);
|
||||
message.WriteRangedSingle(MathHelper.Clamp(fireSource.Size.X / rect.Width, 0.0f, 1.0f), 0, 1.0f, 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ClientRead(ServerNetObject type, NetBuffer message, float sendingTime)
|
||||
{
|
||||
WaterVolume = message.ReadRangedSingle(0.0f, 1.5f, 8) * Volume;
|
||||
OxygenPercentage = message.ReadRangedSingle(0.0f, 100.0f, 8);
|
||||
|
||||
bool hasFireSources = message.ReadBoolean();
|
||||
int fireSourceCount = 0;
|
||||
|
||||
if (hasFireSources)
|
||||
{
|
||||
fireSourceCount = message.ReadRangedInteger(0, 16);
|
||||
for (int i = 0; i < fireSourceCount; i++)
|
||||
{
|
||||
Vector2 pos = Vector2.Zero;
|
||||
float size = 0.0f;
|
||||
pos.X = MathHelper.Clamp(message.ReadRangedSingle(0.0f, 1.0f, 8), 0.05f, 0.95f);
|
||||
pos.Y = MathHelper.Clamp(message.ReadRangedSingle(0.0f, 1.0f, 8), 0.05f, 0.95f);
|
||||
size = message.ReadRangedSingle(0.0f, 1.0f, 8);
|
||||
|
||||
pos = new Vector2(
|
||||
rect.X + rect.Width * pos.X,
|
||||
rect.Y - rect.Height + (rect.Height * pos.Y));
|
||||
size = size * rect.Width;
|
||||
|
||||
var newFire = i < FireSources.Count ?
|
||||
FireSources[i] :
|
||||
new FireSource(Submarine == null ? pos : pos + Submarine.Position, null, true);
|
||||
newFire.Position = pos;
|
||||
newFire.Size = new Vector2(size, newFire.Size.Y);
|
||||
|
||||
//ignore if the fire wasn't added to this room (invalid position)?
|
||||
if (!FireSources.Contains(newFire))
|
||||
{
|
||||
newFire.Remove();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = FireSources.Count - 1; i >= fireSourceCount; i--)
|
||||
{
|
||||
FireSources[i].Remove();
|
||||
if (i < FireSources.Count)
|
||||
{
|
||||
FireSources.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Hull Load(XElement element, Submarine submarine)
|
||||
{
|
||||
Rectangle rect = Rectangle.Empty;
|
||||
|
||||
@@ -1416,15 +1416,15 @@ namespace Barotrauma
|
||||
{
|
||||
wall.Update(deltaTime);
|
||||
}
|
||||
|
||||
if (GameMain.Server != null)
|
||||
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
|
||||
{
|
||||
networkUpdateTimer += deltaTime;
|
||||
if (networkUpdateTimer > NetworkUpdateInterval)
|
||||
{
|
||||
if (extraWalls.Any(w => w.Body.BodyType != BodyType.Static))
|
||||
{
|
||||
GameMain.Server.CreateEntityEvent(this);
|
||||
GameMain.NetworkMember.CreateEntityEvent(this);
|
||||
}
|
||||
networkUpdateTimer = 0.0f;
|
||||
}
|
||||
|
||||
@@ -346,7 +346,9 @@ namespace Barotrauma
|
||||
public Sprite BackgroundSprite { get; private set; }
|
||||
public Sprite BackgroundTopSprite { get; private set; }
|
||||
public Sprite WallSprite { get; private set; }
|
||||
public Sprite WallSpriteSpecular { get; private set; }
|
||||
public Sprite WallEdgeSprite { get; private set; }
|
||||
public Sprite WallEdgeSpriteSpecular { get; private set; }
|
||||
public Sprite WaterParticles { get; private set; }
|
||||
|
||||
public static List<Biome> GetBiomes()
|
||||
@@ -419,9 +421,15 @@ namespace Barotrauma
|
||||
case "wall":
|
||||
WallSprite = new Sprite(subElement);
|
||||
break;
|
||||
case "wallspecular":
|
||||
WallSpriteSpecular = new Sprite(subElement);
|
||||
break;
|
||||
case "walledge":
|
||||
WallEdgeSprite = new Sprite(subElement);
|
||||
break;
|
||||
case "walledgespecular":
|
||||
WallEdgeSpriteSpecular = new Sprite(subElement);
|
||||
break;
|
||||
case "waterparticles":
|
||||
WaterParticles = new Sprite(subElement);
|
||||
break;
|
||||
|
||||
@@ -14,6 +14,9 @@ namespace Barotrauma
|
||||
public readonly LevelObjectPrefab Prefab;
|
||||
public Vector3 Position;
|
||||
|
||||
public float NetworkUpdateTimer;
|
||||
public const float NetworkUpdateInterval = 0.2f;
|
||||
|
||||
public float Scale;
|
||||
|
||||
public float Rotation;
|
||||
|
||||
@@ -336,12 +336,14 @@ namespace Barotrauma
|
||||
{
|
||||
foreach (LevelObject obj in objects)
|
||||
{
|
||||
if (GameMain.Server != null)
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
|
||||
{
|
||||
if (obj.NeedsNetworkSyncing)
|
||||
obj.NetworkUpdateTimer -= deltaTime;
|
||||
if (obj.NeedsNetworkSyncing && obj.NetworkUpdateTimer <= 0.0f)
|
||||
{
|
||||
GameMain.Server.CreateEntityEvent(this, new object[] { obj });
|
||||
GameMain.NetworkMember.CreateEntityEvent(this, new object[] { obj });
|
||||
obj.NeedsNetworkSyncing = false;
|
||||
obj.NetworkUpdateTimer = LevelObject.NetworkUpdateInterval;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -279,6 +279,9 @@ namespace Barotrauma
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
forceFluctuationTimer = Rand.Range(0.0f, ForceFluctuationInterval);
|
||||
randomTriggerTimer = Rand.Range(0.0f, randomTriggerInterval);
|
||||
}
|
||||
|
||||
private void UpdateCollisionCategories()
|
||||
@@ -420,7 +423,12 @@ namespace Barotrauma
|
||||
|
||||
triggerers.RemoveWhere(t => t.Removed);
|
||||
|
||||
if (!UseNetworkSyncing || GameMain.Client == null)
|
||||
bool isNotClient = true;
|
||||
#if CLIENT
|
||||
isNotClient = GameMain.Client == null;
|
||||
#endif
|
||||
|
||||
if (!UseNetworkSyncing || isNotClient)
|
||||
{
|
||||
if (ForceFluctuationStrength > 0.0f)
|
||||
{
|
||||
|
||||
@@ -636,14 +636,13 @@ namespace Barotrauma.RuinGeneration
|
||||
foreach (RuinEntity ruinEntity in ruinEntities)
|
||||
{
|
||||
CreateConnections(ruinEntity);
|
||||
ruinEntity.Entity.ParentRuin = this;
|
||||
}
|
||||
|
||||
foreach (RuinEntity ruinEntity in ruinEntities)
|
||||
{
|
||||
if (ruinEntity.Entity is Item item)
|
||||
{
|
||||
foreach (ItemComponent ic in item.components)
|
||||
foreach (ItemComponent ic in item.Components)
|
||||
{
|
||||
// Prevent wiring & interacting
|
||||
if (ic is ConnectionPanel connectionPanel)
|
||||
@@ -737,6 +736,11 @@ namespace Barotrauma.RuinGeneration
|
||||
}
|
||||
}
|
||||
|
||||
foreach (RuinEntity ruinEntity in ruinEntities)
|
||||
{
|
||||
ruinEntity.Entity.ParentRuin = this;
|
||||
}
|
||||
|
||||
bool hullXIntersect(Rectangle rect1, Rectangle rect2)
|
||||
{
|
||||
return
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Barotrauma
|
||||
partial class Location
|
||||
{
|
||||
public List<LocationConnection> Connections;
|
||||
|
||||
|
||||
private string baseName;
|
||||
private int nameFormatIndex;
|
||||
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
class LocationConnection
|
||||
{
|
||||
private Location[] locations;
|
||||
private Level level;
|
||||
|
||||
public Biome Biome;
|
||||
|
||||
public float Difficulty;
|
||||
@@ -17,24 +13,17 @@ namespace Barotrauma
|
||||
|
||||
public bool Passed;
|
||||
|
||||
public Level Level
|
||||
{
|
||||
get { return level; }
|
||||
set { level = value; }
|
||||
}
|
||||
public Level Level { get; set; }
|
||||
|
||||
public Vector2 CenterPos
|
||||
{
|
||||
get
|
||||
{
|
||||
return (locations[0].MapPosition + locations[1].MapPosition) / 2.0f;
|
||||
return (Locations[0].MapPosition + Locations[1].MapPosition) / 2.0f;
|
||||
}
|
||||
}
|
||||
|
||||
public Location[] Locations
|
||||
{
|
||||
get { return locations; }
|
||||
}
|
||||
public Location[] Locations { get; private set; }
|
||||
|
||||
public float Length
|
||||
{
|
||||
@@ -44,20 +33,20 @@ namespace Barotrauma
|
||||
|
||||
public LocationConnection(Location location1, Location location2)
|
||||
{
|
||||
locations = new Location[] { location1, location2 };
|
||||
Locations = new Location[] { location1, location2 };
|
||||
|
||||
Length = Vector2.Distance(location1.MapPosition, location2.MapPosition);
|
||||
}
|
||||
|
||||
public Location OtherLocation(Location location)
|
||||
{
|
||||
if (locations[0] == location)
|
||||
if (Locations[0] == location)
|
||||
{
|
||||
return locations[1];
|
||||
return Locations[1];
|
||||
}
|
||||
else if (locations[1] == location)
|
||||
else if (Locations[1] == location)
|
||||
{
|
||||
return locations[0];
|
||||
return Locations[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -26,10 +26,9 @@ namespace Barotrauma
|
||||
|
||||
public Dictionary<int, float> CommonnessPerZone = new Dictionary<int, float>();
|
||||
|
||||
public readonly string Identifier;
|
||||
public readonly string Name;
|
||||
|
||||
public readonly string DisplayName;
|
||||
|
||||
public readonly List<LocationTypeChange> CanChangeTo = new List<LocationTypeChange>();
|
||||
|
||||
public List<string> NameFormats
|
||||
@@ -55,14 +54,9 @@ namespace Barotrauma
|
||||
|
||||
private LocationType(XElement element)
|
||||
{
|
||||
Name = element.Name.ToString();
|
||||
DisplayName = element.GetAttributeString("name", "Name");
|
||||
|
||||
nameFormats = new List<string>();
|
||||
foreach (XAttribute nameFormat in element.Element("nameformats").Attributes())
|
||||
{
|
||||
nameFormats.Add(nameFormat.Value);
|
||||
}
|
||||
Identifier = element.Name.ToString();
|
||||
Name = TextManager.Get("LocationName." + Identifier);
|
||||
nameFormats = TextManager.GetAll("LocationNameFormat." + Identifier);
|
||||
|
||||
string nameFile = element.GetAttributeString("namefile", "Content/Map/locationNames.txt");
|
||||
try
|
||||
@@ -71,7 +65,7 @@ namespace Barotrauma
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to read name file for location type \""+Name+"\"!", e);
|
||||
DebugConsole.ThrowError("Failed to read name file for location type \""+Identifier+"\"!", e);
|
||||
names = new List<string>() { "Name file not found" };
|
||||
}
|
||||
|
||||
@@ -83,14 +77,14 @@ namespace Barotrauma
|
||||
!int.TryParse(splitCommonnessPerZone[0].Trim(), out int zoneIndex) ||
|
||||
!float.TryParse(splitCommonnessPerZone[1].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out float zoneCommonness))
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to read commonness values for location type \"" + Name + "\" - commonness should be given in the format \"zone0index: zone0commonness, zone1index: zone1commonness\"");
|
||||
DebugConsole.ThrowError("Failed to read commonness values for location type \"" + Identifier + "\" - commonness should be given in the format \"zone0index: zone0commonness, zone1index: zone1commonness\"");
|
||||
break;
|
||||
}
|
||||
CommonnessPerZone[zoneIndex] = zoneCommonness;
|
||||
}
|
||||
|
||||
hireableJobs = new List<Tuple<JobPrefab, float>>();
|
||||
foreach (XElement subElement in element.Elements())
|
||||
string nameFile = element.GetAttributeString("namefile", "Content/Map/locationNames.txt");
|
||||
try
|
||||
{
|
||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||
{
|
||||
@@ -99,7 +93,7 @@ namespace Barotrauma
|
||||
JobPrefab jobPrefab = null;
|
||||
if (jobIdentifier == "")
|
||||
{
|
||||
DebugConsole.ThrowError("Error in location type \""+ Name + "\" - hireable jobs should be configured using identifiers instead of names.");
|
||||
DebugConsole.ThrowError("Error in location type \""+ Identifier + "\" - hireable jobs should be configured using identifiers instead of names.");
|
||||
jobIdentifier = subElement.GetAttributeString("name", "");
|
||||
jobPrefab = JobPrefab.List.Find(jp => jp.Name.ToLowerInvariant() == jobIdentifier.ToLowerInvariant());
|
||||
}
|
||||
@@ -109,7 +103,7 @@ namespace Barotrauma
|
||||
}
|
||||
if (jobPrefab == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Error in in location type " + Name + " - could not find a job with the identifier \"" + jobIdentifier + "\".");
|
||||
DebugConsole.ThrowError("Error in in location type " + Identifier + " - could not find a job with the identifier \"" + jobIdentifier + "\".");
|
||||
continue;
|
||||
}
|
||||
float jobCommonness = subElement.GetAttributeFloat("commonness", 1.0f);
|
||||
@@ -122,7 +116,7 @@ namespace Barotrauma
|
||||
SpriteColor = subElement.GetAttributeColor("color", Color.White);
|
||||
break;
|
||||
case "changeto":
|
||||
CanChangeTo.Add(new LocationTypeChange(subElement));
|
||||
CanChangeTo.Add(new LocationTypeChange(Identifier, subElement));
|
||||
break;
|
||||
case "portrait":
|
||||
var portrait = new Sprite(subElement);
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace Barotrauma
|
||||
{
|
||||
class LocationTypeChange
|
||||
{
|
||||
public readonly string ChangeTo;
|
||||
public readonly string ChangeToType;
|
||||
public readonly float Probability;
|
||||
public readonly int RequiredDuration;
|
||||
|
||||
@@ -18,22 +18,16 @@ namespace Barotrauma
|
||||
//the change can only happen if there's at least one of the given types of locations next to this one
|
||||
public readonly List<string> RequiredAdjacentLocations;
|
||||
|
||||
public LocationTypeChange(XElement element)
|
||||
public LocationTypeChange(string currentType, XElement element)
|
||||
{
|
||||
ChangeTo = element.GetAttributeString("type", "");
|
||||
ChangeToType = element.GetAttributeString("type", "");
|
||||
Probability = element.GetAttributeFloat("probability", 1.0f);
|
||||
RequiredDuration = element.GetAttributeInt("requiredduration", 0);
|
||||
|
||||
DisallowedAdjacentLocations = element.GetAttributeStringArray("disallowedadjacentlocations", new string[0]).ToList();
|
||||
RequiredAdjacentLocations = element.GetAttributeStringArray("requiredadjacentlocations", new string[0]).ToList();
|
||||
|
||||
foreach (XElement subElement in element.Elements())
|
||||
{
|
||||
if (subElement.Name.ToString().ToLowerInvariant() == "message")
|
||||
{
|
||||
Messages.Add(subElement.GetAttributeString("text", ""));
|
||||
}
|
||||
}
|
||||
Messages = TextManager.GetAll("LocationChange." + currentType + ".ChangeTo." + ChangeToType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace Barotrauma
|
||||
Vector2 center = new Vector2(size, size) / 2;
|
||||
foreach (Location location in Locations)
|
||||
{
|
||||
if (location.Type.Name != "City") continue;
|
||||
if (location.Type.Identifier != "City") continue;
|
||||
float dist = Vector2.DistanceSquared(center, location.MapPosition);
|
||||
if (dist > largestDist)
|
||||
{
|
||||
@@ -430,13 +430,6 @@ namespace Barotrauma
|
||||
}
|
||||
CurrentLocation.SelectedMissionIndex = missionIndex;
|
||||
|
||||
//the destination must be the same as the destination of the mission
|
||||
if (CurrentLocation.SelectedMission != null &&
|
||||
CurrentLocation.SelectedMission.Locations[1] != SelectedLocation)
|
||||
{
|
||||
SelectLocation(CurrentLocation.SelectedMission.Locations[1]);
|
||||
}
|
||||
|
||||
SelectedLocation = location;
|
||||
SelectedConnection = connections.Find(c => c.Locations.Contains(CurrentLocation) && c.Locations.Contains(SelectedLocation));
|
||||
OnLocationSelected?.Invoke(SelectedLocation, SelectedConnection);
|
||||
@@ -494,7 +487,7 @@ namespace Barotrauma
|
||||
bool disallowedFound = false;
|
||||
foreach (string disallowedLocationName in typeChange.DisallowedAdjacentLocations)
|
||||
{
|
||||
if (location.Connections.Any(c => c.OtherLocation(location).Type.Name.ToLowerInvariant() == disallowedLocationName.ToLowerInvariant()))
|
||||
if (location.Connections.Any(c => c.OtherLocation(location).Type.Identifier.ToLowerInvariant() == disallowedLocationName.ToLowerInvariant()))
|
||||
{
|
||||
disallowedFound = true;
|
||||
break;
|
||||
@@ -506,7 +499,7 @@ namespace Barotrauma
|
||||
bool requiredFound = false;
|
||||
foreach (string requiredLocationName in typeChange.RequiredAdjacentLocations)
|
||||
{
|
||||
if (location.Connections.Any(c => c.OtherLocation(location).Type.Name.ToLowerInvariant() == requiredLocationName.ToLowerInvariant()))
|
||||
if (location.Connections.Any(c => c.OtherLocation(location).Type.Identifier.ToLowerInvariant() == requiredLocationName.ToLowerInvariant()))
|
||||
{
|
||||
requiredFound = true;
|
||||
break;
|
||||
@@ -530,7 +523,7 @@ namespace Barotrauma
|
||||
if (selectedTypeChange != null)
|
||||
{
|
||||
string prevName = location.Name;
|
||||
location.ChangeType(LocationType.List.Find(lt => lt.Name.ToLowerInvariant() == selectedTypeChange.ChangeTo.ToLowerInvariant()));
|
||||
location.ChangeType(LocationType.List.Find(lt => lt.Identifier.ToLowerInvariant() == selectedTypeChange.ChangeToType.ToLowerInvariant()));
|
||||
ChangeLocationType(location, prevName, selectedTypeChange);
|
||||
location.TypeChangeTimer = -1;
|
||||
break;
|
||||
@@ -584,7 +577,7 @@ namespace Barotrauma
|
||||
string prevLocationName = location.Name;
|
||||
LocationType prevLocationType = location.Type;
|
||||
location.Discovered = true;
|
||||
location.ChangeType(LocationType.List.Find(lt => lt.Name.ToLowerInvariant() == locationType.ToLowerInvariant()));
|
||||
location.ChangeType(LocationType.List.Find(lt => lt.Identifier.ToLowerInvariant() == locationType.ToLowerInvariant()));
|
||||
location.TypeChangeTimer = typeChangeTimer;
|
||||
location.MissionsCompleted = missionsCompleted;
|
||||
if (showNotifications && prevLocationType != location.Type)
|
||||
@@ -592,7 +585,7 @@ namespace Barotrauma
|
||||
ChangeLocationType(
|
||||
location,
|
||||
prevLocationName,
|
||||
prevLocationType.CanChangeTo.Find(c => c.ChangeTo.ToLowerInvariant() == location.Type.Name.ToLowerInvariant()));
|
||||
prevLocationType.CanChangeTo.Find(c => c.ChangeToType.ToLowerInvariant() == location.Type.Identifier.ToLowerInvariant()));
|
||||
}
|
||||
break;
|
||||
case "connection":
|
||||
@@ -617,7 +610,7 @@ namespace Barotrauma
|
||||
if (!location.Discovered) continue;
|
||||
|
||||
var locationElement = new XElement("location", new XAttribute("i", i));
|
||||
locationElement.Add(new XAttribute("type", location.Type.Name));
|
||||
locationElement.Add(new XAttribute("type", location.Type.Identifier));
|
||||
if (location.TypeChangeTimer > 0)
|
||||
{
|
||||
locationElement.Add(new XAttribute("changetimer", location.TypeChangeTimer));
|
||||
|
||||
@@ -287,12 +287,7 @@ namespace Barotrauma
|
||||
|
||||
mapEntityList.Insert(i, this);
|
||||
}
|
||||
|
||||
public virtual bool IsVisible(Rectangle worldView)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Remove the entity from the entity list without removing links to other entities
|
||||
/// </summary>
|
||||
|
||||
@@ -68,30 +68,34 @@ namespace Barotrauma
|
||||
|
||||
private string CalculateHash(FileStream stream)
|
||||
{
|
||||
MD5 md5 = MD5.Create();
|
||||
byte[] byteHash = md5.ComputeHash(stream);
|
||||
// step 2, convert byte array to hex string
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < byteHash.Length; i++)
|
||||
using (MD5 md5 = MD5.Create())
|
||||
{
|
||||
sb.Append(byteHash[i].ToString("X2"));
|
||||
}
|
||||
byte[] byteHash = md5.ComputeHash(stream);
|
||||
// step 2, convert byte array to hex string
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < byteHash.Length; i++)
|
||||
{
|
||||
sb.Append(byteHash[i].ToString("X2"));
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
private string CalculateHash(byte[] bytes)
|
||||
{
|
||||
MD5 md5 = MD5.Create();
|
||||
byte[] byteHash = md5.ComputeHash(bytes);
|
||||
// step 2, convert byte array to hex string
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < byteHash.Length; i++)
|
||||
using (MD5 md5 = MD5.Create())
|
||||
{
|
||||
sb.Append(byteHash[i].ToString("X2"));
|
||||
}
|
||||
byte[] byteHash = md5.ComputeHash(bytes);
|
||||
// step 2, convert byte array to hex string
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < byteHash.Length; i++)
|
||||
{
|
||||
sb.Append(byteHash[i].ToString("X2"));
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetShortHash(string fullHash)
|
||||
|
||||
@@ -47,7 +47,6 @@ namespace Barotrauma
|
||||
|
||||
const float LeakThreshold = 0.1f;
|
||||
|
||||
private StructurePrefab prefab;
|
||||
private SpriteEffects SpriteEffects = SpriteEffects.None;
|
||||
|
||||
//dimensions of the wall sections' physics bodies (only used for debug rendering)
|
||||
@@ -69,7 +68,7 @@ namespace Barotrauma
|
||||
|
||||
public bool IsPlatform
|
||||
{
|
||||
get { return prefab.Platform; }
|
||||
get { return Prefab.Platform; }
|
||||
}
|
||||
|
||||
public Direction StairDirection
|
||||
@@ -85,14 +84,14 @@ namespace Barotrauma
|
||||
|
||||
public bool HasBody
|
||||
{
|
||||
get { return prefab.Body; }
|
||||
get { return Prefab.Body; }
|
||||
}
|
||||
|
||||
public List<Body> Bodies { get; private set; }
|
||||
|
||||
public bool CastShadow
|
||||
{
|
||||
get { return prefab.CastShadow; }
|
||||
get { return Prefab.CastShadow; }
|
||||
}
|
||||
|
||||
public bool IsHorizontal { get; private set; }
|
||||
@@ -104,14 +103,14 @@ namespace Barotrauma
|
||||
|
||||
public float Health
|
||||
{
|
||||
get { return prefab.Health; }
|
||||
get { return Prefab.Health; }
|
||||
}
|
||||
|
||||
public override bool DrawBelowWater
|
||||
{
|
||||
get
|
||||
{
|
||||
return base.DrawBelowWater || prefab.BackgroundSprite != null;
|
||||
return base.DrawBelowWater || Prefab.BackgroundSprite != null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,18 +126,15 @@ namespace Barotrauma
|
||||
{
|
||||
get
|
||||
{
|
||||
return prefab.Body;
|
||||
return Prefab.Body;
|
||||
}
|
||||
}
|
||||
|
||||
public StructurePrefab Prefab
|
||||
{
|
||||
get { return prefab; }
|
||||
}
|
||||
public StructurePrefab Prefab => prefab as StructurePrefab;
|
||||
|
||||
public HashSet<string> Tags
|
||||
{
|
||||
get { return prefab.Tags; }
|
||||
get { return prefab; }
|
||||
}
|
||||
|
||||
protected Color spriteColor;
|
||||
@@ -159,7 +155,7 @@ namespace Barotrauma
|
||||
{
|
||||
Rectangle oldRect = Rect;
|
||||
base.Rect = value;
|
||||
if (prefab.Body) CreateSections();
|
||||
if (Prefab.Body) CreateSections();
|
||||
else
|
||||
{
|
||||
foreach (WallSection sec in Sections)
|
||||
@@ -179,11 +175,11 @@ namespace Barotrauma
|
||||
|
||||
public float BodyWidth
|
||||
{
|
||||
get { return prefab.BodyWidth > 0.0f ? prefab.BodyWidth : rect.Width; }
|
||||
get { return Prefab.BodyWidth > 0.0f ? Prefab.BodyWidth : rect.Width; }
|
||||
}
|
||||
public float BodyHeight
|
||||
{
|
||||
get { return prefab.BodyHeight > 0.0f ? prefab.BodyHeight : rect.Height; }
|
||||
get { return Prefab.BodyHeight > 0.0f ? Prefab.BodyHeight : rect.Height; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -193,7 +189,7 @@ namespace Barotrauma
|
||||
{
|
||||
get
|
||||
{
|
||||
float rotation = MathHelper.ToRadians(prefab.BodyRotation);
|
||||
float rotation = MathHelper.ToRadians(Prefab.BodyRotation);
|
||||
if (FlippedX) rotation = -MathHelper.Pi - rotation;
|
||||
if (FlippedY) rotation = -rotation;
|
||||
return rotation;
|
||||
@@ -206,7 +202,7 @@ namespace Barotrauma
|
||||
{
|
||||
get
|
||||
{
|
||||
Vector2 bodyOffset = prefab.BodyOffset;
|
||||
Vector2 bodyOffset = Prefab.BodyOffset;
|
||||
if (FlippedX) { bodyOffset.X = -bodyOffset.X; }
|
||||
if (FlippedY) { bodyOffset.Y = -bodyOffset.Y; }
|
||||
return bodyOffset;
|
||||
@@ -255,7 +251,6 @@ namespace Barotrauma
|
||||
System.Diagnostics.Debug.Assert(rectangle.Width > 0 && rectangle.Height > 0);
|
||||
|
||||
rect = rectangle;
|
||||
prefab = sp;
|
||||
#if CLIENT
|
||||
TextureScale = sp.TextureScale;
|
||||
#endif
|
||||
@@ -280,11 +275,11 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
StairDirection = prefab.StairDirection;
|
||||
StairDirection = Prefab.StairDirection;
|
||||
|
||||
SerializableProperties = SerializableProperty.GetProperties(this);
|
||||
|
||||
if (prefab.Body)
|
||||
if (Prefab.Body)
|
||||
{
|
||||
Bodies = new List<Body>();
|
||||
WallList.Add(this);
|
||||
@@ -313,11 +308,11 @@ namespace Barotrauma
|
||||
|
||||
public override MapEntity Clone()
|
||||
{
|
||||
var clone = new Structure(rect, prefab, Submarine);
|
||||
var clone = new Structure(rect, Prefab, Submarine);
|
||||
foreach (KeyValuePair<string, SerializableProperty> property in SerializableProperties)
|
||||
{
|
||||
if (!property.Value.Attributes.OfType<Editable>().Any()) continue;
|
||||
clone.SerializableProperties[property.Key].TrySetValue(property.Value.GetValue());
|
||||
clone.SerializableProperties[property.Key].TrySetValue(clone, property.Value.GetValue(this));
|
||||
}
|
||||
if (FlippedX) clone.FlipX(false);
|
||||
if (FlippedY) clone.FlipY(false);
|
||||
@@ -571,19 +566,9 @@ namespace Barotrauma
|
||||
#endif
|
||||
}
|
||||
|
||||
public override bool IsVisible(Rectangle worldView)
|
||||
{
|
||||
Rectangle worldRect = WorldRect;
|
||||
|
||||
if (worldRect.X > worldView.Right || worldRect.Right < worldView.X) return false;
|
||||
if (worldRect.Y < worldView.Y - worldView.Height || worldRect.Y - worldRect.Height > worldView.Y) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool OnWallCollision(Fixture f1, Fixture f2, Contact contact)
|
||||
{
|
||||
if (prefab.Platform)
|
||||
if (Prefab.Platform)
|
||||
{
|
||||
if (f2.Body.UserData is Limb limb)
|
||||
{
|
||||
@@ -597,7 +582,7 @@ namespace Barotrauma
|
||||
if (character.DisableImpactDamageTimer > 0.0f || ((Limb)f2.Body.UserData).Mass < 100.0f) return true;
|
||||
}
|
||||
|
||||
if (!prefab.Platform && prefab.StairDirection == Direction.None)
|
||||
if (!Prefab.Platform && Prefab.StairDirection == Direction.None)
|
||||
{
|
||||
Vector2 pos = ConvertUnits.ToDisplayUnits(f2.Body.Position);
|
||||
|
||||
@@ -631,7 +616,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (sectionIndex < 0 || sectionIndex >= Sections.Length) return false;
|
||||
|
||||
return (Sections[sectionIndex].damage >= prefab.Health);
|
||||
return (Sections[sectionIndex].damage >= Prefab.Health);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -641,7 +626,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (sectionIndex < 0 || sectionIndex >= Sections.Length) return false;
|
||||
|
||||
return (Sections[sectionIndex].damage >= prefab.Health * LeakThreshold);
|
||||
return (Sections[sectionIndex].damage >= Prefab.Health * LeakThreshold);
|
||||
}
|
||||
|
||||
public int SectionLength(int sectionIndex)
|
||||
@@ -653,7 +638,7 @@ 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;
|
||||
|
||||
@@ -676,7 +661,14 @@ namespace Barotrauma
|
||||
}
|
||||
#endif
|
||||
|
||||
if (GameMain.Client == null) SetDamage(sectionIndex, section.damage + damage, attacker);
|
||||
#if CLIENT
|
||||
if (GameMain.Client == null)
|
||||
{
|
||||
#endif
|
||||
SetDamage(sectionIndex, section.damage + damage, attacker);
|
||||
#if CLIENT
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public int FindSectionIndex(Vector2 displayPos, bool world = false, bool clamp = false)
|
||||
@@ -721,7 +713,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (sectionIndex < 0 || sectionIndex >= Sections.Length) return Vector2.Zero;
|
||||
|
||||
if (prefab.BodyRotation == 0.0f)
|
||||
if (Prefab.BodyRotation == 0.0f)
|
||||
{
|
||||
Vector2 sectionPos = new Vector2(
|
||||
Sections[sectionIndex].rect.X + Sections[sectionIndex].rect.Width / 2.0f,
|
||||
@@ -754,31 +746,12 @@ namespace Barotrauma
|
||||
|
||||
}
|
||||
|
||||
private void AdjustKarma(IDamageable attacker, float amount)
|
||||
{
|
||||
if (GameMain.Server != null)
|
||||
{
|
||||
if (Submarine == null) return;
|
||||
if (attacker == null) return;
|
||||
if (attacker is Character)
|
||||
{
|
||||
Character attackerCharacter = attacker as Character;
|
||||
Barotrauma.Networking.Client attackerClient = GameMain.Server.ConnectedClients.Find(c => c.Character == attackerCharacter);
|
||||
if (attackerClient != null)
|
||||
{
|
||||
if (attackerCharacter.TeamID == Submarine.TeamID)
|
||||
{
|
||||
attackerClient.Karma -= amount * 0.001f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
partial void AdjustKarma(IDamageable attacker, float amount);
|
||||
|
||||
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 (!Prefab.Body || Prefab.Platform || Indestructible) return new AttackResult(0.0f, null);
|
||||
|
||||
Vector2 transformedPos = worldPosition;
|
||||
if (Submarine != null) transformedPos -= Submarine.Position;
|
||||
@@ -811,16 +784,16 @@ namespace Barotrauma
|
||||
private void SetDamage(int sectionIndex, float damage, Character attacker = null, bool createNetworkEvent = true)
|
||||
{
|
||||
if (Submarine != null && Submarine.GodMode || Indestructible) return;
|
||||
if (!prefab.Body) return;
|
||||
if (!Prefab.Body) return;
|
||||
if (!MathUtils.IsValid(damage)) return;
|
||||
|
||||
damage = MathHelper.Clamp(damage, 0.0f, prefab.Health);
|
||||
|
||||
damage = MathHelper.Clamp(damage, 0.0f, Prefab.Health);
|
||||
|
||||
#if SERVER
|
||||
if (GameMain.Server != null && createNetworkEvent && damage != Sections[sectionIndex].damage)
|
||||
{
|
||||
GameMain.Server.CreateEntityEvent(this);
|
||||
}
|
||||
|
||||
bool noGaps = true;
|
||||
for (int i = 0; i < Sections.Length; i++)
|
||||
{
|
||||
@@ -830,17 +803,20 @@ namespace Barotrauma
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (damage < prefab.Health * LeakThreshold)
|
||||
|
||||
if (damage < Prefab.Health * LeakThreshold)
|
||||
{
|
||||
if (Sections[sectionIndex].gap != null)
|
||||
{
|
||||
#if SERVER
|
||||
//the structure doesn't have any other gap, log the structure being fixed
|
||||
if (noGaps && attacker != null)
|
||||
{
|
||||
GameServer.Log((Sections[sectionIndex].gap.IsRoomToRoom ? "Inner" : "Outer") + " wall repaired by " + attacker.Name, ServerLog.MessageType.ItemInteraction);
|
||||
}
|
||||
|
||||
#endif
|
||||
DebugConsole.Log("Removing gap (ID " + Sections[sectionIndex].gap.ID + ", section: " + sectionIndex + ") from wall " + ID);
|
||||
|
||||
//remove existing gap if damage is below leak threshold
|
||||
@@ -884,7 +860,7 @@ namespace Barotrauma
|
||||
gapRect.Height += 20;
|
||||
|
||||
bool horizontalGap = !IsHorizontal;
|
||||
if (prefab.BodyRotation != 0.0f)
|
||||
if (Prefab.BodyRotation != 0.0f)
|
||||
{
|
||||
//rotation within a 90 deg sector (e.g. 100 -> 10, 190 -> 10, -10 -> 80)
|
||||
float sectorizedRotation = MathUtils.WrapAngleTwoPi(BodyRotation) % MathHelper.PiOver2;
|
||||
@@ -908,31 +884,40 @@ namespace Barotrauma
|
||||
DebugConsole.Log("Created gap (ID " + Sections[sectionIndex].gap.ID + ", section: " + sectionIndex + ") on wall " + ID);
|
||||
//AdjustKarma(attacker, 300);
|
||||
|
||||
#if SERVER
|
||||
//the structure didn't have any other gaps yet, log the breach
|
||||
if (noGaps && attacker != null)
|
||||
{
|
||||
GameServer.Log((Sections[sectionIndex].gap.IsRoomToRoom ? "Inner" : "Outer") + " wall breached by " + attacker.Name, ServerLog.MessageType.ItemInteraction);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
float gapOpen = (damage / prefab.Health - LeakThreshold) * (1.0f / (1.0f - LeakThreshold));
|
||||
float gapOpen = (damage / Prefab.Health - LeakThreshold) * (1.0f / (1.0f - LeakThreshold));
|
||||
Sections[sectionIndex].gap.Open = gapOpen;
|
||||
}
|
||||
|
||||
float damageDiff = damage - Sections[sectionIndex].damage;
|
||||
bool hadHole = SectionBodyDisabled(sectionIndex);
|
||||
Sections[sectionIndex].damage = MathHelper.Clamp(damage, 0.0f, prefab.Health);
|
||||
Sections[sectionIndex].damage = MathHelper.Clamp(damage, 0.0f, Prefab.Health);
|
||||
|
||||
//otherwise it's possible to infinitely gain karma by welding fixed things
|
||||
if (attacker != null && damageDiff != 0.0f)
|
||||
{
|
||||
AdjustKarma(attacker, damageDiff);
|
||||
if (damageDiff < 0.0f && GameMain.Client == null)
|
||||
#if CLIENT
|
||||
if (GameMain.Client == null)
|
||||
{
|
||||
attacker.Info.IncreaseSkillLevel("mechanical",
|
||||
-damageDiff * SkillIncreaseMultiplier / Math.Max(attacker.GetSkillLevel("mechanical"), 1.0f),
|
||||
SectionPosition(sectionIndex, true));
|
||||
#endif
|
||||
if (damageDiff < 0.0f)
|
||||
{
|
||||
attacker.Info.IncreaseSkillLevel("mechanical",
|
||||
-damageDiff * SkillIncreaseMultiplier / Math.Max(attacker.GetSkillLevel("mechanical"), 1.0f),
|
||||
SectionPosition(sectionIndex, true));
|
||||
}
|
||||
#if CLIENT
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool hasHole = SectionBodyDisabled(sectionIndex);
|
||||
@@ -1018,7 +1003,7 @@ namespace Barotrauma
|
||||
}
|
||||
if (FlippedX) diffFromCenter = -diffFromCenter;
|
||||
|
||||
Vector2 bodyOffset = ConvertUnits.ToSimUnits(prefab.BodyOffset);
|
||||
Vector2 bodyOffset = ConvertUnits.ToSimUnits(Prefab.BodyOffset);
|
||||
if (FlippedX) { bodyOffset.X = -bodyOffset.X; }
|
||||
if (FlippedY) { bodyOffset.Y = -bodyOffset.Y; }
|
||||
|
||||
@@ -1030,7 +1015,7 @@ namespace Barotrauma
|
||||
//newBody.Position = ConvertUnits.ToSimUnits(new Vector2(rect.X + rect.Width / 2.0f, rect.Y - rect.Height / 2.0f));
|
||||
newBody.Friction = 0.5f;
|
||||
newBody.OnCollision += OnWallCollision;
|
||||
newBody.CollisionCategories = (prefab.Platform) ? Physics.CollisionPlatform : Physics.CollisionWall;
|
||||
newBody.CollisionCategories = (Prefab.Platform) ? Physics.CollisionPlatform : Physics.CollisionWall;
|
||||
newBody.UserData = this;
|
||||
|
||||
Vector2 structureCenter = ConvertUnits.ToSimUnits(Position);
|
||||
@@ -1059,27 +1044,11 @@ namespace Barotrauma
|
||||
|
||||
partial void CreateConvexHull(Vector2 position, Vector2 size, float rotation);
|
||||
|
||||
public void ServerWrite(NetBuffer msg, Client c, object[] extraData = null)
|
||||
{
|
||||
for (int i = 0; i < Sections.Length; i++)
|
||||
{
|
||||
msg.WriteRangedSingle(Sections[i].damage / Health, 0.0f, 1.0f, 8);
|
||||
}
|
||||
}
|
||||
|
||||
public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime)
|
||||
{
|
||||
for (int i = 0; i < Sections.Length; i++)
|
||||
{
|
||||
float damage = msg.ReadRangedSingle(0.0f, 1.0f, 8) * Health;
|
||||
SetDamage(i, damage);
|
||||
}
|
||||
}
|
||||
public override void FlipX(bool relativeToSub)
|
||||
{
|
||||
base.FlipX(relativeToSub);
|
||||
|
||||
if (prefab.CanSpriteFlipX)
|
||||
if (Prefab.CanSpriteFlipX)
|
||||
{
|
||||
SpriteEffects ^= SpriteEffects.FlipHorizontally;
|
||||
}
|
||||
@@ -1105,7 +1074,7 @@ namespace Barotrauma
|
||||
{
|
||||
base.FlipY(relativeToSub);
|
||||
|
||||
if (prefab.CanSpriteFlipY)
|
||||
if (Prefab.CanSpriteFlipY)
|
||||
{
|
||||
SpriteEffects ^= SpriteEffects.FlipVertically;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace Barotrauma
|
||||
|
||||
partial class Submarine : Entity, IServerSerializable
|
||||
{
|
||||
public byte TeamID = 1;
|
||||
public Character.TeamType TeamID = Character.TeamType.None;
|
||||
|
||||
public static string SavePath = "Submarines";
|
||||
|
||||
@@ -109,6 +109,12 @@ namespace Barotrauma
|
||||
set { name = value; }
|
||||
}
|
||||
|
||||
private string displayName;
|
||||
public string DisplayName
|
||||
{
|
||||
get { return displayName; }
|
||||
}
|
||||
|
||||
public bool ShowSonarMarker = true;
|
||||
|
||||
public string Description
|
||||
@@ -316,7 +322,12 @@ namespace Barotrauma
|
||||
|
||||
if (doc != null && doc.Root != null)
|
||||
{
|
||||
Description = doc.Root.GetAttributeString("description", "");
|
||||
displayName = TextManager.Get("Submarine.Name." + name, true);
|
||||
if (displayName == null || displayName.Length == 0) displayName = name;
|
||||
|
||||
Description = TextManager.Get("Submarine.Description." + name, true);
|
||||
if (Description == null || Description.Length == 0) Description = doc.Root.GetAttributeString("description", "");
|
||||
|
||||
GameVersion = new Version(doc.Root.GetAttributeString("gameversion", "0.0.0.0"));
|
||||
Enum.TryParse(doc.Root.GetAttributeString("tags", ""), out tags);
|
||||
Dimensions = doc.Root.GetAttributeVector2("dimensions", Vector2.Zero);
|
||||
@@ -397,7 +408,7 @@ namespace Barotrauma
|
||||
if (me is Item item)
|
||||
{
|
||||
item.Indestructible = true;
|
||||
foreach (ItemComponent ic in item.components)
|
||||
foreach (ItemComponent ic in item.Components)
|
||||
{
|
||||
if (ic is ConnectionPanel connectionPanel)
|
||||
{
|
||||
@@ -507,6 +518,8 @@ namespace Barotrauma
|
||||
{
|
||||
maxX = Math.Min(maxX, ruin.Area.X - 100.0f);
|
||||
}
|
||||
|
||||
if (entity.IsVisible(worldView)) { visibleEntities.Add(entity); }
|
||||
}
|
||||
|
||||
if (minX < 0.0f && maxX > Level.Loaded.Size.X)
|
||||
@@ -533,71 +546,6 @@ namespace Barotrauma
|
||||
return spawnPos - diffFromDockedBorders;
|
||||
}
|
||||
|
||||
//drawing ----------------------------------------------------
|
||||
|
||||
public static void CullEntities(Camera cam)
|
||||
{
|
||||
HashSet<Submarine> visibleSubs = new HashSet<Submarine>();
|
||||
foreach (Submarine sub in Loaded)
|
||||
{
|
||||
if (sub.WorldPosition.Y < Level.MaxEntityDepth) continue;
|
||||
|
||||
Rectangle worldBorders = new Rectangle(
|
||||
sub.Borders.X + (int)sub.WorldPosition.X - 500,
|
||||
sub.Borders.Y + (int)sub.WorldPosition.Y + 500,
|
||||
sub.Borders.Width + 1000,
|
||||
sub.Borders.Height + 1000);
|
||||
|
||||
if (RectsOverlap(worldBorders, cam.WorldView))
|
||||
{
|
||||
visibleSubs.Add(sub);
|
||||
}
|
||||
}
|
||||
|
||||
HashSet<Ruin> visibleRuins = new HashSet<Ruin>();
|
||||
if (Level.Loaded != null)
|
||||
{
|
||||
foreach (Ruin ruin in Level.Loaded.Ruins)
|
||||
{
|
||||
Rectangle worldBorders = new Rectangle(
|
||||
ruin.Area.X - 500,
|
||||
ruin.Area.Y + ruin.Area.Height + 500,
|
||||
ruin.Area.Width + 1000,
|
||||
ruin.Area.Height + 1000);
|
||||
|
||||
if (RectsOverlap(worldBorders, cam.WorldView))
|
||||
{
|
||||
visibleRuins.Add(ruin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (visibleEntities == null)
|
||||
{
|
||||
visibleEntities = new List<MapEntity>(MapEntity.mapEntityList.Count);
|
||||
}
|
||||
else
|
||||
{
|
||||
visibleEntities.Clear();
|
||||
}
|
||||
|
||||
Rectangle worldView = cam.WorldView;
|
||||
foreach (MapEntity entity in MapEntity.mapEntityList)
|
||||
{
|
||||
if (entity.Submarine != null)
|
||||
{
|
||||
if (!visibleSubs.Contains(entity.Submarine)) { continue; }
|
||||
|
||||
}
|
||||
else if(entity.ParentRuin != null)
|
||||
{
|
||||
if (!visibleRuins.Contains(entity.ParentRuin)) { continue; }
|
||||
}
|
||||
|
||||
if (entity.IsVisible(worldView)) { visibleEntities.Add(entity); }
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateTransform()
|
||||
{
|
||||
DrawPosition = Timing.Interpolate(prevPosition, Position);
|
||||
@@ -751,7 +699,50 @@ namespace Barotrauma
|
||||
|
||||
return closestBody;
|
||||
}
|
||||
|
||||
|
||||
public static List<Body> PickBodies(Vector2 rayStart, Vector2 rayEnd, List<Body> ignoredBodies = null, Category? collisionCategory = null, bool ignoreSensors = true, Predicate<Fixture> customPredicate = null)
|
||||
{
|
||||
if (Vector2.DistanceSquared(rayStart, rayEnd) < 0.00001f)
|
||||
{
|
||||
rayEnd += Vector2.UnitX * 0.001f;
|
||||
}
|
||||
|
||||
float closestFraction = 1.0f;
|
||||
List<Body> bodies = new List<Body>();
|
||||
GameMain.World.RayCast((fixture, point, normal, fraction) =>
|
||||
{
|
||||
if (fixture == null ||
|
||||
(ignoreSensors && fixture.IsSensor) ||
|
||||
fixture.CollisionCategories == Category.None ||
|
||||
fixture.CollisionCategories == Physics.CollisionItem) return -1;
|
||||
|
||||
if (customPredicate != null && !customPredicate(fixture)) return -1;
|
||||
|
||||
if (collisionCategory != null &&
|
||||
!fixture.CollisionCategories.HasFlag((Category)collisionCategory) &&
|
||||
!((Category)collisionCategory).HasFlag(fixture.CollisionCategories)) return -1;
|
||||
|
||||
if (ignoredBodies != null && ignoredBodies.Contains(fixture.Body)) return -1;
|
||||
|
||||
if (fixture.Body.UserData is Structure structure)
|
||||
{
|
||||
if (structure.IsPlatform && collisionCategory != null && !((Category)collisionCategory).HasFlag(Physics.CollisionPlatform)) return -1;
|
||||
}
|
||||
|
||||
bodies.Add(fixture.Body);
|
||||
if (fraction < closestFraction)
|
||||
{
|
||||
lastPickedPosition = rayStart + (rayEnd - rayStart) * fraction;
|
||||
lastPickedFraction = fraction;
|
||||
lastPickedNormal = normal;
|
||||
}
|
||||
|
||||
return fraction;
|
||||
}, rayStart, rayEnd);
|
||||
|
||||
return bodies;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// check visibility between two points (in sim units)
|
||||
/// </summary>
|
||||
@@ -1438,16 +1429,6 @@ namespace Barotrauma
|
||||
PreviewImage = null;
|
||||
#endif
|
||||
}
|
||||
|
||||
public void ServerWrite(NetBuffer msg, Client c, object[] extraData = null)
|
||||
{
|
||||
msg.Write(ID);
|
||||
//length in bytes
|
||||
msg.Write((byte)(4 + 4));
|
||||
|
||||
msg.Write(PhysicsBody.SimPosition.X);
|
||||
msg.Write(PhysicsBody.SimPosition.Y);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ using Voronoi2;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
class SubmarineBody
|
||||
partial class SubmarineBody
|
||||
{
|
||||
public const float NeutralBallastPercentage = 0.07f;
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace Barotrauma
|
||||
|
||||
public readonly PhysicsBody Body;
|
||||
|
||||
private List<PosInfo> memPos = new List<PosInfo>();
|
||||
private List<PosInfo> positionBuffer = new List<PosInfo>();
|
||||
|
||||
public Rectangle Borders
|
||||
{
|
||||
@@ -62,9 +62,9 @@ namespace Barotrauma
|
||||
get { return ConvertUnits.ToDisplayUnits(Body.SimPosition); }
|
||||
}
|
||||
|
||||
public List<PosInfo> MemPos
|
||||
public List<PosInfo> PositionBuffer
|
||||
{
|
||||
get { return memPos; }
|
||||
get { return positionBuffer; }
|
||||
}
|
||||
|
||||
public bool AtDamageDepth
|
||||
@@ -246,58 +246,8 @@ namespace Barotrauma
|
||||
{
|
||||
if (Body.FarseerBody.IsStatic) { return; }
|
||||
|
||||
if (GameMain.Client != null)
|
||||
{
|
||||
if (memPos.Count == 0) return;
|
||||
|
||||
Vector2 newVelocity = Body.LinearVelocity;
|
||||
Vector2 newPosition = Body.SimPosition;
|
||||
|
||||
Body.CorrectPosition(memPos, deltaTime, out newVelocity, out newPosition);
|
||||
Vector2 moveAmount = ConvertUnits.ToDisplayUnits(newPosition - Body.SimPosition);
|
||||
newVelocity = newVelocity.ClampLength(100.0f);
|
||||
if (!MathUtils.IsValid(newVelocity))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<Submarine> subsToMove = submarine.GetConnectedSubs();
|
||||
foreach (Submarine dockedSub in subsToMove)
|
||||
{
|
||||
if (dockedSub == submarine) continue;
|
||||
//clear the position buffer of the docked subs to prevent unnecessary position corrections
|
||||
dockedSub.SubBody.memPos.Clear();
|
||||
}
|
||||
|
||||
Submarine closestSub = null;
|
||||
if (Character.Controlled == null)
|
||||
{
|
||||
closestSub = Submarine.FindClosest(GameMain.GameScreen.Cam.WorldViewCenter);
|
||||
}
|
||||
else
|
||||
{
|
||||
closestSub = Character.Controlled.Submarine;
|
||||
}
|
||||
|
||||
bool displace = moveAmount.LengthSquared() > 100.0f * 100.0f;
|
||||
foreach (Submarine sub in subsToMove)
|
||||
{
|
||||
sub.PhysicsBody.SetTransform(sub.PhysicsBody.SimPosition + ConvertUnits.ToSimUnits(moveAmount), 0.0f);
|
||||
sub.PhysicsBody.LinearVelocity = newVelocity;
|
||||
|
||||
if (displace) sub.SubBody.DisplaceCharacters(moveAmount);
|
||||
}
|
||||
|
||||
if (closestSub != null && subsToMove.Contains(closestSub))
|
||||
{
|
||||
GameMain.GameScreen.Cam.Position += moveAmount;
|
||||
if (GameMain.GameScreen.Cam.TargetPos != Vector2.Zero) GameMain.GameScreen.Cam.TargetPos += moveAmount;
|
||||
|
||||
if (Character.Controlled != null) Character.Controlled.CursorPosition += moveAmount;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
ClientUpdatePosition(deltaTime);
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; }
|
||||
|
||||
//if outside left or right edge of the level
|
||||
if (Position.X < 0 || Position.X > Level.Loaded.Size.X)
|
||||
@@ -348,7 +298,9 @@ namespace Barotrauma
|
||||
|
||||
UpdateDepthDamage(deltaTime);
|
||||
}
|
||||
|
||||
|
||||
partial void ClientUpdatePosition(float deltaTime);
|
||||
|
||||
/// <summary>
|
||||
/// Moves away any character that is inside the bounding box of the sub (but not inside the sub)
|
||||
/// </summary>
|
||||
@@ -537,10 +489,10 @@ namespace Barotrauma
|
||||
|
||||
float impact = Math.Min(Vector2.Dot(Velocity - limb.LinearVelocity, -normal), 50.0f) / 5.0f * Math.Min(limb.Mass / 200.0f, 1);
|
||||
|
||||
ApplyImpact(impact, -normal, contact);
|
||||
ApplyImpact(impact, -normal, contact, applyDamage: false);
|
||||
foreach (Submarine dockedSub in submarine.DockedTo)
|
||||
{
|
||||
dockedSub.SubBody.ApplyImpact(impact, -normal, contact);
|
||||
dockedSub.SubBody.ApplyImpact(impact, -normal, contact, applyDamage: false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -581,7 +533,7 @@ namespace Barotrauma
|
||||
avgContactNormal += contactNormal;
|
||||
|
||||
//apply impacts at the positions where this sub is touching the limb
|
||||
ApplyImpact((Vector2.Dot(-Velocity, contactNormal) / 2.0f) / levelContacts.Count, contactNormal, levelContact);
|
||||
ApplyImpact((Vector2.Dot(-Velocity, contactNormal) / 2.0f) / levelContacts.Count, contactNormal, levelContact, applyDamage: false);
|
||||
}
|
||||
avgContactNormal /= levelContacts.Count;
|
||||
|
||||
@@ -736,9 +688,11 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyImpact(float impact, Vector2 direction, Contact contact)
|
||||
private void ApplyImpact(float impact, Vector2 direction, Contact contact, bool applyDamage = true)
|
||||
{
|
||||
if (impact < 3.0f) return;
|
||||
float minImpact = 3.0f;
|
||||
|
||||
if (impact < minImpact) { return; }
|
||||
|
||||
contact.GetWorldManifold(out Vector2 tempNormal, out FixedArray2<Vector2> worldPoints);
|
||||
Vector2 lastContactPoint = worldPoints[0];
|
||||
@@ -776,14 +730,17 @@ namespace Barotrauma
|
||||
|
||||
item.body.ApplyLinearImpulse(item.body.Mass * impulse, 20.0f);
|
||||
}
|
||||
|
||||
var damagedStructures = Explosion.RangedStructureDamage(ConvertUnits.ToDisplayUnits(lastContactPoint), impact * 50.0f, impact * ImpactDamageMultiplier);
|
||||
|
||||
var damagedStructures = Explosion.RangedStructureDamage(
|
||||
ConvertUnits.ToDisplayUnits(lastContactPoint),
|
||||
impact * 50.0f,
|
||||
applyDamage ? impact * ImpactDamageMultiplier : 0.0f);
|
||||
|
||||
#if CLIENT
|
||||
//play a damage sound for the structure that took the most damage
|
||||
float maxDamage = 0.0f;
|
||||
Structure maxDamageStructure = null;
|
||||
foreach (KeyValuePair<Structure,float> structureDamage in damagedStructures)
|
||||
foreach (KeyValuePair<Structure, float> structureDamage in damagedStructures)
|
||||
{
|
||||
if (maxDamageStructure == null || structureDamage.Value > maxDamage)
|
||||
{
|
||||
@@ -798,7 +755,7 @@ namespace Barotrauma
|
||||
"StructureBlunt",
|
||||
impact * 10.0f,
|
||||
ConvertUnits.ToDisplayUnits(lastContactPoint),
|
||||
MathHelper.Clamp(maxDamage * 4.0f, 2000.0f, 10000.0f),
|
||||
MathHelper.Lerp(2000.0f, 10000.0f, (impact - minImpact) / 2.0f),
|
||||
maxDamageStructure.Tags);
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user