Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Evil Factory
2025-12-08 12:35:44 -03:00
122 changed files with 1614 additions and 819 deletions
@@ -30,7 +30,7 @@ namespace Barotrauma
partial class Character : Entity, IDamageable, ISerializableEntity, IClientSerializable, IServerPositionSync
{
public readonly static List<Character> CharacterList = new List<Character>();
public static readonly List<Character> CharacterList = new List<Character>();
public static int CharacterUpdateInterval = 1;
private static int characterUpdateTick = 1;
@@ -42,7 +42,13 @@ namespace Barotrauma
partial void UpdateLimbLightSource(Limb limb);
private bool enabled = true;
private bool initialized;
private bool enabled;
//characters start disabled in the multiplayer mode, and are enabled if/when
// - controlled by the player
// - client receives a position update from the server
// - server receives an input message from the client controlling the character
// - if an AICharacter, the server enables it when close enough to any of the players
public bool Enabled
{
get
@@ -51,7 +57,12 @@ namespace Barotrauma
}
set
{
if (value == enabled) { return; }
if (initialized && value == enabled)
{
// Ensure that we'll set the value and run the code below at least once, because otherwise the states might be out of sync.
return;
}
initialized = true;
if (Removed)
{
@@ -83,7 +94,6 @@ namespace Barotrauma
//we only want to enable the physics body if it's an actual holdable item, not e.g. a wearable item like handcuffs
item.body.Enabled = true;
}
}
AnimController.Collider.Enabled = value;
}
@@ -112,6 +122,13 @@ namespace Barotrauma
if (!CharacterList.Contains(this)) { CharacterList.Add(this); }
if (AiTarget != null && !AITarget.List.Contains(AiTarget)) { AITarget.List.Add(AiTarget); }
}
if (Inventory != null)
{
foreach (var item in Inventory.FindAllItems(recursive: true))
{
item.IsActive = !disabledByEvent;
}
}
}
}
@@ -1625,18 +1642,14 @@ namespace Barotrauma
PressureProtection = int.MaxValue;
}
AnimController.SetPosition(ConvertUnits.ToSimUnits(position));
CharacterHealth.CheckForErrors();
AnimController.FindHull(null);
AnimController.SetPosition(ConvertUnits.ToSimUnits(position));
AnimController.FindHull(setInWater: true);
if (AnimController.CurrentHull != null) { Submarine = AnimController.CurrentHull.Submarine; }
CharacterList.Add(this);
//characters start disabled in the multiplayer mode, and are enabled if/when
// - controlled by the player
// - client receives a position update from the server
// - server receives an input message from the client controlling the character
// - if an AICharacter, the server enables it when close enough to any of the players
Enabled = GameMain.NetworkMember == null;
if (info != null)
@@ -3311,17 +3324,22 @@ namespace Barotrauma
public static void UpdateAll(float deltaTime, Camera cam)
{
if (GameMain.NetworkMember == null || !GameMain.NetworkMember.IsClient)
if (GameMain.NetworkMember == null || !GameMain.NetworkMember.IsClient) // single player or server
{
foreach (Character c in CharacterList)
{
if (c is not AICharacter && !c.IsRemotePlayer) { continue; }
if (c.IsPlayer || (c.IsBot && !c.IsDead))
// TODO: The logic below seems to be overly complicated and quite confusing
if (c is not AICharacter && !c.IsRemotePlayer) { continue; } // confusing -> what this line is intended for? local player? But that's handled below...
if (c.IsRemotePlayer)
{
// Let the client tell when to enable the character. If we force it enabled here, it may e.g. get killed while still loading a round.
continue;
}
if (c.IsLocalPlayer || (c.IsBot && !c.IsDead))
{
c.Enabled = true;
}
else if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer)
else if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer) // mp server
{
//disable AI characters that are far away from all clients and the host's character and not controlled by anyone
float closestPlayerDist = c.GetDistanceToClosestPlayer();
@@ -3338,7 +3356,7 @@ namespace Barotrauma
c.Enabled = true;
}
}
else if (Submarine.MainSub != null)
else if (Submarine.MainSub != null) // sp only?
{
//disable AI characters that are far away from the sub and the controlled character
float distSqr = Vector2.DistanceSquared(Submarine.MainSub.WorldPosition, c.WorldPosition);
@@ -3382,7 +3400,7 @@ namespace Barotrauma
foreach (Character character in GameMain.LuaCs.Game.UpdatePriorityCharacters)
{
if (character.Removed) { continue; }
Debug.Assert(character is { Removed: false });
character.Update(deltaTime, cam);
}
@@ -3444,8 +3462,7 @@ namespace Barotrauma
foreach (Item item in Inventory.GetAllItems(checkForDuplicates: false))
{
if (item.body == null || item.body.Enabled) { continue; }
item.SetTransform(SimPosition, 0.0f);
item.Submarine = Submarine;
item.SetTransform(SimPosition, 0.0f, forceSubmarine: Submarine);
}
}
@@ -4600,7 +4617,10 @@ namespace Barotrauma
SetStun(stun);
if (attacker != null && attacker != this && GameMain.NetworkMember != null && !GameMain.NetworkMember.ServerSettings.AllowFriendlyFire)
if (attacker != null && attacker != this &&
attacker.IsOnPlayerTeam &&
GameMain.NetworkMember != null &&
!GameMain.NetworkMember.ServerSettings.AllowFriendlyFire)
{
if (attacker.TeamID == TeamID)
{