Unstable 1.8.4.0

This commit is contained in:
Markus Isberg
2025-03-12 12:56:27 +00:00
parent a4c3e868e4
commit a4a3427e4e
627 changed files with 29860 additions and 10018 deletions
@@ -36,7 +36,8 @@ namespace Barotrauma
{
return
lastActiveAction != null &&
lastActiveAction.ParentEvent != ParentEvent &&
!lastActiveAction.ParentEvent.IsFinished &&
lastActiveAction.ParentEvent != ParentEvent &&
Timing.TotalTime < lastActiveAction.lastActiveTime + duration;
}
@@ -101,6 +102,7 @@ namespace Barotrauma
conversationList.BarScroll = (prevSize - conversationList.Content.Rect.Height) / (conversationList.TotalSize - conversationList.Content.Rect.Height);
conversationList.ScrollToEnd(duration: 0.5f);
lastMessageBox.SetBackgroundIcon(eventSprite);
MarkMessageBoxAsLastAction(lastMessageBox);
return;
}
}
@@ -123,16 +125,7 @@ namespace Barotrauma
messageBox.AutoClose = false;
GUIStyle.Apply(messageBox.InnerFrame, "DialogBox");
if (actionInstance != null)
{
lastActiveAction = actionInstance;
actionInstance.lastActiveTime = Timing.TotalTime;
actionInstance.dialogBox = messageBox;
}
else
{
messageBox.UserData = new Pair<string, UInt16>("ConversationAction", actionId.Value);
}
MarkMessageBoxAsLastAction(messageBox);
int padding = GUI.IntScale(16);
@@ -155,6 +148,20 @@ namespace Barotrauma
};
shadow.SetAsFirstChild();
void MarkMessageBoxAsLastAction(GUIMessageBox messageBox)
{
if (actionInstance != null)
{
lastActiveAction = actionInstance;
actionInstance.lastActiveTime = Timing.TotalTime;
actionInstance.dialogBox = messageBox;
}
else
{
messageBox.UserData = new Pair<string, UInt16>("ConversationAction", actionId.Value);
}
}
static void RecalculateLastMessage(GUIListBox conversationList, bool append)
{
if (conversationList.Content.Children.LastOrDefault() is GUILayoutGroup lastElement)
@@ -48,6 +48,7 @@ partial class EventLog
textContent,
difficultyIconCount,
icon, GUIStyle.Red,
difficultyTooltipText: null,
out GUIImage missionIcon);
if (traitorResults != null &&
@@ -549,6 +549,33 @@ namespace Barotrauma
}
public void ClientRead(IReadMessage msg)
{
if (GameMain.GameSession.IsRunning && !GameMain.Instance.LoadingScreenOpen)
{
ClientApplyNetworkMessage(msg);
}
else
{
//if the game session is not currently running (round still loading),
//we need to wait because the entities the status effect / conversation / etc targets may not exist yet
CoroutineManager.StartCoroutine(ApplyNetworkMessageWhenRoundLoaded(msg));
}
}
public IEnumerable<CoroutineStatus> ApplyNetworkMessageWhenRoundLoaded(IReadMessage msg)
{
while (GameMain.GameSession is { IsRunning: false } || GameMain.Instance.LoadingScreenOpen)
{
yield return new WaitForSeconds(1.0f);
}
if (GameMain.GameSession != null && GameMain.Client != null)
{
ClientApplyNetworkMessage(msg);
}
yield return CoroutineStatus.Success;
}
public void ClientApplyNetworkMessage(IReadMessage msg)
{
NetworkEventType eventType = (NetworkEventType)msg.ReadByte();
switch (eventType)
@@ -1,4 +1,4 @@
using Barotrauma.Extensions;
using Barotrauma.Extensions;
using Barotrauma.Networking;
namespace Barotrauma
@@ -21,7 +21,12 @@ namespace Barotrauma
}
}
public override bool DisplayAsCompleted => State > 0 && requireRescue.None();
public override bool DisplayAsCompleted =>
!DisplayAsFailed &&
State > 0 &&
//don't display as completed mid-round if there's NPCs to rescue (mission isn't guaranteed to complete yet)
requireRescue.None();
public override bool DisplayAsFailed => State == HostagesKilledState;
public override void ClientReadInitial(IReadMessage msg)
@@ -47,7 +52,7 @@ namespace Barotrauma
#if CLIENT
if (allowOrderingRescuees)
{
GameMain.GameSession.CrewManager.AddCharacterToCrewList(character);
GameMain.GameSession.CrewManager?.AddCharacterToCrewList(character);
}
#endif
}
@@ -59,10 +64,13 @@ namespace Barotrauma
if (character.Submarine != null && character.AIController is EnemyAIController enemyAi)
{
enemyAi.UnattackableSubmarines.Add(character.Submarine);
enemyAi.UnattackableSubmarines.Add(Submarine.MainSub);
foreach (Submarine sub in Submarine.MainSub.DockedTo)
if (Submarine.MainSub != null)
{
enemyAi.UnattackableSubmarines.Add(sub);
enemyAi.UnattackableSubmarines.Add(Submarine.MainSub);
foreach (Submarine sub in Submarine.MainSub.DockedTo)
{
enemyAi.UnattackableSubmarines.Add(sub);
}
}
}
}
@@ -1,7 +1,17 @@
namespace Barotrauma
using Barotrauma.Networking;
using Microsoft.Xna.Framework;
using System.Collections.Generic;
namespace Barotrauma
{
partial class CombatMission : Mission
{
private readonly Dictionary<byte, int> clientKills = new Dictionary<byte, int>();
private readonly Dictionary<byte, int> clientDeaths = new Dictionary<byte, int>();
private readonly Dictionary<ushort, int> botKills = new Dictionary<ushort, int>();
private readonly Dictionary<ushort, int> botDeaths = new Dictionary<ushort, int>();
public override LocalizedString Description
{
get
@@ -21,5 +31,93 @@
public override bool DisplayAsCompleted => false;
public override bool DisplayAsFailed => false;
public override IEnumerable<(LocalizedString Label, Vector2 Position)> SonarLabels
{
get
{
if (targetSubmarine == null)
{
yield break;
}
else
{
yield return (targetSubmarineSonarLabel is { Loaded: true } ? targetSubmarineSonarLabel : targetSubmarine.Info.DisplayName, targetSubmarine.WorldPosition);
}
}
}
public static Color GetTeamColor(CharacterTeamType teamID)
{
if (teamID == CharacterTeamType.Team1)
{
return GUIStyle.GetComponentStyle("CoalitionIcon")?.Color ?? GUIStyle.Blue;
}
else if (teamID == CharacterTeamType.Team2)
{
return GUIStyle.GetComponentStyle("SeparatistIcon")?.Color ?? GUIStyle.Orange;
}
return Color.White;
}
public int GetClientKillCount(Client client)
{
if (clientKills.TryGetValue(client.SessionId, out int kills))
{
return kills;
}
return 0;
}
public int GetClientDeathCount(Client client)
{
if (clientDeaths.TryGetValue(client.SessionId, out int deaths))
{
return deaths;
}
return 0;
}
public int GetBotKillCount(CharacterInfo botInfo)
{
if (botKills.TryGetValue(botInfo.ID, out int kills))
{
return kills;
}
return 0;
}
public int GetBotDeathCount(CharacterInfo botInfo)
{
if (botDeaths.TryGetValue(botInfo.ID, out int deaths))
{
return deaths;
}
return 0;
}
public override void ClientRead(IReadMessage msg)
{
base.ClientRead(msg);
Scores[0] = msg.ReadUInt16();
Scores[1] = msg.ReadUInt16();
uint clientCount = msg.ReadVariableUInt32();
for (int i = 0; i < clientCount; i++)
{
byte clientId = msg.ReadByte();
clientDeaths[clientId] = (int)msg.ReadVariableUInt32();
clientKills[clientId] = (int)msg.ReadVariableUInt32();
}
uint botCount = msg.ReadVariableUInt32();
for (int i = 0; i < botCount; i++)
{
ushort botId = msg.ReadUInt16();
botDeaths[botId] = (int)msg.ReadVariableUInt32();
botKills[botId] = (int)msg.ReadVariableUInt32();
}
}
}
}
@@ -4,7 +4,6 @@ using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using static Barotrauma.MissionPrefab;
namespace Barotrauma
{
@@ -61,6 +60,16 @@ namespace Barotrauma
return RichString.Rich(TextManager.GetWithVariable("missionreward", "[reward]", "‖color:gui.orange‖" + rewardText + "‖end‖"));
}
public RichString GetDifficultyToolTipText()
{
// 2 skulls give +10% XP, 3 skulls +20% XP and 4 skulls give +30% XP.
float xpBonusMultiplier = CalculateDifficultyXPMultiplier();
float xpBonusPercentage = (xpBonusMultiplier - 1f) * 100f;
int bonusRounded = (int)Math.Round(xpBonusPercentage);
LocalizedString tooltipText = TextManager.GetWithVariable(tag: "missiondifficultyxpbonustooltip", varName: "[bonus]", value: bonusRounded.ToString());
return RichString.Rich(tooltipText);
}
public RichString GetReputationRewardText()
{
List<LocalizedString> reputationRewardTexts = new List<LocalizedString>();
@@ -117,6 +126,7 @@ namespace Barotrauma
return string.Empty;
}
}
partial void DistributeExperienceToCrew(IEnumerable<Character> crew, int experienceGain)
{
foreach (Character character in crew)
@@ -49,7 +49,8 @@ namespace Barotrauma
{
return hudIconColor ?? IconColor;
}
}
}
public Color ProgressBarColor { get; private set; }
private Sprite hudIcon;
private Color? hudIconColor;
@@ -90,6 +91,7 @@ namespace Barotrauma
}
this.portraits = portraits.ToImmutableArray();
overrideMusicOnState = overrideMusic.ToImmutableDictionary();
ProgressBarColor = element.GetAttributeColor(nameof(ProgressBarColor), GUIStyle.Blue);
}
public Identifier GetOverrideMusicType(int state)
@@ -1,4 +1,6 @@
using Barotrauma.Networking;
using System.Collections.Generic;
using System.Linq;
using Barotrauma.Networking;
using FarseerPhysics;
namespace Barotrauma
@@ -7,26 +9,51 @@ namespace Barotrauma
{
public override bool DisplayAsCompleted => false;
public override bool DisplayAsFailed => false;
private void TryShowPickedUpMessage() => HandleMessage(ref pickedUpMessage);
private void TryShowRetrievedMessage()
{
if (DetermineCompleted())
{
if (!allRetrievedMessage.IsNullOrEmpty()) { CreateMessageBox(string.Empty, allRetrievedMessage); }
//no need to show this again, clear it
allRetrievedMessage = string.Empty;
HandleMessage(ref allRetrievedMessage);
}
else
{
if (!partiallyRetrievedMessage.IsNullOrEmpty()) { CreateMessageBox(string.Empty, partiallyRetrievedMessage); }
//no need to show this again, clear it
partiallyRetrievedMessage = string.Empty;
HandleMessage(ref partiallyRetrievedMessage);
}
}
private void HandleMessage(ref LocalizedString message)
{
if (!message.IsNullOrEmpty()) { CreateMessageBox(string.Empty, message); }
//no need to show this again, clear it
message = string.Empty;
}
public override void ClientReadInitial(IReadMessage msg)
{
base.ClientReadInitial(msg);
byte characterCount = msg.ReadByte();
for (int i = 0; i < characterCount; i++)
{
Character character = Character.ReadSpawnData(msg);
characters.Add(character);
ushort itemCount = msg.ReadUInt16();
for (int j = 0; j < itemCount; j++)
{
Item.ReadSpawnData(msg);
}
}
if (characters.Contains(null))
{
throw new System.Exception("Error in SalvageMission.ClientReadInitial: character list contains null (mission: " + Prefab.Identifier + ")");
}
if (characters.Count != characterCount)
{
throw new System.Exception("Error in SalvageMission.ClientReadInitial: character count does not match the server count (" + characters + " != " + characters.Count + "mission: " + Prefab.Identifier + ")");
}
foreach (var target in targets)
{
@@ -81,24 +108,37 @@ namespace Barotrauma
{
base.ClientRead(msg);
bool atLeastOneTargetWasRetrieved = false;
bool showPickedUpMsg = false;
int targetCount = msg.ReadByte();
for (int i = 0; i < targetCount; i++)
{
var state = (Target.RetrievalState)msg.ReadByte();
if (i < targets.Count)
{
bool wasRetrieved = targets[i].Retrieved;
Target target = targets[i];
bool wasRetrieved = target.Retrieved;
bool wasPickedUp = target.State == Target.RetrievalState.PickedUp;
targets[i].State = state;
if (!wasRetrieved && targets[i].Retrieved)
if (!wasRetrieved && target.Retrieved)
{
atLeastOneTargetWasRetrieved = true;
}
else if (!wasPickedUp && target.State == Target.RetrievalState.PickedUp)
{
showPickedUpMsg = true;
}
}
}
if (atLeastOneTargetWasRetrieved)
{
TryShowRetrievedMessage();
}
if (showPickedUpMsg)
{
TryShowPickedUpMessage();
}
}
public override IEnumerable<Entity> HudIconTargets => targets.Where(static t => !t.Retrieved && t.Item.GetRootInventoryOwner() is not Character { IsLocalPlayer: true }).Select(static t => t.Item);
}
}
@@ -7,20 +7,7 @@ namespace Barotrauma
{
partial class ScanMission : Mission
{
public override IEnumerable<Entity> HudIconTargets
{
get
{
if (State == 0)
{
return scanTargets.Where(kvp => !kvp.Value).Select(kvp => kvp.Key);
}
else
{
return Enumerable.Empty<Entity>();
}
}
}
public override IEnumerable<Entity> HudIconTargets => scanTargets.Where(kvp => !kvp.Value).Select(kvp => kvp.Key);
public override bool DisplayAsCompleted => false;
public override bool DisplayAsFailed => false;
@@ -62,7 +49,7 @@ namespace Barotrauma
ushort id = msg.ReadUInt16();
bool scanned = msg.ReadBoolean();
Entity entity = Entity.FindEntityByID(id);
if (!(entity is WayPoint wayPoint))
if (entity is not WayPoint wayPoint)
{
string errorMsg = $"Failed to find a waypoint in ScanMission.ClientReadScanTargetStatus. Entity {id} was {(entity?.ToString() ?? null)}";
DebugConsole.ThrowError(errorMsg);