v1.4.4.1 (Blood in the Water Update)
This commit is contained in:
@@ -16,7 +16,7 @@ namespace Barotrauma
|
||||
|
||||
public void ApplyDeathEffects()
|
||||
{
|
||||
RespawnManager.ReduceCharacterSkills(this);
|
||||
RespawnManager.ReduceCharacterSkillsOnDeath(this);
|
||||
RemoveSavedStatValuesOnDeath();
|
||||
CauseOfDeath = null;
|
||||
}
|
||||
@@ -68,8 +68,7 @@ namespace Barotrauma
|
||||
msg.WriteColorR8G8B8(Head.SkinColor);
|
||||
msg.WriteColorR8G8B8(Head.HairColor);
|
||||
msg.WriteColorR8G8B8(Head.FacialHairColor);
|
||||
|
||||
msg.WriteString(ragdollFileName);
|
||||
|
||||
msg.WriteIdentifier(HumanPrefabIds.NpcIdentifier);
|
||||
msg.WriteIdentifier(MinReputationToHire.factionId);
|
||||
if (!MinReputationToHire.factionId.IsEmpty)
|
||||
@@ -80,11 +79,13 @@ namespace Barotrauma
|
||||
{
|
||||
msg.WriteUInt32(Job.Prefab.UintIdentifier);
|
||||
msg.WriteByte((byte)Job.Variant);
|
||||
var skills = Job.Prefab.Skills.OrderBy(s => s.Identifier);
|
||||
|
||||
var skills = Job.GetSkills().OrderBy(s => s.Identifier);
|
||||
msg.WriteByte((byte)skills.Count());
|
||||
foreach (SkillPrefab skillPrefab in skills)
|
||||
foreach (var skill in skills)
|
||||
{
|
||||
msg.WriteSingle(Job.GetSkill(skillPrefab.Identifier)?.Level ?? 0.0f);
|
||||
msg.WriteIdentifier(skill.Identifier);
|
||||
msg.WriteSingle(skill.Level);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace Barotrauma
|
||||
NetConfig.HighPrioCharacterPositionUpdateInterval,
|
||||
priority);
|
||||
|
||||
if (IsDead)
|
||||
if (IsDead && !AnimController.IsDraggedWithRope)
|
||||
{
|
||||
interval = Math.Max(interval * 2, 0.1f);
|
||||
}
|
||||
@@ -590,6 +590,31 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LatchedOntoTargetEventData latchedOntoTargetEventData:
|
||||
msg.WriteBoolean(latchedOntoTargetEventData.IsLatched);
|
||||
if (latchedOntoTargetEventData.IsLatched)
|
||||
{
|
||||
msg.WriteSingle(SimPosition.X);
|
||||
msg.WriteSingle(SimPosition.Y);
|
||||
msg.WriteSingle(latchedOntoTargetEventData.AttachSurfaceNormal.X);
|
||||
msg.WriteSingle(latchedOntoTargetEventData.AttachSurfaceNormal.Y);
|
||||
msg.WriteSingle(latchedOntoTargetEventData.AttachPos.X);
|
||||
msg.WriteSingle(latchedOntoTargetEventData.AttachPos.Y);
|
||||
msg.WriteInt32(latchedOntoTargetEventData.TargetLevelWallIndex);
|
||||
if (latchedOntoTargetEventData.TargetStructureID != NullEntityID)
|
||||
{
|
||||
msg.WriteUInt16(latchedOntoTargetEventData.TargetStructureID);
|
||||
}
|
||||
else if (latchedOntoTargetEventData.TargetCharacterID != NullEntityID)
|
||||
{
|
||||
msg.WriteUInt16(latchedOntoTargetEventData.TargetCharacterID);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.WriteUInt16(NullEntityID);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new Exception($"Malformed character event: did not expect {eventData.GetType().Name}");
|
||||
}
|
||||
|
||||
@@ -1185,7 +1185,9 @@ namespace Barotrauma
|
||||
if (GameMain.Server == null) { return; }
|
||||
GameMain.Server.ServerSettings.SetPassword(args.Length > 0 ? args[0] : "");
|
||||
NewMessage(client.Name + " " + (GameMain.Server.ServerSettings.HasPassword ? " changed the server password to \"" + args[0] + "\"." : " removed password protection from the server."));
|
||||
GameMain.Server.SendConsoleMessage(GameMain.Server.ServerSettings.HasPassword ? "Changed the server password." : "Removed password protection from the server.", client);
|
||||
GameMain.Server.SendChatMessage(
|
||||
TextManager.GetWithVariable(GameMain.Server.ServerSettings.HasPassword ? "PasswordChangedByClient" : "PasswordRemovedByClient", "[clientname]", client.Name).Value,
|
||||
ChatMessageType.Server);
|
||||
});
|
||||
|
||||
commands.Add(new Command("setmaxplayers|maxplayers", "setmaxplayers [max players]: Sets the maximum player count of the server that's being hosted.", (string[] args) =>
|
||||
@@ -1278,12 +1280,11 @@ namespace Barotrauma
|
||||
commands.Add(new Command("servername", "servername [name]: Change the name of the server.", (string[] args) =>
|
||||
{
|
||||
GameMain.Server.ServerName = string.Join(" ", args);
|
||||
GameMain.NetLobbyScreen.ChangeServerName(string.Join(" ", args));
|
||||
}));
|
||||
|
||||
commands.Add(new Command("servermsg", "servermsg [message]: Change the message displayed in the server lobby.", (string[] args) =>
|
||||
{
|
||||
GameMain.NetLobbyScreen.ChangeServerMessage(string.Join(" ", args));
|
||||
GameMain.Server.ServerSettings.ServerMessageText = string.Join(" ", args);
|
||||
}));
|
||||
|
||||
commands.Add(new Command("seed|levelseed", "seed/levelseed: Changes the level seed for the next round.", (string[] args) =>
|
||||
|
||||
@@ -48,6 +48,7 @@ namespace Barotrauma
|
||||
spawnInfo[target].OriginalInventoryID,
|
||||
spawnInfo[target].OriginalItemContainerIndex,
|
||||
spawnInfo[target].OriginalSlotIndex);
|
||||
msg.WriteUInt16(target.ParentTarget?.Item?.ID ?? Entity.NullEntityID);
|
||||
}
|
||||
|
||||
msg.WriteByte((byte)spawnInfo[target].ExecutedEffectIndices.Count);
|
||||
|
||||
+20
-21
@@ -470,6 +470,11 @@ namespace Barotrauma
|
||||
return characterData.Find(cd => cd.MatchesClient(client));
|
||||
}
|
||||
|
||||
public CharacterCampaignData GetCharacterData(CharacterInfo characterInfo)
|
||||
{
|
||||
return characterData.Find(cd => cd.CharacterInfo == characterInfo);
|
||||
}
|
||||
|
||||
public CharacterCampaignData SetClientCharacterData(Client client)
|
||||
{
|
||||
characterData.RemoveAll(cd => cd.MatchesClient(client));
|
||||
@@ -970,7 +975,7 @@ namespace Barotrauma
|
||||
{
|
||||
int desiredQuantity = purchasedItem.Quantity;
|
||||
if (prevPurchasedItems.TryGetValue(storeId, out var alreadyPurchasedList) &&
|
||||
alreadyPurchasedList.FirstOrDefault(p => p.ItemPrefab == purchasedItem.ItemPrefab) is { } alreadyPurchased)
|
||||
alreadyPurchasedList.FirstOrDefault(p => p.ItemPrefab == purchasedItem.ItemPrefab && p.DeliverImmediately == purchasedItem.DeliverImmediately) is { } alreadyPurchased)
|
||||
{
|
||||
desiredQuantity -= alreadyPurchased.Quantity;
|
||||
}
|
||||
@@ -1198,14 +1203,13 @@ namespace Barotrauma
|
||||
if (fireCharacter) { firedIdentifier = msg.ReadInt32(); }
|
||||
|
||||
Location location = map?.CurrentLocation;
|
||||
List<CharacterInfo> hiredCharacters = new List<CharacterInfo>();
|
||||
CharacterInfo firedCharacter = null;
|
||||
|
||||
if (location != null && AllowedToManageCampaign(sender, ClientPermissions.ManageHires))
|
||||
{
|
||||
if (fireCharacter)
|
||||
{
|
||||
firedCharacter = CrewManager.CharacterInfos.FirstOrDefault(info => info.GetIdentifier() == firedIdentifier);
|
||||
firedCharacter = CrewManager.GetCharacterInfos().FirstOrDefault(info => info.GetIdentifier() == firedIdentifier);
|
||||
if (firedCharacter != null && (firedCharacter.Character?.IsBot ?? true))
|
||||
{
|
||||
CrewManager.FireCharacter(firedCharacter);
|
||||
@@ -1221,7 +1225,7 @@ namespace Barotrauma
|
||||
CharacterInfo characterInfo = null;
|
||||
if (existingCrewMember && CrewManager != null)
|
||||
{
|
||||
characterInfo = CrewManager.CharacterInfos.FirstOrDefault(info => info.GetIdentifierUsingOriginalName() == renamedIdentifier);
|
||||
characterInfo = CrewManager.GetCharacterInfos().FirstOrDefault(info => info.GetIdentifierUsingOriginalName() == renamedIdentifier);
|
||||
}
|
||||
else if(!existingCrewMember && location.HireManager != null)
|
||||
{
|
||||
@@ -1251,10 +1255,7 @@ namespace Barotrauma
|
||||
{
|
||||
foreach (CharacterInfo hireInfo in location.HireManager.PendingHires)
|
||||
{
|
||||
if (TryHireCharacter(location, hireInfo, sender.Character, sender))
|
||||
{
|
||||
hiredCharacters.Add(hireInfo);
|
||||
}
|
||||
TryHireCharacter(location, hireInfo, client: sender);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1271,7 +1272,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
pendingHireInfos.Add(match);
|
||||
if (pendingHireInfos.Count + CrewManager.CharacterInfos.Count() >= CrewManager.MaxCrewSize)
|
||||
if (pendingHireInfos.Count + CrewManager.GetCharacterInfos().Count() >= CrewManager.MaxCrewSize)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -1281,7 +1282,7 @@ namespace Barotrauma
|
||||
|
||||
location.HireManager.AvailableCharacters.ForEachMod(info =>
|
||||
{
|
||||
if(!location.HireManager.PendingHires.Contains(info))
|
||||
if (!location.HireManager.PendingHires.Contains(info))
|
||||
{
|
||||
location.HireManager.RenameCharacter(info, info.OriginalName);
|
||||
}
|
||||
@@ -1292,11 +1293,11 @@ namespace Barotrauma
|
||||
// bounce back
|
||||
if (renameCharacter && existingCrewMember)
|
||||
{
|
||||
SendCrewState(hiredCharacters, (renamedIdentifier, newName), firedCharacter);
|
||||
SendCrewState((renamedIdentifier, newName), firedCharacter);
|
||||
}
|
||||
else
|
||||
{
|
||||
SendCrewState(hiredCharacters, default, firedCharacter);
|
||||
SendCrewState(firedCharacter: firedCharacter);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1310,7 +1311,7 @@ namespace Barotrauma
|
||||
/// the client and the server when there's only one person on the server but when a second person joins both of
|
||||
/// their available hires are different from the server.
|
||||
/// </remarks>
|
||||
public void SendCrewState(List<CharacterInfo> hiredCharacters, (int id, string newName) renamedCrewMember, CharacterInfo firedCharacter)
|
||||
public void SendCrewState((int id, string newName) renamedCrewMember = default, CharacterInfo firedCharacter = null)
|
||||
{
|
||||
List<CharacterInfo> availableHires = new List<CharacterInfo>();
|
||||
List<CharacterInfo> pendingHires = new List<CharacterInfo>();
|
||||
@@ -1332,21 +1333,19 @@ namespace Barotrauma
|
||||
hire.ServerWrite(msg);
|
||||
msg.WriteInt32(hire.Salary);
|
||||
}
|
||||
|
||||
|
||||
msg.WriteUInt16((ushort)pendingHires.Count);
|
||||
foreach (CharacterInfo pendingHire in pendingHires)
|
||||
{
|
||||
msg.WriteInt32(pendingHire.GetIdentifierUsingOriginalName());
|
||||
}
|
||||
|
||||
msg.WriteUInt16((ushort)(hiredCharacters?.Count ?? 0));
|
||||
if(hiredCharacters != null)
|
||||
var hiredCharacters = CrewManager.GetCharacterInfos().Where(ci => ci.IsNewHire);
|
||||
msg.WriteUInt16((ushort)hiredCharacters.Count());
|
||||
foreach (CharacterInfo info in hiredCharacters)
|
||||
{
|
||||
foreach (CharacterInfo info in hiredCharacters)
|
||||
{
|
||||
info.ServerWrite(msg);
|
||||
msg.WriteInt32(info.Salary);
|
||||
}
|
||||
info.ServerWrite(msg);
|
||||
msg.WriteInt32(info.Salary);
|
||||
}
|
||||
|
||||
bool validRenaming = renamedCrewMember.id > -1 && !string.IsNullOrEmpty(renamedCrewMember.newName);
|
||||
|
||||
@@ -27,6 +27,9 @@ namespace Barotrauma.Items.Components
|
||||
//opening a partially stuck door makes it less stuck
|
||||
if (isOpen) { stuck = MathHelper.Clamp(stuck - StuckReductionOnOpen, 0.0f, 100.0f); }
|
||||
|
||||
ActionType actionType = open ? ActionType.OnOpen : ActionType.OnClose;
|
||||
item.ApplyStatusEffects(actionType, deltaTime: 1.0f);
|
||||
|
||||
if (sendNetworkMessage)
|
||||
{
|
||||
item.CreateServerEvent(this, new EventData(forcedOpen));
|
||||
|
||||
@@ -11,20 +11,20 @@ namespace Barotrauma.Items.Components
|
||||
if (!Snapped)
|
||||
{
|
||||
msg.WriteUInt16(target?.ID ?? Entity.NullEntityID);
|
||||
if (source is Entity entity && !entity.Removed)
|
||||
switch (source)
|
||||
{
|
||||
msg.WriteUInt16(entity?.ID ?? Entity.NullEntityID);
|
||||
msg.WriteByte((byte)0);
|
||||
}
|
||||
else if (source is Limb limb && limb.character != null && !limb.character.Removed)
|
||||
{
|
||||
msg.WriteUInt16(limb.character?.ID ?? Entity.NullEntityID);
|
||||
msg.WriteByte((byte)limb.character.AnimController.Limbs.IndexOf(limb));
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.WriteUInt16(Entity.NullEntityID);
|
||||
msg.WriteByte((byte)0);
|
||||
case Entity { Removed: false } entity:
|
||||
msg.WriteUInt16(entity.ID);
|
||||
msg.WriteByte((byte)0);
|
||||
break;
|
||||
case Limb { character.Removed: false } limb:
|
||||
msg.WriteUInt16(limb.character.ID);
|
||||
msg.WriteByte((byte)limb.character.AnimController.Limbs.IndexOf(limb));
|
||||
break;
|
||||
default:
|
||||
msg.WriteUInt16(Entity.NullEntityID);
|
||||
msg.WriteByte((byte)0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ namespace Barotrauma.Items.Components
|
||||
return (msg, deliveryMethod);
|
||||
}
|
||||
|
||||
public void CreateServerEvent(INetSerializableStruct data)
|
||||
public void CreateServerEvent(INetSerializableStruct data)
|
||||
=> item.CreateServerEvent(this, new CircuitBoxEventData(data));
|
||||
|
||||
public void ServerEventWrite(IWriteMessage msg, Client c, NetEntityEvent.IData? extraData = null)
|
||||
@@ -120,7 +120,7 @@ namespace Barotrauma.Items.Components
|
||||
case CircuitBoxOpcode.AddComponent:
|
||||
{
|
||||
var data = INetSerializableStruct.Read<CircuitBoxAddComponentEvent>(msg);
|
||||
if (!item.CanClientAccess(c)) { break; }
|
||||
if (!CanAccessAndUnlocked(c)) { break; }
|
||||
|
||||
var prefab = ItemPrefab.Prefabs.Find(p => p.UintIdentifier == data.PrefabIdentifier);
|
||||
if (prefab is null)
|
||||
@@ -158,14 +158,14 @@ namespace Barotrauma.Items.Components
|
||||
var data = INetSerializableStruct.Read<CircuitBoxMoveComponentEvent>(msg);
|
||||
if (!item.CanClientAccess(c)) { break; }
|
||||
|
||||
MoveNodesInternal(data.TargetIDs, data.IOs, data.MoveAmount);
|
||||
MoveNodesInternal(data.TargetIDs, data.IOs, data.LabelIDs, data.MoveAmount);
|
||||
CreateServerEvent(data);
|
||||
break;
|
||||
}
|
||||
case CircuitBoxOpcode.DeleteComponent:
|
||||
{
|
||||
var data = INetSerializableStruct.Read<CircuitBoxRemoveComponentEvent>(msg);
|
||||
if (!data.TargetIDs.Any() || !item.CanClientAccess(c)) { break; }
|
||||
if (!data.TargetIDs.Any() || !CanAccessAndUnlocked(c)) { break; }
|
||||
|
||||
CreateRefundItemsForUsedResources(data.TargetIDs, c.Character);
|
||||
GameServer.Log($"{NetworkMember.ClientLogName(c)} removed {GetLogComponentName(data.TargetIDs)} from circuit box.", ServerLog.MessageType.Wiring);
|
||||
@@ -180,6 +180,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
SelectComponentsInternal(data.TargetIDs, c.CharacterID, data.Overwrite);
|
||||
SelectInputOutputInternal(data.IOs, c.CharacterID, data.Overwrite);
|
||||
SelectLabelsInternal(data.LabelIDs, c.CharacterID, data.Overwrite);
|
||||
BroadcastSelectionStatus();
|
||||
break;
|
||||
}
|
||||
@@ -195,7 +196,7 @@ namespace Barotrauma.Items.Components
|
||||
case CircuitBoxOpcode.AddWire:
|
||||
{
|
||||
var data = INetSerializableStruct.Read<CircuitBoxClientAddWireEvent>(msg);
|
||||
if (!item.CanClientAccess(c)) { break; }
|
||||
if (!CanAccessAndUnlocked(c)) { break; }
|
||||
|
||||
var prefab = ItemPrefab.Prefabs.Find(p => p.UintIdentifier == data.SelectedWirePrefabIdentifier);
|
||||
if (prefab is null)
|
||||
@@ -229,13 +230,56 @@ namespace Barotrauma.Items.Components
|
||||
case CircuitBoxOpcode.RemoveWire:
|
||||
{
|
||||
var data = INetSerializableStruct.Read<CircuitBoxRemoveWireEvent>(msg);
|
||||
if (!data.TargetIDs.Any() || !item.CanClientAccess(c)) { break; }
|
||||
if (!data.TargetIDs.Any() || !CanAccessAndUnlocked(c)) { break; }
|
||||
|
||||
GameServer.Log($"{NetworkMember.ClientLogName(c)} removed {GetLogWireName(data.TargetIDs)} from circuit box.", ServerLog.MessageType.Wiring);
|
||||
RemoveWireInternal(data.TargetIDs);
|
||||
CreateServerEvent(data);
|
||||
break;
|
||||
}
|
||||
case CircuitBoxOpcode.RenameLabel:
|
||||
{
|
||||
var data = INetSerializableStruct.Read<CircuitBoxRenameLabelEvent>(msg);
|
||||
if (!CanAccessAndUnlocked(c)) { break; }
|
||||
|
||||
RenameLabelInternal(data.LabelId, data.Color, data.NewHeader, data.NewBody);
|
||||
CreateServerEvent(data);
|
||||
break;
|
||||
}
|
||||
case CircuitBoxOpcode.AddLabel:
|
||||
{
|
||||
var data = INetSerializableStruct.Read<CircuitBoxAddLabelEvent>(msg);
|
||||
if (!CanAccessAndUnlocked(c)) { break; }
|
||||
|
||||
ushort id = ICircuitBoxIdentifiable.FindFreeID(Labels);
|
||||
if (id is ICircuitBoxIdentifiable.NullComponentID)
|
||||
{
|
||||
ThrowError("Unable to add label because there are no available IDs left.", c);
|
||||
return;
|
||||
}
|
||||
|
||||
AddLabelInternal(id, data.Color, data.Position, data.Header, data.Body);
|
||||
CreateServerEvent(new CircuitBoxServerAddLabelEvent(id, data.Position, new Vector2(256), data.Color, data.Header, data.Body));
|
||||
break;
|
||||
}
|
||||
case CircuitBoxOpcode.RemoveLabel:
|
||||
{
|
||||
var data = INetSerializableStruct.Read<CircuitBoxRemoveLabelEvent>(msg);
|
||||
if (!CanAccessAndUnlocked(c)) { break; }
|
||||
|
||||
RemoveLabelInternal(data.TargetIDs);
|
||||
CreateServerEvent(data);
|
||||
break;
|
||||
}
|
||||
case CircuitBoxOpcode.ResizeLabel:
|
||||
{
|
||||
var data = INetSerializableStruct.Read<CircuitBoxResizeLabelEvent>(msg);
|
||||
if (!CanAccessAndUnlocked(c)) { break; }
|
||||
|
||||
ResizeLabelInternal(data.ID, data.Position, data.Size);
|
||||
CreateServerEvent(data with { Size = Vector2.Max(data.Size, CircuitBoxLabelNode.MinSize) });
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(header), header, "This opcode cannot be handled using entity events");
|
||||
}
|
||||
@@ -253,6 +297,8 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
return wire.BackingWire.TryUnwrap(out var backingWire) ? backingWire.Name : "a wire";
|
||||
}
|
||||
|
||||
bool CanAccessAndUnlocked(Client client) => item.CanClientAccess(client) && !Locked;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -280,6 +326,7 @@ namespace Barotrauma.Items.Components
|
||||
CircuitBoxInitializeStateFromServerEvent data = new(
|
||||
Components: Components.Select(EventFromComponent).ToImmutableArray(),
|
||||
Wires: Wires.Select(EventFromWire).ToImmutableArray(),
|
||||
Labels: Labels.Select(EventFromLabel).ToImmutableArray(),
|
||||
InputPos: inputPos,
|
||||
OutputPos: outputPos);
|
||||
|
||||
@@ -297,6 +344,9 @@ namespace Barotrauma.Items.Components
|
||||
var request = new CircuitBoxClientAddWireEvent(wire.Color, from, to, wire.UsedItemPrefab.UintIdentifier);
|
||||
return new CircuitBoxServerCreateWireEvent(request, wire.ID, backingWire);
|
||||
}
|
||||
|
||||
static CircuitBoxServerAddLabelEvent EventFromLabel(CircuitBoxLabelNode label)
|
||||
=> new(label.ID, label.Position, label.Size, label.Color, label.HeaderText, label.BodyText);
|
||||
}
|
||||
|
||||
// we don't care about updating the view on server
|
||||
@@ -314,8 +364,9 @@ namespace Barotrauma.Items.Components
|
||||
var nodes = Components.Select(static c => new CircuitBoxIdSelectionPair(c.ID, c.IsSelected ? Option.Some(c.SelectedBy) : Option.None)).ToImmutableArray();
|
||||
var wires = Wires.Select(static w => new CircuitBoxIdSelectionPair(w.ID, w.IsSelected ? Option.Some(w.SelectedBy) : Option.None)).ToImmutableArray();
|
||||
var ios = InputOutputNodes.Select(static n => new CircuitBoxTypeSelectionPair(n.NodeType, n.IsSelected ? Option.Some(n.SelectedBy) : Option.None)).ToImmutableArray();
|
||||
var labels = Labels.Select(static n => new CircuitBoxIdSelectionPair(n.ID, n.IsSelected ? Option.Some(n.SelectedBy) : Option.None)).ToImmutableArray();
|
||||
|
||||
CreateServerEvent(new CircuitBoxServerUpdateSelection(nodes, wires, ios));
|
||||
CreateServerEvent(new CircuitBoxServerUpdateSelection(nodes, wires, ios, labels));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,8 +13,6 @@ namespace Barotrauma
|
||||
|
||||
public void ServerEventRead(IReadMessage msg, Client c)
|
||||
{
|
||||
List<Item> prevItems = new List<Item>(AllItems.Distinct());
|
||||
|
||||
if (!receivedItemIds.TryGetValue(c, out List<ushort>[] receivedItemIdsFromClient))
|
||||
{
|
||||
receivedItemIdsFromClient = new List<ushort>[capacity];
|
||||
@@ -60,8 +58,21 @@ namespace Barotrauma
|
||||
return;
|
||||
}
|
||||
|
||||
List<Inventory> prevItemInventories = new List<Inventory>() { this };
|
||||
//we need to check which of the items the client can access at this point, before we start shuffling things around
|
||||
//otherwise if you're e.g. holding an item to access a cabinet, and picking up an item from the cabinet unequips the item you're holding,
|
||||
//you would fail to pick up the item because it gets unequipped before checking whether you can access the cabinet.
|
||||
Dictionary<Item, bool> canAccessItem = new Dictionary<Item, bool>();
|
||||
for (int i = 0; i < capacity; i++)
|
||||
{
|
||||
foreach (ushort id in receivedItemIdsFromClient[i])
|
||||
{
|
||||
if (Entity.FindEntityByID(id) is not Item item) { continue; }
|
||||
canAccessItem[item] = item.CanClientAccess(c);
|
||||
}
|
||||
}
|
||||
|
||||
List<Item> prevItems = new List<Item>(AllItems.Distinct());
|
||||
List<Inventory> prevItemInventories = new List<Inventory>() { this };
|
||||
for (int i = 0; i < capacity; i++)
|
||||
{
|
||||
foreach (Item item in slots[i].Items.ToList())
|
||||
@@ -119,7 +130,7 @@ namespace Barotrauma
|
||||
var holdable = item.GetComponent<Holdable>();
|
||||
if (holdable != null && !holdable.CanBeDeattached()) { continue; }
|
||||
|
||||
if (!prevItems.Contains(item) && !item.CanClientAccess(c) &&
|
||||
if (!prevItems.Contains(item) && !canAccessItem[item] &&
|
||||
(c.Character == null || item.PreviousParentInventory == null || !c.Character.CanAccessInventory(item.PreviousParentInventory)))
|
||||
{
|
||||
#if DEBUG || UNSTABLE
|
||||
|
||||
@@ -1,10 +1,22 @@
|
||||
using System;
|
||||
using Barotrauma.Networking;
|
||||
using Barotrauma.Networking;
|
||||
using System;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class Submarine
|
||||
{
|
||||
public readonly struct SetLayerEnabledEventData : NetEntityEvent.IData
|
||||
{
|
||||
public readonly Identifier Layer;
|
||||
public readonly bool Enabled;
|
||||
|
||||
public SetLayerEnabledEventData(Identifier layer, bool enabled)
|
||||
{
|
||||
Layer = layer;
|
||||
Enabled = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
public void ServerWritePosition(ReadWriteMessage tempBuffer, Client c)
|
||||
{
|
||||
subBody.Body.ServerWrite(tempBuffer);
|
||||
@@ -12,7 +24,15 @@ namespace Barotrauma
|
||||
|
||||
public void ServerEventWrite(IWriteMessage msg, Client c, NetEntityEvent.IData extraData = null)
|
||||
{
|
||||
throw new Exception($"Error while writing a network event for the submarine \"{Info.Name} ({ID})\". Submarines are not even supposed to send events!");
|
||||
if (extraData is SetLayerEnabledEventData setLayerEnabledEventData)
|
||||
{
|
||||
msg.WriteIdentifier(setLayerEnabledEventData.Layer);
|
||||
msg.WriteBoolean(setLayerEnabledEventData.Enabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"Error while writing a network event for the submarine \"{Info.Name} ({ID})\". Unrecognized event data: {extraData?.GetType().Name ?? "null"}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,7 +349,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
UInt32 id = incMsg.ReadUInt32();
|
||||
BannedPlayer? bannedPlayer = bannedPlayers.Find(p => p.UniqueIdentifier == id);
|
||||
if (bannedPlayer != null)
|
||||
if (bannedPlayer != null && c.HasPermission(ClientPermissions.Unban))
|
||||
{
|
||||
GameServer.Log(GameServer.ClientLogName(c) + " unbanned " + bannedPlayer.Name + " (" + bannedPlayer.AddressOrAccountId + ")", ServerLog.MessageType.ConsoleUsage);
|
||||
RemoveBan(bannedPlayer);
|
||||
|
||||
@@ -282,15 +282,19 @@ namespace Barotrauma.Networking
|
||||
SendConsoleMessage("Granted all permissions to " + newClient.Name + ".", newClient);
|
||||
}
|
||||
|
||||
SendChatMessage($"ServerMessage.JoinedServer~[client]={ClientLogName(newClient)}", ChatMessageType.Server, null, changeType: PlayerConnectionChangeType.Joined);
|
||||
SendChatMessage($"ServerMessage.JoinedServer~[client]={ClientLogName(newClient)}", ChatMessageType.Server, changeType: PlayerConnectionChangeType.Joined);
|
||||
ServerSettings.ServerDetailsChanged = true;
|
||||
|
||||
if (previousPlayer != null && previousPlayer.Name != newClient.Name)
|
||||
{
|
||||
string prevNameSanitized = previousPlayer.Name.Replace("‖", "");
|
||||
SendChatMessage($"ServerMessage.PreviousClientName~[client]={ClientLogName(newClient)}~[previousname]={prevNameSanitized}", ChatMessageType.Server, null);
|
||||
SendChatMessage($"ServerMessage.PreviousClientName~[client]={ClientLogName(newClient)}~[previousname]={prevNameSanitized}", ChatMessageType.Server);
|
||||
previousPlayer.Name = newClient.Name;
|
||||
}
|
||||
if (!ServerSettings.ServerMessageText.IsNullOrEmpty())
|
||||
{
|
||||
SendDirectChatMessage((TextManager.Get("servermotd") + '\n' + ServerSettings.ServerMessageText).Value, newClient, ChatMessageType.Server);
|
||||
}
|
||||
|
||||
var savedPermissions = ServerSettings.ClientPermissions.Find(scp =>
|
||||
scp.AddressOrAccountId.TryGet(out AccountId accountId)
|
||||
@@ -434,12 +438,12 @@ namespace Barotrauma.Networking
|
||||
endRoundDelay = 5.0f;
|
||||
endRoundTimer += deltaTime;
|
||||
}
|
||||
else if (subAtLevelEnd && !(GameMain.GameSession?.GameMode is CampaignMode))
|
||||
else if (subAtLevelEnd && GameMain.GameSession?.GameMode is not CampaignMode)
|
||||
{
|
||||
endRoundDelay = 5.0f;
|
||||
endRoundTimer += deltaTime;
|
||||
}
|
||||
else if (isCrewDead && RespawnManager == null)
|
||||
else if (isCrewDead && (RespawnManager == null || !RespawnManager.CanRespawnAgain))
|
||||
{
|
||||
#if !DEBUG
|
||||
if (endRoundTimer <= 0.0f)
|
||||
@@ -1136,6 +1140,10 @@ namespace Barotrauma.Networking
|
||||
//check if midround syncing is needed due to missed unique events
|
||||
if (!midroundSyncingDone) { entityEventManager.InitClientMidRoundSync(c); }
|
||||
MissionAction.NotifyMissionsUnlockedThisRound(c);
|
||||
if (GameMain.GameSession.Campaign is MultiPlayerCampaign mpCampaign)
|
||||
{
|
||||
mpCampaign.SendCrewState();
|
||||
}
|
||||
c.InGame = true;
|
||||
}
|
||||
}
|
||||
@@ -2322,7 +2330,7 @@ namespace Barotrauma.Networking
|
||||
if (campaign != null)
|
||||
{
|
||||
campaign.CargoManager.CreatePurchasedItems();
|
||||
campaign.SendCrewState(null, default, null);
|
||||
campaign.SendCrewState();
|
||||
}
|
||||
|
||||
Level.Loaded?.SpawnNPCs();
|
||||
@@ -2792,8 +2800,6 @@ namespace Barotrauma.Networking
|
||||
logMsg = message.TextWithSender;
|
||||
}
|
||||
Log(logMsg, ServerLog.MessageType.Chat);
|
||||
|
||||
base.AddChatMessage(message);
|
||||
}
|
||||
|
||||
private bool ReadClientNameChange(Client c, IReadMessage inc)
|
||||
|
||||
+18
-4
@@ -78,6 +78,11 @@ namespace Barotrauma.Networking
|
||||
|
||||
public bool IsProcessed;
|
||||
|
||||
/// <summary>
|
||||
/// Does the client need to be controlling a character for the server to consider the event valid?
|
||||
/// </summary>
|
||||
public bool RequireCharacter = true;
|
||||
|
||||
public BufferedEvent(Client sender, Character senderCharacter, UInt16 characterStateID, IClientSerializable targetEntity, ReadWriteMessage data)
|
||||
{
|
||||
this.Sender = sender;
|
||||
@@ -157,15 +162,19 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
if (bufferedEvent.Character == null || bufferedEvent.Character.IsDead)
|
||||
{
|
||||
bufferedEvent.IsProcessed = true;
|
||||
continue;
|
||||
if (bufferedEvent.RequireCharacter)
|
||||
{
|
||||
bufferedEvent.IsProcessed = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
//delay reading the events until the inputs for the corresponding frame have been processed
|
||||
|
||||
//UNLESS the character is unconscious, in which case we'll read the messages immediately (because further inputs will be ignored)
|
||||
//atm the "give in" command is the only thing unconscious characters can do, other types of events are ignored
|
||||
if (!bufferedEvent.Character.IsIncapacitated &&
|
||||
if (bufferedEvent.Character != null &&
|
||||
!bufferedEvent.Character.IsIncapacitated &&
|
||||
NetIdUtils.IdMoreRecent(bufferedEvent.CharacterStateID, bufferedEvent.Character.LastProcessedID))
|
||||
{
|
||||
DebugConsole.Log($"Delaying reading entity event sent by a client until the character state has been processed. Event's character state: {bufferedEvent.CharacterStateID}, last processed character state: {bufferedEvent.Character.LastProcessedID}");
|
||||
@@ -503,7 +512,12 @@ namespace Barotrauma.Networking
|
||||
byte[] temp = msg.ReadBytes(msgLength - 2);
|
||||
buffer.WriteBytes(temp, 0, msgLength - 2);
|
||||
buffer.BitPosition = 0;
|
||||
BufferEvent(new BufferedEvent(sender, sender.Character, characterStateID, entity, buffer));
|
||||
BufferEvent(
|
||||
new BufferedEvent(sender, sender.Character, characterStateID, entity, buffer)
|
||||
{
|
||||
//hull updates can be sent without a character to allow editing water and fire in spectator mode
|
||||
RequireCharacter = entity is not Hull
|
||||
});
|
||||
|
||||
sender.LastSentEntityEventID++;
|
||||
}
|
||||
|
||||
+2
-1
@@ -272,7 +272,8 @@ namespace Barotrauma.Networking
|
||||
ServerName = GameMain.Server.ServerName,
|
||||
ContentPackages = contentPackages
|
||||
.Select(contentPackage => new ServerContentPackage(contentPackage, timeNow))
|
||||
.ToImmutableArray()
|
||||
.ToImmutableArray(),
|
||||
AllowModDownloads = serverSettings.AllowModDownloads
|
||||
};
|
||||
|
||||
break;
|
||||
|
||||
@@ -323,8 +323,8 @@ namespace Barotrauma.Networking
|
||||
var clients = GetClientsToRespawn().ToList();
|
||||
foreach (Client c in clients)
|
||||
{
|
||||
//get rid of the existing character
|
||||
c.Character?.DespawnNow();
|
||||
// Get rid of the existing character
|
||||
if (c.Character is Character character) { character.DespawnNow(); }
|
||||
|
||||
c.WaitForNextRoundRespawn = null;
|
||||
|
||||
@@ -369,12 +369,9 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
divingSuitPrefab = ItemPrefab.Prefabs.FirstOrDefault(it => it.Tags.Any(t => t == "respawnsuitdeep"));
|
||||
}
|
||||
if (divingSuitPrefab == null)
|
||||
{
|
||||
divingSuitPrefab =
|
||||
divingSuitPrefab ??=
|
||||
ItemPrefab.Prefabs.FirstOrDefault(it => it.Tags.Any(t => t == "respawnsuit")) ??
|
||||
ItemPrefab.Find(null, "divingsuit".ToIdentifier());
|
||||
}
|
||||
ItemPrefab oxyPrefab = ItemPrefab.Find(null, "oxygentank".ToIdentifier());
|
||||
ItemPrefab scooterPrefab = ItemPrefab.Find(null, "underwaterscooter".ToIdentifier());
|
||||
ItemPrefab batteryPrefab = ItemPrefab.Find(null, "batterycell".ToIdentifier());
|
||||
@@ -387,6 +384,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
characterInfos[i].ClearCurrentOrders();
|
||||
|
||||
CharacterCampaignData characterCampaignData = null;
|
||||
bool forceSpawnInMainSub = false;
|
||||
if (!bot)
|
||||
{
|
||||
@@ -398,16 +396,16 @@ namespace Barotrauma.Networking
|
||||
clients[i].PendingName = null;
|
||||
}
|
||||
|
||||
var matchingData = campaign?.GetClientCharacterData(clients[i]);
|
||||
if (matchingData != null)
|
||||
characterCampaignData = campaign?.GetClientCharacterData(clients[i]);
|
||||
if (characterCampaignData != null)
|
||||
{
|
||||
if (!matchingData.HasSpawned)
|
||||
if (!characterCampaignData.HasSpawned)
|
||||
{
|
||||
forceSpawnInMainSub = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ReduceCharacterSkills(characterInfos[i]);
|
||||
ReduceCharacterSkillsOnDeath(characterInfos[i]);
|
||||
characterInfos[i].RemoveSavedStatValuesOnDeath();
|
||||
characterInfos[i].CauseOfDeath = null;
|
||||
}
|
||||
@@ -415,6 +413,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
var character = Character.Create(characterInfos[i], (forceSpawnInMainSub ? mainSubSpawnPoints[i] : shuttleSpawnPoints[i]).WorldPosition, characterInfos[i].Name, isRemotePlayer: !bot, hasAi: bot);
|
||||
characterCampaignData?.ApplyWalletData(character);
|
||||
character.TeamID = CharacterTeamType.Team1;
|
||||
character.LoadTalents();
|
||||
|
||||
@@ -505,11 +504,10 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
var characterData = campaign?.GetClientCharacterData(clients[i]);
|
||||
// NOTE: This was where Reaper's tax got applied
|
||||
if (characterData != null && Level.Loaded?.Type != LevelData.LevelType.Outpost && characterData.HasSpawned)
|
||||
{
|
||||
//we need to reapply the previous respawn penalty affliction or successive deaths won't make it stack
|
||||
characterData.ApplyHealthData(character, (AfflictionPrefab ap) => ap == GetRespawnPenaltyAfflictionPrefab());
|
||||
GiveRespawnPenaltyAffliction(character);
|
||||
ReduceCharacterSkillsOnDeath(characterInfos[i], applyExtraSkillLoss: true);
|
||||
}
|
||||
if (characterData == null || characterData.HasSpawned)
|
||||
{
|
||||
@@ -541,14 +539,37 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
public static void ReduceCharacterSkills(CharacterInfo characterInfo)
|
||||
/// <summary>
|
||||
/// Reduce any skill gains the character may have made over the job's default
|
||||
/// skill levels by percentages defined in server settings. There are two
|
||||
/// reductions, a base one that always applies, and an extra loss that only
|
||||
/// applies when the player chooses to respawn ASAP rather than wait.
|
||||
/// </summary>
|
||||
public static void ReduceCharacterSkillsOnDeath(CharacterInfo characterInfo, bool applyExtraSkillLoss = false)
|
||||
{
|
||||
if (characterInfo?.Job == null) { return; }
|
||||
|
||||
float resistanceMultiplier;
|
||||
float skillLossPercentage;
|
||||
if (applyExtraSkillLoss)
|
||||
{
|
||||
DebugConsole.Log($"Calculating extra skill loss on respawn for {characterInfo.Name}:");
|
||||
resistanceMultiplier = characterInfo.LastResistanceMultiplierSkillLossRespawn;
|
||||
skillLossPercentage = SkillLossPercentageOnImmediateRespawn;
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.Log($"Calculating base skill loss on death for {characterInfo.Name}:");
|
||||
resistanceMultiplier = characterInfo.LastResistanceMultiplierSkillLossDeath;
|
||||
skillLossPercentage = SkillLossPercentageOnDeath;
|
||||
}
|
||||
skillLossPercentage *= resistanceMultiplier;
|
||||
|
||||
foreach (Skill skill in characterInfo.Job.GetSkills())
|
||||
{
|
||||
var skillPrefab = characterInfo.Job.Prefab.Skills.Find(s => skill.Identifier == s.Identifier);
|
||||
if (skillPrefab == null || skill.Level < skillPrefab.LevelRange.End) { continue; }
|
||||
skill.Level = MathHelper.Lerp(skill.Level, skillPrefab.LevelRange.End, SkillLossPercentageOnDeath / 100.0f);
|
||||
skill.Level = MathHelper.Lerp(skill.Level, skillPrefab.LevelRange.End, skillLossPercentage / 100.0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -95,15 +95,6 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
NetFlags requiredFlags = GetRequiredFlags(c);
|
||||
outMsg.WriteByte((byte)requiredFlags);
|
||||
if (requiredFlags.HasFlag(NetFlags.Name))
|
||||
{
|
||||
outMsg.WriteString(ServerName);
|
||||
}
|
||||
|
||||
if (requiredFlags.HasFlag(NetFlags.Message))
|
||||
{
|
||||
outMsg.WriteString(ServerMessageText);
|
||||
}
|
||||
outMsg.WriteByte((byte)PlayStyle);
|
||||
outMsg.WriteByte((byte)MaxPlayers);
|
||||
outMsg.WriteBoolean(HasPassword);
|
||||
@@ -122,8 +113,7 @@ namespace Barotrauma.Networking
|
||||
WriteHiddenSubs(outMsg);
|
||||
}
|
||||
|
||||
if (c.HasPermission(Networking.ClientPermissions.ManageSettings)
|
||||
&& NetIdUtils.IdMoreRecent(
|
||||
if (NetIdUtils.IdMoreRecent(
|
||||
newID: LastUpdateIdForFlag[NetFlags.Properties],
|
||||
oldID: c.LastRecvServerSettingsUpdate))
|
||||
{
|
||||
@@ -147,20 +137,6 @@ namespace Barotrauma.Networking
|
||||
|
||||
bool changed = false;
|
||||
|
||||
if (flags.HasFlag(NetFlags.Name))
|
||||
{
|
||||
string serverName = incMsg.ReadString();
|
||||
if (ServerName != serverName) { changed = true; }
|
||||
ServerName = serverName;
|
||||
}
|
||||
|
||||
if (flags.HasFlag(NetFlags.Message))
|
||||
{
|
||||
string serverMessageText = incMsg.ReadString();
|
||||
if (ServerMessageText != serverMessageText) { changed = true; }
|
||||
ServerMessageText = serverMessageText;
|
||||
}
|
||||
|
||||
if (flags.HasFlag(NetFlags.Properties))
|
||||
{
|
||||
bool propertiesChanged = ReadExtraCargo(incMsg);
|
||||
@@ -217,42 +193,9 @@ namespace Barotrauma.Networking
|
||||
int andBits = incMsg.ReadRangedInteger(0, (int)Barotrauma.MissionType.All) & (int)Barotrauma.MissionType.All;
|
||||
GameMain.NetLobbyScreen.MissionType = (MissionType)(((int)GameMain.NetLobbyScreen.MissionType | orBits) & andBits);
|
||||
|
||||
bool changedTraitorProbability = incMsg.ReadBoolean();
|
||||
float traitorProbability = incMsg.ReadSingle();
|
||||
if (changedTraitorProbability)
|
||||
{
|
||||
TraitorProbability = traitorProbability;
|
||||
}
|
||||
//the byte indicates the direction we're changing the value, subtract one to get negative values from a byte
|
||||
TraitorDangerLevel = TraitorDangerLevel + incMsg.ReadByte() - 1;
|
||||
|
||||
int botCount = BotCount + incMsg.ReadByte() - 1;
|
||||
if (botCount < 0) { botCount = MaxBotCount; }
|
||||
if (botCount > MaxBotCount) { botCount = 0; }
|
||||
BotCount = botCount;
|
||||
|
||||
int botSpawnMode = (int)BotSpawnMode + incMsg.ReadByte() - 1;
|
||||
if (botSpawnMode < 0) { botSpawnMode = 1; }
|
||||
if (botSpawnMode > 1) { botSpawnMode = 0; }
|
||||
BotSpawnMode = (BotSpawnMode)botSpawnMode;
|
||||
|
||||
float levelDifficulty = incMsg.ReadSingle();
|
||||
if (levelDifficulty >= 0.0f) { SelectedLevelDifficulty = levelDifficulty; }
|
||||
|
||||
bool changedUseRespawnShuttle = incMsg.ReadBoolean();
|
||||
bool useRespawnShuttle = incMsg.ReadBoolean();
|
||||
if (changedUseRespawnShuttle)
|
||||
{
|
||||
UseRespawnShuttle = useRespawnShuttle;
|
||||
}
|
||||
|
||||
bool changedAutoRestart = incMsg.ReadBoolean();
|
||||
bool autoRestart = incMsg.ReadBoolean();
|
||||
if (changedAutoRestart)
|
||||
{
|
||||
AutoRestart = autoRestart;
|
||||
}
|
||||
|
||||
changed |= true;
|
||||
UpdateFlag(NetFlags.Misc);
|
||||
}
|
||||
@@ -292,8 +235,6 @@ namespace Barotrauma.Networking
|
||||
doc.Root.SetAttributeValue("enableupnp", EnableUPnP);
|
||||
doc.Root.SetAttributeValue("autorestart", autoRestart);
|
||||
|
||||
doc.Root.SetAttributeValue("LevelDifficulty", ((int)selectedLevelDifficulty).ToString());
|
||||
|
||||
doc.Root.SetAttributeValue("ServerMessage", ServerMessageText);
|
||||
|
||||
doc.Root.SetAttributeValue("HiddenSubs", string.Join(",", HiddenSubs));
|
||||
@@ -304,6 +245,8 @@ namespace Barotrauma.Networking
|
||||
SerializableProperty.SerializeProperties(this, doc.Root, true);
|
||||
doc.Root.Add(CampaignSettings.Save());
|
||||
|
||||
doc.Root.SetAttributeValue("DisabledMonsters", string.Join(",", MonsterEnabled.Where(kvp => !kvp.Value).Select(kvp => kvp.Key.Value)));
|
||||
|
||||
System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings
|
||||
{
|
||||
Indent = true,
|
||||
@@ -351,9 +294,6 @@ namespace Barotrauma.Networking
|
||||
AllowSubVoting = SubSelectionMode == SelectionMode.Vote;
|
||||
AllowModeVoting = ModeSelectionMode == SelectionMode.Vote;
|
||||
|
||||
selectedLevelDifficulty = doc.Root.GetAttributeFloat("LevelDifficulty", 20.0f);
|
||||
GameMain.NetLobbyScreen.SetLevelDifficulty(selectedLevelDifficulty);
|
||||
|
||||
GameMain.NetLobbyScreen.SetTraitorProbability(traitorProbability);
|
||||
|
||||
HiddenSubs.UnionWith(doc.Root.GetAttributeStringArray("HiddenSubs", Array.Empty<string>()));
|
||||
@@ -448,6 +388,14 @@ namespace Barotrauma.Networking
|
||||
GameMain.NetLobbyScreen.SetBotCount(BotCount);
|
||||
|
||||
MonsterEnabled ??= CharacterPrefab.Prefabs.Select(p => (p.Identifier, true)).ToDictionary();
|
||||
var disabledMonsters = doc.Root.GetAttributeIdentifierArray("DisabledMonsters", Array.Empty<Identifier>());
|
||||
foreach (var disabledMonster in disabledMonsters)
|
||||
{
|
||||
if (MonsterEnabled.ContainsKey(disabledMonster))
|
||||
{
|
||||
MonsterEnabled[disabledMonster] = false;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (XElement element in doc.Root.Elements())
|
||||
{
|
||||
|
||||
@@ -112,13 +112,13 @@ namespace Barotrauma.Networking
|
||||
if (recipientSpectating)
|
||||
{
|
||||
if (recipient.SpectatePos == null) { return true; }
|
||||
distanceFactor = MathHelper.Clamp(Vector2.Distance(sender.Character.WorldPosition, recipient.SpectatePos.Value) / ChatMessage.SpeakRange, 0.0f, 1.0f);
|
||||
distanceFactor = MathHelper.Clamp(Vector2.Distance(sender.Character.WorldPosition, recipient.SpectatePos.Value) / ChatMessage.SpeakRangeVOIP, 0.0f, 1.0f);
|
||||
return distanceFactor < 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
//otherwise do a distance check
|
||||
float garbleAmount = ChatMessage.GetGarbleAmount(recipient.Character, sender.Character, ChatMessage.SpeakRange);
|
||||
float garbleAmount = ChatMessage.GetGarbleAmount(recipient.Character, sender.Character, ChatMessage.SpeakRangeVOIP);
|
||||
distanceFactor = garbleAmount;
|
||||
return garbleAmount < 1.0f;
|
||||
}
|
||||
|
||||
@@ -106,24 +106,6 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public void ChangeServerName(string n)
|
||||
{
|
||||
GameMain.Server.ServerSettings.ServerName = n; lastUpdateID++;
|
||||
}
|
||||
|
||||
public void ChangeServerMessage(string m)
|
||||
{
|
||||
GameMain.Server.ServerSettings.ServerMessageText = m; lastUpdateID++;
|
||||
}
|
||||
|
||||
public List<JobPrefab> JobPreferences
|
||||
{
|
||||
get
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public NetLobbyScreen()
|
||||
{
|
||||
LevelSeed = ToolBox.RandomSeed(8);
|
||||
@@ -170,7 +152,7 @@ namespace Barotrauma
|
||||
}
|
||||
set
|
||||
{
|
||||
if (levelSeed == value) return;
|
||||
if (levelSeed == value) { return; }
|
||||
|
||||
lastUpdateID++;
|
||||
levelSeed = value;
|
||||
@@ -200,6 +182,12 @@ namespace Barotrauma
|
||||
{
|
||||
GameMain.GameSession = null;
|
||||
}
|
||||
if (GameMain.Server.ServerSettings.SelectedSubmarine.IsNullOrEmpty())
|
||||
{
|
||||
//if no sub is selected in the settings,
|
||||
//select the random sub we selected in the constructor
|
||||
GameMain.Server.ServerSettings.SelectedSubmarine = SelectedSub?.Name;
|
||||
}
|
||||
}
|
||||
|
||||
public void RandomizeSettings()
|
||||
|
||||
@@ -334,7 +334,7 @@ namespace Barotrauma
|
||||
|
||||
private void CreateTraitorEvent(EventManager eventManager, TraitorEventPrefab selectedPrefab, Client traitor)
|
||||
{
|
||||
if (selectedPrefab.TryCreateInstance<TraitorEvent>(out var newEvent))
|
||||
if (selectedPrefab.TryCreateInstance<TraitorEvent>(eventManager.RandomSeed, out var newEvent))
|
||||
{
|
||||
var secondaryTraitors = SelectSecondaryTraitors(newEvent, traitor);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user