Unstable 0.17.1.0
This commit is contained in:
@@ -7,6 +7,7 @@ using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.Extensions;
|
||||
using Barotrauma.Items.Components;
|
||||
using Barotrauma.Networking;
|
||||
using FarseerPhysics;
|
||||
using FarseerPhysics.Dynamics;
|
||||
using Microsoft.Xna.Framework;
|
||||
@@ -58,7 +59,9 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
|
||||
public float AccumulatedDamage;
|
||||
public float DamageVisualizationTimer;
|
||||
#if CLIENT
|
||||
public Vector2 ShakeAmount;
|
||||
#endif
|
||||
|
||||
// Adjacent tiles, used to free up sides when this branch gets removed
|
||||
public readonly Dictionary<TileSide, BallastFloraBranch> Connections = new Dictionary<TileSide, BallastFloraBranch>();
|
||||
@@ -286,7 +289,7 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
public float PowerConsumptionTimer;
|
||||
|
||||
private float defenseCooldown, toxinsCooldown, fireCheckCooldown;
|
||||
private float selfDamageTimer, toxinsTimer;
|
||||
private float selfDamageTimer, toxinsTimer, toxinsSpawnTimer;
|
||||
|
||||
private readonly List<BallastFloraBranch> branchesVulnerableToFire = new List<BallastFloraBranch>();
|
||||
|
||||
@@ -552,11 +555,12 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
Anger -= deltaTime;
|
||||
}
|
||||
|
||||
// This entire scope is probably very heavy for GC, need to experiment
|
||||
if (toxinsTimer > 0.1f)
|
||||
{
|
||||
if (!AttackItemPrefab.IsEmpty)
|
||||
toxinsSpawnTimer -= deltaTime;
|
||||
if (!AttackItemPrefab.IsEmpty && toxinsSpawnTimer <= 0.0f)
|
||||
{
|
||||
toxinsSpawnTimer = 1.0f;
|
||||
Dictionary<Hull, List<BallastFloraBranch>> branches = new Dictionary<Hull, List<BallastFloraBranch>>();
|
||||
foreach (BallastFloraBranch branch in Branches)
|
||||
{
|
||||
@@ -581,7 +585,7 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
randomBranch.SpawningItem = true;
|
||||
|
||||
ItemPrefab prefab = ItemPrefab.Find(null, AttackItemPrefab);
|
||||
#warning TODO: Parent needs a nullability sanity check
|
||||
#warning TODO: Parent needs a nullability sanity check
|
||||
Entity.Spawner?.AddItemToSpawnQueue(prefab, Parent!.Position + Offset + randomBranch.Position, Parent.Submarine, onSpawned: item =>
|
||||
{
|
||||
randomBranch.AttackItem = item;
|
||||
@@ -826,13 +830,13 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
{
|
||||
if (root != null)
|
||||
{
|
||||
Vector2 rootGrowthPos = Rand.Vector(rootGrowthCount * Rand.Range(3.0f, 5.0f));
|
||||
Vector2 rootGrowthPos = Rand.Vector(Math.Max(rootGrowthCount, 1) * Rand.Range(3.0f, 5.0f));
|
||||
TryGrowBranch(root, TileSide.None, out List<BallastFloraBranch> newRootGrowth, isRootGrowth: true, forcePosition: rootGrowthPos);
|
||||
}
|
||||
}
|
||||
|
||||
#if SERVER
|
||||
SendNetworkMessage(this, NetworkHeader.BranchCreate, newBranch, parent.ID);
|
||||
SendNetworkMessage(new BranchCreateEventData(newBranch, parent));
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
@@ -874,7 +878,7 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
#if SERVER
|
||||
if (!load)
|
||||
{
|
||||
SendNetworkMessage(this, NetworkHeader.Infect, target.ID, true, branch);
|
||||
SendNetworkMessage(new InfectEventData(target, InfectEventData.InfectState.Yes, branch));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1002,8 +1006,10 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
StateMachine.EnterState(new DefendWithPumpState(branch, ClaimedTargets, attacker));
|
||||
defenseCooldown = 180f;
|
||||
}
|
||||
|
||||
defenseCooldown = 10f;
|
||||
else
|
||||
{
|
||||
defenseCooldown = 10f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1104,7 +1110,7 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
#if SERVER
|
||||
if (!wasRemoved)
|
||||
{
|
||||
SendNetworkMessage(this, NetworkHeader.BranchRemove, branch);
|
||||
SendNetworkMessage(new BranchRemoveEventData(branch));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1135,7 +1141,7 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
}
|
||||
});
|
||||
#if SERVER
|
||||
SendNetworkMessage(this, NetworkHeader.Infect, item.ID, false);
|
||||
SendNetworkMessage(new InfectEventData(item, InfectEventData.InfectState.No, null));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1153,7 +1159,7 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
|
||||
StateMachine?.State?.Exit();
|
||||
#if SERVER
|
||||
SendNetworkMessage(this, NetworkHeader.Kill);
|
||||
SendNetworkMessage(new KillEventData());
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1175,7 +1181,7 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
|
||||
_entityList.Remove(this);
|
||||
#if SERVER
|
||||
SendNetworkMessage(this, NetworkHeader.Remove);
|
||||
SendNetworkMessage(new KillEventData());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
using Barotrauma.Networking;
|
||||
|
||||
namespace Barotrauma.MapCreatures.Behavior
|
||||
{
|
||||
internal partial class BallastFloraBehavior
|
||||
{
|
||||
public interface IEventData : NetEntityEvent.IData
|
||||
{
|
||||
public NetworkHeader NetworkHeader { get; }
|
||||
}
|
||||
|
||||
public readonly struct SpawnEventData : IEventData
|
||||
{
|
||||
public NetworkHeader NetworkHeader => NetworkHeader.Spawn;
|
||||
}
|
||||
|
||||
private readonly struct KillEventData : IEventData
|
||||
{
|
||||
public NetworkHeader NetworkHeader => NetworkHeader.Kill;
|
||||
}
|
||||
|
||||
private readonly struct BranchCreateEventData : IEventData
|
||||
{
|
||||
public NetworkHeader NetworkHeader => NetworkHeader.BranchCreate;
|
||||
public readonly BallastFloraBranch NewBranch;
|
||||
public readonly BallastFloraBranch Parent;
|
||||
|
||||
public BranchCreateEventData(BallastFloraBranch newBranch, BallastFloraBranch parent)
|
||||
{
|
||||
NewBranch = newBranch;
|
||||
Parent = parent;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly struct BranchRemoveEventData : IEventData
|
||||
{
|
||||
public NetworkHeader NetworkHeader => NetworkHeader.BranchRemove;
|
||||
public readonly BallastFloraBranch Branch;
|
||||
|
||||
public BranchRemoveEventData(BallastFloraBranch branch)
|
||||
{
|
||||
Branch = branch;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly struct BranchDamageEventData : IEventData
|
||||
{
|
||||
public NetworkHeader NetworkHeader => NetworkHeader.BranchDamage;
|
||||
public readonly BallastFloraBranch Branch;
|
||||
|
||||
public BranchDamageEventData(BallastFloraBranch branch)
|
||||
{
|
||||
Branch = branch;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly struct InfectEventData : IEventData
|
||||
{
|
||||
public enum InfectState { Yes, No }
|
||||
|
||||
public NetworkHeader NetworkHeader => NetworkHeader.Infect;
|
||||
public readonly Item Item;
|
||||
public readonly InfectState Infect;
|
||||
public readonly BallastFloraBranch Infector;
|
||||
|
||||
public InfectEventData(Item item, InfectState infect, BallastFloraBranch infector)
|
||||
{
|
||||
Item = item;
|
||||
Infect = infect;
|
||||
Infector = infector;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -17,6 +17,8 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
{
|
||||
lastState = State;
|
||||
State?.Exit();
|
||||
State = null;
|
||||
|
||||
newState.Enter();
|
||||
State = newState;
|
||||
}
|
||||
@@ -35,11 +37,9 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
{
|
||||
case ExitState.Running:
|
||||
break;
|
||||
|
||||
case ExitState.ReturnLast when lastState != null && lastState.GetState() == ExitState.Running:
|
||||
EnterState(lastState);
|
||||
break;
|
||||
|
||||
default:
|
||||
EnterState(new GrowIdleState(parent));
|
||||
break;
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Diagnostics;
|
||||
using Barotrauma.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Barotrauma.Networking;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
|
||||
@@ -237,9 +237,9 @@ namespace Barotrauma
|
||||
if (!fireProof)
|
||||
{
|
||||
item.ApplyStatusEffects(ActionType.OnFire, 1.0f);
|
||||
if (item.Condition <= 0.0f && GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
|
||||
if (item.Condition <= 0.0f && GameMain.NetworkMember is { IsServer: true })
|
||||
{
|
||||
GameMain.NetworkMember.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.ApplyStatusEffect, ActionType.OnFire });
|
||||
GameMain.NetworkMember.CreateEntityEvent(item, new Item.ApplyStatusEffectEventData(ActionType.OnFire));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -363,9 +363,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.NetworkMember != null && GameMain.NetworkMember.IsServer)
|
||||
if (item.Condition <= 0.0f && GameMain.NetworkMember is { IsServer: true })
|
||||
{
|
||||
GameMain.NetworkMember.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.ApplyStatusEffect, ActionType.OnFire });
|
||||
GameMain.NetworkMember.CreateEntityEvent(item, new Item.ApplyStatusEffectEventData(ActionType.OnFire));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,16 +248,17 @@ namespace Barotrauma
|
||||
}
|
||||
linkedTo.Clear();
|
||||
|
||||
int tolerance = 1;
|
||||
Vector2[] searchPos = new Vector2[2];
|
||||
if (IsHorizontal)
|
||||
{
|
||||
searchPos[0] = new Vector2(rect.X, rect.Y - rect.Height / 2);
|
||||
searchPos[1] = new Vector2(rect.Right, rect.Y - rect.Height / 2);
|
||||
searchPos[0] = new Vector2(rect.X - tolerance, rect.Y - rect.Height / 2);
|
||||
searchPos[1] = new Vector2(rect.Right + tolerance, rect.Y - rect.Height / 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
searchPos[0] = new Vector2(rect.Center.X, rect.Y);
|
||||
searchPos[1] = new Vector2(rect.Center.X, rect.Y - rect.Height);
|
||||
searchPos[0] = new Vector2(rect.Center.X, rect.Y + tolerance);
|
||||
searchPos[1] = new Vector2(rect.Center.X, rect.Y - rect.Height - tolerance);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
|
||||
@@ -320,7 +320,8 @@ namespace Barotrauma
|
||||
roomName != null && (
|
||||
roomName.Contains("ballast", StringComparison.OrdinalIgnoreCase) ||
|
||||
roomName.Contains("bilge", StringComparison.OrdinalIgnoreCase) ||
|
||||
roomName.Contains("airlock", StringComparison.OrdinalIgnoreCase));
|
||||
roomName.Contains("airlock", StringComparison.OrdinalIgnoreCase) ||
|
||||
roomName.Contains("dockingport", StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
private bool isWetRoom;
|
||||
[Editable, Serialize(false, IsPropertySaveable.Yes, description: "It's normal for this hull to be filled with water. If the room name contains 'ballast', 'bilge', or 'airlock', you can't disable this setting.")]
|
||||
@@ -729,9 +730,9 @@ namespace Barotrauma
|
||||
var decal = DecalManager.CreateDecal(decalName, scale, worldPosition, this, spriteIndex);
|
||||
if (decal != null)
|
||||
{
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
|
||||
if (GameMain.NetworkMember is { IsServer: true })
|
||||
{
|
||||
GameMain.NetworkMember.CreateEntityEvent(this, new object[] { false });
|
||||
GameMain.NetworkMember.CreateEntityEvent(this, new DecalEventData());
|
||||
}
|
||||
decals.Add(decal);
|
||||
}
|
||||
@@ -739,6 +740,96 @@ namespace Barotrauma
|
||||
return decal;
|
||||
}
|
||||
|
||||
#region Shared network write
|
||||
private void SharedStatusWrite(IWriteMessage msg)
|
||||
{
|
||||
msg.WriteRangedSingle(MathHelper.Clamp(waterVolume / Volume, 0.0f, 1.5f), 0.0f, 1.5f, 8);
|
||||
|
||||
msg.WriteRangedInteger(Math.Min(FireSources.Count, 16), 0, 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);
|
||||
|
||||
msg.WriteRangedSingle(MathHelper.Clamp(normalizedPos.X, 0.0f, 1.0f), 0.0f, 1.0f, 8);
|
||||
msg.WriteRangedSingle(MathHelper.Clamp(normalizedPos.Y, 0.0f, 1.0f), 0.0f, 1.0f, 8);
|
||||
msg.WriteRangedSingle(MathHelper.Clamp(fireSource.Size.X / rect.Width, 0.0f, 1.0f), 0, 1.0f, 8);
|
||||
}
|
||||
}
|
||||
|
||||
private void SharedBackgroundSectionsWrite(IWriteMessage msg, in BackgroundSectionsEventData backgroundSectionsEventData)
|
||||
{
|
||||
int sectorToUpdate = backgroundSectionsEventData.SectorStartIndex;
|
||||
int start = sectorToUpdate * BackgroundSectionsPerNetworkEvent;
|
||||
int end = Math.Min((sectorToUpdate + 1) * BackgroundSectionsPerNetworkEvent, BackgroundSections.Count - 1);
|
||||
msg.WriteRangedInteger(sectorToUpdate, 0, BackgroundSections.Count - 1);
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
msg.WriteRangedSingle(BackgroundSections[i].ColorStrength, 0.0f, 1.0f, 8);
|
||||
msg.Write(BackgroundSections[i].Color.PackedValue);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Shared network read
|
||||
public readonly struct NetworkFireSource
|
||||
{
|
||||
public readonly Vector2 Position;
|
||||
public readonly float Size;
|
||||
|
||||
public NetworkFireSource(Hull hull, Vector2 normalizedPosition, float normalizedSize)
|
||||
{
|
||||
Position = hull.Rect.Location.ToVector2()
|
||||
+ new Vector2(0, -hull.Rect.Height)
|
||||
+ normalizedPosition * hull.Rect.Size.ToVector2();
|
||||
Size = normalizedSize * hull.Rect.Width;
|
||||
}
|
||||
}
|
||||
|
||||
private void SharedStatusRead(IReadMessage msg, out float newWaterVolume, out NetworkFireSource[] newFireSources)
|
||||
{
|
||||
newWaterVolume = msg.ReadRangedSingle(0.0f, 1.5f, 8) * Volume;
|
||||
|
||||
int fireSourceCount = msg.ReadRangedInteger(0, 16);
|
||||
newFireSources = new NetworkFireSource[fireSourceCount];
|
||||
for (int i = 0; i < fireSourceCount; i++)
|
||||
{
|
||||
float x = MathHelper.Clamp(msg.ReadRangedSingle(0.0f, 1.0f, 8), 0.05f, 0.95f);
|
||||
float y = MathHelper.Clamp(msg.ReadRangedSingle(0.0f, 1.0f, 8), 0.05f, 0.95f);
|
||||
float size = msg.ReadRangedSingle(0.0f, 1.0f, 8);
|
||||
newFireSources[i] = new NetworkFireSource(this, new Vector2(x, y), size);
|
||||
}
|
||||
}
|
||||
|
||||
private readonly struct BackgroundSectionNetworkUpdate
|
||||
{
|
||||
public readonly int SectionIndex;
|
||||
public readonly Color Color;
|
||||
public readonly float ColorStrength;
|
||||
public BackgroundSectionNetworkUpdate(int sectionIndex, Color color, float colorStrength)
|
||||
{
|
||||
SectionIndex = sectionIndex;
|
||||
Color = color;
|
||||
ColorStrength = colorStrength;
|
||||
}
|
||||
}
|
||||
|
||||
private void SharedBackgroundSectionRead(IReadMessage msg, Action<BackgroundSectionNetworkUpdate> action, out int sectorToUpdate)
|
||||
{
|
||||
sectorToUpdate = msg.ReadRangedInteger(0, BackgroundSections.Count - 1);
|
||||
int start = sectorToUpdate * BackgroundSectionsPerNetworkEvent;
|
||||
int end = Math.Min((sectorToUpdate + 1) * BackgroundSectionsPerNetworkEvent, BackgroundSections.Count - 1);
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
float colorStrength = msg.ReadRangedSingle(0.0f, 1.0f, 8);
|
||||
Color color = new Color(msg.ReadUInt32());
|
||||
|
||||
action(new BackgroundSectionNetworkUpdate(i, color, colorStrength));
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using Barotrauma.Extensions;
|
||||
using Barotrauma.MapCreatures.Behavior;
|
||||
using Barotrauma.Networking;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class Hull
|
||||
{
|
||||
[Flags]
|
||||
public enum EventType
|
||||
{
|
||||
Status = 0,
|
||||
Decal = 1,
|
||||
BackgroundSections = 2,
|
||||
BallastFlora = 3,
|
||||
|
||||
MinValue = 0,
|
||||
MaxValue = 3
|
||||
}
|
||||
|
||||
public interface IEventData : NetEntityEvent.IData
|
||||
{
|
||||
public EventType EventType { get; }
|
||||
}
|
||||
|
||||
private readonly struct StatusEventData : IEventData
|
||||
{
|
||||
public EventType EventType => EventType.Status;
|
||||
}
|
||||
|
||||
private readonly struct DecalEventData : IEventData
|
||||
{
|
||||
public EventType EventType => EventType.Decal;
|
||||
public readonly Decal Decal;
|
||||
|
||||
public DecalEventData(Decal decal)
|
||||
{
|
||||
Decal = decal;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly struct BackgroundSectionsEventData : IEventData
|
||||
{
|
||||
public EventType EventType => EventType.BackgroundSections;
|
||||
public readonly int SectorStartIndex;
|
||||
|
||||
public BackgroundSectionsEventData(int sectorStartIndex)
|
||||
{
|
||||
SectorStartIndex = sectorStartIndex;
|
||||
}
|
||||
}
|
||||
|
||||
public readonly struct BallastFloraEventData : IEventData
|
||||
{
|
||||
public EventType EventType => EventType.BallastFlora;
|
||||
public readonly BallastFloraBehavior Behavior;
|
||||
public readonly BallastFloraBehavior.IEventData SubEventData;
|
||||
|
||||
public BallastFloraEventData(BallastFloraBehavior behavior, BallastFloraBehavior.IEventData subEventData)
|
||||
{
|
||||
Behavior = behavior;
|
||||
SubEventData = subEventData;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +1,31 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Barotrauma.Networking;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
interface IDamageable
|
||||
{
|
||||
Vector2 SimPosition
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
Vector2 WorldPosition
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
float Health
|
||||
{
|
||||
get;
|
||||
}
|
||||
Vector2 SimPosition { get; }
|
||||
Vector2 WorldPosition { get; }
|
||||
float Health { get; }
|
||||
|
||||
AttackResult AddDamage(Character attacker, Vector2 worldPosition, Attack attack, float deltaTime, bool playSound=true);
|
||||
|
||||
|
||||
public readonly struct AttackEventData
|
||||
{
|
||||
public readonly ISpatialEntity Attacker;
|
||||
public readonly IDamageable TargetEntity;
|
||||
public readonly Limb TargetLimb;
|
||||
public readonly Vector2 AttackSimPosition;
|
||||
|
||||
public AttackEventData(ISpatialEntity attacker, IDamageable targetEntity, Limb targetLimb, Vector2 attackSimPosition)
|
||||
{
|
||||
Attacker = attacker;
|
||||
TargetEntity = targetEntity;
|
||||
TargetLimb = targetLimb;
|
||||
AttackSimPosition = attackSimPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,12 @@ namespace Barotrauma
|
||||
{
|
||||
partial class Level : Entity, IServerSerializable
|
||||
{
|
||||
public enum EventType
|
||||
{
|
||||
SingleDestructibleWall,
|
||||
GlobalDestructibleWall
|
||||
}
|
||||
|
||||
//all entities are disabled after they reach this depth
|
||||
public const int MaxEntityDepth = -300000;
|
||||
public const float ShaftHeight = 1000.0f;
|
||||
@@ -3136,13 +3142,14 @@ namespace Barotrauma
|
||||
UnsyncedExtraWalls[i].Update(deltaTime);
|
||||
}
|
||||
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
|
||||
#if SERVER
|
||||
if (GameMain.NetworkMember is { IsServer: true })
|
||||
{
|
||||
foreach (LevelWall wall in ExtraWalls)
|
||||
{
|
||||
if (wall is DestructibleLevelWall destructibleWall && destructibleWall.NetworkUpdatePending)
|
||||
if (wall is DestructibleLevelWall { NetworkUpdatePending: true } destructibleWall)
|
||||
{
|
||||
GameMain.NetworkMember.CreateEntityEvent(this, new object[] { destructibleWall });
|
||||
GameMain.NetworkMember.CreateEntityEvent(this, new SingleLevelWallEventData(destructibleWall));
|
||||
destructibleWall.NetworkUpdatePending = false;
|
||||
}
|
||||
}
|
||||
@@ -3151,11 +3158,12 @@ namespace Barotrauma
|
||||
{
|
||||
if (ExtraWalls.Any(w => w.Body.BodyType != BodyType.Static))
|
||||
{
|
||||
GameMain.NetworkMember.CreateEntityEvent(this);
|
||||
GameMain.NetworkMember.CreateEntityEvent(this, new GlobalLevelWallEventData());
|
||||
}
|
||||
networkUpdateTimer = 0.0f;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CLIENT
|
||||
backgroundCreatureManager.Update(deltaTime, cam);
|
||||
@@ -4288,28 +4296,5 @@ namespace Barotrauma
|
||||
|
||||
Loaded = null;
|
||||
}
|
||||
|
||||
public void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null)
|
||||
{
|
||||
if (extraData != null && extraData.Length > 0 && extraData[0] is DestructibleLevelWall destructibleWall)
|
||||
{
|
||||
int index = ExtraWalls.IndexOf(destructibleWall);
|
||||
msg.Write(false);
|
||||
msg.Write((ushort)(index == -1 ? ushort.MaxValue : index));
|
||||
//write health using one byte
|
||||
msg.Write((byte)MathHelper.Clamp((int)(MathUtils.InverseLerp(0.0f, destructibleWall.MaxHealth, destructibleWall.Damage) * 255.0f), 0, 255));
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.Write(true);
|
||||
foreach (LevelWall levelWall in ExtraWalls)
|
||||
{
|
||||
if (levelWall.Body.BodyType == BodyType.Static) { continue; }
|
||||
msg.Write(levelWall.Body.Position.X);
|
||||
msg.Write(levelWall.Body.Position.Y);
|
||||
msg.WriteRangedSingle(levelWall.MoveState, 0.0f, MathHelper.TwoPi, 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+15
-4
@@ -30,6 +30,16 @@ namespace Barotrauma
|
||||
{
|
||||
}
|
||||
|
||||
private readonly struct EventData : NetEntityEvent.IData
|
||||
{
|
||||
public readonly LevelObject LevelObject;
|
||||
|
||||
public EventData(LevelObject levelObject)
|
||||
{
|
||||
LevelObject = levelObject;
|
||||
}
|
||||
}
|
||||
|
||||
class SpawnPosition
|
||||
{
|
||||
public readonly GraphEdge GraphEdge;
|
||||
@@ -522,12 +532,12 @@ namespace Barotrauma
|
||||
|
||||
foreach (LevelObject obj in updateableObjects)
|
||||
{
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
|
||||
if (GameMain.NetworkMember is { IsServer: true })
|
||||
{
|
||||
obj.NetworkUpdateTimer -= deltaTime;
|
||||
if (obj.NeedsNetworkSyncing && obj.NetworkUpdateTimer <= 0.0f)
|
||||
{
|
||||
GameMain.NetworkMember.CreateEntityEvent(this, new object[] { obj });
|
||||
GameMain.NetworkMember.CreateEntityEvent(this, new EventData(obj));
|
||||
obj.NeedsNetworkSyncing = false;
|
||||
obj.NetworkUpdateTimer = NetConfig.LevelObjectUpdateInterval;
|
||||
}
|
||||
@@ -607,9 +617,10 @@ namespace Barotrauma
|
||||
|
||||
partial void RemoveProjSpecific();
|
||||
|
||||
public void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null)
|
||||
public void ServerEventWrite(IWriteMessage msg, Client c, NetEntityEvent.IData extraData = null)
|
||||
{
|
||||
LevelObject obj = extraData[0] as LevelObject;
|
||||
if (!(extraData is EventData eventData)) { throw new Exception($"Malformed LevelObjectManager event: expected {nameof(LevelObjectManager)}.{nameof(EventData)}"); }
|
||||
LevelObject obj = eventData.LevelObject;
|
||||
msg.WriteRangedInteger(objects.IndexOf(obj), 0, objects.Count);
|
||||
obj.ServerWrite(msg, c);
|
||||
}
|
||||
|
||||
@@ -734,7 +734,7 @@ namespace Barotrauma
|
||||
if (prefab == null) { continue; }
|
||||
var qty = stockElement.GetAttributeInt("qty", 0);
|
||||
if (qty < 1) { continue; }
|
||||
StoreStock.Add(new PurchasedItem(prefab, qty));
|
||||
StoreStock.Add(new PurchasedItem(prefab, qty, buyer: null));
|
||||
}
|
||||
|
||||
StepsSinceSpecialsUpdated = storeElement.GetAttributeInt("stepssincespecialsupdated", 0);
|
||||
@@ -792,7 +792,7 @@ namespace Barotrauma
|
||||
{
|
||||
quantity = priceInfo.MinAvailableAmount;
|
||||
}
|
||||
stock.Add(new PurchasedItem(prefab, quantity));
|
||||
stock.Add(new PurchasedItem(prefab, quantity, buyer: null));
|
||||
}
|
||||
}
|
||||
return stock;
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace Barotrauma
|
||||
|
||||
public override Sprite Sprite { get; }
|
||||
|
||||
public override string OriginalName => Name.Value;
|
||||
public override string OriginalName { get; }
|
||||
|
||||
public override ImmutableHashSet<Identifier> Tags { get; }
|
||||
|
||||
@@ -132,7 +132,7 @@ namespace Barotrauma
|
||||
|
||||
public StructurePrefab(ContentXElement element, StructureFile file) : base(element, file)
|
||||
{
|
||||
Name = element.GetAttributeString("name", "");
|
||||
OriginalName = element.GetAttributeString("name", "");
|
||||
ConfigElement = element;
|
||||
|
||||
var parentType = element.Parent?.GetAttributeIdentifier("prefabtype", Identifier.Empty) ?? Identifier.Empty;
|
||||
@@ -144,20 +144,16 @@ namespace Barotrauma
|
||||
|
||||
Identifier descriptionIdentifier = element.GetAttributeIdentifier("descriptionidentifier", "");
|
||||
|
||||
if (Name.IsNullOrEmpty())
|
||||
{
|
||||
Name = TextManager.Get($"EntityName.{Identifier}");
|
||||
if (!nameIdentifier.IsEmpty)
|
||||
{
|
||||
Name = TextManager.Get($"EntityName.{nameIdentifier}").Fallback(Name);
|
||||
}
|
||||
Name = TextManager.Get(nameIdentifier.IsEmpty
|
||||
? $"EntityName.{Identifier}"
|
||||
: $"EntityName.{nameIdentifier}",
|
||||
$"EntityName.{fallbackNameIdentifier}");
|
||||
|
||||
if (!fallbackNameIdentifier.IsEmpty)
|
||||
{
|
||||
Name = Name.Fallback(TextManager.Get($"EntityName.{fallbackNameIdentifier}"));
|
||||
}
|
||||
if (parentType == "wrecked")
|
||||
{
|
||||
Name = TextManager.GetWithVariable("wreckeditemformat", "[name]", Name);
|
||||
}
|
||||
|
||||
|
||||
var tags = new HashSet<Identifier>();
|
||||
string joinedTags = element.GetAttributeString("tags", "");
|
||||
if (string.IsNullOrEmpty(joinedTags)) joinedTags = element.GetAttributeString("Tags", "");
|
||||
@@ -251,14 +247,6 @@ namespace Barotrauma
|
||||
DecorativeSpriteGroups = decorativeSpriteGroups.Select(kvp => (kvp.Key, kvp.Value.ToImmutableArray())).ToImmutableDictionary();
|
||||
#endif
|
||||
|
||||
if (parentType == "wrecked")
|
||||
{
|
||||
if (!Name.IsNullOrEmpty())
|
||||
{
|
||||
Name = TextManager.GetWithVariable("wreckeditemformat", "[name]", Name);
|
||||
}
|
||||
}
|
||||
|
||||
string categoryStr = element.GetAttributeString("category", "Structure");
|
||||
if (!Enum.TryParse(categoryStr, true, out MapEntityCategory category))
|
||||
{
|
||||
@@ -323,6 +311,15 @@ namespace Barotrauma
|
||||
DebugConsole.ThrowError(
|
||||
"Structure prefab \"" + Name + "\" has no identifier. All structure prefabs have a unique identifier string that's used to differentiate between items during saving and loading.");
|
||||
}
|
||||
#if DEBUG
|
||||
if (!Category.HasFlag(MapEntityCategory.Legacy) && !HideInMenus)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(OriginalName))
|
||||
{
|
||||
DebugConsole.AddWarning($"Structure \"{(Identifier == Identifier.Empty ? Name : Identifier.Value)}\" has a hard-coded name, and won't be localized to other languages.");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Tags = tags.ToImmutableHashSet();
|
||||
AllowedLinks = Enumerable.Empty<Identifier>().ToImmutableHashSet();
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Barotrauma
|
||||
None = 0, Left = 1, Right = 2
|
||||
}
|
||||
|
||||
partial class Submarine : Entity, IServerSerializable
|
||||
partial class Submarine : Entity, IServerPositionSync
|
||||
{
|
||||
public SubmarineInfo Info { get; private set; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user