Unstable 1.1.14.0

This commit is contained in:
Markus Isberg
2023-10-02 16:43:54 +03:00
parent 94f5a93a0c
commit cf8f0de659
606 changed files with 21906 additions and 11456 deletions
@@ -42,15 +42,15 @@ namespace Barotrauma
partial void ShowDialog(Character speaker, Character targetCharacter)
{
CreateDialog(Text, speaker, Options.Select(opt => opt.Text), GetEndingOptions(), actionInstance: this, spriteIdentifier: EventSprite, fadeToBlack: FadeToBlack, dialogType: DialogType, continueConversation: ContinueConversation);
CreateDialog(GetDisplayText(), speaker, Options.Select(opt => opt.Text), GetEndingOptions(), actionInstance: this, spriteIdentifier: EventSprite, fadeToBlack: FadeToBlack, dialogType: DialogType, continueConversation: ContinueConversation);
}
public static void CreateDialog(string text, Character speaker, IEnumerable<string> options, int[] closingOptions, string eventSprite, UInt16 actionId, bool fadeToBlack, DialogTypes dialogType, bool continueConversation = false)
public static void CreateDialog(LocalizedString text, Character speaker, IEnumerable<string> options, int[] closingOptions, string eventSprite, UInt16 actionId, bool fadeToBlack, DialogTypes dialogType, bool continueConversation = false)
{
CreateDialog(text, speaker, options, closingOptions, actionInstance: null, actionId: actionId, spriteIdentifier: eventSprite, fadeToBlack: fadeToBlack, dialogType: dialogType, continueConversation: continueConversation);
}
private static void CreateDialog(string text, Character speaker, IEnumerable<string> options, int[] closingOptions, string spriteIdentifier = null,
private static void CreateDialog(LocalizedString text, Character speaker, IEnumerable<string> options, int[] closingOptions, string spriteIdentifier = null,
ConversationAction actionInstance = null, UInt16? actionId = null, bool fadeToBlack = false, DialogTypes dialogType = DialogTypes.Regular, bool continueConversation = false)
{
Debug.Assert(actionInstance == null || actionId == null);
@@ -126,6 +126,7 @@ namespace Barotrauma
if (actionInstance != null)
{
lastActiveAction = actionInstance;
actionInstance.lastActiveTime = Timing.TotalTime;
actionInstance.dialogBox = messageBox;
}
else
@@ -313,7 +314,7 @@ namespace Barotrauma
};
}
private static List<GUIButton> CreateConversation(GUIListBox parentBox, string text, Character speaker, IEnumerable<string> options, bool drawChathead = true)
private static List<GUIButton> CreateConversation(GUIListBox parentBox, LocalizedString text, Character speaker, IEnumerable<string> options, bool drawChathead = true)
{
var content = new GUILayoutGroup(new RectTransform(Vector2.One, parentBox.Content.RectTransform), childAnchor: Anchor.TopLeft, isHorizontal: true)
{
@@ -322,9 +323,11 @@ namespace Barotrauma
AlwaysOverrideCursor = true
};
LocalizedString translatedText = speaker?.DisplayName is not null ?
TextManager.GetWithVariable(text, "[speakername]", speaker?.DisplayName) :
TextManager.Get(text);
LocalizedString translatedText = text.Replace("\\n", "\n");
if (speaker?.DisplayName is not null)
{
translatedText = translatedText.Replace("[speakername]", speaker.DisplayName);
}
translatedText = TextManager.ParseInputTypes(translatedText).Fallback(text);
if (speaker?.Info != null && drawChathead)
@@ -341,7 +344,7 @@ namespace Barotrauma
AbsoluteSpacing = GUI.IntScale(5)
};
var textBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), textContent.RectTransform), translatedText, wrap: true)
var textBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), textContent.RectTransform), RichString.Rich(translatedText), wrap: true)
{
AlwaysOverrideCursor = true,
UserData = "text"
@@ -0,0 +1,11 @@
#nullable enable
namespace Barotrauma;
partial class EventLogAction : EventAction
{
partial void AddEntryProjSpecific(EventLog? eventLog, string displayText)
{
eventLog?.AddEntry(ParentEvent.Prefab.Identifier, Id, displayText);
}
}
@@ -0,0 +1,66 @@
#nullable enable
namespace Barotrauma;
partial class EventObjectiveAction : EventAction
{
public static void Trigger(
SegmentActionType Type,
Identifier Identifier,
Identifier ObjectiveTag,
Identifier ParentObjectiveId,
Identifier TextTag,
bool CanBeCompleted,
bool autoPlayVideo = false,
string videoFile = "",
int width = 450,
int height = 80)
{
ObjectiveManager.Segment? segment = null;
// Only need to create the segment when it's being triggered (otherwise the tutorial already has the segment instance)
if (Type == SegmentActionType.Trigger)
{
segment = ObjectiveManager.Segment.CreateInfoBoxSegment(Identifier, ObjectiveTag, autoPlayVideo ? Tutorials.AutoPlayVideo.Yes : Tutorials.AutoPlayVideo.No,
new ObjectiveManager.Segment.Text(TextTag, width, height, Anchor.Center),
new ObjectiveManager.Segment.Video(videoFile, TextTag, width, height));
}
else if (Type == SegmentActionType.Add)
{
segment = ObjectiveManager.Segment.CreateObjectiveSegment(Identifier, !ObjectiveTag.IsEmpty ? ObjectiveTag : Identifier);
}
if (segment is not null)
{
segment.CanBeCompleted = CanBeCompleted;
segment.ParentId = ParentObjectiveId;
}
switch (Type)
{
case SegmentActionType.Trigger:
case SegmentActionType.Add:
ObjectiveManager.TriggerSegment(segment);
break;
case SegmentActionType.Complete:
ObjectiveManager.CompleteSegment(Identifier);
break;
case SegmentActionType.Remove:
ObjectiveManager.RemoveSegment(Identifier);
break;
case SegmentActionType.CompleteAndRemove:
ObjectiveManager.CompleteSegment(Identifier);
ObjectiveManager.RemoveSegment(Identifier);
break;
case SegmentActionType.Fail:
ObjectiveManager.FailSegment(Identifier);
break;
case SegmentActionType.FailAndRemove:
ObjectiveManager.FailSegment(Identifier);
ObjectiveManager.RemoveSegment(Identifier);
break;
}
}
partial void UpdateProjSpecific()
{
Trigger(Type, Identifier, ObjectiveTag, ParentObjectiveId, TextTag, CanBeCompleted, AutoPlayVideo, VideoFile, Width, Height);
}
}
@@ -17,7 +17,7 @@ partial class MessageBoxAction : EventAction
var segment = ObjectiveManager.Segment.CreateMessageBoxSegment(id, ObjectiveTag, CreateMessageBox);
segment.CanBeCompleted = ObjectiveCanBeCompleted;
segment.ParentId = ParentObjectiveId;
ObjectiveManager.TriggerTutorialSegment(segment, connectObjective: Type == ActionType.ConnectObjective);
ObjectiveManager.TriggerSegment(segment, connectObjective: Type == ActionType.ConnectObjective);
}
}
else if (Type == ActionType.Close)
@@ -1,43 +0,0 @@
namespace Barotrauma;
partial class TutorialSegmentAction : EventAction
{
private ObjectiveManager.Segment segment;
partial void UpdateProjSpecific()
{
// Only need to create the segment when it's being triggered (otherwise the tutorial already has the segment instance)
if (Type == SegmentActionType.Trigger)
{
segment = ObjectiveManager.Segment.CreateInfoBoxSegment(Identifier, ObjectiveTag, AutoPlayVideo ? Tutorials.AutoPlayVideo.Yes : Tutorials.AutoPlayVideo.No,
new ObjectiveManager.Segment.Text(TextTag, Width, Height, Anchor.Center),
new ObjectiveManager.Segment.Video(VideoFile, TextTag, Width, Height));
}
else if (Type == SegmentActionType.Add)
{
segment = ObjectiveManager.Segment.CreateObjectiveSegment(Identifier, !ObjectiveTag.IsEmpty ? ObjectiveTag : Identifier);
}
if (segment is not null)
{
segment.CanBeCompleted = CanBeCompleted;
segment.ParentId = ParentObjectiveId;
}
switch (Type)
{
case SegmentActionType.Trigger:
case SegmentActionType.Add:
ObjectiveManager.TriggerTutorialSegment(segment);
break;
case SegmentActionType.Complete:
ObjectiveManager.CompleteTutorialSegment(Identifier);
break;
case SegmentActionType.Remove:
ObjectiveManager.RemoveTutorialSegment(Identifier);
break;
case SegmentActionType.CompleteAndRemove:
ObjectiveManager.CompleteTutorialSegment(Identifier);
ObjectiveManager.RemoveTutorialSegment(Identifier);
break;
}
}
}
@@ -0,0 +1,61 @@
#nullable enable
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Barotrauma;
partial class EventLog
{
public bool UnreadEntries { get; private set; }
public void AddEntry(Identifier eventPrefabId, Identifier entryId, string text)
{
TryAddEntryInternal(eventPrefabId, entryId, text);
GameMain.GameSession?.EnableEventLogNotificationIcon(enabled: true);
UnreadEntries = true;
}
public void CreateEventLogUI(GUIComponent parent, TraitorManager.TraitorResults? traitorResults = null)
{
UnreadEntries = false;
int spacing = GUI.IntScale(5);
foreach (var ev in events.Values)
{
LocalizedString nameString = string.Empty;
int difficultyIconCount = 0;
EventPrefab.Prefabs.TryGet(ev.EventIdentifier, out EventPrefab? eventPrefab);
if (eventPrefab is not null)
{
nameString = RichString.Rich(eventPrefab.Name);
if (eventPrefab is TraitorEventPrefab traitorEventPrefab)
{
difficultyIconCount = traitorEventPrefab.DangerLevel;
}
}
var textContent = new List<LocalizedString>();
textContent.AddRange(ev.Entries.Select(e => (LocalizedString)e.Text));
var icon = GUIStyle.GetComponentStyle("TraitorMissionIcon")?.GetDefaultSprite();
RoundSummary.CreateMissionEntry(
parent,
nameString,
textContent,
difficultyIconCount,
icon, GUIStyle.Red,
out GUIImage missionIcon);
if (traitorResults != null &&
traitorResults.Value.TraitorEventIdentifier == ev.EventIdentifier)
{
RoundSummary.UpdateMissionStateIcon(traitorResults.Value.ObjectiveSuccessful, missionIcon);
}
}
}
}
@@ -413,23 +413,9 @@ namespace Barotrauma
private Rectangle DrawScriptedEvent(SpriteBatch spriteBatch, ScriptedEvent scriptedEvent, Rectangle? parentRect = null)
{
EventAction? currentEvent = !scriptedEvent.IsFinished ? scriptedEvent.Actions[scriptedEvent.CurrentActionIndex] : null;
List<DebugLine> positions = new List<DebugLine>();
string text = $"Finished: {scriptedEvent.IsFinished.ColorizeObject()}\n" +
$"Action index: {scriptedEvent.CurrentActionIndex.ColorizeObject()}\n" +
$"Current action: {currentEvent?.ToDebugString() ?? ToolBox.ColorizeObject(null)}\n";
text += "All actions:\n";
text += FindActions(scriptedEvent).Aggregate(string.Empty, (current, action) => current + $"{new string(' ', action.Item1 * 6)}{action.Item2.ToDebugString()}\n");
text += "Targets:\n";
foreach (var (key, value) in scriptedEvent.Targets)
{
text += $" {key.ColorizeObject()}: {value.Aggregate(string.Empty, (current, entity) => current + $"{entity.ColorizeObject()} ")}\n";
}
string text = scriptedEvent.GetDebugInfo();
if (scriptedEvent.Targets != null)
{
foreach ((_, List<Entity> entities) in scriptedEvent.Targets)
@@ -452,10 +438,7 @@ namespace Barotrauma
{
debugPositions.Clear();
string text = $"Finished: {artifactEvent.IsFinished.ColorizeObject()}\n" +
$"Item: {artifactEvent.Item.ColorizeObject()}\n" +
$"Spawn pending: {artifactEvent.SpawnPending.ColorizeObject()}\n" +
$"Spawn position: {artifactEvent.SpawnPos.ColorizeObject()}\n";
string text = artifactEvent.GetDebugInfo();
if (artifactEvent.Item != null && !artifactEvent.Item.Removed)
{
@@ -470,10 +453,7 @@ namespace Barotrauma
{
debugPositions.Clear();
string text = $"Finished: {monsterEvent.IsFinished.ColorizeObject()}\n" +
$"Amount: {monsterEvent.MinAmount.ColorizeObject()} - {monsterEvent.MaxAmount.ColorizeObject()}\n" +
$"Spawn pending: {monsterEvent.SpawnPending.ColorizeObject()}\n" +
$"Spawn position: {monsterEvent.SpawnPos.ColorizeObject()}\n";
string text = monsterEvent.GetDebugInfo();
if (monsterEvent.SpawnPos != null && Submarine.MainSub != null)
{
@@ -712,7 +692,30 @@ namespace Barotrauma
}
}
break;
case NetworkEventType.EVENTLOG:
ClientReadEventLog(GameMain.Client, msg);
break;
case NetworkEventType.EVENTOBJECTIVE:
ClientReadEventObjective(GameMain.Client, msg);
break;
}
}
private void ClientReadEventLog(GameClient client, IReadMessage msg)
{
NetEventLogEntry entry = INetSerializableStruct.Read<NetEventLogEntry>(msg);
EventLog.AddEntry(entry.EventPrefabId, entry.LogEntryId, entry.Text.Replace("\\n", "\n"));
}
private static void ClientReadEventObjective(GameClient client, IReadMessage msg)
{
NetEventObjective entry = INetSerializableStruct.Read<NetEventObjective>(msg);
EventObjectiveAction.Trigger(
entry.Type,
entry.Identifier,
entry.ObjectiveTag,
entry.ParentObjectiveId,
entry.TextTag,
entry.CanBeCompleted);
}
}
}
@@ -1,4 +1,5 @@
using Barotrauma.Items.Components;
using Barotrauma.Extensions;
using Barotrauma.Items.Components;
using Barotrauma.Networking;
using System.Collections.Generic;
@@ -9,22 +10,37 @@ namespace Barotrauma
public override bool DisplayAsCompleted => false;
public override bool DisplayAsFailed => false;
public override int State
{
get => base.State;
set
{
base.State = value;
if (base.State > 0)
{
caves.ForEach(c => c.MissionsToDisplayOnSonar.Remove(this));
}
}
}
public override void ClientReadInitial(IReadMessage msg)
{
base.ClientReadInitial(msg);
byte caveCount = msg.ReadByte();
for (int i = 0; i < caveCount; i++)
{
byte selectedCave = msg.ReadByte();
if (selectedCave < 255 && Level.Loaded != null)
byte selectedCaveIndex = msg.ReadByte();
if (selectedCaveIndex < 255 && Level.Loaded != null)
{
if (selectedCave < Level.Loaded.Caves.Count)
if (selectedCaveIndex < Level.Loaded.Caves.Count)
{
Level.Loaded.Caves[selectedCave].DisplayOnSonar = true;
var selectedCave = Level.Loaded.Caves[selectedCaveIndex];
selectedCave.MissionsToDisplayOnSonar.Add(this);
caves.Add(selectedCave);
}
else
{
DebugConsole.ThrowError($"Cave index out of bounds when reading nest mission data. Index: {selectedCave}, number of caves: {Level.Loaded.Caves.Count}");
DebugConsole.ThrowError($"Cave index out of bounds when reading nest mission data. Index: {selectedCaveIndex}, number of caves: {Level.Loaded.Caves.Count}");
}
}
}
@@ -4,6 +4,7 @@ using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using static Barotrauma.MissionPrefab;
namespace Barotrauma
{
@@ -27,7 +28,11 @@ namespace Barotrauma
public Color GetDifficultyColor()
{
int v = Difficulty ?? MissionPrefab.MinDifficulty;
return GetDifficultyColor(Difficulty ?? MissionPrefab.MinDifficulty);
}
public static Color GetDifficultyColor(int difficulty)
{
int v = difficulty;
float t = MathUtils.InverseLerp(MissionPrefab.MinDifficulty, MissionPrefab.MaxDifficulty, v);
return ToolBox.GradientLerp(t, GUIStyle.Green, GUIStyle.Orange, GUIStyle.Red);
}
@@ -61,36 +66,48 @@ namespace Barotrauma
List<LocalizedString> reputationRewardTexts = new List<LocalizedString>();
foreach (var reputationReward in ReputationRewards)
{
FactionPrefab targetFactionPrefab;
if (reputationReward.Key == "location" )
FactionPrefab factionPrefab;
if (reputationReward.FactionIdentifier == "location" )
{
targetFactionPrefab = OriginLocation.Faction?.Prefab;
factionPrefab = OriginLocation.Faction?.Prefab;
}
else
{
FactionPrefab.Prefabs.TryGet(reputationReward.Key, out targetFactionPrefab);
}
if (targetFactionPrefab == null)
{
return string.Empty;
FactionPrefab.Prefabs.TryGet(reputationReward.FactionIdentifier, out factionPrefab);
}
float totalReputationChange = reputationReward.Value;
if (GameMain.GameSession?.Campaign?.Factions.Find(f => f.Prefab == targetFactionPrefab) is Faction faction)
if (factionPrefab != null)
{
totalReputationChange = reputationReward.Value * faction.Reputation.GetReputationChangeMultiplier(reputationReward.Value);
AddReputationText(factionPrefab, reputationReward.Amount);
if (!MathUtils.NearlyEqual(reputationReward.AmountForOpposingFaction, 0.0f) &&
FactionPrefab.Prefabs.TryGet(factionPrefab.OpposingFaction, out var opposingFactionPrefab))
{
AddReputationText(opposingFactionPrefab, reputationReward.AmountForOpposingFaction);
}
}
}
void AddReputationText(FactionPrefab factionPrefab, float amount)
{
if (factionPrefab == null) { return; }
float totalReputationChange = amount;
if (GameMain.GameSession?.Campaign?.Factions.Find(f => f.Prefab == factionPrefab) is Faction faction)
{
totalReputationChange = amount * faction.Reputation.GetReputationChangeMultiplier(amount);
}
LocalizedString name = $"‖color:{XMLExtensions.ToStringHex(targetFactionPrefab.IconColor)}‖{targetFactionPrefab.Name}‖end‖";
LocalizedString name = $"‖color:{XMLExtensions.ToStringHex(factionPrefab.IconColor)}‖{factionPrefab.Name}‖end‖";
float normalizedValue = MathUtils.InverseLerp(-100.0f, 100.0f, totalReputationChange);
string formattedValue = ((int)Math.Round(totalReputationChange)).ToString("+#;-#;0"); //force plus sign for positive numbers
LocalizedString rewardText = TextManager.GetWithVariables(
"reputationformat",
("[reputationname]", name),
("[reputationvalue]", $"‖color:{XMLExtensions.ToStringHex(Reputation.GetReputationColor(normalizedValue))}‖{formattedValue}‖end‖" ));
("[reputationvalue]", $"‖color:{XMLExtensions.ToStringHex(Reputation.GetReputationColor(normalizedValue))}‖{formattedValue}‖end‖"));
reputationRewardTexts.Add(rewardText.Value);
}
if (reputationRewardTexts.Any())
{
return RichString.Rich(TextManager.AddPunctuation(':', TextManager.Get("reputation"), LocalizedString.Join(", ", reputationRewardTexts)));
@@ -100,6 +117,20 @@ namespace Barotrauma
return string.Empty;
}
}
partial void DistributeExperienceToCrew(IEnumerable<Character> crew, int experienceGain)
{
foreach (Character character in crew)
{
GiveMissionExperience(character.Info);
}
void GiveMissionExperience(CharacterInfo info)
{
if (info == null) { return; }
var experienceGainMultiplierIndividual = new AbilityMissionExperienceGainMultiplier(this, 1f);
info.Character?.CheckTalents(AbilityEffectType.OnGainMissionExperience, experienceGainMultiplierIndividual);
info.GiveExperience((int)(experienceGain * experienceGainMultiplierIndividual.Value));
}
}
partial void ShowMessageProjSpecific(int missionState)
{
@@ -9,6 +9,19 @@ namespace Barotrauma
public override bool DisplayAsCompleted => State > 0 && !requireDelivery;
public override bool DisplayAsFailed => false;
public override int State
{
get => base.State;
set
{
base.State = value;
if (base.State > 0 && selectedCave != null)
{
selectedCave.MissionsToDisplayOnSonar.Remove(this);
}
}
}
public override void ClientReadInitial(IReadMessage msg)
{
base.ClientReadInitial(msg);
@@ -20,8 +33,9 @@ namespace Barotrauma
{
if (selectedCaveIndex < Level.Loaded.Caves.Count)
{
Level.Loaded.Caves[selectedCaveIndex].DisplayOnSonar = true;
SpawnNestObjects(Level.Loaded, Level.Loaded.Caves[selectedCaveIndex]);
selectedCave = Level.Loaded.Caves[selectedCaveIndex];
selectedCave.MissionsToDisplayOnSonar.Add(this);
SpawnNestObjects(Level.Loaded, selectedCave);
}
else
{