v0.13.0.11
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -18,6 +18,8 @@ namespace Barotrauma
|
||||
protected Color overlayTextColor;
|
||||
protected Sprite overlaySprite;
|
||||
|
||||
private TransitionType prevCampaignUIAutoOpenType;
|
||||
|
||||
protected GUIButton endRoundButton;
|
||||
|
||||
public GUIButton ReadyCheckButton;
|
||||
@@ -53,19 +55,26 @@ namespace Barotrauma
|
||||
{
|
||||
chatBox.ToggleOpen = wasChatBoxOpen;
|
||||
}
|
||||
if (!value && CampaignUI?.SelectedTab == InteractionType.PurchaseSub)
|
||||
{
|
||||
SubmarinePreview.Close();
|
||||
}
|
||||
showCampaignUI = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override void ShowStartMessage()
|
||||
{
|
||||
if (Mission == null) return;
|
||||
|
||||
new GUIMessageBox(Mission.Name, Mission.Description, new string[0], type: GUIMessageBox.Type.InGame, icon: Mission.Prefab.Icon)
|
||||
foreach (Mission mission in Missions)
|
||||
{
|
||||
IconColor = Mission.Prefab.IconColor,
|
||||
UserData = "missionstartmessage"
|
||||
};
|
||||
new GUIMessageBox(
|
||||
mission.Prefab.IsSideObjective ? TextManager.AddPunctuation(':', TextManager.Get("sideobjective"), mission.Name) : mission.Name,
|
||||
mission.Description, new string[0], type: GUIMessageBox.Type.InGame, icon: mission.Prefab.Icon, parseRichText: true)
|
||||
{
|
||||
IconColor = mission.Prefab.IconColor,
|
||||
UserData = "missionstartmessage"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -119,22 +128,22 @@ namespace Barotrauma
|
||||
{
|
||||
var backgroundSprite = GUI.Style.GetComponentStyle("CommandBackground").GetDefaultSprite();
|
||||
Vector2 centerPos = new Vector2(GameMain.GraphicsWidth, GameMain.GraphicsHeight) / 2;
|
||||
string wrappedText = ToolBox.WrapText(overlayText, GameMain.GraphicsWidth / 3, GUI.Font);
|
||||
Vector2 textSize = GUI.Font.MeasureString(wrappedText);
|
||||
Vector2 textPos = centerPos - textSize / 2;
|
||||
backgroundSprite.Draw(spriteBatch,
|
||||
centerPos,
|
||||
Color.White * (overlayTextColor.A / 255.0f),
|
||||
origin: backgroundSprite.size / 2,
|
||||
rotate: 0.0f,
|
||||
scale: new Vector2(1.5f, 0.7f) * (GameMain.GraphicsWidth / 3 / backgroundSprite.size.X));
|
||||
scale: new Vector2(GameMain.GraphicsWidth / 2 / backgroundSprite.size.X, textSize.Y / backgroundSprite.size.Y * 1.5f));
|
||||
|
||||
string wrappedText = ToolBox.WrapText(overlayText, GameMain.GraphicsWidth / 3, GUI.Font);
|
||||
Vector2 textSize = GUI.Font.MeasureString(wrappedText);
|
||||
Vector2 textPos = centerPos - textSize / 2;
|
||||
GUI.DrawString(spriteBatch, textPos + Vector2.One, wrappedText, Color.Black * (overlayTextColor.A / 255.0f));
|
||||
GUI.DrawString(spriteBatch, textPos, wrappedText, overlayTextColor);
|
||||
|
||||
if (!string.IsNullOrEmpty(overlayTextBottom))
|
||||
{
|
||||
Vector2 bottomTextPos = centerPos + new Vector2(0.0f, textSize.Y + 30 * GUI.Scale) - GUI.Font.MeasureString(overlayTextBottom) / 2;
|
||||
Vector2 bottomTextPos = centerPos + new Vector2(0.0f, textSize.Y / 2 + 40 * GUI.Scale) - GUI.Font.MeasureString(overlayTextBottom) / 2;
|
||||
GUI.DrawString(spriteBatch, bottomTextPos + Vector2.One, overlayTextBottom, Color.Black * (overlayTextColor.A / 255.0f));
|
||||
GUI.DrawString(spriteBatch, bottomTextPos, overlayTextBottom, overlayTextColor);
|
||||
}
|
||||
@@ -147,7 +156,7 @@ namespace Barotrauma
|
||||
if (ReadyCheckButton != null) { ReadyCheckButton.Visible = false; }
|
||||
return;
|
||||
}
|
||||
if (Submarine.MainSub == null) { return; }
|
||||
if (Submarine.MainSub == null || Level.Loaded == null) { return; }
|
||||
|
||||
endRoundButton.Visible = false;
|
||||
var availableTransition = GetAvailableTransition(out _, out Submarine leavingSub);
|
||||
@@ -158,7 +167,8 @@ namespace Barotrauma
|
||||
case TransitionType.ProgressToNextEmptyLocation:
|
||||
if (Level.Loaded.EndOutpost == null || !Level.Loaded.EndOutpost.DockedTo.Contains(leavingSub))
|
||||
{
|
||||
buttonText = TextManager.GetWithVariable("EnterLocation", "[locationname]", Level.Loaded.EndLocation?.Name ?? "[ERROR]");
|
||||
string textTag = availableTransition == TransitionType.ProgressToNextLocation ? "EnterLocation" : "EnterEmptyLocation";
|
||||
buttonText = TextManager.GetWithVariable(textTag, "[locationname]", Level.Loaded.EndLocation?.Name ?? "[ERROR]");
|
||||
endRoundButton.Visible = !ForceMapUI && !ShowCampaignUI;
|
||||
}
|
||||
break;
|
||||
@@ -170,7 +180,8 @@ namespace Barotrauma
|
||||
case TransitionType.ReturnToPreviousEmptyLocation:
|
||||
if (Level.Loaded.StartOutpost == null || !Level.Loaded.StartOutpost.DockedTo.Contains(leavingSub))
|
||||
{
|
||||
buttonText = TextManager.GetWithVariable("EnterLocation", "[locationname]", Level.Loaded.StartLocation?.Name ?? "[ERROR]");
|
||||
string textTag = availableTransition == TransitionType.ReturnToPreviousLocation ? "EnterLocation" : "EnterEmptyLocation";
|
||||
buttonText = TextManager.GetWithVariable(textTag, "[locationname]", Level.Loaded.StartLocation?.Name ?? "[ERROR]");
|
||||
endRoundButton.Visible = !ForceMapUI && !ShowCampaignUI;
|
||||
}
|
||||
|
||||
@@ -194,7 +205,20 @@ namespace Barotrauma
|
||||
|
||||
if (endRoundButton.Visible)
|
||||
{
|
||||
if (!AllowedToEndRound()) { buttonText = TextManager.Get("map"); }
|
||||
if (!AllowedToEndRound())
|
||||
{
|
||||
buttonText = TextManager.Get("map");
|
||||
}
|
||||
else if (prevCampaignUIAutoOpenType != availableTransition &&
|
||||
(availableTransition == TransitionType.ProgressToNextEmptyLocation || availableTransition == TransitionType.ReturnToPreviousEmptyLocation))
|
||||
{
|
||||
HintManager.OnAvailableTransition(availableTransition);
|
||||
//opening the campaign map pauses the game and prevents HintManager from running -> update it manually to get the hint to show up immediately
|
||||
HintManager.Update();
|
||||
Map.SelectLocation(-1);
|
||||
endRoundButton.OnClicked(EndRoundButton, null);
|
||||
prevCampaignUIAutoOpenType = availableTransition;
|
||||
}
|
||||
endRoundButton.Text = ToolBox.LimitString(buttonText, endRoundButton.Font, endRoundButton.Rect.Width - 5);
|
||||
if (endRoundButton.Text != buttonText)
|
||||
{
|
||||
@@ -209,15 +233,20 @@ namespace Barotrauma
|
||||
{
|
||||
endRoundButton.RectTransform.ScreenSpaceOffset = new Point(0, Character.Controlled.CharacterHealth.SuicideButton.Rect.Height);
|
||||
}
|
||||
else if (GameMain.Client != null && GameMain.Client.IsFollowSubTickBoxVisible)
|
||||
{
|
||||
endRoundButton.RectTransform.ScreenSpaceOffset = new Point(0, HUDLayoutSettings.Padding + GameMain.Client.FollowSubTickBox.Rect.Height);
|
||||
}
|
||||
else
|
||||
{
|
||||
endRoundButton.RectTransform.ScreenSpaceOffset = Point.Zero;
|
||||
}
|
||||
}
|
||||
endRoundButton.DrawManually(spriteBatch);
|
||||
if (this is MultiPlayerCampaign)
|
||||
if (this is MultiPlayerCampaign && ReadyCheckButton != null)
|
||||
{
|
||||
ReadyCheckButton?.DrawManually(spriteBatch);
|
||||
ReadyCheckButton.RectTransform.ScreenSpaceOffset = endRoundButton.RectTransform.ScreenSpaceOffset;
|
||||
ReadyCheckButton.DrawManually(spriteBatch);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+62
-23
@@ -227,6 +227,11 @@ namespace Barotrauma
|
||||
float timer = 0.0f;
|
||||
while (timer < textDuration)
|
||||
{
|
||||
if (GameMain.GameSession == null || Screen.Selected != GameMain.GameScreen)
|
||||
{
|
||||
GUI.DisableHUD = false;
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
// Try to grab the controlled here to prevent inputs, assigned late on multiplayer
|
||||
if (Character.Controlled != null)
|
||||
{
|
||||
@@ -239,11 +244,20 @@ namespace Barotrauma
|
||||
timer = Math.Min(timer + CoroutineManager.DeltaTime, textDuration);
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
var outpost = GameMain.GameSession.Level.StartOutpost;
|
||||
var borders = outpost.GetDockedBorders();
|
||||
borders.Location += outpost.WorldPosition.ToPoint();
|
||||
GameMain.GameScreen.Cam.Position = new Vector2(borders.X + borders.Width / 2, borders.Y - borders.Height / 2);
|
||||
float startZoom = 0.8f /
|
||||
((float)Math.Max(borders.Width, borders.Height) / (float)GameMain.GameScreen.Cam.Resolution.X);
|
||||
GameMain.GameScreen.Cam.MinZoom = Math.Min(startZoom, GameMain.GameScreen.Cam.MinZoom);
|
||||
var transition = new CameraTransition(prevControlled, GameMain.GameScreen.Cam,
|
||||
null, null,
|
||||
fadeOut: false,
|
||||
duration: 5,
|
||||
startZoom: 1.5f, endZoom: 1.0f)
|
||||
losFadeIn: true,
|
||||
waitDuration: 1,
|
||||
panDuration: 5,
|
||||
startZoom: startZoom, endZoom: 1.0f)
|
||||
{
|
||||
AllowInterrupt = true,
|
||||
RemoveControlFromCharacter = false
|
||||
@@ -274,7 +288,8 @@ namespace Barotrauma
|
||||
var transition = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam,
|
||||
null, null,
|
||||
fadeOut: false,
|
||||
duration: 5,
|
||||
losFadeIn: true,
|
||||
panDuration: 5,
|
||||
startZoom: 0.5f, endZoom: 1.0f)
|
||||
{
|
||||
AllowInterrupt = true,
|
||||
@@ -311,6 +326,7 @@ namespace Barotrauma
|
||||
Level prevLevel = Level.Loaded;
|
||||
|
||||
bool success = CrewManager.GetCharacters().Any(c => !c.IsDead);
|
||||
GUI.SetSavingIndicatorState(success);
|
||||
crewDead = false;
|
||||
|
||||
var continueButton = GameMain.GameSession.RoundSummary?.ContinueButton;
|
||||
@@ -327,7 +343,7 @@ namespace Barotrauma
|
||||
var endTransition = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam, null,
|
||||
Alignment.Center,
|
||||
fadeOut: false,
|
||||
duration: EndTransitionDuration);
|
||||
panDuration: EndTransitionDuration);
|
||||
GameMain.Client.EndCinematic = endTransition;
|
||||
|
||||
Location portraitLocation = Map?.SelectedLocation ?? Map?.CurrentLocation ?? Level.Loaded?.StartLocation;
|
||||
@@ -335,7 +351,7 @@ namespace Barotrauma
|
||||
{
|
||||
overlaySprite = portraitLocation.Type.GetPortrait(portraitLocation.PortraitId);
|
||||
}
|
||||
float fadeOutDuration = endTransition.Duration;
|
||||
float fadeOutDuration = endTransition.PanDuration;
|
||||
float t = 0.0f;
|
||||
while (t < fadeOutDuration || endTransition.Running)
|
||||
{
|
||||
@@ -368,6 +384,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
GUI.SetSavingIndicatorState(false);
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
|
||||
@@ -420,7 +437,7 @@ namespace Barotrauma
|
||||
{
|
||||
//wasn't initially docked (sub doesn't have a docking port?)
|
||||
// -> choose a destination when the sub is far enough from the start outpost
|
||||
if (!Submarine.MainSub.AtStartPosition)
|
||||
if (!Submarine.MainSub.AtStartExit)
|
||||
{
|
||||
ForceMapUI = true;
|
||||
if (CampaignUI == null) { InitCampaignUI(); }
|
||||
@@ -437,8 +454,10 @@ namespace Barotrauma
|
||||
{
|
||||
ShowCampaignUI = false;
|
||||
}
|
||||
HintManager.OnAvailableTransition(transitionType);
|
||||
}
|
||||
}
|
||||
|
||||
public override void End(TransitionType transitionType = TransitionType.None)
|
||||
{
|
||||
base.End(transitionType);
|
||||
@@ -496,7 +515,7 @@ namespace Barotrauma
|
||||
var transition = new CameraTransition(endObject ?? Submarine.MainSub, GameMain.GameScreen.Cam,
|
||||
null, Alignment.Center,
|
||||
fadeOut: true,
|
||||
duration: 10,
|
||||
panDuration: 10,
|
||||
startZoom: null, endZoom: 0.2f);
|
||||
|
||||
while (transition.Running)
|
||||
@@ -649,7 +668,7 @@ namespace Barotrauma
|
||||
{
|
||||
string savePath = SaveUtil.CreateSavePath(SaveUtil.SaveType.Multiplayer);
|
||||
|
||||
GameMain.GameSession = new GameSession(null, savePath, GameModePreset.MultiPlayerCampaign, mapSeed);
|
||||
GameMain.GameSession = new GameSession(null, savePath, GameModePreset.MultiPlayerCampaign, CampaignSettings.Unsure, mapSeed);
|
||||
campaign = (MultiPlayerCampaign)GameMain.GameSession.GameMode;
|
||||
campaign.CampaignID = campaignID;
|
||||
GameMain.NetLobbyScreen.ToggleCampaignMode(true);
|
||||
@@ -711,13 +730,20 @@ namespace Barotrauma
|
||||
DebugConsole.ThrowError($"Error when receiving campaign data from the server: mission prefab \"{availableMission.First}\" not found.");
|
||||
continue;
|
||||
}
|
||||
if (availableMission.Second < 0 || availableMission.Second >= campaign.Map.CurrentLocation.Connections.Count)
|
||||
if (availableMission.Second == 255)
|
||||
{
|
||||
DebugConsole.ThrowError($"Error when receiving campaign data from the server: connection index for mission \"{availableMission.First}\" out of range (index: {availableMission.Second}, current location: {campaign.Map.CurrentLocation.Name}, connections: {campaign.Map.CurrentLocation.Connections.Count}).");
|
||||
continue;
|
||||
campaign.Map.CurrentLocation.UnlockMission(missionPrefab);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (availableMission.Second < 0 || availableMission.Second >= campaign.Map.CurrentLocation.Connections.Count)
|
||||
{
|
||||
DebugConsole.ThrowError($"Error when receiving campaign data from the server: connection index for mission \"{availableMission.First}\" out of range (index: {availableMission.Second}, current location: {campaign.Map.CurrentLocation.Name}, connections: {campaign.Map.CurrentLocation.Connections.Count}).");
|
||||
continue;
|
||||
}
|
||||
LocationConnection connection = campaign.Map.CurrentLocation.Connections[availableMission.Second];
|
||||
campaign.Map.CurrentLocation.UnlockMission(missionPrefab, connection);
|
||||
}
|
||||
LocationConnection connection = campaign.Map.CurrentLocation.Connections[availableMission.Second];
|
||||
campaign.Map.CurrentLocation.UnlockMission(missionPrefab, connection);
|
||||
}
|
||||
|
||||
GameMain.NetLobbyScreen.ToggleCampaignMode(true);
|
||||
@@ -770,16 +796,29 @@ namespace Barotrauma
|
||||
{
|
||||
pendingHires.Add(msg.ReadInt32());
|
||||
}
|
||||
|
||||
bool validateHires = msg.ReadBoolean();
|
||||
|
||||
ushort hiredLength = msg.ReadUInt16();
|
||||
List<CharacterInfo> hiredCharacters = new List<CharacterInfo>();
|
||||
for (int i = 0; i < hiredLength; i++)
|
||||
{
|
||||
CharacterInfo hired = CharacterInfo.ClientRead("human", msg);
|
||||
hired.Salary = msg.ReadInt32();
|
||||
hiredCharacters.Add(hired);
|
||||
}
|
||||
|
||||
bool renameCrewMember = msg.ReadBoolean();
|
||||
if (renameCrewMember)
|
||||
{
|
||||
int renamedIdentifier = msg.ReadInt32();
|
||||
string newName = msg.ReadString();
|
||||
CharacterInfo renamedCharacter = CrewManager.CharacterInfos.FirstOrDefault(info => info.GetIdentifierUsingOriginalName() == renamedIdentifier);
|
||||
if (renamedCharacter != null) { CrewManager.RenameCharacter(renamedCharacter, newName); }
|
||||
}
|
||||
|
||||
bool fireCharacter = msg.ReadBoolean();
|
||||
|
||||
int firedIdentifier = -1;
|
||||
if (fireCharacter) { firedIdentifier = msg.ReadInt32(); }
|
||||
|
||||
if (fireCharacter)
|
||||
{
|
||||
int firedIdentifier = msg.ReadInt32();
|
||||
CharacterInfo firedCharacter = CrewManager.CharacterInfos.FirstOrDefault(info => info.GetIdentifier() == firedIdentifier);
|
||||
// this one might and is allowed to be null since the character is already fired on the original sender's game
|
||||
if (firedCharacter != null) { CrewManager.FireCharacter(firedCharacter); }
|
||||
@@ -787,10 +826,10 @@ namespace Barotrauma
|
||||
|
||||
if (map?.CurrentLocation?.HireManager != null && CampaignUI?.CrewManagement != null)
|
||||
{
|
||||
CampaignUI?.CrewManagement?.SetHireables(map.CurrentLocation, availableHires);
|
||||
if (validateHires) { CampaignUI?.CrewManagement.ValidatePendingHires(); }
|
||||
CampaignUI?.CrewManagement?.SetPendingHires(pendingHires, map?.CurrentLocation);
|
||||
if (fireCharacter) { CampaignUI?.CrewManagement.UpdateCrew(); }
|
||||
CampaignUI.CrewManagement.SetHireables(map.CurrentLocation, availableHires);
|
||||
if (hiredCharacters.Any()) { CampaignUI.CrewManagement.ValidateHires(hiredCharacters); }
|
||||
CampaignUI.CrewManagement.SetPendingHires(pendingHires, map.CurrentLocation);
|
||||
if (renameCrewMember || fireCharacter) { CampaignUI.CrewManagement.UpdateCrew(); }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+43
-27
@@ -22,7 +22,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (CoroutineManager.IsCoroutineRunning("LevelTransition") || CoroutineManager.IsCoroutineRunning("SubmarineTransition") || gameOver) { return; }
|
||||
|
||||
if (PlayerInput.RightButtonClicked() ||
|
||||
if (PlayerInput.SecondaryMouseButtonClicked() ||
|
||||
PlayerInput.KeyHit(Microsoft.Xna.Framework.Input.Keys.Escape))
|
||||
{
|
||||
ShowCampaignUI = false;
|
||||
@@ -57,11 +57,12 @@ namespace Barotrauma
|
||||
/// <summary>
|
||||
/// Instantiates a new single player campaign
|
||||
/// </summary>
|
||||
private SinglePlayerCampaign(string mapSeed) : base(GameModePreset.SinglePlayerCampaign)
|
||||
private SinglePlayerCampaign(string mapSeed, CampaignSettings settings) : base(GameModePreset.SinglePlayerCampaign)
|
||||
{
|
||||
CampaignMetadata = new CampaignMetadata(this);
|
||||
UpgradeManager = new UpgradeManager(this);
|
||||
map = new Map(this, mapSeed);
|
||||
map = new Map(this, mapSeed, settings);
|
||||
Settings = settings;
|
||||
foreach (JobPrefab jobPrefab in JobPrefab.Prefabs)
|
||||
{
|
||||
for (int i = 0; i < jobPrefab.InitialCount; i++)
|
||||
@@ -85,11 +86,14 @@ namespace Barotrauma
|
||||
{
|
||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||
{
|
||||
case "campaignsettings":
|
||||
Settings = new CampaignSettings(subElement);
|
||||
break;
|
||||
case "crew":
|
||||
GameMain.GameSession.CrewManager = new CrewManager(subElement, true);
|
||||
break;
|
||||
case "map":
|
||||
map = Map.Load(this, subElement);
|
||||
map = Map.Load(this, subElement, Settings);
|
||||
break;
|
||||
case "metadata":
|
||||
CampaignMetadata = new CampaignMetadata(this, subElement);
|
||||
@@ -141,9 +145,9 @@ namespace Barotrauma
|
||||
/// <summary>
|
||||
/// Start a completely new single player campaign
|
||||
/// </summary>
|
||||
public static SinglePlayerCampaign StartNew(string mapSeed, SubmarineInfo selectedSub)
|
||||
public static SinglePlayerCampaign StartNew(string mapSeed, SubmarineInfo selectedSub, CampaignSettings settings)
|
||||
{
|
||||
var campaign = new SinglePlayerCampaign(mapSeed);
|
||||
var campaign = new SinglePlayerCampaign(mapSeed, settings);
|
||||
return campaign;
|
||||
}
|
||||
|
||||
@@ -213,6 +217,7 @@ namespace Barotrauma
|
||||
|
||||
if (!savedOnStart)
|
||||
{
|
||||
GUI.SetSavingIndicatorState(true);
|
||||
SaveUtil.SaveGame(GameMain.GameSession.SavePath);
|
||||
savedOnStart = true;
|
||||
}
|
||||
@@ -224,6 +229,8 @@ namespace Barotrauma
|
||||
{
|
||||
PetBehavior.LoadPets(petsElement);
|
||||
}
|
||||
|
||||
GUI.DisableSavingIndicatorDelayed();
|
||||
}
|
||||
|
||||
protected override void LoadInitialLevel()
|
||||
@@ -290,15 +297,29 @@ namespace Barotrauma
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (GameMain.GameSession == null)
|
||||
{
|
||||
GUI.DisableHUD = false;
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
overlayTextColor = Color.Lerp(Color.Transparent, Color.White, (timer - 1.0f) / fadeInDuration);
|
||||
timer = Math.Min(timer + CoroutineManager.DeltaTime, textDuration);
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
var outpost = GameMain.GameSession.Level.StartOutpost;
|
||||
var borders = outpost.GetDockedBorders();
|
||||
borders.Location += outpost.WorldPosition.ToPoint();
|
||||
GameMain.GameScreen.Cam.Position = new Vector2(borders.X + borders.Width / 2, borders.Y - borders.Height / 2);
|
||||
float startZoom = 0.8f /
|
||||
((float)Math.Max(borders.Width, borders.Height) / (float)GameMain.GameScreen.Cam.Resolution.X);
|
||||
GameMain.GameScreen.Cam.MinZoom = Math.Min(startZoom, GameMain.GameScreen.Cam.MinZoom);
|
||||
var transition = new CameraTransition(prevControlled, GameMain.GameScreen.Cam,
|
||||
null, null,
|
||||
fadeOut: false,
|
||||
duration: 5,
|
||||
startZoom: 1.5f, endZoom: 1.0f)
|
||||
losFadeIn: true,
|
||||
waitDuration: 1,
|
||||
panDuration: 5,
|
||||
startZoom: startZoom, endZoom: 1.0f)
|
||||
{
|
||||
AllowInterrupt = true,
|
||||
RemoveControlFromCharacter = false
|
||||
@@ -323,19 +344,13 @@ namespace Barotrauma
|
||||
else
|
||||
{
|
||||
ISpatialEntity transitionTarget;
|
||||
if (prevControlled != null)
|
||||
{
|
||||
transitionTarget = prevControlled;
|
||||
}
|
||||
else
|
||||
{
|
||||
transitionTarget = Submarine.MainSub;
|
||||
}
|
||||
transitionTarget = (ISpatialEntity)prevControlled ?? Submarine.MainSub;
|
||||
|
||||
var transition = new CameraTransition(transitionTarget, GameMain.GameScreen.Cam,
|
||||
null, null,
|
||||
fadeOut: false,
|
||||
duration: 5,
|
||||
losFadeIn: prevControlled != null,
|
||||
panDuration: 5,
|
||||
startZoom: 0.5f, endZoom: 1.0f)
|
||||
{
|
||||
AllowInterrupt = true,
|
||||
@@ -370,11 +385,9 @@ namespace Barotrauma
|
||||
bool success = CrewManager.GetCharacters().Any(c => !c.IsDead);
|
||||
SoundPlayer.OverrideMusicType = success ? "endround" : "crewdead";
|
||||
SoundPlayer.OverrideMusicDuration = 18.0f;
|
||||
GUI.SetSavingIndicatorState(success);
|
||||
crewDead = false;
|
||||
|
||||
LevelData lvlData = GameMain.GameSession.LevelData;
|
||||
bool beaconActive = GameMain.GameSession.Level.CheckBeaconActive();
|
||||
|
||||
GameMain.GameSession.EndRound("", traitorResults, transitionType);
|
||||
var continueButton = GameMain.GameSession.RoundSummary?.ContinueButton;
|
||||
RoundSummary roundSummary = null;
|
||||
@@ -408,13 +421,13 @@ namespace Barotrauma
|
||||
var endTransition = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam, null,
|
||||
transitionType == TransitionType.LeaveLocation ? Alignment.BottomCenter : Alignment.Center,
|
||||
fadeOut: false,
|
||||
duration: EndTransitionDuration);
|
||||
panDuration: EndTransitionDuration);
|
||||
|
||||
GUI.ClearMessages();
|
||||
|
||||
Location portraitLocation = Map.SelectedLocation ?? Map.CurrentLocation;
|
||||
overlaySprite = portraitLocation.Type.GetPortrait(portraitLocation.PortraitId);
|
||||
float fadeOutDuration = endTransition.Duration;
|
||||
float fadeOutDuration = endTransition.PanDuration;
|
||||
float t = 0.0f;
|
||||
while (t < fadeOutDuration || endTransition.Running)
|
||||
{
|
||||
@@ -459,8 +472,6 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
lvlData.IsBeaconActive = beaconActive;
|
||||
|
||||
SaveUtil.SaveGame(GameMain.GameSession.SavePath);
|
||||
}
|
||||
else
|
||||
@@ -484,6 +495,7 @@ namespace Barotrauma
|
||||
overlayColor = Color.Transparent;
|
||||
});
|
||||
|
||||
GUI.SetSavingIndicatorState(false);
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
|
||||
@@ -510,7 +522,7 @@ namespace Barotrauma
|
||||
var transition = new CameraTransition(endObject ?? Submarine.MainSub, GameMain.GameScreen.Cam,
|
||||
null, Alignment.Center,
|
||||
fadeOut: true,
|
||||
duration: 10,
|
||||
panDuration: 10,
|
||||
startZoom: null, endZoom: 0.2f);
|
||||
|
||||
while (transition.Running)
|
||||
@@ -530,6 +542,8 @@ namespace Barotrauma
|
||||
if (CoroutineManager.IsCoroutineRunning("LevelTransition") || CoroutineManager.IsCoroutineRunning("SubmarineTransition") || gameOver) { return; }
|
||||
|
||||
base.Update(deltaTime);
|
||||
|
||||
Map?.Radiation?.UpdateRadiation(deltaTime);
|
||||
|
||||
if (PlayerInput.SecondaryMouseButtonClicked() ||
|
||||
PlayerInput.KeyHit(Microsoft.Xna.Framework.Input.Keys.Escape))
|
||||
@@ -583,7 +597,7 @@ namespace Barotrauma
|
||||
{
|
||||
//wasn't initially docked (sub doesn't have a docking port?)
|
||||
// -> choose a destination when the sub is far enough from the start outpost
|
||||
if (!Submarine.MainSub.AtStartPosition)
|
||||
if (!Submarine.MainSub.AtStartExit)
|
||||
{
|
||||
ForceMapUI = true;
|
||||
CampaignUI.SelectTab(InteractionType.Map);
|
||||
@@ -611,6 +625,7 @@ namespace Barotrauma
|
||||
{
|
||||
ShowCampaignUI = false;
|
||||
}
|
||||
HintManager.OnAvailableTransition(transitionType);
|
||||
}
|
||||
|
||||
if (!crewDead)
|
||||
@@ -632,9 +647,9 @@ namespace Barotrauma
|
||||
if (nextLevel == null)
|
||||
{
|
||||
//no level selected -> force the player to select one
|
||||
ForceMapUI = true;
|
||||
CampaignUI.SelectTab(InteractionType.Map);
|
||||
map.SelectLocation(-1);
|
||||
ForceMapUI = true;
|
||||
return false;
|
||||
}
|
||||
else if (transitionType == TransitionType.ProgressToNextEmptyLocation)
|
||||
@@ -707,6 +722,7 @@ namespace Barotrauma
|
||||
new XAttribute("purchasedhullrepairs", PurchasedHullRepairs),
|
||||
new XAttribute("purchaseditemrepairs", PurchasedItemRepairs),
|
||||
new XAttribute("cheatsenabled", CheatsEnabled));
|
||||
modeElement.Add(Settings.Save());
|
||||
|
||||
//save and remove all items that are in someone's inventory so they don't get included in the sub file as well
|
||||
foreach (Character c in Character.CharacterList)
|
||||
|
||||
+1
-1
@@ -614,7 +614,7 @@ namespace Barotrauma.Tutorials
|
||||
GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
|
||||
GameMain.LightManager.LosEnabled = false;
|
||||
|
||||
var cinematic = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam, Alignment.CenterLeft, Alignment.CenterRight, duration: 5.0f);
|
||||
var cinematic = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam, Alignment.CenterLeft, Alignment.CenterRight, panDuration: 5.0f);
|
||||
|
||||
while (cinematic.Running)
|
||||
{
|
||||
|
||||
+5
-5
@@ -99,7 +99,7 @@ namespace Barotrauma.Tutorials
|
||||
captain_medicSpawnPos = Item.ItemList.Find(i => i.HasTag("captain_medicspawnpos")).WorldPosition;
|
||||
tutorial_submarineDoor = Item.ItemList.Find(i => i.HasTag("tutorial_submarinedoor")).GetComponent<Door>();
|
||||
tutorial_submarineDoorLight = Item.ItemList.Find(i => i.HasTag("tutorial_submarinedoorlight")).GetComponent<LightComponent>();
|
||||
var medicInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, "", JobPrefab.Get("medicaldoctor"));
|
||||
var medicInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: JobPrefab.Get("medicaldoctor"));
|
||||
captain_medic = Character.Create(medicInfo, captain_medicSpawnPos, "medicaldoctor");
|
||||
captain_medic.TeamID = CharacterTeamType.Team1;
|
||||
captain_medic.GiveJobItems(null);
|
||||
@@ -122,17 +122,17 @@ namespace Barotrauma.Tutorials
|
||||
SetDoorAccess(tutorial_lockedDoor_1, null, false);
|
||||
SetDoorAccess(tutorial_lockedDoor_2, null, false);
|
||||
|
||||
var mechanicInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, "", JobPrefab.Get("mechanic"));
|
||||
var mechanicInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: JobPrefab.Get("mechanic"));
|
||||
captain_mechanic = Character.Create(mechanicInfo, WayPoint.GetRandom(SpawnType.Human, mechanicInfo.Job, Submarine.MainSub).WorldPosition, "mechanic");
|
||||
captain_mechanic.TeamID = CharacterTeamType.Team1;
|
||||
captain_mechanic.GiveJobItems();
|
||||
|
||||
var securityInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, "", JobPrefab.Get("securityofficer"));
|
||||
var securityInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: JobPrefab.Get("securityofficer"));
|
||||
captain_security = Character.Create(securityInfo, WayPoint.GetRandom(SpawnType.Human, securityInfo.Job, Submarine.MainSub).WorldPosition, "securityofficer");
|
||||
captain_security.TeamID = CharacterTeamType.Team1;
|
||||
captain_security.GiveJobItems();
|
||||
|
||||
var engineerInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, "", JobPrefab.Get("engineer"));
|
||||
var engineerInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: JobPrefab.Get("engineer"));
|
||||
captain_engineer = Character.Create(engineerInfo, WayPoint.GetRandom(SpawnType.Human, engineerInfo.Job, Submarine.MainSub).WorldPosition, "engineer");
|
||||
captain_engineer.TeamID = CharacterTeamType.Team1;
|
||||
captain_engineer.GiveJobItems();
|
||||
@@ -249,7 +249,7 @@ namespace Barotrauma.Tutorials
|
||||
{
|
||||
//captain_navConsoleCustomInterface.HighlightElement(0, uiHighlightColor, duration: 1.0f, pulsateAmount: 0.0f);
|
||||
yield return new WaitForSeconds(1.0f, false);
|
||||
} while (!Submarine.MainSub.AtEndPosition || !Submarine.MainSub.DockedTo.Any());
|
||||
} while (!Submarine.MainSub.AtEndExit || !Submarine.MainSub.DockedTo.Any());
|
||||
RemoveCompletedObjective(segments[6]);
|
||||
yield return new WaitForSeconds(3f, false);
|
||||
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.GetWithVariable("Captain.Radio.Complete", "[OUTPOSTNAME]", GameMain.GameSession.EndLocation.Name), ChatMessageType.Radio, null);
|
||||
|
||||
+6
-6
@@ -78,7 +78,7 @@ namespace Barotrauma.Tutorials
|
||||
var patientHull2 = WayPoint.WayPointList.Find(wp => wp.IdCardDesc == "airlock").CurrentHull;
|
||||
medBay = WayPoint.WayPointList.Find(wp => wp.IdCardDesc == "medbay").CurrentHull;
|
||||
|
||||
var assistantInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, "", JobPrefab.Get("assistant"));
|
||||
var assistantInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: JobPrefab.Get("assistant"));
|
||||
patient1 = Character.Create(assistantInfo, patientHull1.WorldPosition, "1");
|
||||
patient1.TeamID = CharacterTeamType.Team1;
|
||||
patient1.GiveJobItems(null);
|
||||
@@ -86,26 +86,26 @@ namespace Barotrauma.Tutorials
|
||||
patient1.AddDamage(patient1.WorldPosition, new List<Affliction>() { new Affliction(AfflictionPrefab.Burn, 15.0f) }, stun: 0, playSound: false);
|
||||
patient1.AIController.Enabled = false;
|
||||
|
||||
assistantInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, "", JobPrefab.Get("assistant"));
|
||||
assistantInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: JobPrefab.Get("assistant"));
|
||||
patient2 = Character.Create(assistantInfo, patientHull2.WorldPosition, "2");
|
||||
patient2.TeamID = CharacterTeamType.Team1;
|
||||
patient2.GiveJobItems(null);
|
||||
patient2.CanSpeak = false;
|
||||
patient2.AIController.Enabled = false;
|
||||
|
||||
var mechanicInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, "", JobPrefab.Get("engineer"));
|
||||
var mechanicInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: JobPrefab.Get("engineer"));
|
||||
var subPatient1 = Character.Create(mechanicInfo, WayPoint.GetRandom(SpawnType.Human, mechanicInfo.Job, Submarine.MainSub).WorldPosition, "3");
|
||||
subPatient1.TeamID = CharacterTeamType.Team1;
|
||||
subPatient1.AddDamage(patient1.WorldPosition, new List<Affliction>() { new Affliction(AfflictionPrefab.Burn, 40.0f) }, stun: 0, playSound: false);
|
||||
subPatients.Add(subPatient1);
|
||||
|
||||
var securityInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, "", JobPrefab.Get("securityofficer"));
|
||||
var securityInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: JobPrefab.Get("securityofficer"));
|
||||
var subPatient2 = Character.Create(securityInfo, WayPoint.GetRandom(SpawnType.Human, securityInfo.Job, Submarine.MainSub).WorldPosition, "3");
|
||||
subPatient2.TeamID = CharacterTeamType.Team1;
|
||||
subPatient2.AddDamage(patient1.WorldPosition, new List<Affliction>() { new Affliction(AfflictionPrefab.InternalDamage, 40.0f) }, stun: 0, playSound: false);
|
||||
subPatients.Add(subPatient2);
|
||||
|
||||
var engineerInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, "", JobPrefab.Get("engineer"));
|
||||
var engineerInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: JobPrefab.Get("engineer"));
|
||||
var subPatient3 = Character.Create(securityInfo, WayPoint.GetRandom(SpawnType.Human, engineerInfo.Job, Submarine.MainSub).WorldPosition, "3");
|
||||
subPatient3.TeamID = CharacterTeamType.Team1;
|
||||
subPatient3.AddDamage(patient1.WorldPosition, new List<Affliction>() { new Affliction(AfflictionPrefab.Burn, 20.0f) }, stun: 0, playSound: false);
|
||||
@@ -283,7 +283,7 @@ namespace Barotrauma.Tutorials
|
||||
doctor.RemoveActiveObjectiveEntity(patient1);
|
||||
TriggerTutorialSegment(3, GameMain.Config.KeyBindText(InputType.Command)); // Get the patient to medbay
|
||||
|
||||
while (patient1.CurrentOrder == null || patient1.CurrentOrder.Identifier != "follow")
|
||||
while (patient1.GetCurrentOrderWithTopPriority()?.Order?.Identifier != "follow")
|
||||
{
|
||||
// TODO: Rework order highlighting for new command UI
|
||||
// GameMain.GameSession.CrewManager.HighlightOrderButton(patient1, "follow", highlightColor, new Vector2(5, 5));
|
||||
|
||||
+2
-1
@@ -317,7 +317,8 @@ namespace Barotrauma.Tutorials
|
||||
yield return new WaitForSeconds(2f, false);
|
||||
TriggerTutorialSegment(4, GameMain.Config.KeyBindText(InputType.Select), GameMain.Config.KeyBindText(InputType.Shoot), GameMain.Config.KeyBindText(InputType.Deselect)); // Kill hammerhead
|
||||
officer_hammerhead = SpawnMonster("hammerhead", officer_hammerheadSpawnPos);
|
||||
((EnemyAIController)officer_hammerhead.AIController).StayInsideLevel = false;
|
||||
officer_hammerhead.Params.AI.AvoidAbyss = false;
|
||||
officer_hammerhead.Params.AI.StayInAbyss = false;
|
||||
officer_hammerhead.AIController.SelectTarget(officer.AiTarget);
|
||||
SetHighlight(officer_coilgunPeriscope, true);
|
||||
float originalDistance = Vector2.Distance(officer_coilgunPeriscope.WorldPosition, officer_hammerheadSpawnPos);
|
||||
|
||||
+6
-6
@@ -62,7 +62,7 @@ namespace Barotrauma.Tutorials
|
||||
|
||||
yield return CoroutineStatus.Running;
|
||||
|
||||
GameMain.GameSession = new GameSession(subInfo, GameModePreset.Tutorial, missionPrefab: null);
|
||||
GameMain.GameSession = new GameSession(subInfo, GameModePreset.Tutorial, missionPrefabs: null);
|
||||
(GameMain.GameSession.GameMode as TutorialMode).Tutorial = this;
|
||||
|
||||
if (generationParams != null)
|
||||
@@ -110,7 +110,7 @@ namespace Barotrauma.Tutorials
|
||||
}
|
||||
|
||||
CharacterInfo charInfo = configElement.Element("Character") == null ?
|
||||
new CharacterInfo(CharacterPrefab.HumanSpeciesName, "", JobPrefab.Get("engineer")) :
|
||||
new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: JobPrefab.Get("engineer")) :
|
||||
new CharacterInfo(configElement.Element("Character"));
|
||||
|
||||
WayPoint wayPoint = GetSpawnPoint(charInfo);
|
||||
@@ -182,7 +182,8 @@ namespace Barotrauma.Tutorials
|
||||
|
||||
protected bool HasOrder(Character character, string identifier, string option = null)
|
||||
{
|
||||
if (character.CurrentOrder?.Identifier == identifier)
|
||||
var currentOrderInfo = character.GetCurrentOrderWithTopPriority();
|
||||
if (currentOrderInfo?.Order?.Identifier == identifier)
|
||||
{
|
||||
if (option == null)
|
||||
{
|
||||
@@ -190,8 +191,7 @@ namespace Barotrauma.Tutorials
|
||||
}
|
||||
else
|
||||
{
|
||||
HumanAIController humanAI = character.AIController as HumanAIController;
|
||||
return humanAI.CurrentOrderOption == option;
|
||||
return currentOrderInfo?.OrderOption == option;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,7 +288,7 @@ namespace Barotrauma.Tutorials
|
||||
|
||||
yield return new WaitForSeconds(waitBeforeFade);
|
||||
|
||||
var endCinematic = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam, null, Alignment.Center, duration: fadeOutTime);
|
||||
var endCinematic = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam, null, Alignment.Center, panDuration: fadeOutTime);
|
||||
currentTutorialCompleted = Completed = true;
|
||||
while (endCinematic.Running) yield return null;
|
||||
Stop();
|
||||
|
||||
+3
-3
@@ -535,15 +535,15 @@ namespace Barotrauma.Tutorials
|
||||
titleBlock.RectTransform.IsFixedSize = true;
|
||||
}
|
||||
|
||||
List<RichTextData> richTextData = RichTextData.GetRichTextData(text, out text);
|
||||
List<RichTextData> richTextData = RichTextData.GetRichTextData(" " + text, out text);
|
||||
GUITextBlock textBlock;
|
||||
if (richTextData == null)
|
||||
{
|
||||
textBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoContent.RectTransform), " " + text, wrap: true);
|
||||
textBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoContent.RectTransform), text, wrap: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
textBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoContent.RectTransform), richTextData, " " + text, wrap: true);
|
||||
textBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoContent.RectTransform), richTextData, text, wrap: true);
|
||||
}
|
||||
|
||||
textBlock.RectTransform.IsFixedSize = true;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -26,6 +27,7 @@ namespace Barotrauma
|
||||
if (tabMenu == null && GameMode is TutorialMode == false)
|
||||
{
|
||||
tabMenu = new TabMenu();
|
||||
HintManager.OnShowTabMenu();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -36,12 +38,106 @@ namespace Barotrauma
|
||||
return true;
|
||||
}
|
||||
|
||||
private GUILayoutGroup topLeftButtonGroup;
|
||||
private GUIButton crewListButton, commandButton, tabMenuButton;
|
||||
|
||||
private GUIComponent respawnInfoFrame, respawnButtonContainer;
|
||||
private GUITextBlock respawnInfoText;
|
||||
private GUITickBox respawnTickBox;
|
||||
private GUILayoutGroup TopLeftButtonGroup;
|
||||
private void CreateTopLeftButtons()
|
||||
{
|
||||
if (topLeftButtonGroup != null)
|
||||
{
|
||||
topLeftButtonGroup.RectTransform.Parent = null;
|
||||
topLeftButtonGroup = null;
|
||||
crewListButton = commandButton = tabMenuButton = null;
|
||||
}
|
||||
topLeftButtonGroup = new GUILayoutGroup(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.ButtonAreaTop, GUI.Canvas), isHorizontal: true, childAnchor: Anchor.CenterLeft)
|
||||
{
|
||||
AbsoluteSpacing = HUDLayoutSettings.Padding,
|
||||
CanBeFocused = false
|
||||
};
|
||||
topLeftButtonGroup.RectTransform.ParentChanged += (_) =>
|
||||
{
|
||||
GameMain.Instance.ResolutionChanged -= CreateTopLeftButtons;
|
||||
};
|
||||
int buttonHeight = GUI.IntScale(40);
|
||||
Vector2 buttonSpriteSize = GUI.Style.GetComponentStyle("CrewListToggleButton").GetDefaultSprite().size;
|
||||
int buttonWidth = (int)((buttonHeight / buttonSpriteSize.Y) * buttonSpriteSize.X);
|
||||
Point buttonSize = new Point(buttonWidth, buttonHeight);
|
||||
crewListButton = new GUIButton(new RectTransform(buttonSize, parent: topLeftButtonGroup.RectTransform), style: "CrewListToggleButton")
|
||||
{
|
||||
ToolTip = TextManager.GetWithVariable("hudbutton.crewlist", "[key]", GameMain.Config.KeyBindText(InputType.CrewOrders)),
|
||||
OnClicked = (GUIButton btn, object userdata) =>
|
||||
{
|
||||
if (CrewManager == null) { return false; }
|
||||
CrewManager.IsCrewMenuOpen = !CrewManager.IsCrewMenuOpen;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
commandButton = new GUIButton(new RectTransform(buttonSize, parent: topLeftButtonGroup.RectTransform), style: "CommandButton")
|
||||
{
|
||||
ToolTip = TextManager.GetWithVariable("hudbutton.commandinterface", "[key]", GameMain.Config.KeyBindText(InputType.Command)),
|
||||
OnClicked = (button, userData) =>
|
||||
{
|
||||
if (CrewManager == null) { return false; }
|
||||
CrewManager.ToggleCommandUI();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
tabMenuButton = new GUIButton(new RectTransform(buttonSize, parent: topLeftButtonGroup.RectTransform), style: "TabMenuButton")
|
||||
{
|
||||
ToolTip = TextManager.GetWithVariable("hudbutton.tabmenu", "[key]", GameMain.Config.KeyBindText(InputType.InfoTab)),
|
||||
OnClicked = (button, userData) =>
|
||||
{
|
||||
return ToggleTabMenu();
|
||||
}
|
||||
};
|
||||
GameMain.Instance.ResolutionChanged += CreateTopLeftButtons;
|
||||
|
||||
respawnInfoFrame = new GUIFrame(new RectTransform(new Vector2(0.5f, 1.0f), parent: topLeftButtonGroup.RectTransform)
|
||||
{ MaxSize = new Point(HUDLayoutSettings.ButtonAreaTop.Width / 3, int.MaxValue) }, style: null)
|
||||
{
|
||||
Visible = false
|
||||
};
|
||||
respawnInfoText = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), respawnInfoFrame.RectTransform), "", wrap: true);
|
||||
respawnButtonContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 1.0f), respawnInfoFrame.RectTransform, Anchor.CenterRight), isHorizontal: true, childAnchor: Anchor.CenterLeft)
|
||||
{
|
||||
AbsoluteSpacing = HUDLayoutSettings.Padding,
|
||||
Stretch = true
|
||||
};
|
||||
respawnTickBox = new GUITickBox(new RectTransform(Vector2.One * 0.9f, respawnButtonContainer.RectTransform, Anchor.Center), TextManager.Get("respawnquestionpromptrespawn"))
|
||||
{
|
||||
ToolTip = TextManager.Get("respawnquestionprompt"),
|
||||
OnSelected = (tickbox) =>
|
||||
{
|
||||
GameMain.Client?.SendRespawnPromptResponse(waitForNextRoundRespawn: !tickbox.Selected);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void AddToGUIUpdateList()
|
||||
{
|
||||
if (GUI.DisableHUD) return;
|
||||
if (GUI.DisableHUD) { return; }
|
||||
GameMode?.AddToGUIUpdateList();
|
||||
tabMenu?.AddToGUIUpdateList();
|
||||
|
||||
if ((!(GameMode is CampaignMode campaign) || (!campaign.ForceMapUI && !campaign.ShowCampaignUI)) &&
|
||||
!CoroutineManager.IsCoroutineRunning("LevelTransition") && !CoroutineManager.IsCoroutineRunning("SubmarineTransition"))
|
||||
{
|
||||
if (topLeftButtonGroup == null)
|
||||
{
|
||||
CreateTopLeftButtons();
|
||||
}
|
||||
crewListButton.Selected = CrewManager != null && CrewManager.IsCrewMenuOpen;
|
||||
commandButton.Selected = CrewManager.IsCommandInterfaceOpen;
|
||||
commandButton.Enabled = CrewManager.CanIssueOrders;
|
||||
tabMenuButton.Selected = IsTabMenuOpen;
|
||||
topLeftButtonGroup.AddToGUIUpdateList();
|
||||
}
|
||||
|
||||
if (GameMain.NetworkMember != null)
|
||||
{
|
||||
GameMain.NetLobbyScreen?.HeadSelectionList?.AddToGUIUpdateList();
|
||||
@@ -55,7 +151,7 @@ namespace Barotrauma
|
||||
|
||||
if (tabMenu == null)
|
||||
{
|
||||
if (PlayerInput.KeyHit(InputType.InfoTab) && GUI.KeyboardDispatcher.Subscriber is GUITextBox == false)
|
||||
if (PlayerInput.KeyHit(InputType.InfoTab) && !(GUI.KeyboardDispatcher.Subscriber is GUITextBox))
|
||||
{
|
||||
ToggleTabMenu();
|
||||
}
|
||||
@@ -63,8 +159,8 @@ namespace Barotrauma
|
||||
else
|
||||
{
|
||||
tabMenu.Update();
|
||||
|
||||
if (PlayerInput.KeyHit(InputType.InfoTab) && GUI.KeyboardDispatcher.Subscriber is GUITextBox == false)
|
||||
if ((PlayerInput.KeyHit(InputType.InfoTab) || PlayerInput.KeyHit(Microsoft.Xna.Framework.Input.Keys.Escape)) &&
|
||||
!(GUI.KeyboardDispatcher.Subscriber is GUITextBox))
|
||||
{
|
||||
ToggleTabMenu();
|
||||
}
|
||||
@@ -88,6 +184,19 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HintManager.Update();
|
||||
}
|
||||
|
||||
public void SetRespawnInfo(bool visible, string text, Color textColor, bool buttonsVisible, bool waitForNextRoundRespawn)
|
||||
{
|
||||
if (topLeftButtonGroup == null) { return; }
|
||||
respawnInfoFrame.Visible = visible;
|
||||
if (!visible) { return; }
|
||||
respawnInfoText.Text = text;
|
||||
respawnInfoText.TextColor = textColor;
|
||||
respawnButtonContainer.Visible = buttonsVisible;
|
||||
respawnTickBox.Selected = !waitForNextRoundRespawn;
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch)
|
||||
|
||||
@@ -0,0 +1,731 @@
|
||||
using Barotrauma.Extensions;
|
||||
using Barotrauma.IO;
|
||||
using Barotrauma.Items.Components;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
static class HintManager
|
||||
{
|
||||
private const string HintManagerFile = "hintmanager.xml";
|
||||
private static HashSet<string> HintIdentifiers { get; set; }
|
||||
private static Dictionary<string, HashSet<string>> HintTags { get; } = new Dictionary<string, HashSet<string>>();
|
||||
private static Dictionary<string, (string identifier, string option)> HintOrders { get; } = new Dictionary<string, (string orderIdentifier, string orderOption)>();
|
||||
/// <summary>
|
||||
/// Hints that have already been shown this round and shouldn't be shown shown again until the next round
|
||||
/// </summary>
|
||||
private static HashSet<string> HintsIgnoredThisRound { get; } = new HashSet<string>();
|
||||
private static GUIMessageBox ActiveHintMessageBox { get; set; }
|
||||
private static Action OnUpdate { get; set; }
|
||||
private static double TimeStoppedInteracting { get; set; }
|
||||
private static double TimeRoundStarted { get; set; }
|
||||
/// <summary>
|
||||
/// Seconds before any reminders can be shown
|
||||
/// </summary>
|
||||
private static int TimeBeforeReminders { get; set; }
|
||||
/// <summary>
|
||||
/// Seconds before another reminder can be shown
|
||||
/// </summary>
|
||||
private static int ReminderCooldown { get; set; }
|
||||
private static double TimeReminderLastDisplayed { get; set; }
|
||||
private static HashSet<Hull> BallastHulls { get; } = new HashSet<Hull>();
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
if (File.Exists(HintManagerFile))
|
||||
{
|
||||
var doc = XMLExtensions.TryLoadXml(HintManagerFile);
|
||||
if (doc?.Root != null)
|
||||
{
|
||||
HintIdentifiers = new HashSet<string>();
|
||||
foreach (var element in doc.Root.Elements())
|
||||
{
|
||||
GetHintsRecursive(element, element.Name.ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.ThrowError($"File \"{HintManagerFile}\" is empty - cannot initialize the HintManager!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.ThrowError($"File \"{HintManagerFile}\" is missing - cannot initialize the HintManager!");
|
||||
}
|
||||
|
||||
static void GetHintsRecursive(XElement element, string identifier)
|
||||
{
|
||||
if (!element.HasElements)
|
||||
{
|
||||
HintIdentifiers.Add(identifier);
|
||||
if (element.GetAttributeStringArray("tags", null, convertToLowerInvariant: true) is string[] tags)
|
||||
{
|
||||
HintTags.TryAdd(identifier, tags.ToHashSet());
|
||||
}
|
||||
if (element.GetAttributeString("order", null) is string orderIdentifier && !string.IsNullOrEmpty(orderIdentifier))
|
||||
{
|
||||
string orderOption = element.GetAttributeString("orderoption", "");
|
||||
HintOrders.Add(identifier, (orderIdentifier, orderOption));
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (element.Name.ToString().Equals("reminder"))
|
||||
{
|
||||
TimeBeforeReminders = element.GetAttributeInt("timebeforereminders", TimeBeforeReminders);
|
||||
ReminderCooldown = element.GetAttributeInt("remindercooldown", ReminderCooldown);
|
||||
}
|
||||
foreach (var childElement in element.Elements())
|
||||
{
|
||||
GetHintsRecursive(childElement, $"{identifier}.{childElement.Name}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Update()
|
||||
{
|
||||
if (HintIdentifiers == null || GameMain.Config.DisableInGameHints) { return; }
|
||||
if (GameMain.GameSession == null || !GameMain.GameSession.IsRunning) { return; }
|
||||
|
||||
if (ActiveHintMessageBox != null)
|
||||
{
|
||||
if (ActiveHintMessageBox.Closed)
|
||||
{
|
||||
ActiveHintMessageBox = null;
|
||||
OnUpdate = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
OnUpdate?.Invoke();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CheckIsInteracting();
|
||||
CheckIfDivingGearOutOfOxygen();
|
||||
CheckHulls();
|
||||
CheckReminders();
|
||||
}
|
||||
|
||||
public static void OnSetSelectedConstruction(Character character, Item oldConstruction, Item newConstruction)
|
||||
{
|
||||
if (oldConstruction == newConstruction) { return; }
|
||||
|
||||
if (Character.Controlled != null && Character.Controlled == character && oldConstruction != null && oldConstruction.GetComponent<Ladder>() == null)
|
||||
{
|
||||
TimeStoppedInteracting = Timing.TotalTime;
|
||||
}
|
||||
|
||||
if (newConstruction == null) { return; }
|
||||
if (newConstruction.GetComponent<Ladder>() != null) { return; }
|
||||
if (newConstruction.GetComponent<ConnectionPanel>() is ConnectionPanel cp && cp.User == character) { return; }
|
||||
OnStartedInteracting(character, newConstruction);
|
||||
}
|
||||
|
||||
private static void OnStartedInteracting(Character character, Item item)
|
||||
{
|
||||
if (!CanDisplayHints()) { return; }
|
||||
if (character != Character.Controlled || item == null) { return; }
|
||||
|
||||
string hintIdentifierBase = "onstartedinteracting";
|
||||
|
||||
// onstartedinteracting.brokenitem
|
||||
if (item.Repairables.Any(r => item.ConditionPercentage < r.RepairThreshold))
|
||||
{
|
||||
if (DisplayHint($"{hintIdentifierBase}.brokenitem")) { return; }
|
||||
}
|
||||
|
||||
// Don't display other item-related hints if the repair interface is displayed
|
||||
if (item.Repairables.Any(r => r.ShouldDrawHUD(character))) { return; }
|
||||
|
||||
// onstartedinteracting.lootingisstealing
|
||||
if (item.Submarine?.Info?.Type == SubmarineType.Outpost &&
|
||||
item.ContainedItems.Any(i => !i.AllowStealing))
|
||||
{
|
||||
if (DisplayHint($"{hintIdentifierBase}.lootingisstealing")) { return; }
|
||||
}
|
||||
|
||||
// onstartedinteracting.turretperiscope
|
||||
if (item.HasTag("periscope") &&
|
||||
item.GetConnectedComponents<Turret>().FirstOrDefault(t => t.Item.HasTag("turret")) is Turret)
|
||||
{
|
||||
if (DisplayHint($"{hintIdentifierBase}.turretperiscope",
|
||||
variableTags: new string[] { "[shootkey]", "[deselectkey]", },
|
||||
variableValues: new string[] { GameMain.Config.KeyBindText(InputType.Shoot), GameMain.Config.KeyBindText(InputType.Deselect) }))
|
||||
{ return; }
|
||||
}
|
||||
|
||||
// onstartedinteracting.item...
|
||||
hintIdentifierBase += ".item";
|
||||
foreach (string hintIdentifier in HintIdentifiers)
|
||||
{
|
||||
if (!hintIdentifier.StartsWith(hintIdentifierBase)) { continue; }
|
||||
if (!HintTags.TryGetValue(hintIdentifier, out var hintTags)) { continue; }
|
||||
if (!item.HasTag(hintTags)) { continue; }
|
||||
if (DisplayHint(hintIdentifier)) { return; }
|
||||
}
|
||||
}
|
||||
|
||||
private static void CheckIsInteracting()
|
||||
{
|
||||
if (!CanDisplayHints()) { return; }
|
||||
if (Character.Controlled?.SelectedConstruction == null) { return; }
|
||||
|
||||
if (Character.Controlled.SelectedConstruction.GetComponent<Reactor>() is Reactor reactor && reactor.PowerOn &&
|
||||
Character.Controlled.SelectedConstruction.OwnInventory?.AllItems is IEnumerable<Item> containedItems &&
|
||||
containedItems.Count(i => i.HasTag("reactorfuel")) > 1)
|
||||
{
|
||||
if (DisplayHint("onisinteracting.reactorwithextrarods")) { return; }
|
||||
}
|
||||
}
|
||||
|
||||
public static void OnRoundStarted()
|
||||
{
|
||||
// Make sure everything's been reset properly, OnRoundEnded() isn't always called when exiting a game
|
||||
Reset();
|
||||
TimeRoundStarted = GameMain.GameScreen.GameTime;
|
||||
|
||||
var initRoundHandle = CoroutineManager.StartCoroutine(InitRound(), "HintManager.InitRound");
|
||||
if (!CanDisplayHints(requireGameScreen: false, requireControllingCharacter: false)) { return; }
|
||||
CoroutineManager.StartCoroutine(DisplayRoundStartedHints(initRoundHandle), "HintManager.DisplayRoundStartedHints");
|
||||
|
||||
static IEnumerable<object> InitRound()
|
||||
{
|
||||
while (Character.Controlled == null) { yield return CoroutineStatus.Running; }
|
||||
// Get the ballast hulls on round start not to find them again and again later
|
||||
BallastHulls.Clear();
|
||||
var sub = Submarine.MainSubs.FirstOrDefault(s => s != null && s.TeamID == Character.Controlled.TeamID);
|
||||
if (sub != null)
|
||||
{
|
||||
foreach (var item in sub.GetItems(true))
|
||||
{
|
||||
if (item.CurrentHull == null) { continue; }
|
||||
if (item.GetComponent<Pump>() == null) { continue; }
|
||||
if (!item.HasTag("ballast")) { continue; }
|
||||
BallastHulls.Add(item.CurrentHull);
|
||||
}
|
||||
}
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
|
||||
static IEnumerable<object> DisplayRoundStartedHints(CoroutineHandle initRoundHandle)
|
||||
{
|
||||
while (GameMain.Instance.LoadingScreenOpen || Screen.Selected != GameMain.GameScreen ||
|
||||
CoroutineManager.IsCoroutineRunning(initRoundHandle) ||
|
||||
CoroutineManager.IsCoroutineRunning("LevelTransition") ||
|
||||
CoroutineManager.IsCoroutineRunning("SinglePlayerCampaign.DoInitialCameraTransition") ||
|
||||
CoroutineManager.IsCoroutineRunning("MultiPlayerCampaign.DoInitialCameraTransition") ||
|
||||
GUIMessageBox.VisibleBox != null || Character.Controlled == null)
|
||||
{
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
OnStartedControlling();
|
||||
|
||||
while (ActiveHintMessageBox != null)
|
||||
{
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
if (!GameMain.GameSession.GameMode.IsSinglePlayer &&
|
||||
GameMain.Config.VoiceSetting == GameSettings.VoiceMode.Disabled)
|
||||
{
|
||||
DisplayHint("onroundstarted.voipdisabled", onUpdate: () =>
|
||||
{
|
||||
if (GameMain.Config.VoiceSetting == GameSettings.VoiceMode.Disabled) { return; }
|
||||
ActiveHintMessageBox.Close();
|
||||
});
|
||||
}
|
||||
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
}
|
||||
|
||||
public static void OnRoundEnded()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
private static void Reset()
|
||||
{
|
||||
CoroutineManager.StopCoroutines("HintManager.InitRound");
|
||||
CoroutineManager.StopCoroutines("HintManager.DisplayRoundStartedHints");
|
||||
if (ActiveHintMessageBox != null)
|
||||
{
|
||||
GUIMessageBox.MessageBoxes.Remove(ActiveHintMessageBox);
|
||||
ActiveHintMessageBox = null;
|
||||
}
|
||||
OnUpdate = null;
|
||||
HintsIgnoredThisRound.Clear();
|
||||
}
|
||||
|
||||
public static void OnSonarSpottedCharacter(Item sonar, Character spottedCharacter)
|
||||
{
|
||||
if (!CanDisplayHints()) { return; }
|
||||
if (sonar == null || sonar.Removed) { return; }
|
||||
if (spottedCharacter == null || spottedCharacter.Removed || spottedCharacter.IsDead) { return; }
|
||||
if (Character.Controlled.SelectedConstruction != sonar) { return; }
|
||||
if (HumanAIController.IsFriendly(Character.Controlled, spottedCharacter)) { return; }
|
||||
DisplayHint("onsonarspottedenemy");
|
||||
}
|
||||
|
||||
public static void OnAfflictionDisplayed(Character character, List<Affliction> displayedAfflictions)
|
||||
{
|
||||
if (!CanDisplayHints()) { return; }
|
||||
if (character != Character.Controlled || displayedAfflictions == null) { return; }
|
||||
foreach (var affliction in displayedAfflictions)
|
||||
{
|
||||
if (affliction?.Prefab == null) { continue; }
|
||||
if (affliction.Prefab.IsBuff) { continue; }
|
||||
if (affliction.Prefab == AfflictionPrefab.OxygenLow) { continue; }
|
||||
if (affliction.Prefab == AfflictionPrefab.RadiationSickness && (GameMain.GameSession.Map?.Radiation?.IsEntityRadiated(character) ?? false)) { continue; }
|
||||
if (affliction.Strength < affliction.Prefab.ShowIconThreshold) { continue; }
|
||||
DisplayHint("onafflictiondisplayed",
|
||||
variableTags: new string[1] { "[key]" },
|
||||
variableValues: new string[1] { GameMain.Config.KeyBindText(InputType.Health) },
|
||||
icon: affliction.Prefab.Icon,
|
||||
iconColor: CharacterHealth.GetAfflictionIconColor(affliction),
|
||||
onUpdate: () =>
|
||||
{
|
||||
if (CharacterHealth.OpenHealthWindow == null) { return; }
|
||||
ActiveHintMessageBox.Close();
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public static void OnShootWithoutAiming(Character character, Item item)
|
||||
{
|
||||
if (!CanDisplayHints()) { return; }
|
||||
if (character != Character.Controlled) { return; }
|
||||
if (character.SelectedConstruction != null || character.FocusedItem != null) { return; }
|
||||
if (item == null || !item.IsShootable || !item.RequireAimToUse) { return; }
|
||||
if (TimeStoppedInteracting + 1 > Timing.TotalTime) { return; }
|
||||
if (GUI.MouseOn != null) { return; }
|
||||
if (Character.Controlled.Inventory?.visualSlots != null && Character.Controlled.Inventory.visualSlots.Any(s => s.InteractRect.Contains(PlayerInput.MousePosition))) { return; }
|
||||
string hintIdentifier = "onshootwithoutaiming";
|
||||
if (!HintTags.TryGetValue(hintIdentifier, out var tags)) { return; }
|
||||
if (!item.HasTag(tags)) { return; }
|
||||
DisplayHint(hintIdentifier,
|
||||
variableTags: new string[1] { "[key]" },
|
||||
variableValues: new string[1] { GameMain.Config.KeyBindText(InputType.Aim) },
|
||||
onUpdate: () =>
|
||||
{
|
||||
if (character.SelectedConstruction == null && GUI.MouseOn == null && PlayerInput.KeyDown(InputType.Aim))
|
||||
{
|
||||
ActiveHintMessageBox.Close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void OnWeldingDoor(Character character, Door door)
|
||||
{
|
||||
if (!CanDisplayHints()) { return; }
|
||||
if (character != Character.Controlled) { return; }
|
||||
if (door == null || door.Stuck < 20.0f) { return; }
|
||||
DisplayHint("onweldingdoor");
|
||||
}
|
||||
|
||||
public static void OnTryOpenStuckDoor(Character character)
|
||||
{
|
||||
if (!CanDisplayHints()) { return; }
|
||||
if (character != Character.Controlled) { return; }
|
||||
DisplayHint("ontryopenstuckdoor");
|
||||
}
|
||||
|
||||
public static void OnShowCampaignInterface(CampaignMode.InteractionType interactionType)
|
||||
{
|
||||
if (!CanDisplayHints()) { return; }
|
||||
if (interactionType == CampaignMode.InteractionType.None) { return; }
|
||||
string hintIdentifier = $"onshowcampaigninterface.{interactionType.ToString().ToLowerInvariant()}";
|
||||
DisplayHint(hintIdentifier, onUpdate: () =>
|
||||
{
|
||||
|
||||
if (!(GameMain.GameSession?.Campaign is CampaignMode campaign) ||
|
||||
(!campaign.ShowCampaignUI && !campaign.ForceMapUI) ||
|
||||
campaign.CampaignUI?.SelectedTab != CampaignMode.InteractionType.Map)
|
||||
{
|
||||
ActiveHintMessageBox.Close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void OnShowCommandInterface()
|
||||
{
|
||||
IgnoreReminder("commandinterface");
|
||||
if (!CanDisplayHints()) { return; }
|
||||
DisplayHint("onshowcommandinterface", onUpdate: () =>
|
||||
{
|
||||
if (CrewManager.IsCommandInterfaceOpen) { return; }
|
||||
ActiveHintMessageBox.Close();
|
||||
});
|
||||
}
|
||||
|
||||
public static void OnShowHealthInterface()
|
||||
{
|
||||
if (!CanDisplayHints()) { return; }
|
||||
if (CharacterHealth.OpenHealthWindow == null) { return; }
|
||||
DisplayHint("onshowhealthinterface", onUpdate: () =>
|
||||
{
|
||||
if (CharacterHealth.OpenHealthWindow != null) { return; }
|
||||
ActiveHintMessageBox.Close();
|
||||
});
|
||||
}
|
||||
|
||||
public static void OnShowTabMenu()
|
||||
{
|
||||
IgnoreReminder("tabmenu");
|
||||
}
|
||||
|
||||
public static void OnStoleItem(Character character, Item item)
|
||||
{
|
||||
if (!CanDisplayHints()) { return; }
|
||||
if (character != Character.Controlled) { return; }
|
||||
if (item == null || item.AllowStealing || !item.StolenDuringRound) { return; }
|
||||
DisplayHint("onstoleitem", onUpdate: () =>
|
||||
{
|
||||
if (item == null || item.Removed || item.GetRootInventoryOwner() != character)
|
||||
{
|
||||
ActiveHintMessageBox.Close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void OnHandcuffed(Character character)
|
||||
{
|
||||
if (!CanDisplayHints()) { return; }
|
||||
if (character != Character.Controlled || !character.LockHands) { return; }
|
||||
DisplayHint("onhandcuffed", onUpdate: () =>
|
||||
{
|
||||
if (character != null && !character.Removed && character.LockHands) { return; }
|
||||
ActiveHintMessageBox.Close();
|
||||
});
|
||||
}
|
||||
|
||||
public static void OnReactorOutOfFuel(Reactor reactor)
|
||||
{
|
||||
if (!CanDisplayHints()) { return; }
|
||||
if (reactor == null) { return; }
|
||||
if (reactor.Item.Submarine?.Info?.Type != SubmarineType.Player || reactor.Item.Submarine.TeamID != Character.Controlled.TeamID) { return; }
|
||||
if (!HasValidJob("engineer")) { return; }
|
||||
DisplayHint("onreactoroutoffuel", onUpdate: () =>
|
||||
{
|
||||
if (reactor?.Item != null && !reactor.Item.Removed && reactor.AvailableFuel < 1) { return; }
|
||||
ActiveHintMessageBox.Close();
|
||||
});
|
||||
}
|
||||
|
||||
public static void OnAvailableTransition(CampaignMode.TransitionType transitionType)
|
||||
{
|
||||
if (!CanDisplayHints()) { return; }
|
||||
if (transitionType == CampaignMode.TransitionType.None) { return; }
|
||||
DisplayHint($"onavailabletransition.{transitionType.ToString().ToLowerInvariant()}");
|
||||
}
|
||||
|
||||
public static void OnShowSubInventory(Item item)
|
||||
{
|
||||
if (item?.Prefab == null) { return; }
|
||||
if (item.Prefab.Identifier.Equals("toolbelt", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
IgnoreReminder("toolbelt");
|
||||
}
|
||||
}
|
||||
|
||||
public static void OnChangeCharacter()
|
||||
{
|
||||
IgnoreReminder("characterchange");
|
||||
}
|
||||
|
||||
public static void OnCharacterUnconscious(Character character)
|
||||
{
|
||||
if (!CanDisplayHints()) { return; }
|
||||
if (character != Character.Controlled) { return; }
|
||||
if (character.IsDead) { return; }
|
||||
if (character.CharacterHealth != null && character.Vitality < character.CharacterHealth.MinVitality) { return; }
|
||||
DisplayHint("oncharacterunconscious");
|
||||
}
|
||||
|
||||
public static void OnCharacterKilled(Character character)
|
||||
{
|
||||
if (!CanDisplayHints()) { return; }
|
||||
if (character != Character.Controlled) { return; }
|
||||
if (GameMain.IsMultiplayer) { return; }
|
||||
if (GameMain.GameSession?.CrewManager == null) { return; }
|
||||
if (GameMain.GameSession.CrewManager.GetCharacters().None(c => !c.IsDead)) { return; }
|
||||
DisplayHint("oncharacterkilled");
|
||||
}
|
||||
|
||||
private static void OnStartedControlling()
|
||||
{
|
||||
if (Level.IsLoadedOutpost) { return; }
|
||||
if (Character.Controlled?.Info?.Job?.Prefab == null) { return; }
|
||||
string hintIdentifier = $"onstartedcontrolling.job.{Character.Controlled.Info.Job.Prefab.Identifier}";
|
||||
DisplayHint(hintIdentifier,
|
||||
icon: Character.Controlled.Info.Job.Prefab.Icon,
|
||||
iconColor: Character.Controlled.Info.Job.Prefab.UIColor,
|
||||
onDisplay: () =>
|
||||
{
|
||||
if (!HintOrders.TryGetValue(hintIdentifier, out var orderInfo)) { return; }
|
||||
var orderPrefab = Order.GetPrefab(orderInfo.identifier);
|
||||
if (orderPrefab == null) { return; }
|
||||
Item targetEntity = null;
|
||||
ItemComponent targetItem = null;
|
||||
if (orderPrefab.MustSetTarget)
|
||||
{
|
||||
targetEntity = orderPrefab.GetMatchingItems(true, interactableFor: Character.Controlled).FirstOrDefault();
|
||||
if (targetEntity == null) { return; }
|
||||
targetItem = orderPrefab.GetTargetItemComponent(targetEntity);
|
||||
}
|
||||
var order = new Order(orderPrefab, targetEntity as Entity, targetItem, orderGiver: Character.Controlled);
|
||||
GameMain.GameSession.CrewManager.SetCharacterOrder(Character.Controlled, order, orderInfo.option, CharacterInfo.HighestManualOrderPriority, Character.Controlled);
|
||||
});
|
||||
}
|
||||
|
||||
public static void OnAutoPilotPathUpdated(Steering steering)
|
||||
{
|
||||
if (!CanDisplayHints()) { return; }
|
||||
if (!HasValidJob("captain")) { return; }
|
||||
if (steering?.Item?.Submarine?.Info == null) { return; }
|
||||
if (steering.Item.Submarine.Info.Type != SubmarineType.Player) { return; }
|
||||
if (steering.Item.Submarine.TeamID != Character.Controlled.TeamID) { return; }
|
||||
if (!steering.AutoPilot || steering.MaintainPos) { return; }
|
||||
if (steering.SteeringPath?.CurrentNode?.Tunnel?.Type != Level.TunnelType.MainPath) { return; }
|
||||
if (!steering.SteeringPath.Finished && steering.SteeringPath.NextNode != null) { return; }
|
||||
if (steering.LevelStartSelected && (Level.Loaded.StartOutpost == null || !steering.Item.Submarine.AtStartExit)) { return; }
|
||||
if (steering.LevelEndSelected && (Level.Loaded.EndOutpost == null || !steering.Item.Submarine.AtEndExit)) { return; }
|
||||
DisplayHint("onautopilotreachedoutpost");
|
||||
}
|
||||
|
||||
public static void OnStatusEffectApplied(ItemComponent component, ActionType actionType, Character character)
|
||||
{
|
||||
if (!CanDisplayHints()) { return; }
|
||||
if (character != Character.Controlled) { return; }
|
||||
// Could make this more generic if there will ever be any other status effect related hints
|
||||
if (!(component is Repairable) || actionType != ActionType.OnFailure) { return; }
|
||||
DisplayHint("onrepairfailed");
|
||||
}
|
||||
|
||||
public static void OnActiveOrderAdded(Order order)
|
||||
{
|
||||
if (!CanDisplayHints()) { return; }
|
||||
if (order == null) { return; }
|
||||
|
||||
if (order.Identifier == "reportballastflora" &&
|
||||
order.TargetEntity is Hull h &&
|
||||
h.Submarine?.TeamID == Character.Controlled.TeamID)
|
||||
{
|
||||
DisplayHint("onballastflorainfected");
|
||||
}
|
||||
}
|
||||
|
||||
private static void CheckIfDivingGearOutOfOxygen()
|
||||
{
|
||||
if (!CanDisplayHints()) { return; }
|
||||
var divingGear = Character.Controlled.GetEquippedItem("diving");
|
||||
if (divingGear?.OwnInventory == null) { return; }
|
||||
if (divingGear.GetContainedItemConditionPercentage() > 0.0f) { return; }
|
||||
DisplayHint("ondivinggearoutofoxygen", onUpdate: () =>
|
||||
{
|
||||
if (divingGear == null || divingGear.Removed ||
|
||||
Character.Controlled == null || !Character.Controlled.HasEquippedItem(divingGear) ||
|
||||
divingGear.GetContainedItemConditionPercentage() > 0.0f)
|
||||
{
|
||||
ActiveHintMessageBox.Close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void CheckHulls()
|
||||
{
|
||||
if (!CanDisplayHints()) { return; }
|
||||
if (Character.Controlled.CurrentHull == null) { return; }
|
||||
if (HumanAIController.IsBallastFloraNoticeable(Character.Controlled, Character.Controlled.CurrentHull))
|
||||
{
|
||||
if (DisplayHint("onballastflorainfected")) { return; }
|
||||
}
|
||||
foreach (var gap in Character.Controlled.CurrentHull.ConnectedGaps)
|
||||
{
|
||||
if (gap.ConnectedDoor == null || gap.ConnectedDoor.Impassable) { continue; }
|
||||
if (Vector2.DistanceSquared(Character.Controlled.WorldPosition, gap.ConnectedDoor.Item.WorldPosition) > 400 * 400) { continue; }
|
||||
if (!gap.IsRoomToRoom)
|
||||
{
|
||||
if (!(Character.Controlled.GetEquippedItem("deepdiving") is Item)) { continue; }
|
||||
if (Character.Controlled.IsProtectedFromPressure()) { continue; }
|
||||
if (DisplayHint("divingsuitwarning", extendTextTag: false)) { return; }
|
||||
continue;
|
||||
}
|
||||
foreach (var me in gap.linkedTo)
|
||||
{
|
||||
if (me == Character.Controlled.CurrentHull) { continue; }
|
||||
if (!(me is Hull adjacentHull)) { continue; }
|
||||
if (adjacentHull.LethalPressure > 5.0f && DisplayHint("onadjacenthull.highpressure")) { return; }
|
||||
if (adjacentHull.WaterPercentage > 75 && !BallastHulls.Contains(adjacentHull) && DisplayHint("onadjacenthull.highwaterpercentage")) { return; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void CheckReminders()
|
||||
{
|
||||
if (!CanDisplayHints()) { return; }
|
||||
if (Level.Loaded == null) { return; }
|
||||
if (GameMain.GameScreen.GameTime < TimeRoundStarted + TimeBeforeReminders) { return; }
|
||||
if (GameMain.GameScreen.GameTime < TimeReminderLastDisplayed + ReminderCooldown) { return; }
|
||||
|
||||
string hintIdentifierBase = "reminder";
|
||||
|
||||
if (GameMain.GameSession.GameMode.IsSinglePlayer)
|
||||
{
|
||||
if (DisplayHint($"{hintIdentifierBase}.characterchange"))
|
||||
{
|
||||
TimeReminderLastDisplayed = GameMain.GameScreen.GameTime;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (Level.Loaded.Type != LevelData.LevelType.Outpost)
|
||||
{
|
||||
if (DisplayHint($"{hintIdentifierBase}.commandinterface",
|
||||
variableTags: new string[] { "[commandkey]" },
|
||||
variableValues: new string[] { GameMain.Config.KeyBindText(InputType.Command) },
|
||||
onUpdate: () =>
|
||||
{
|
||||
if (!CrewManager.IsCommandInterfaceOpen) { return; }
|
||||
ActiveHintMessageBox.Close();
|
||||
}))
|
||||
{
|
||||
TimeReminderLastDisplayed = GameMain.GameScreen.GameTime;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (DisplayHint($"{hintIdentifierBase}.tabmenu",
|
||||
variableTags: new string[] { "[infotabkey]" },
|
||||
variableValues: new string[] { GameMain.Config.KeyBindText(InputType.InfoTab) },
|
||||
onUpdate: () =>
|
||||
{
|
||||
if (!GameSession.IsTabMenuOpen) { return; }
|
||||
ActiveHintMessageBox.Close();
|
||||
}))
|
||||
{
|
||||
TimeReminderLastDisplayed = GameMain.GameScreen.GameTime;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Character.Controlled.Inventory?.GetItemInLimbSlot(InvSlotType.Bag)?.Prefab?.Identifier == "toolbelt")
|
||||
{
|
||||
if (DisplayHint($"{hintIdentifierBase}.toolbelt"))
|
||||
{
|
||||
TimeReminderLastDisplayed = GameMain.GameScreen.GameTime;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool DisplayHint(string hintIdentifier, bool extendTextTag = true, string[] variableTags = null, string[] variableValues = null, Sprite icon = null, Color? iconColor = null, Action onDisplay = null, Action onUpdate = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(hintIdentifier)) { return false; }
|
||||
if (!HintIdentifiers.Contains(hintIdentifier)) { return false; }
|
||||
if (GameMain.Config.IgnoredHints.Contains(hintIdentifier)) { return false; }
|
||||
if (HintsIgnoredThisRound.Contains(hintIdentifier)) { return false; }
|
||||
|
||||
string text;
|
||||
string textTag = extendTextTag ? $"hint.{hintIdentifier}" : hintIdentifier;
|
||||
if (variableTags != null && variableTags != null && variableTags.Length > 0 && variableTags.Length == variableValues.Length)
|
||||
{
|
||||
text = TextManager.GetWithVariables(textTag, variableTags, variableValues, returnNull: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
text = TextManager.Get(textTag, returnNull: true);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(text))
|
||||
{
|
||||
#if DEBUG
|
||||
DebugConsole.ThrowError($"No hint text found for text tag \"{textTag}\"");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
HintsIgnoredThisRound.Add(hintIdentifier);
|
||||
|
||||
ActiveHintMessageBox = new GUIMessageBox(hintIdentifier, text, icon);
|
||||
if (iconColor.HasValue) { ActiveHintMessageBox.IconColor = iconColor.Value; }
|
||||
OnUpdate = onUpdate;
|
||||
|
||||
SoundPlayer.PlayUISound(GUISoundType.UIMessage);
|
||||
ActiveHintMessageBox.InnerFrame.Flash(color: iconColor ?? Color.Orange, flashDuration: 0.75f);
|
||||
onDisplay?.Invoke();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool OnDontShowAgain(GUITickBox tickBox)
|
||||
{
|
||||
IgnoreHint((string)tickBox.UserData, ignore: tickBox.Selected);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void IgnoreHint(string hintIdentifier, bool ignore = true)
|
||||
{
|
||||
if (string.IsNullOrEmpty(hintIdentifier)) { return; }
|
||||
if (!HintIdentifiers.Contains(hintIdentifier))
|
||||
{
|
||||
#if DEBUG
|
||||
DebugConsole.ThrowError($"Tried to ignore a hint not defined in {HintManagerFile}: {hintIdentifier}");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
if (ignore)
|
||||
{
|
||||
GameMain.Config.IgnoredHints.Add(hintIdentifier);
|
||||
}
|
||||
else
|
||||
{
|
||||
GameMain.Config.IgnoredHints.Remove(hintIdentifier);
|
||||
}
|
||||
}
|
||||
|
||||
private static void IgnoreReminder(string reminderIdentifier)
|
||||
{
|
||||
HintsIgnoredThisRound.Add($"reminder.{reminderIdentifier}");
|
||||
}
|
||||
|
||||
public static bool OnDisableHints(GUITickBox tickBox)
|
||||
{
|
||||
GameMain.Config.DisableInGameHints = tickBox.Selected;
|
||||
return GameMain.Config.SaveNewPlayerConfig();
|
||||
}
|
||||
|
||||
private static bool CanDisplayHints(bool requireGameScreen = true, bool requireControllingCharacter = true)
|
||||
{
|
||||
if (HintIdentifiers == null) { return false; }
|
||||
if (GameMain.Config.DisableInGameHints) { return false; }
|
||||
if (ActiveHintMessageBox != null) { return false; }
|
||||
if (requireControllingCharacter && Character.Controlled == null) { return false; }
|
||||
var gameMode = GameMain.GameSession?.GameMode;
|
||||
if (!(gameMode is CampaignMode || gameMode is MissionMode)) { return false; }
|
||||
if (requireGameScreen && Screen.Selected != GameMain.GameScreen) { return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool HasValidJob(string jobIdentifier)
|
||||
{
|
||||
// In singleplayer, we can control all character so we don't care about job restrictions
|
||||
if (GameMain.GameSession.GameMode.IsSinglePlayer) { return true; }
|
||||
if (Character.Controlled.HasJob(jobIdentifier)) { return true; }
|
||||
// In multiplayer, if there are players with the job, display the hint to all players
|
||||
foreach (var c in GameMain.GameSession.CrewManager.GetCharacters())
|
||||
{
|
||||
if (c == null || !c.IsRemotePlayer) { continue; }
|
||||
if (c.IsUnconscious || c.IsDead || c.Removed) { continue; }
|
||||
if (!c.HasJob(jobIdentifier)) { continue; }
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,6 +48,7 @@ namespace Barotrauma
|
||||
msgBox.Buttons[0].OnClicked = delegate
|
||||
{
|
||||
msgBox.Close();
|
||||
if (GameMain.Client == null) { return true; }
|
||||
SendState(ReadyStatus.Yes);
|
||||
CreateResultsMessage();
|
||||
return true;
|
||||
@@ -57,6 +58,7 @@ namespace Barotrauma
|
||||
msgBox.Buttons[1].OnClicked = delegate
|
||||
{
|
||||
msgBox.Close();
|
||||
if (GameMain.Client == null) { return true; }
|
||||
SendState(ReadyStatus.No);
|
||||
CreateResultsMessage();
|
||||
return true;
|
||||
@@ -65,6 +67,8 @@ namespace Barotrauma
|
||||
|
||||
private void CreateResultsMessage()
|
||||
{
|
||||
if (GameMain.Client == null) { return; }
|
||||
|
||||
Vector2 relativeSize = new Vector2(0.2f, 0.3f);
|
||||
Point minSize = new Point(300, 400);
|
||||
resultsBox = new GUIMessageBox(readyCheckHeader, string.Empty, new[] { closeButton }, relativeSize, minSize, type: GUIMessageBox.Type.Vote) { UserData = ResultData, Draggable = true };
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Barotrauma
|
||||
private int jobColumnWidth, characterColumnWidth, statusColumnWidth;
|
||||
|
||||
private readonly SubmarineInfo sub;
|
||||
private readonly Mission selectedMission;
|
||||
private readonly List<Mission> selectedMissions;
|
||||
private readonly Location startLocation, endLocation;
|
||||
|
||||
private readonly GameMode gameMode;
|
||||
@@ -32,11 +32,11 @@ namespace Barotrauma
|
||||
|
||||
|
||||
|
||||
public RoundSummary(SubmarineInfo sub, GameMode gameMode, Mission selectedMission, Location startLocation, Location endLocation)
|
||||
public RoundSummary(SubmarineInfo sub, GameMode gameMode, IEnumerable<Mission> selectedMissions, Location startLocation, Location endLocation)
|
||||
{
|
||||
this.sub = sub;
|
||||
this.gameMode = gameMode;
|
||||
this.selectedMission = selectedMission;
|
||||
this.selectedMissions = selectedMissions.ToList();
|
||||
this.startLocation = startLocation;
|
||||
this.endLocation = endLocation;
|
||||
initialLocationReputation = startLocation?.Reputation?.Value ?? 0.0f;
|
||||
@@ -75,7 +75,7 @@ namespace Barotrauma
|
||||
|
||||
//crew panel -------------------------------------------------------------------------------
|
||||
|
||||
GUIFrame crewFrame = new GUIFrame(new RectTransform(new Vector2(0.35f, 0.55f), background.RectTransform, Anchor.TopCenter, minSize: new Point(minWidth, minHeight)));
|
||||
GUIFrame crewFrame = new GUIFrame(new RectTransform(new Vector2(0.35f, 0.45f), background.RectTransform, Anchor.TopCenter, minSize: new Point(minWidth, minHeight)));
|
||||
GUIFrame crewFrameInner = new GUIFrame(new RectTransform(new Point(crewFrame.Rect.Width - padding * 2, crewFrame.Rect.Height - padding * 2), crewFrame.RectTransform, Anchor.Center), style: "InnerFrame");
|
||||
|
||||
var crewContent = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.95f), crewFrameInner.RectTransform, Anchor.Center))
|
||||
@@ -90,10 +90,10 @@ namespace Barotrauma
|
||||
CreateCrewList(crewContent, gameSession.CrewManager.GetCharacterInfos().Where(c => c.TeamID != CharacterTeamType.Team2));
|
||||
|
||||
//another crew frame for the 2nd team in combat missions
|
||||
if (gameSession.Mission is CombatMission)
|
||||
if (gameSession.Missions.Any(m => m is CombatMission))
|
||||
{
|
||||
crewHeader.Text = CombatMission.GetTeamName(CharacterTeamType.Team1);
|
||||
GUIFrame crewFrame2 = new GUIFrame(new RectTransform(new Vector2(0.35f, 0.55f), background.RectTransform, Anchor.TopCenter, minSize: new Point(minWidth, minHeight)));
|
||||
GUIFrame crewFrame2 = new GUIFrame(new RectTransform(new Vector2(0.35f, 0.45f), background.RectTransform, Anchor.TopCenter, minSize: new Point(minWidth, minHeight)));
|
||||
rightPanels.Add(crewFrame2);
|
||||
GUIFrame crewFrameInner2 = new GUIFrame(new RectTransform(new Point(crewFrame2.Rect.Width - padding * 2, crewFrame2.Rect.Height - padding * 2), crewFrame2.RectTransform, Anchor.Center), style: "InnerFrame");
|
||||
var crewContent2 = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.95f), crewFrameInner2.RectTransform, Anchor.Center))
|
||||
@@ -183,7 +183,8 @@ namespace Barotrauma
|
||||
|
||||
//reputation panel -------------------------------------------------------------------------------
|
||||
|
||||
if (gameMode is CampaignMode campaignMode)
|
||||
var campaignMode = gameMode as CampaignMode;
|
||||
if (campaignMode != null)
|
||||
{
|
||||
GUIFrame reputationframe = new GUIFrame(new RectTransform(crewFrame.RectTransform.RelativeSize, background.RectTransform, Anchor.TopCenter, minSize: crewFrame.RectTransform.MinSize));
|
||||
rightPanels.Add(reputationframe);
|
||||
@@ -198,158 +199,154 @@ namespace Barotrauma
|
||||
TextManager.Get("reputation"), textAlignment: Alignment.TopLeft, font: GUI.SubHeadingFont);
|
||||
reputationHeader.RectTransform.MinSize = new Point(0, GUI.IntScale(reputationHeader.Rect.Height * 2.0f));
|
||||
|
||||
GUIListBox reputationList = new GUIListBox(new RectTransform(Vector2.One, reputationContent.RectTransform))
|
||||
{
|
||||
Padding = new Vector4(2, 5, 0, 0)
|
||||
};
|
||||
reputationList.ContentBackground.Color = Color.Transparent;
|
||||
|
||||
if (startLocation.Type.HasOutpost && startLocation.Reputation != null)
|
||||
{
|
||||
var iconStyle = GUI.Style.GetComponentStyle("LocationReputationIcon");
|
||||
CreateReputationElement(
|
||||
reputationList.Content,
|
||||
startLocation.Name,
|
||||
startLocation.Reputation.Value, startLocation.Reputation.NormalizedValue, initialLocationReputation,
|
||||
startLocation.Type.Name, "",
|
||||
iconStyle?.GetDefaultSprite(), startLocation.Type.GetPortrait(0), iconStyle?.Color ?? Color.White);
|
||||
}
|
||||
|
||||
foreach (Faction faction in campaignMode.Factions)
|
||||
{
|
||||
float initialReputation = faction.Reputation.Value;
|
||||
if (initialFactionReputations.ContainsKey(faction))
|
||||
{
|
||||
initialReputation = initialFactionReputations[faction];
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.AddWarning($"Could not determine reputation change for faction \"{faction.Prefab.Name}\" (faction was not present at the start of the round).");
|
||||
}
|
||||
CreateReputationElement(
|
||||
reputationList.Content,
|
||||
faction.Prefab.Name,
|
||||
faction.Reputation.Value, faction.Reputation.NormalizedValue, initialReputation,
|
||||
faction.Prefab.ShortDescription, faction.Prefab.Description,
|
||||
faction.Prefab.Icon, faction.Prefab.BackgroundPortrait, faction.Prefab.IconColor);
|
||||
}
|
||||
|
||||
float otherElementHeight = 0.0f;
|
||||
float maxDescriptionHeight = 0.0f;
|
||||
foreach (GUIComponent child in reputationList.Content.Children)
|
||||
{
|
||||
var descriptionElement = child.FindChild("description", recursive: true) as GUITextBlock;
|
||||
maxDescriptionHeight = Math.Max(maxDescriptionHeight, descriptionElement.TextSize.Y * 1.1f);
|
||||
otherElementHeight = Math.Max(otherElementHeight, descriptionElement.Parent.Rect.Height - descriptionElement.TextSize.Y);
|
||||
}
|
||||
foreach (GUIComponent child in reputationList.Content.Children)
|
||||
{
|
||||
var descriptionElement = child.FindChild("description", recursive: true) as GUITextBlock;
|
||||
descriptionElement.RectTransform.MaxSize = new Point(int.MaxValue, (int)(maxDescriptionHeight));
|
||||
child.RectTransform.MaxSize = new Point(int.MaxValue, (int)((maxDescriptionHeight + otherElementHeight) * 1.2f));
|
||||
(descriptionElement?.Parent as GUILayoutGroup).Recalculate();
|
||||
}
|
||||
CreateReputationInfoPanel(reputationContent, campaignMode);
|
||||
}
|
||||
|
||||
//mission panel -------------------------------------------------------------------------------
|
||||
|
||||
GUIFrame missionframe = new GUIFrame(new RectTransform(new Vector2(0.39f, 0.22f), background.RectTransform, Anchor.TopCenter, minSize: new Point(minWidth, minHeight / 4)));
|
||||
GUIFrame missionframeInner = new GUIFrame(new RectTransform(new Point(missionframe.Rect.Width - padding * 2, missionframe.Rect.Height - padding * 2), missionframe.RectTransform, Anchor.Center), style: "InnerFrame");
|
||||
|
||||
var missionContent = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.9f), missionframeInner.RectTransform, Anchor.Center))
|
||||
GUIFrame missionframe = new GUIFrame(new RectTransform(new Vector2(0.39f, 0.3f), background.RectTransform, Anchor.TopCenter, minSize: new Point(minWidth, minHeight / 4)));
|
||||
GUILayoutGroup missionFrameContent = new GUILayoutGroup(new RectTransform(new Point(missionframe.Rect.Width - padding * 2, missionframe.Rect.Height - padding * 2), missionframe.RectTransform, Anchor.Center))
|
||||
{
|
||||
Stretch = true,
|
||||
RelativeSpacing = 0.05f
|
||||
};
|
||||
GUIFrame missionframeInner = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.9f), missionFrameContent.RectTransform, Anchor.Center), style: "InnerFrame");
|
||||
|
||||
var missionContent = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.93f), missionframeInner.RectTransform, Anchor.Center))
|
||||
{
|
||||
RelativeSpacing = 0.05f,
|
||||
Stretch = true
|
||||
};
|
||||
|
||||
List<Mission> missionsToDisplay = new List<Mission>(selectedMissions);
|
||||
if (!selectedMissions.Any() && startLocation?.SelectedMission != null)
|
||||
{
|
||||
if (startLocation.SelectedMission.Locations[0] == startLocation.SelectedMission.Locations[1] ||
|
||||
startLocation.SelectedMission.Locations.Contains(campaignMode?.Map.SelectedLocation))
|
||||
{
|
||||
missionsToDisplay.Add(startLocation.SelectedMission);
|
||||
}
|
||||
}
|
||||
|
||||
if (missionsToDisplay.Any())
|
||||
{
|
||||
var missionHeader = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionContent.RectTransform),
|
||||
TextManager.Get(missionsToDisplay.Count > 1 ? "Missions" : "Mission"), textAlignment: Alignment.TopLeft, font: GUI.SubHeadingFont);
|
||||
missionHeader.RectTransform.MinSize = new Point(0, (int)(missionHeader.Rect.Height * 1.2f));
|
||||
}
|
||||
|
||||
GUIListBox missionList = new GUIListBox(new RectTransform(Vector2.One, missionContent.RectTransform, Anchor.Center))
|
||||
{
|
||||
Padding = new Vector4(4, 10, 0, 0) * GUI.Scale
|
||||
};
|
||||
missionList.ContentBackground.Color = Color.Transparent;
|
||||
|
||||
ButtonArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.1f), missionFrameContent.RectTransform, Anchor.BottomCenter), isHorizontal: true, childAnchor: Anchor.BottomRight)
|
||||
{
|
||||
RelativeSpacing = 0.025f
|
||||
};
|
||||
|
||||
missionFrameContent.Recalculate();
|
||||
missionContent.Recalculate();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(endMessage))
|
||||
{
|
||||
var endText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionContent.RectTransform),
|
||||
TextManager.GetServerMessage(endMessage), wrap: true);
|
||||
var endText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionList.Content.RectTransform),
|
||||
TextManager.GetServerMessage(endMessage), wrap: true)
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
endText.RectTransform.MinSize = new Point(0, endText.Rect.Height);
|
||||
var line = new GUIFrame(new RectTransform(new Vector2(0.5f, 0.1f), missionContent.RectTransform), style: "HorizontalLine");
|
||||
var line = new GUIFrame(new RectTransform(new Vector2(0.5f, 0.1f), missionList.Content.RectTransform), style: "HorizontalLine");
|
||||
line.RectTransform.NonScaledSize = new Point(line.Rect.Width, GUI.IntScale(5.0f));
|
||||
}
|
||||
|
||||
var missionContentHorizontal = new GUILayoutGroup(new RectTransform(Vector2.One, missionContent.RectTransform), childAnchor: Anchor.TopLeft, isHorizontal: true)
|
||||
foreach (Mission displayedMission in missionsToDisplay)
|
||||
{
|
||||
RelativeSpacing = 0.025f,
|
||||
Stretch = true
|
||||
};
|
||||
|
||||
Mission displayedMission = selectedMission ?? startLocation.SelectedMission;
|
||||
string missionMessage = "";
|
||||
GUIImage missionIcon;
|
||||
if (displayedMission != null)
|
||||
{
|
||||
missionMessage =
|
||||
displayedMission == selectedMission ?
|
||||
displayedMission.Completed ? displayedMission.SuccessMessage : displayedMission.FailureMessage :
|
||||
displayedMission.Description;
|
||||
missionIcon = new GUIImage(new RectTransform(new Point(missionContentHorizontal.Rect.Height), missionContentHorizontal.RectTransform), displayedMission.Prefab.Icon, scaleToFit: true)
|
||||
var missionContentHorizontal = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.8f), missionList.Content.RectTransform), childAnchor: Anchor.CenterLeft, isHorizontal: true)
|
||||
{
|
||||
Color = displayedMission.Prefab.IconColor
|
||||
RelativeSpacing = 0.025f,
|
||||
Stretch = true
|
||||
};
|
||||
if (displayedMission == selectedMission)
|
||||
{
|
||||
new GUIImage(new RectTransform(Vector2.One, missionIcon.RectTransform), displayedMission.Completed ? "MissionCompletedIcon" : "MissionFailedIcon", scaleToFit: true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
missionIcon = new GUIImage(new RectTransform(new Point(missionContentHorizontal.Rect.Height), missionContentHorizontal.RectTransform), style: "NoMissionIcon", scaleToFit: true);
|
||||
}
|
||||
var missionTextContent = new GUILayoutGroup(new RectTransform(Vector2.One, missionContentHorizontal.RectTransform))
|
||||
{
|
||||
RelativeSpacing = 0.05f
|
||||
};
|
||||
missionContentHorizontal.Recalculate();
|
||||
missionContent.Recalculate();
|
||||
missionIcon.RectTransform.MinSize = new Point(0, missionContentHorizontal.Rect.Height);
|
||||
missionTextContent.RectTransform.MaxSize = new Point(int.MaxValue, missionIcon.Rect.Width);
|
||||
|
||||
GUITextBlock missionDescription = null;
|
||||
if (displayedMission == null)
|
||||
{
|
||||
string missionMessage =
|
||||
selectedMissions.Contains(displayedMission) ?
|
||||
displayedMission.Completed ? displayedMission.SuccessMessage : displayedMission.FailureMessage :
|
||||
displayedMission.Description;
|
||||
GUIImage missionIcon = new GUIImage(new RectTransform(new Point((int)(missionContentHorizontal.Rect.Height)), missionContentHorizontal.RectTransform), displayedMission.Prefab.Icon, scaleToFit: true)
|
||||
{
|
||||
Color = displayedMission.Prefab.IconColor,
|
||||
HoverColor = displayedMission.Prefab.IconColor,
|
||||
SelectedColor = displayedMission.Prefab.IconColor
|
||||
};
|
||||
missionIcon.RectTransform.MinSize = new Point((int)(missionContentHorizontal.Rect.Height * 0.9f));
|
||||
if (selectedMissions.Contains(displayedMission))
|
||||
{
|
||||
new GUIImage(new RectTransform(Vector2.One, missionIcon.RectTransform), displayedMission.Completed ? "MissionCompletedIcon" : "MissionFailedIcon", scaleToFit: true);
|
||||
}
|
||||
|
||||
var missionTextContent = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.8f), missionContentHorizontal.RectTransform))
|
||||
{
|
||||
RelativeSpacing = 0.05f
|
||||
};
|
||||
var missionNameTextBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform),
|
||||
displayedMission.Name, font: GUI.SubHeadingFont);
|
||||
if (displayedMission.Difficulty.HasValue)
|
||||
{
|
||||
var groupSize = missionNameTextBlock.Rect.Size;
|
||||
groupSize.X -= (int)(missionNameTextBlock.Padding.X + missionNameTextBlock.Padding.Z);
|
||||
var indicatorGroup = new GUILayoutGroup(new RectTransform(groupSize, missionTextContent.RectTransform) { AbsoluteOffset = new Point((int)missionNameTextBlock.Padding.X, 0) },
|
||||
isHorizontal: true, childAnchor: Anchor.CenterLeft)
|
||||
{
|
||||
AbsoluteSpacing = 1
|
||||
};
|
||||
var difficultyColor = displayedMission.GetDifficultyColor();
|
||||
for (int i = 0; i < displayedMission.Difficulty; i++)
|
||||
{
|
||||
new GUIImage(new RectTransform(Vector2.One, indicatorGroup.RectTransform, scaleBasis: ScaleBasis.Smallest) { IsFixedSize = true }, "DifficultyIndicator", scaleToFit: true)
|
||||
{
|
||||
CanBeFocused = false,
|
||||
Color = difficultyColor
|
||||
};
|
||||
}
|
||||
}
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform),
|
||||
TextManager.Get("nomission"), font: GUI.LargeFont);
|
||||
}
|
||||
else
|
||||
{
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform),
|
||||
TextManager.AddPunctuation(':', TextManager.Get("Mission"), displayedMission.Name), font: GUI.SubHeadingFont);
|
||||
missionDescription = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform),
|
||||
missionMessage, wrap: true);
|
||||
if (displayedMission == selectedMission && displayedMission.Completed)
|
||||
missionMessage, wrap: true, parseRichText: true);
|
||||
if (selectedMissions.Contains(displayedMission) && displayedMission.Completed && displayedMission.Reward > 0)
|
||||
{
|
||||
string rewardText = TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", displayedMission.Reward));
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform),
|
||||
TextManager.GetWithVariable("MissionReward", "[reward]", rewardText));
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform), displayedMission.GetMissionRewardText(), parseRichText: true);
|
||||
}
|
||||
|
||||
if (displayedMission != missionsToDisplay.Last())
|
||||
{
|
||||
var spacing = new GUIFrame(new RectTransform(new Vector2(1.0f, 1.0f), missionList.Content.RectTransform) { MaxSize = new Point(int.MaxValue, GUI.IntScale(15)) }, style: null);
|
||||
new GUIFrame(new RectTransform(new Vector2(0.8f, 1.0f), spacing.RectTransform, Anchor.Center) { RelativeOffset = new Vector2(0.1f, 0.0f) }, "HorizontalLine");
|
||||
}
|
||||
}
|
||||
|
||||
ButtonArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.1f), missionContent.RectTransform, Anchor.BottomCenter), isHorizontal: true, childAnchor: Anchor.BottomRight)
|
||||
if (!missionsToDisplay.Any())
|
||||
{
|
||||
IgnoreLayoutGroups = true,
|
||||
RelativeSpacing = 0.025f
|
||||
};
|
||||
var missionContentHorizontal = new GUILayoutGroup(new RectTransform(Vector2.One, missionList.Content.RectTransform), childAnchor: Anchor.TopLeft, isHorizontal: true)
|
||||
{
|
||||
RelativeSpacing = 0.025f,
|
||||
Stretch = true
|
||||
};
|
||||
GUIImage missionIcon = new GUIImage(new RectTransform(new Point((int)(missionContentHorizontal.Rect.Height * 0.7f)), missionContentHorizontal.RectTransform), style: "NoMissionIcon", scaleToFit: true);
|
||||
missionIcon.RectTransform.MinSize = new Point((int)(missionContentHorizontal.Rect.Height * 0.7f));
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionContentHorizontal.RectTransform),
|
||||
TextManager.Get("nomission"), font: GUI.LargeFont);
|
||||
}
|
||||
|
||||
/*missionContentHorizontal.Recalculate();
|
||||
missionContent.Recalculate();
|
||||
missionIcon.RectTransform.MinSize = new Point(0, missionContentHorizontal.Rect.Height);
|
||||
missionTextContent.RectTransform.MaxSize = new Point(int.MaxValue, missionIcon.Rect.Width);*/
|
||||
|
||||
ContinueButton = new GUIButton(new RectTransform(new Vector2(0.25f, 1.0f), ButtonArea.RectTransform), TextManager.Get("Close"));
|
||||
ButtonArea.RectTransform.NonScaledSize = new Point(ButtonArea.Rect.Width, ContinueButton.Rect.Height);
|
||||
ButtonArea.RectTransform.IsFixedSize = true;
|
||||
|
||||
missionContent.Recalculate();
|
||||
//description overlapping with the buttons -> switch to small font
|
||||
if (missionDescription != null && missionDescription.Rect.Y + missionDescription.TextSize.Y > ButtonArea.Rect.Y)
|
||||
{
|
||||
missionDescription.Font = GUI.Style.SmallFont;
|
||||
//still overlapping -> shorten the text
|
||||
if (missionDescription.Rect.Y + missionDescription.TextSize.Y > ButtonArea.Rect.Y && missionDescription.WrappedText.Contains('\n'))
|
||||
{
|
||||
missionDescription.ToolTip = missionDescription.Text;
|
||||
missionDescription.Text = missionDescription.WrappedText.Split('\n').First() + "...";
|
||||
}
|
||||
}
|
||||
missionFrameContent.Recalculate();
|
||||
|
||||
// set layout -------------------------------------------------------------------
|
||||
|
||||
@@ -378,9 +375,114 @@ namespace Barotrauma
|
||||
return background;
|
||||
}
|
||||
|
||||
public void CreateReputationInfoPanel(GUIComponent parent, CampaignMode campaignMode)
|
||||
{
|
||||
GUIListBox reputationList = new GUIListBox(new RectTransform(Vector2.One, parent.RectTransform))
|
||||
{
|
||||
Padding = new Vector4(4, 10, 0, 0) * GUI.Scale
|
||||
};
|
||||
reputationList.ContentBackground.Color = Color.Transparent;
|
||||
|
||||
if (startLocation.Type.HasOutpost && startLocation.Reputation != null)
|
||||
{
|
||||
var iconStyle = GUI.Style.GetComponentStyle("LocationReputationIcon");
|
||||
var locationFrame = CreateReputationElement(
|
||||
reputationList.Content,
|
||||
startLocation.Name,
|
||||
startLocation.Reputation.Value, startLocation.Reputation.NormalizedValue, initialLocationReputation,
|
||||
startLocation.Type.Name, "",
|
||||
iconStyle?.GetDefaultSprite(), startLocation.Type.GetPortrait(0), iconStyle?.Color ?? Color.White);
|
||||
CreatePathUnlockElement(locationFrame, null, startLocation);
|
||||
}
|
||||
|
||||
foreach (Faction faction in campaignMode.Factions)
|
||||
{
|
||||
float initialReputation = faction.Reputation.Value;
|
||||
if (initialFactionReputations.ContainsKey(faction))
|
||||
{
|
||||
initialReputation = initialFactionReputations[faction];
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.AddWarning($"Could not determine reputation change for faction \"{faction.Prefab.Name}\" (faction was not present at the start of the round).");
|
||||
}
|
||||
var factionFrame = CreateReputationElement(
|
||||
reputationList.Content,
|
||||
faction.Prefab.Name,
|
||||
faction.Reputation.Value, faction.Reputation.NormalizedValue, initialReputation,
|
||||
faction.Prefab.ShortDescription, faction.Prefab.Description,
|
||||
faction.Prefab.Icon, faction.Prefab.BackgroundPortrait, faction.Prefab.IconColor);
|
||||
CreatePathUnlockElement(factionFrame, faction, null);
|
||||
}
|
||||
|
||||
float maxDescriptionHeight = 0.0f;
|
||||
foreach (GUIComponent child in reputationList.Content.Children)
|
||||
{
|
||||
var descriptionElement = child.FindChild("description", recursive: true) as GUITextBlock;
|
||||
maxDescriptionHeight = Math.Max(maxDescriptionHeight, descriptionElement.TextSize.Y * 1.1f);
|
||||
}
|
||||
foreach (GUIComponent child in reputationList.Content.Children)
|
||||
{
|
||||
var headerElement = child.FindChild("header", recursive: true) as GUITextBlock;
|
||||
var descriptionElement = child.FindChild("description", recursive: true) as GUITextBlock;
|
||||
descriptionElement.RectTransform.NonScaledSize = new Point(descriptionElement.Rect.Width, (int)maxDescriptionHeight);
|
||||
descriptionElement.RectTransform.IsFixedSize = true;
|
||||
child.RectTransform.NonScaledSize = new Point(child.Rect.Width, headerElement.Rect.Height + descriptionElement.RectTransform.Parent.Children.Sum(c => c.Rect.Height + ((GUILayoutGroup)descriptionElement.Parent).AbsoluteSpacing));
|
||||
}
|
||||
|
||||
void CreatePathUnlockElement(GUIComponent reputationFrame, Faction faction, Location location)
|
||||
{
|
||||
if (GameMain.GameSession?.Campaign?.Map != null)
|
||||
{
|
||||
foreach (LocationConnection connection in GameMain.GameSession.Campaign.Map.Connections)
|
||||
{
|
||||
if (!connection.Locked || (!connection.Locations[0].Discovered && !connection.Locations[1].Discovered)) { continue; }
|
||||
|
||||
var gateLocation = connection.Locations[0].IsGateBetweenBiomes ? connection.Locations[0] : connection.Locations[1];
|
||||
var unlockEvent =
|
||||
EventSet.PrefabList.Find(ep => ep.UnlockPathEvent && ep.BiomeIdentifier == gateLocation.LevelData.Biome.Identifier) ??
|
||||
EventSet.PrefabList.Find(ep => ep.UnlockPathEvent && string.IsNullOrEmpty(ep.BiomeIdentifier));
|
||||
|
||||
if (unlockEvent == null) { continue; }
|
||||
if (string.IsNullOrEmpty(unlockEvent.UnlockPathFaction) || unlockEvent.UnlockPathFaction.Equals("location", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (location == null || gateLocation != location) { continue; }
|
||||
}
|
||||
else
|
||||
{
|
||||
if (faction == null || !faction.Prefab.Identifier.Equals(unlockEvent.UnlockPathFaction, StringComparison.OrdinalIgnoreCase)) { continue; }
|
||||
}
|
||||
|
||||
if (unlockEvent != null)
|
||||
{
|
||||
Reputation unlockReputation = gateLocation.Reputation;
|
||||
Faction unlockFaction = null;
|
||||
if (!string.IsNullOrEmpty(unlockEvent.UnlockPathFaction))
|
||||
{
|
||||
unlockFaction = GameMain.GameSession.Campaign.Factions.Find(f => f.Prefab.Identifier.Equals(unlockEvent.UnlockPathFaction, StringComparison.OrdinalIgnoreCase));
|
||||
unlockReputation = unlockFaction?.Reputation;
|
||||
}
|
||||
float normalizedUnlockReputation = MathUtils.InverseLerp(unlockReputation.MinReputation, unlockReputation.MaxReputation, unlockEvent.UnlockPathReputation);
|
||||
string unlockText = TextManager.GetWithVariables(
|
||||
"lockedpathreputationrequirement",
|
||||
new string[] { "[reputation]", "[biomename]" },
|
||||
new string[] { Reputation.GetFormattedReputationText(normalizedUnlockReputation, unlockEvent.UnlockPathReputation, addColorTags: true), $"‖color:gui.orange‖{connection.LevelData.Biome.DisplayName}‖end‖" });
|
||||
var unlockInfoPanel = new GUITextBlock(new RectTransform(new Vector2(0.8f, 0.0f), reputationFrame.RectTransform, Anchor.BottomCenter) { MinSize = new Point(0, GUI.IntScale(30)), AbsoluteOffset = new Point(0, GUI.IntScale(3)) },
|
||||
unlockText, style: "GUIButtonRound", textAlignment: Alignment.Center, textColor: GUI.Style.TextColor, parseRichText: true);
|
||||
unlockInfoPanel.Color = Color.Lerp(unlockInfoPanel.Color, Color.Black, 0.8f);
|
||||
if (unlockInfoPanel.TextSize.X > unlockInfoPanel.Rect.Width * 0.7f)
|
||||
{
|
||||
unlockInfoPanel.Font = GUI.SmallFont;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string GetHeaderText(bool gameOver, CampaignMode.TransitionType transitionType)
|
||||
{
|
||||
string locationName = Submarine.MainSub.AtEndPosition ? endLocation?.Name : startLocation?.Name;
|
||||
string locationName = Submarine.MainSub.AtEndExit ? endLocation?.Name : startLocation?.Name;
|
||||
|
||||
string textTag;
|
||||
if (gameOver)
|
||||
@@ -396,17 +498,23 @@ namespace Barotrauma
|
||||
textTag = "RoundSummaryLeaving";
|
||||
break;
|
||||
case CampaignMode.TransitionType.ProgressToNextLocation:
|
||||
case CampaignMode.TransitionType.ProgressToNextEmptyLocation:
|
||||
locationName = endLocation?.Name;
|
||||
textTag = "RoundSummaryProgress";
|
||||
break;
|
||||
case CampaignMode.TransitionType.ProgressToNextEmptyLocation:
|
||||
locationName = endLocation?.Name;
|
||||
textTag = "RoundSummaryProgressToEmptyLocation";
|
||||
break;
|
||||
case CampaignMode.TransitionType.ReturnToPreviousLocation:
|
||||
case CampaignMode.TransitionType.ReturnToPreviousEmptyLocation:
|
||||
locationName = startLocation?.Name;
|
||||
textTag = "RoundSummaryReturn";
|
||||
break;
|
||||
case CampaignMode.TransitionType.ReturnToPreviousEmptyLocation:
|
||||
locationName = startLocation?.Name;
|
||||
textTag = "RoundSummaryReturnToEmptyLocation";
|
||||
break;
|
||||
default:
|
||||
textTag = Submarine.MainSub.AtEndPosition ? "RoundSummaryProgress" : "RoundSummaryReturn";
|
||||
textTag = Submarine.MainSub.AtEndExit ? "RoundSummaryProgress" : "RoundSummaryReturn";
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -456,7 +564,7 @@ namespace Barotrauma
|
||||
|
||||
GUIListBox crewList = new GUIListBox(new RectTransform(Vector2.One, parent.RectTransform))
|
||||
{
|
||||
Padding = new Vector4(2, 5, 0, 0),
|
||||
Padding = new Vector4(4, 10, 0, 0) * GUI.Scale,
|
||||
AutoHideScrollBar = false
|
||||
};
|
||||
crewList.ContentBackground.Color = Color.Transparent;
|
||||
@@ -547,11 +655,11 @@ namespace Barotrauma
|
||||
ToolBox.LimitString(statusText, GUI.Font, characterColumnWidth), textAlignment: Alignment.Center, textColor: statusColor);
|
||||
}
|
||||
|
||||
private void CreateReputationElement(GUIComponent parent,
|
||||
private GUIFrame CreateReputationElement(GUIComponent parent,
|
||||
string name, float reputation, float normalizedReputation, float initialReputation,
|
||||
string shortDescription, string fullDescription, Sprite icon, Sprite backgroundPortrait, Color iconColor)
|
||||
{
|
||||
var factionFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.3f), parent.RectTransform), style: null);
|
||||
var factionFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.1f), parent.RectTransform), style: null);
|
||||
|
||||
if (backgroundPortrait != null)
|
||||
{
|
||||
@@ -568,13 +676,13 @@ namespace Barotrauma
|
||||
|
||||
var factionInfoHorizontal = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.9f), factionFrame.RectTransform, Anchor.Center), childAnchor: Anchor.CenterLeft, isHorizontal: true)
|
||||
{
|
||||
RelativeSpacing = 0.02f,
|
||||
AbsoluteSpacing = GUI.IntScale(5),
|
||||
Stretch = true
|
||||
};
|
||||
|
||||
var factionTextContent = new GUILayoutGroup(new RectTransform(Vector2.One, factionInfoHorizontal.RectTransform))
|
||||
{
|
||||
RelativeSpacing = 0.05f,
|
||||
AbsoluteSpacing = GUI.IntScale(10),
|
||||
Stretch = true
|
||||
};
|
||||
var factionIcon = new GUIImage(new RectTransform(new Point((int)(factionInfoHorizontal.Rect.Height * 0.7f)), factionInfoHorizontal.RectTransform, scaleBasis: ScaleBasis.Smallest), icon, scaleToFit: true)
|
||||
@@ -583,12 +691,48 @@ namespace Barotrauma
|
||||
};
|
||||
factionInfoHorizontal.Recalculate();
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), factionTextContent.RectTransform),
|
||||
var header = new GUITextBlock(new RectTransform(new Point(factionTextContent.Rect.Width, GUI.IntScale(40)), factionTextContent.RectTransform),
|
||||
name, font: GUI.SubHeadingFont)
|
||||
{
|
||||
Padding = Vector4.Zero
|
||||
Padding = Vector4.Zero,
|
||||
UserData = "header"
|
||||
};
|
||||
var factionDescription = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.6f), factionTextContent.RectTransform),
|
||||
header.RectTransform.IsFixedSize = true;
|
||||
|
||||
var sliderHolder = new GUILayoutGroup(new RectTransform(new Point((int)(factionTextContent.Rect.Width * 0.8f), GUI.IntScale(20.0f)), factionTextContent.RectTransform),
|
||||
childAnchor: Anchor.CenterLeft, isHorizontal: true)
|
||||
{
|
||||
RelativeSpacing = 0.05f,
|
||||
Stretch = true
|
||||
};
|
||||
sliderHolder.RectTransform.IsFixedSize = true;
|
||||
factionTextContent.Recalculate();
|
||||
|
||||
new GUICustomComponent(new RectTransform(new Vector2(0.8f, 1.0f), sliderHolder.RectTransform),
|
||||
onDraw: (sb, customComponent) => DrawReputationBar(sb, customComponent.Rect, normalizedReputation));
|
||||
|
||||
string reputationText = Reputation.GetFormattedReputationText(normalizedReputation, reputation, addColorTags: true);
|
||||
int reputationChange = (int)Math.Round(reputation - initialReputation);
|
||||
if (Math.Abs(reputationChange) > 0)
|
||||
{
|
||||
string changeText = $"{(reputationChange > 0 ? "+" : "") + reputationChange}";
|
||||
string colorStr = XMLExtensions.ColorToString(reputationChange > 0 ? GUI.Style.Green : GUI.Style.Red);
|
||||
var rtData = RichTextData.GetRichTextData($"{reputationText} (‖color:{colorStr}‖{changeText}‖color:end‖)", out string sanitizedText);
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), sliderHolder.RectTransform),
|
||||
rtData, sanitizedText,
|
||||
textAlignment: Alignment.CenterLeft, font: GUI.SubHeadingFont);
|
||||
}
|
||||
else
|
||||
{
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), sliderHolder.RectTransform),
|
||||
reputationText,
|
||||
textAlignment: Alignment.CenterLeft, font: GUI.SubHeadingFont, parseRichText: true);
|
||||
}
|
||||
|
||||
//spacing
|
||||
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.0f), factionTextContent.RectTransform) { MinSize = new Point(0, GUI.IntScale(5)) }, style: null);
|
||||
|
||||
var factionDescription = new GUITextBlock(new RectTransform(new Vector2(0.8f, 0.6f), factionTextContent.RectTransform),
|
||||
shortDescription, font: GUI.SmallFont, wrap: true)
|
||||
{
|
||||
UserData = "description",
|
||||
@@ -599,51 +743,32 @@ namespace Barotrauma
|
||||
factionDescription.ToolTip = fullDescription;
|
||||
}
|
||||
|
||||
var sliderHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.1f), factionTextContent.RectTransform),
|
||||
childAnchor: Anchor.CenterLeft, isHorizontal: true)
|
||||
{
|
||||
RelativeSpacing = 0.05f,
|
||||
Stretch = true
|
||||
};
|
||||
sliderHolder.RectTransform.MaxSize = new Point(int.MaxValue, GUI.IntScale(25.0f));
|
||||
//spacing
|
||||
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.0f), factionTextContent.RectTransform) { MinSize = new Point(0, GUI.IntScale(5)) }, style: null);
|
||||
|
||||
factionInfoHorizontal.Recalculate();
|
||||
factionTextContent.Recalculate();
|
||||
|
||||
new GUICustomComponent(new RectTransform(new Vector2(0.8f, 1.0f), sliderHolder.RectTransform),
|
||||
onDraw: (sb, customComponent) => DrawReputationBar(sb, customComponent.Rect, normalizedReputation));
|
||||
|
||||
string reputationText = ((int)Math.Round(reputation)).ToString();
|
||||
int reputationChange = (int)Math.Round( reputation - initialReputation);
|
||||
if (Math.Abs(reputationChange) > 0)
|
||||
{
|
||||
string changeText = $"{(reputationChange > 0 ? "+" : "") + reputationChange}";
|
||||
string colorStr = XMLExtensions.ColorToString(reputationChange > 0 ? GUI.Style.Green : GUI.Style.Red);
|
||||
var rtData = RichTextData.GetRichTextData($"{reputationText} (‖color:{colorStr}‖{changeText}‖color:end‖)", out string sanitizedText);
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), sliderHolder.RectTransform),
|
||||
rtData, sanitizedText,
|
||||
textAlignment: Alignment.CenterLeft, font: GUI.SubHeadingFont);
|
||||
}
|
||||
else
|
||||
{
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), sliderHolder.RectTransform),
|
||||
reputationText,
|
||||
textAlignment: Alignment.CenterLeft, font: GUI.SubHeadingFont);
|
||||
}
|
||||
return factionFrame;
|
||||
}
|
||||
|
||||
public static void DrawReputationBar(SpriteBatch sb, Rectangle rect, float normalizedReputation)
|
||||
{
|
||||
GUI.DrawRectangle(sb, rect, GUI.Style.ColorInventoryBackground, isFilled: true);
|
||||
if (normalizedReputation < 0.5f)
|
||||
int segmentWidth = rect.Width / 5;
|
||||
rect.Width = segmentWidth * 5;
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
int barWidth = (int)((0.5f - normalizedReputation) * rect.Width);
|
||||
GUI.DrawRectangle(sb, new Rectangle(rect.Center.X - barWidth, rect.Y, barWidth, rect.Height), GUI.Style.Red, isFilled: true);
|
||||
GUI.DrawRectangle(sb, new Rectangle(rect.X + (segmentWidth * i), rect.Y, segmentWidth, rect.Height), Reputation.GetReputationColor(i / 5.0f), isFilled: true);
|
||||
GUI.DrawRectangle(sb, new Rectangle(rect.X + (segmentWidth * i), rect.Y, segmentWidth, rect.Height), GUI.Style.ColorInventoryBackground, isFilled: false);
|
||||
}
|
||||
else if (normalizedReputation > 0.5f)
|
||||
{
|
||||
int barWidth = (int)((normalizedReputation - 0.5f) * rect.Width);
|
||||
GUI.DrawRectangle(sb, new Rectangle(rect.Center.X, rect.Y, barWidth, rect.Height), GUI.Style.Green, isFilled: true);
|
||||
}
|
||||
GUI.DrawLine(sb, new Vector2(rect.Center.X, rect.Y - 2), new Vector2(rect.Center.X, rect.Bottom + 2), GUI.Style.TextColor);
|
||||
GUI.DrawRectangle(sb, rect, GUI.Style.ColorInventoryBackground, isFilled: false);
|
||||
|
||||
GUI.Arrow.Draw(sb, new Vector2(rect.X + rect.Width * normalizedReputation, rect.Y), GUI.Style.ColorInventoryBackground, scale: GUI.Scale, spriteEffect: SpriteEffects.FlipVertically);
|
||||
GUI.Arrow.Draw(sb, new Vector2(rect.X + rect.Width * normalizedReputation, rect.Y), GUI.Style.TextColor, scale: GUI.Scale * 0.8f, spriteEffect: SpriteEffects.FlipVertically);
|
||||
|
||||
GUI.DrawString(sb, new Vector2(rect.X, rect.Bottom), "-100", GUI.Style.TextColor, font: GUI.SmallFont);
|
||||
Vector2 textSize = GUI.SmallFont.MeasureString("100");
|
||||
GUI.DrawString(sb, new Vector2(rect.Right - textSize.X, rect.Bottom), "100", GUI.Style.TextColor, font: GUI.SmallFont);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user