Release 1.9.7.0 - Summer Update 2025
This commit is contained in:
@@ -673,6 +673,7 @@ namespace Barotrauma
|
||||
{
|
||||
msg.WriteUInt32(CauseOfDeath.Affliction.UintIdentifier);
|
||||
}
|
||||
msg.WriteUInt16(CauseOfDeath.Killer?.ID ?? NullEntityID);
|
||||
msg.WriteBoolean(forceAfflictionData);
|
||||
if (forceAfflictionData)
|
||||
{
|
||||
|
||||
@@ -2107,9 +2107,33 @@ namespace Barotrauma
|
||||
"freecam",
|
||||
(Client client, Vector2 cursorWorldPos, string[] args) =>
|
||||
{
|
||||
client.UsingFreeCam = true;
|
||||
GameMain.Server.SetClientCharacter(client, null);
|
||||
client.SpectateOnly = true;
|
||||
if (client.UsingFreeCam)
|
||||
{
|
||||
// Exiting freecam - try to return to previous character
|
||||
Character prevCharacter = null;
|
||||
if (client.PreviousCharacter != null && client.PreviousCharacter.TryGetTarget(out prevCharacter) &&
|
||||
prevCharacter != null && !prevCharacter.IsDead && !prevCharacter.Removed)
|
||||
{
|
||||
GameMain.Server.SendConsoleMessage($"{client.Name}: Exiting freecam mode", client, Color.Yellow);
|
||||
client.UsingFreeCam = false;
|
||||
GameMain.Server.SetClientCharacter(client, prevCharacter);
|
||||
client.SpectateOnly = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
GameMain.Server.SendConsoleMessage($"{client.Name}: Could not regain control of the previous character (dead or removed).", client, Color.Red);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Entering freecam - store current character ID
|
||||
GameMain.Server.SendConsoleMessage($"{client.Name}: Entering freecam mode", client, Color.Yellow);
|
||||
Character currentCharacter = client.Character;
|
||||
client.PreviousCharacter = new WeakReference<Character>(currentCharacter);
|
||||
client.UsingFreeCam = true;
|
||||
client.SpectateOnly = true;
|
||||
GameMain.Server.SetClientCharacter(client, null);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
+20
-5
@@ -92,6 +92,7 @@ namespace Barotrauma
|
||||
purchasedHullRepairs = value;
|
||||
PurchasedHullRepairsInLatestSave |= value;
|
||||
IncrementLastUpdateIdForFlag(NetFlags.Misc);
|
||||
DebugConsole.NewMessage("Set PurchasedHullRepairs to " + PurchasedHullRepairs, Color.Cyan);
|
||||
}
|
||||
}
|
||||
public override bool PurchasedLostShuttles
|
||||
@@ -861,6 +862,13 @@ namespace Barotrauma
|
||||
purchasedItemSwaps.Add(new PurchasedItemSwap(itemToRemove, itemToInstall));
|
||||
}
|
||||
|
||||
if (purchasedUpgradeCount > 0 || purchasedItemSwapCount > 0)
|
||||
{
|
||||
//if the client attempted to purchase something, increment flag regardless of whether the upgrades were actually purchased or not
|
||||
//so we can sync the correct state in case the client incorrectly assumed they can buy something (e.g. lost permissions just as they were purchasing)
|
||||
IncrementLastUpdateIdForFlag(NetFlags.UpgradeManager);
|
||||
}
|
||||
|
||||
int hullRepairCost = GetHullRepairCost();
|
||||
int itemRepairCost = GetItemRepairCost();
|
||||
int shuttleRetrieveCost = CampaignMode.ShuttleReplaceCost;
|
||||
@@ -1100,7 +1108,7 @@ namespace Barotrauma
|
||||
var characterList = GameSession.GetSessionCrewCharacters(CharacterType.Both);
|
||||
foreach (var (prefab, category, _) in purchasedUpgrades)
|
||||
{
|
||||
UpgradeManager.PurchaseUpgrade(prefab, category, client: sender);
|
||||
UpgradeManager.TryPurchaseUpgrade(prefab, category, client: sender);
|
||||
|
||||
// unstable logging
|
||||
int price = prefab.Price.GetBuyPrice(prefab, UpgradeManager.GetUpgradeLevel(prefab, category), Map?.CurrentLocation, characterList);
|
||||
@@ -1111,7 +1119,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (purchasedItemSwap.ItemToInstall == null)
|
||||
{
|
||||
UpgradeManager.CancelItemSwap(purchasedItemSwap.ItemToRemove);
|
||||
UpgradeManager.CancelItemSwap(purchasedItemSwap.ItemToRemove, client: sender);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1502,11 +1510,13 @@ namespace Barotrauma
|
||||
{
|
||||
element.Add(new XAttribute("campaignid", CampaignID));
|
||||
XElement modeElement = new XElement("MultiPlayerCampaign",
|
||||
new XAttribute("purchasedlostshuttles", PurchasedLostShuttles),
|
||||
new XAttribute("purchasedhullrepairs", PurchasedHullRepairs),
|
||||
new XAttribute("purchaseditemrepairs", PurchasedItemRepairs),
|
||||
new XAttribute("purchasedlostshuttles", PurchasedLostShuttlesInLatestSave),
|
||||
new XAttribute("purchasedhullrepairs", PurchasedHullRepairsInLatestSave),
|
||||
new XAttribute("purchaseditemrepairs", PurchasedItemRepairsInLatestSave),
|
||||
new XAttribute("cheatsenabled", CheatsEnabled));
|
||||
|
||||
DebugConsole.NewMessage("Saved PurchasedHullRepairs: "+ PurchasedHullRepairs+" (in last save "+PurchasedHullRepairsInLatestSave+")", Color.Magenta);
|
||||
|
||||
modeElement.Add(Settings.Save());
|
||||
modeElement.Add(SaveStats());
|
||||
if (GameMain.Server?.TraitorManager is TraitorManager traitorManager)
|
||||
@@ -1520,6 +1530,11 @@ namespace Barotrauma
|
||||
modeElement.Add(GameMain.GameSession?.EventManager.Save());
|
||||
}
|
||||
|
||||
foreach (Identifier unlockedRecipe in GameMain.GameSession.UnlockedRecipes)
|
||||
{
|
||||
modeElement.Add(new XElement("unlockedrecipe", new XAttribute("identifier", unlockedRecipe)));
|
||||
}
|
||||
|
||||
CampaignMetadata?.Save(modeElement);
|
||||
Map.Save(modeElement);
|
||||
CargoManager?.SavePurchasedItems(modeElement);
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public void ServerEventWrite(IWriteMessage msg, Client c, NetEntityEvent.IData extraData = null)
|
||||
{
|
||||
msg.WriteRangedSingle(Health, 0f, (float)MaxHealth, 8);
|
||||
msg.WriteRangedSingle(Health, 0f, (float)MaxWater, 8);
|
||||
if (TryExtractEventData(extraData, out EventData eventData))
|
||||
{
|
||||
int offset = eventData.Offset;
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
base.ServerEventWrite(msg, c, extraData);
|
||||
|
||||
bool writeAttachData = attachable && body != null;
|
||||
bool writeAttachData = attachable && originalBody != null;
|
||||
msg.WriteBoolean(writeAttachData);
|
||||
if (!writeAttachData) { return; }
|
||||
|
||||
@@ -22,8 +22,8 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
msg.WriteBoolean(Attached);
|
||||
msg.WriteSingle(body.SimPosition.X);
|
||||
msg.WriteSingle(body.SimPosition.Y);
|
||||
msg.WriteSingle(originalBody.SimPosition.X);
|
||||
msg.WriteSingle(originalBody.SimPosition.Y);
|
||||
msg.WriteUInt16(item.Submarine?.ID ?? Entity.NullEntityID);
|
||||
msg.WriteUInt16(attacherId);
|
||||
}
|
||||
@@ -40,6 +40,9 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
Drop(false, null);
|
||||
item.SetTransform(simPosition, 0.0f, findNewHull: false);
|
||||
//don't find the new hull in SetTransform, because that'd also potentially change the submarine (teleport the item outside if it's attached outside)
|
||||
//instead just find the hull, so the item is considered to be in the right hull
|
||||
item.CurrentHull = Hull.FindHull(item.WorldPosition, item.CurrentHull);
|
||||
AttachToWall();
|
||||
OnUsed.Invoke(new ItemUseInfo(item, c.Character));
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#nullable enable
|
||||
using Barotrauma.Networking;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
internal partial class PowerDistributor : PowerTransfer, IServerSerializable, IClientSerializable
|
||||
{
|
||||
#region Networking
|
||||
public void ServerEventRead(IReadMessage msg, Client c)
|
||||
{
|
||||
SharedEventRead(msg, out EventType eventType, out PowerGroup powerGroup, out string newName, out float newRatio);
|
||||
|
||||
if (item.CanClientAccess(c))
|
||||
{
|
||||
switch (eventType)
|
||||
{
|
||||
case EventType.NameChange:
|
||||
powerGroup.Name = newName;
|
||||
break;
|
||||
case EventType.RatioChange:
|
||||
powerGroup.SupplyRatio = newRatio;
|
||||
GameServer.Log($"{GameServer.CharacterLogName(c.Character)} changed supply ratio of power group \"{powerGroup.Name}\" to \"{powerGroup.SupplyRatio}\"", ServerLog.MessageType.ItemInteraction);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
item.CreateServerEvent(this, new EventData(powerGroup, eventType));
|
||||
}
|
||||
|
||||
public void ServerEventWrite(IWriteMessage msg, Client c, NetEntityEvent.IData? extraData = null) => SharedEventWrite(msg, extraData);
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -274,6 +274,7 @@ namespace Barotrauma
|
||||
msg.WriteByte(originalSlotIndex < 0 ? (byte)255 : (byte)originalSlotIndex);
|
||||
}
|
||||
|
||||
msg.WriteBoolean(OnInsertedEffectsAppliedOnPreviousRound);
|
||||
msg.WriteByte(body == null ? (byte)0 : (byte)body.BodyType);
|
||||
msg.WriteBoolean(SpawnedInCurrentOutpost);
|
||||
msg.WriteBoolean(AllowStealing);
|
||||
|
||||
@@ -30,8 +30,8 @@ namespace Barotrauma
|
||||
//don't create updates if all clients are very far from the hull
|
||||
float hullUpdateDistanceSqr = NetConfig.HullUpdateDistance * NetConfig.HullUpdateDistance;
|
||||
if (!GameMain.Server.ConnectedClients.Any(c =>
|
||||
c.Character != null &&
|
||||
Vector2.DistanceSquared(c.Character.WorldPosition, WorldPosition) < hullUpdateDistanceSqr))
|
||||
(c.Character != null && Vector2.DistanceSquared(c.Character.WorldPosition, WorldPosition) < hullUpdateDistanceSqr) ||
|
||||
(c.SpectatePos != null && Vector2.DistanceSquared(c.SpectatePos.Value, WorldPosition) < hullUpdateDistanceSqr)) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -76,6 +76,11 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public void ForceStatusUpdate()
|
||||
{
|
||||
statusUpdateTimer = NetConfig.SparseHullUpdateInterval;
|
||||
}
|
||||
|
||||
|
||||
public void CreateStatusEvent()
|
||||
{
|
||||
@@ -137,6 +142,12 @@ namespace Barotrauma
|
||||
|
||||
WaterVolume = newWaterVolume;
|
||||
|
||||
if (newFireSources.Length != FireSources.Count)
|
||||
{
|
||||
//number of fire sources has changed, force a network update
|
||||
ForceStatusUpdate();
|
||||
}
|
||||
|
||||
for (int i = 0; i < newFireSources.Length; i++)
|
||||
{
|
||||
Vector2 pos = newFireSources[i].Position;
|
||||
|
||||
@@ -166,9 +166,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
else
|
||||
{
|
||||
ChatMessage denyMsg = Create("", TextManager.Get("SpamFilterBlocked").Value, ChatMessageType.Server, null);
|
||||
c.ChatSpamTimer = 10.0f;
|
||||
GameMain.Server.SendDirectChatMessage(denyMsg, c);
|
||||
BlockBySpamFilter();
|
||||
}
|
||||
flaggedAsSpam = true;
|
||||
return;
|
||||
@@ -178,14 +176,20 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (c.ChatSpamTimer > 0.0f && !isSpamExempt)
|
||||
{
|
||||
ChatMessage denyMsg = Create("", TextManager.Get("SpamFilterBlocked").Value, ChatMessageType.Server, null);
|
||||
c.ChatSpamTimer = 10.0f;
|
||||
GameMain.Server.SendDirectChatMessage(denyMsg, c);
|
||||
BlockBySpamFilter();
|
||||
flaggedAsSpam = true;
|
||||
return;
|
||||
}
|
||||
|
||||
flaggedAsSpam = false;
|
||||
|
||||
void BlockBySpamFilter()
|
||||
{
|
||||
ChatMessage denyMsg = Create("", TextManager.Get("SpamFilterBlocked").Value, ChatMessageType.BlockedBySpamFilter, null);
|
||||
c.ChatSpamTimer = BlockedBySpamFilterTime;
|
||||
GameMain.Server.SendDirectChatMessage(denyMsg, c);
|
||||
GameServer.Log(c.Name + " blocked by spam filter", ServerLog.MessageType.ServerMessage);
|
||||
}
|
||||
}
|
||||
|
||||
public int EstimateLengthBytesServer(Client c)
|
||||
|
||||
@@ -138,6 +138,8 @@ namespace Barotrauma.Networking
|
||||
get { return kickVoters.Count; }
|
||||
}
|
||||
|
||||
public WeakReference<Character> PreviousCharacter;
|
||||
|
||||
partial void InitProjSpecific()
|
||||
{
|
||||
kickVoters = new List<Client>();
|
||||
|
||||
@@ -4222,6 +4222,9 @@ namespace Barotrauma.Networking
|
||||
public void GiveAchievement(Client client, Identifier achievementIdentifier)
|
||||
{
|
||||
if (client.GivenAchievements.Contains(achievementIdentifier)) { return; }
|
||||
|
||||
DebugConsole.NewMessage($"Attempting to give the achievement {achievementIdentifier} to {client.Name}...");
|
||||
|
||||
client.GivenAchievements.Add(achievementIdentifier);
|
||||
|
||||
IWriteMessage msg = new WriteOnlyMessage();
|
||||
@@ -4231,6 +4234,17 @@ namespace Barotrauma.Networking
|
||||
serverPeer.Send(msg, client.Connection, DeliveryMethod.Reliable);
|
||||
}
|
||||
|
||||
public void UnlockRecipe(Identifier identifier)
|
||||
{
|
||||
foreach (var client in connectedClients)
|
||||
{
|
||||
IWriteMessage msg = new WriteOnlyMessage();
|
||||
msg.WriteByte((byte)ServerPacketHeader.UNLOCKRECIPE);
|
||||
msg.WriteIdentifier(identifier);
|
||||
serverPeer.Send(msg, client.Connection, DeliveryMethod.Reliable);
|
||||
}
|
||||
}
|
||||
|
||||
public void IncrementStat(Client client, AchievementStat stat, int amount)
|
||||
{
|
||||
IWriteMessage msg = new WriteOnlyMessage();
|
||||
|
||||
Reference in New Issue
Block a user