v0.19.8.0
This commit is contained in:
@@ -399,12 +399,9 @@ namespace Barotrauma
|
||||
progressBar.Draw(spriteBatch, cam);
|
||||
}
|
||||
|
||||
void DrawInteractionIcon(Entity entity, string iconStyle)
|
||||
void DrawInteractionIcon(Entity entity, Identifier iconStyle)
|
||||
{
|
||||
if (entity == null || entity.Removed) { return; }
|
||||
var characterEntity = entity as Character;
|
||||
if (characterEntity is not null && (characterEntity.IsDead || characterEntity.IsIncapacitated)) { return; }
|
||||
if (GUIStyle.GetComponentStyle(iconStyle) is not GUIComponentStyle style) { return; }
|
||||
|
||||
Hull currentHull = entity switch
|
||||
{
|
||||
@@ -412,20 +409,28 @@ namespace Barotrauma
|
||||
Item item => item.CurrentHull,
|
||||
_ => null
|
||||
};
|
||||
|
||||
Range<float> visibleRange = new Range<float>(currentHull == Character.Controlled.CurrentHull ? 500.0f : 100.0f, float.PositiveInfinity);
|
||||
if (characterEntity?.CampaignInteractionType == CampaignMode.InteractionType.Examine)
|
||||
LocalizedString label = null;
|
||||
if (entity is Character characterEntity)
|
||||
{
|
||||
//TODO: we could probably do better than just hardcoding
|
||||
//a check for InteractionType.Examine here.
|
||||
if (characterEntity.IsDead || characterEntity.IsIncapacitated) { return; }
|
||||
if (characterEntity?.CampaignInteractionType == CampaignMode.InteractionType.Examine)
|
||||
{
|
||||
//TODO: we could probably do better than just hardcoding
|
||||
//a check for InteractionType.Examine here.
|
||||
|
||||
if (Vector2.DistanceSquared(character.Position, entity.Position) > 500f * 500f) { return; }
|
||||
if (Vector2.DistanceSquared(character.Position, entity.Position) > 500f * 500f) { return; }
|
||||
|
||||
var body = Submarine.CheckVisibility(character.SimPosition, entity.SimPosition, ignoreLevel: true);
|
||||
if (body != null && body.UserData != entity) { return; }
|
||||
var body = Submarine.CheckVisibility(character.SimPosition, entity.SimPosition, ignoreLevel: true);
|
||||
if (body != null && body.UserData != entity) { return; }
|
||||
|
||||
visibleRange = new Range<float>(-100f, 500f);
|
||||
visibleRange = new Range<float>(-100f, 500f);
|
||||
}
|
||||
label = characterEntity?.Info?.Title;
|
||||
}
|
||||
|
||||
if (GUIStyle.GetComponentStyle(iconStyle) is not GUIComponentStyle style) { return; }
|
||||
|
||||
float dist = Vector2.Distance(character.WorldPosition, entity.WorldPosition);
|
||||
float distFactor = 1.0f - MathUtils.InverseLerp(1000.0f, 3000.0f, dist);
|
||||
float alpha = MathHelper.Lerp(0.3f, 1.0f, distFactor);
|
||||
@@ -436,13 +441,13 @@ namespace Barotrauma
|
||||
visibleRange,
|
||||
style.GetDefaultSprite(),
|
||||
style.Color * alpha,
|
||||
label: characterEntity?.Info?.Title);
|
||||
label: label);
|
||||
}
|
||||
|
||||
foreach (Character npc in Character.CharacterList)
|
||||
{
|
||||
if (npc.CampaignInteractionType == CampaignMode.InteractionType.None) { continue; }
|
||||
DrawInteractionIcon(npc, "CampaignInteractionIcon." + npc.CampaignInteractionType);
|
||||
DrawInteractionIcon(npc, ("CampaignInteractionIcon." + npc.CampaignInteractionType).ToIdentifier());
|
||||
}
|
||||
|
||||
if (GameMain.GameSession?.GameMode is TutorialMode tutorialMode && tutorialMode.Tutorial is not null)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using Barotrauma.Networking;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
@@ -141,7 +142,7 @@ namespace Barotrauma
|
||||
|
||||
public virtual void ClientEventWrite(IWriteMessage msg, NetEntityEvent.IData extraData = null)
|
||||
{
|
||||
if (!(extraData is IEventData eventData)) { throw new Exception($"Malformed character event: expected {nameof(Character)}.{nameof(IEventData)}"); }
|
||||
if (extraData is not IEventData eventData) { throw new Exception($"Malformed character event: expected {nameof(Character)}.{nameof(IEventData)}"); }
|
||||
|
||||
msg.WriteRangedInteger((int)eventData.EventType, (int)EventType.MinValue, (int)EventType.MaxValue);
|
||||
switch (eventData)
|
||||
@@ -471,25 +472,11 @@ namespace Barotrauma
|
||||
break;
|
||||
case EventType.AddToCrew:
|
||||
GameMain.GameSession.CrewManager.AddCharacter(this);
|
||||
CharacterTeamType teamID = (CharacterTeamType)msg.ReadByte();
|
||||
ushort itemCount = msg.ReadUInt16();
|
||||
for (int i = 0; i < itemCount; i++)
|
||||
{
|
||||
ushort itemID = msg.ReadUInt16();
|
||||
if (!(Entity.FindEntityByID(itemID) is Item item)) { continue; }
|
||||
item.AllowStealing = true;
|
||||
var wifiComponent = item.GetComponent<WifiComponent>();
|
||||
if (wifiComponent != null)
|
||||
{
|
||||
wifiComponent.TeamID = teamID;
|
||||
}
|
||||
var idCard = item.GetComponent<IdCard>();
|
||||
if (idCard != null)
|
||||
{
|
||||
idCard.TeamID = teamID;
|
||||
idCard.SubmarineSpecificID = 0;
|
||||
}
|
||||
}
|
||||
ReadItemTeamChange(msg, true);
|
||||
break;
|
||||
case EventType.RemoveFromCrew:
|
||||
GameMain.GameSession.CrewManager.RemoveCharacter(this, removeInfo: true);
|
||||
ReadItemTeamChange(msg, false);
|
||||
break;
|
||||
case EventType.UpdateExperience:
|
||||
int experienceAmount = msg.ReadInt32();
|
||||
@@ -520,9 +507,27 @@ namespace Barotrauma
|
||||
info?.ChangeSavedStatValue(statType, statValue, statIdentifier, removeOnDeath, setValue: true);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
msg.ReadPadBits();
|
||||
|
||||
static void ReadItemTeamChange(IReadMessage msg, bool allowStealing)
|
||||
{
|
||||
var itemTeamChange = INetSerializableStruct.Read<ItemTeamChange>(msg);
|
||||
foreach (var itemID in itemTeamChange.ItemIds)
|
||||
{
|
||||
if (FindEntityByID(itemID) is not Item item) { continue; }
|
||||
item.AllowStealing = allowStealing;
|
||||
if (item.GetComponent<WifiComponent>() is { } wifiComponent)
|
||||
{
|
||||
wifiComponent.TeamID = itemTeamChange.TeamId;
|
||||
}
|
||||
if (item.GetComponent<IdCard>() is { } idCard)
|
||||
{
|
||||
idCard.TeamID = itemTeamChange.TeamId;
|
||||
idCard.SubmarineSpecificID = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Character ReadSpawnData(IReadMessage inc)
|
||||
|
||||
@@ -280,6 +280,7 @@ namespace Barotrauma
|
||||
|
||||
cprButton = new GUIButton(new RectTransform(new Vector2(0.17f, 0.17f), characterIndicatorArea.RectTransform, Anchor.BottomLeft, scaleBasis: ScaleBasis.Smallest), text: "", style: "CPRButton")
|
||||
{
|
||||
UserData = UIHighlightAction.ElementId.CPRButton,
|
||||
OnClicked = (button, userData) =>
|
||||
{
|
||||
Character selectedCharacter = Character.Controlled?.SelectedCharacter;
|
||||
@@ -690,7 +691,7 @@ namespace Barotrauma
|
||||
{
|
||||
distortTimer = (distortTimer + deltaTime * distortSpeed) % MathHelper.TwoPi;
|
||||
Character.BlurStrength = (float)(Math.Sin(distortTimer) + 1.5f) * 0.25f * blurStrength;
|
||||
Character.DistortStrength = (float)(Math.Sin(distortTimer) + 1.0f) * 0.1f * distortStrength;
|
||||
Character.DistortStrength = (float)(Math.Sin(distortTimer) + 1.0f) * 0.05f * distortStrength;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1294,6 +1295,7 @@ namespace Barotrauma
|
||||
Dictionary<Identifier, float> treatmentSuitability = new Dictionary<Identifier, float>();
|
||||
GetSuitableTreatments(treatmentSuitability,
|
||||
normalize: true,
|
||||
user: Character.Controlled,
|
||||
ignoreHiddenAfflictions: true,
|
||||
limb: selectedLimbIndex == -1 ? null : Character.AnimController.Limbs.Find(l => l.HealthIndex == selectedLimbIndex));
|
||||
|
||||
@@ -1337,13 +1339,13 @@ namespace Barotrauma
|
||||
};
|
||||
|
||||
var innerFrame = new GUIButton(new RectTransform(Vector2.One, itemSlot.RectTransform, Anchor.Center, Pivot.Center, scaleBasis: ScaleBasis.Smallest), style: "SubtreeHeader")
|
||||
{
|
||||
{
|
||||
UserData = item,
|
||||
DisabledColor = Color.White * 0.1f,
|
||||
PlaySoundOnSelect = false,
|
||||
OnClicked = (btn, userdata) =>
|
||||
{
|
||||
if (!(userdata is ItemPrefab itemPrefab)) { return false; }
|
||||
if (userdata is not ItemPrefab itemPrefab) { return false; }
|
||||
var item = Character.Controlled.Inventory.FindItem(it => it.Prefab == itemPrefab, recursive: true);
|
||||
if (item == null) { return false; }
|
||||
Limb targetLimb = Character.AnimController.Limbs.FirstOrDefault(l => l.HealthIndex == selectedLimbIndex);
|
||||
@@ -1900,6 +1902,7 @@ namespace Barotrauma
|
||||
public void ClientRead(IReadMessage inc)
|
||||
{
|
||||
newAfflictions.Clear();
|
||||
newPeriodicEffects.Clear();
|
||||
byte afflictionCount = inc.ReadByte();
|
||||
for (int i = 0; i < afflictionCount; i++)
|
||||
{
|
||||
@@ -1921,7 +1924,7 @@ namespace Barotrauma
|
||||
int periodicAfflictionCount = inc.ReadByte();
|
||||
for (int j = 0; j < periodicAfflictionCount; j++)
|
||||
{
|
||||
float periodicAfflictionTimer = inc.ReadRangedSingle(afflictionPrefab.PeriodicEffects[j].MinInterval, afflictionPrefab.PeriodicEffects[j].MaxInterval, 8);
|
||||
float periodicAfflictionTimer = inc.ReadRangedSingle(0, afflictionPrefab.PeriodicEffects[j].MaxInterval, 8);
|
||||
newPeriodicEffects.Add((afflictionPrefab.PeriodicEffects[j], periodicAfflictionTimer));
|
||||
}
|
||||
newAfflictions.Add((null, afflictionPrefab, afflictionStrength));
|
||||
@@ -1991,13 +1994,13 @@ namespace Barotrauma
|
||||
//timer has wrapped around, apply the effect
|
||||
if (periodicEffect.timer - existingAffliction.PeriodicEffectTimers[periodicEffect.effect] > periodicEffect.effect.MinInterval / 2)
|
||||
{
|
||||
existingAffliction.PeriodicEffectTimers[periodicEffect.effect] = periodicEffect.timer;
|
||||
foreach (StatusEffect effect in periodicEffect.effect.StatusEffects)
|
||||
{
|
||||
Limb targetLimb = Character.AnimController.Limbs.FirstOrDefault(l => l.HealthIndex == limbHealths.IndexOf(limb));
|
||||
existingAffliction.ApplyStatusEffect(ActionType.OnActive, effect, deltaTime: 1.0f, this, targetLimb: targetLimb);
|
||||
}
|
||||
}
|
||||
existingAffliction.PeriodicEffectTimers[periodicEffect.effect] = periodicEffect.timer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -92,11 +92,13 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
float prevSize = conversationList.TotalSize;
|
||||
|
||||
List<GUIButton> extraButtons = CreateConversation(conversationList, text, speaker, options, string.IsNullOrWhiteSpace(spriteIdentifier));
|
||||
AssignActionsToButtons(extraButtons, lastMessageBox);
|
||||
RecalculateLastMessage(conversationList, true);
|
||||
|
||||
conversationList.ScrollToEnd(0.5f);
|
||||
conversationList.BarScroll = (prevSize - conversationList.Content.Rect.Height) / (conversationList.TotalSize - conversationList.Content.Rect.Height);
|
||||
conversationList.ScrollToEnd(duration: 0.5f);
|
||||
lastMessageBox.SetBackgroundIcon(eventSprite);
|
||||
return;
|
||||
}
|
||||
@@ -112,7 +114,7 @@ namespace Barotrauma
|
||||
};
|
||||
messageBox.OnAddedToGUIUpdateList += (GUIComponent component) =>
|
||||
{
|
||||
if (!(Screen.Selected is GameScreen)) { messageBox.Close(); }
|
||||
if (Screen.Selected is not GameScreen) { messageBox.Close(); }
|
||||
};
|
||||
lastMessageBox = messageBox;
|
||||
|
||||
@@ -321,7 +323,7 @@ namespace Barotrauma
|
||||
AlwaysOverrideCursor = true
|
||||
};
|
||||
|
||||
LocalizedString translatedText = TextManager.Get(text).Fallback(text);
|
||||
LocalizedString translatedText = TextManager.ParseInputTypes(TextManager.Get(text)).Fallback(text);
|
||||
|
||||
if (speaker?.Info != null && drawChathead)
|
||||
{
|
||||
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma;
|
||||
|
||||
partial class InventoryHighlightAction : EventAction
|
||||
{
|
||||
private static readonly Color highlightColor = Color.Orange;
|
||||
|
||||
partial void UpdateProjSpecific()
|
||||
{
|
||||
foreach (var target in ParentEvent.GetTargets(TargetTag))
|
||||
{
|
||||
SetHighlight(target);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetHighlight(Entity entity)
|
||||
{
|
||||
if (entity is Item item)
|
||||
{
|
||||
int i = 0;
|
||||
foreach (var itemContainer in item.GetComponents<Items.Components.ItemContainer>())
|
||||
{
|
||||
if (ItemContainerIndex == -1 || i == ItemContainerIndex)
|
||||
{
|
||||
SetHighlight(itemContainer.Inventory);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else if (entity is Character c)
|
||||
{
|
||||
SetHighlight(c.Inventory);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetHighlight(Inventory inventory)
|
||||
{
|
||||
if (inventory?.visualSlots == null) { return; }
|
||||
for (int i = 0; i < inventory.visualSlots.Length; i++)
|
||||
{
|
||||
if (inventory.visualSlots[i].HighlightTimer > 0) { continue; }
|
||||
Item item = inventory.GetItemAt(i);
|
||||
if (IsSuitableItem(item) ||
|
||||
(Recursive && item?.OwnInventory != null && item.OwnInventory.FindAllItems(it => IsSuitableItem(it), recursive: true).Any()))
|
||||
{
|
||||
inventory.visualSlots[i].ShowBorderHighlight(highlightColor, 0.5f, 0.5f, 0.1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsSuitableItem(Item item)
|
||||
{
|
||||
return (ItemIdentifier.IsEmpty && item == null) ||
|
||||
(item != null && (item.Prefab.Identifier == ItemIdentifier || item.HasTag(ItemIdentifier)));
|
||||
}
|
||||
}
|
||||
@@ -8,20 +8,24 @@ partial class MessageBoxAction : EventAction
|
||||
{
|
||||
partial void UpdateProjSpecific()
|
||||
{
|
||||
if (Type == ActionType.Create)
|
||||
if (Type == ActionType.Create || Type == ActionType.ConnectObjective)
|
||||
{
|
||||
CreateMessageBox();
|
||||
if (!ObjectiveTag.IsEmpty && GameMain.GameSession?.GameMode is TutorialMode tutorialMode)
|
||||
{
|
||||
Identifier id = Identifier.IsEmpty ? Text : Identifier;
|
||||
Identifier id = Identifier.IfEmpty(Text);
|
||||
var segment = Tutorial.Segment.CreateMessageBoxSegment(id, ObjectiveTag, CreateMessageBox);
|
||||
tutorialMode.Tutorial?.TriggerTutorialSegment(segment);
|
||||
tutorialMode.Tutorial?.TriggerTutorialSegment(segment, connectObjective: Type == ActionType.ConnectObjective);
|
||||
}
|
||||
}
|
||||
else if (Type == ActionType.Close)
|
||||
{
|
||||
GUIMessageBox.Close(Tag);
|
||||
}
|
||||
else if (Type == ActionType.Clear)
|
||||
{
|
||||
GUIMessageBox.CloseAll();
|
||||
}
|
||||
}
|
||||
|
||||
public void CreateMessageBox()
|
||||
|
||||
+9
-9
@@ -4,7 +4,7 @@ namespace Barotrauma;
|
||||
|
||||
partial class TutorialHighlightAction : EventAction
|
||||
{
|
||||
private static readonly Color highlightColor = Color.OrangeRed;
|
||||
private static readonly Color highlightColor = Color.Orange;
|
||||
|
||||
partial void UpdateProjSpecific()
|
||||
{
|
||||
@@ -19,32 +19,32 @@ partial class TutorialHighlightAction : EventAction
|
||||
{
|
||||
if (entity is Item i)
|
||||
{
|
||||
SetHighlight(i);
|
||||
SetItemHighlight(i);
|
||||
}
|
||||
else if (entity is Structure s)
|
||||
{
|
||||
SetHighlight(s);
|
||||
SetStructureHighlight(s);
|
||||
}
|
||||
else if (entity is Character c)
|
||||
{
|
||||
SetHighlight(c);
|
||||
SetCharacterHighlight(c);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetHighlight(Item item)
|
||||
private void SetItemHighlight(Item item)
|
||||
{
|
||||
if (item.ExternalHighlight == State) { return; }
|
||||
item.SpriteColor = (State) ? highlightColor : Color.White;
|
||||
item.HighlightColor = State ? highlightColor : null;
|
||||
item.ExternalHighlight = State;
|
||||
}
|
||||
|
||||
private void SetHighlight(Structure structure)
|
||||
private void SetStructureHighlight(Structure structure)
|
||||
{
|
||||
structure.SpriteColor = (State) ? highlightColor : Color.White;
|
||||
structure.SpriteColor = State ? highlightColor : Color.White;
|
||||
structure.ExternalHighlight = State;
|
||||
}
|
||||
|
||||
private void SetHighlight(Character character)
|
||||
private void SetCharacterHighlight(Character character)
|
||||
{
|
||||
character.ExternalHighlight = State;
|
||||
}
|
||||
|
||||
+7
-7
@@ -11,13 +11,13 @@ partial class TutorialSegmentAction : EventAction
|
||||
// Only need to create the segment when it's being triggered (otherwise the tutorial already has the segment instance)
|
||||
if (Type == SegmentActionType.Trigger)
|
||||
{
|
||||
segment = Tutorial.Segment.CreateInfoBoxSegment(Id, ObjectiveTag, AutoPlayVideo ? Tutorials.AutoPlayVideo.Yes : Tutorials.AutoPlayVideo.No,
|
||||
segment = Tutorial.Segment.CreateInfoBoxSegment(Identifier, ObjectiveTag, AutoPlayVideo ? Tutorials.AutoPlayVideo.Yes : Tutorials.AutoPlayVideo.No,
|
||||
new Tutorial.Segment.Text(TextTag, Width, Height, Anchor.Center),
|
||||
new Tutorial.Segment.Video(VideoFile, TextTag, Width, Height));
|
||||
}
|
||||
else if (Type == SegmentActionType.Add)
|
||||
{
|
||||
segment = Tutorial.Segment.CreateObjectiveSegment(Id, !ObjectiveTag.IsEmpty ? ObjectiveTag : Id);
|
||||
segment = Tutorial.Segment.CreateObjectiveSegment(Identifier, !ObjectiveTag.IsEmpty ? ObjectiveTag : Identifier);
|
||||
}
|
||||
if (GameMain.GameSession?.GameMode is TutorialMode tutorialMode)
|
||||
{
|
||||
@@ -30,21 +30,21 @@ partial class TutorialSegmentAction : EventAction
|
||||
tutorial.TriggerTutorialSegment(segment);
|
||||
break;
|
||||
case SegmentActionType.Complete:
|
||||
tutorial.CompleteTutorialSegment(Id);
|
||||
tutorial.CompleteTutorialSegment(Identifier);
|
||||
break;
|
||||
case SegmentActionType.Remove:
|
||||
tutorial.RemoveTutorialSegment(Id);
|
||||
tutorial.RemoveTutorialSegment(Identifier);
|
||||
break;
|
||||
case SegmentActionType.CompleteAndRemove:
|
||||
tutorial.CompleteTutorialSegment(Id);
|
||||
tutorial.RemoveTutorialSegment(Id);
|
||||
tutorial.CompleteTutorialSegment(Identifier);
|
||||
tutorial.RemoveTutorialSegment(Identifier);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.ShowError($"Error in event \"{ParentEvent.Prefab.Identifier}\": attempting to use TutorialSegmentAction during a non-Tutorial game mode!");
|
||||
DebugConsole.ThrowError($"Error in event \"{ParentEvent.Prefab.Identifier}\": attempting to use TutorialSegmentAction during a non-Tutorial game mode!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma;
|
||||
|
||||
partial class UIHighlightAction : EventAction
|
||||
{
|
||||
private static readonly Color highlightColor = Color.Orange;
|
||||
|
||||
partial void UpdateProjSpecific()
|
||||
{
|
||||
bool useCircularFlash = false;
|
||||
GUIComponent component = null;
|
||||
|
||||
if (Id != ElementId.None)
|
||||
{
|
||||
component = GUI.GetAdditions().FirstOrDefault(c => Equals(Id, c.UserData));
|
||||
}
|
||||
else if (!EntityIdentifier.IsEmpty)
|
||||
{
|
||||
component = GUI.GetAdditions().FirstOrDefault(c =>
|
||||
c.UserData is MapEntityPrefab mep && mep.Identifier == EntityIdentifier || c.UserData is MapEntity me && me.Prefab.Identifier == EntityIdentifier);
|
||||
}
|
||||
else if (!OrderIdentifier.IsEmpty)
|
||||
{
|
||||
useCircularFlash = true;
|
||||
if (!OrderTargetTag.IsEmpty)
|
||||
{
|
||||
component =
|
||||
GUI.GetAdditions().FirstOrDefault(c =>
|
||||
c.UserData is CrewManager.MinimapNodeData nodeData && nodeData.Order is Order order &&
|
||||
order.Identifier == OrderIdentifier && order.Option == OrderOption && order.TargetEntity is Item item && item.HasTag(OrderTargetTag));
|
||||
}
|
||||
component ??=
|
||||
GUI.GetAdditions().FirstOrDefault(c => c.UserData is Order order && order.Identifier == OrderIdentifier && order.Option == OrderOption) ??
|
||||
GUI.GetAdditions().FirstOrDefault(c => c.UserData is Order order && order.Identifier == OrderIdentifier) ??
|
||||
GUI.GetAdditions().FirstOrDefault(c => Equals(OrderCategory, c.UserData));
|
||||
}
|
||||
|
||||
if (component != null && component.FlashTimer <= 0.0f)
|
||||
{
|
||||
component.Flash(highlightColor, useCircularFlash: useCircularFlash);
|
||||
component.Bounce |= Bounce;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -651,11 +651,11 @@ namespace Barotrauma
|
||||
break;
|
||||
case NetworkEventType.MISSION:
|
||||
Identifier missionIdentifier = msg.ReadIdentifier();
|
||||
|
||||
string missionName = msg.ReadString();
|
||||
MissionPrefab? prefab = MissionPrefab.Prefabs.Find(mp => mp.Identifier == missionIdentifier);
|
||||
if (prefab != null)
|
||||
{
|
||||
new GUIMessageBox(string.Empty, TextManager.GetWithVariable("missionunlocked", "[missionname]", prefab.Name),
|
||||
new GUIMessageBox(string.Empty, TextManager.GetWithVariable("missionunlocked", "[missionname]", missionName),
|
||||
Array.Empty<LocalizedString>(), type: GUIMessageBox.Type.InGame, icon: prefab.Icon, relativeSize: new Vector2(0.3f, 0.15f), minSize: new Point(512, 128))
|
||||
{
|
||||
IconColor = prefab.IconColor
|
||||
|
||||
@@ -410,7 +410,7 @@ namespace Barotrauma
|
||||
{
|
||||
y += yStep;
|
||||
DrawString(spriteBatch, new Vector2(10, y),
|
||||
"Sub pos: " + Submarine.MainSub.Position.ToPoint(),
|
||||
"Sub pos: " + Submarine.MainSub.WorldPosition.ToPoint(),
|
||||
Color.White, Color.Black * 0.5f, 0, GUIStyle.SmallFont);
|
||||
}
|
||||
|
||||
@@ -879,6 +879,11 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<GUIComponent> GetAdditions()
|
||||
{
|
||||
return additions;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public static GUIComponent MouseOn { get; private set; }
|
||||
|
||||
@@ -486,7 +486,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (bounceTimer > 3.0f || bounceDown)
|
||||
{
|
||||
RectTransform.ScreenSpaceOffset = new Point(RectTransform.ScreenSpaceOffset.X, (int) -(bounceJump * 10f));
|
||||
RectTransform.ScreenSpaceOffset = new Point(RectTransform.ScreenSpaceOffset.X, (int) -(bounceJump * 15f * GUI.Scale));
|
||||
if (!bounceDown)
|
||||
{
|
||||
bounceJump += deltaTime * 4;
|
||||
@@ -503,6 +503,7 @@ namespace Barotrauma
|
||||
bounceJump = 0.0f;
|
||||
bounceTimer = 0.0f;
|
||||
bounceDown = false;
|
||||
Bounce = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,11 +85,11 @@ namespace Barotrauma
|
||||
get { return sprite; }
|
||||
set
|
||||
{
|
||||
if (sprite == value) return;
|
||||
if (sprite == value) { return; }
|
||||
sprite = value;
|
||||
sourceRect = value == null ? Rectangle.Empty : value.SourceRect;
|
||||
origin = value == null ? Vector2.Zero : value.size / 2;
|
||||
if (scaleToFit) RecalculateScale();
|
||||
if (scaleToFit) { RecalculateScale(); }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -601,16 +601,13 @@ namespace Barotrauma
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
float t = 0.0f;
|
||||
float startScroll = BarScroll * BarSize;
|
||||
float startScroll = BarScroll;
|
||||
float distanceToTravel = ScrollBar.MaxValue - startScroll;
|
||||
float progress = startScroll;
|
||||
float speed = distanceToTravel / duration;
|
||||
|
||||
while (t < duration && !MathUtils.NearlyEqual(ScrollBar.MaxValue, progress))
|
||||
while (t < duration && !MathUtils.NearlyEqual(ScrollBar.MaxValue, BarScroll))
|
||||
{
|
||||
t += CoroutineManager.DeltaTime;
|
||||
progress += speed * CoroutineManager.DeltaTime;
|
||||
BarScroll = progress;
|
||||
BarScroll += speed * CoroutineManager.DeltaTime;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
|
||||
@@ -207,7 +207,7 @@ namespace Barotrauma
|
||||
{
|
||||
InnerFrame.RectTransform.AbsoluteOffset = new Point(0, GameMain.GraphicsHeight);
|
||||
CanBeFocused = false;
|
||||
AutoClose = true;
|
||||
AutoClose = type == Type.InGame;
|
||||
GUIStyle.Apply(InnerFrame, "", this);
|
||||
|
||||
var horizontalLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.98f, 0.95f), InnerFrame.RectTransform, Anchor.Center),
|
||||
|
||||
@@ -160,8 +160,13 @@ namespace Barotrauma
|
||||
|
||||
public static Point ItemFrameOffset => new Point(0, 3).Multiply(GUI.SlicedSpriteScale);
|
||||
|
||||
public static GUIComponentStyle GetComponentStyle(string name)
|
||||
=> ComponentStyles.TryGet(name, out var style) ? style : null;
|
||||
public static GUIComponentStyle GetComponentStyle(string styleName)
|
||||
{
|
||||
return GetComponentStyle(styleName.ToIdentifier());
|
||||
}
|
||||
|
||||
public static GUIComponentStyle GetComponentStyle(Identifier identifier)
|
||||
=> ComponentStyles.TryGet(identifier, out var style) ? style : null;
|
||||
|
||||
public static void Apply(GUIComponent targetComponent, string styleName = "", GUIComponent parent = null)
|
||||
{
|
||||
|
||||
@@ -238,7 +238,7 @@ namespace Barotrauma
|
||||
errorId = "Store.SelectStore:StoreDoesntExist";
|
||||
msg = $"Error selecting store with identifier \"{identifier}\" at {CurrentLocation}: store with the identifier doesn't exist at the location.";
|
||||
}
|
||||
DebugConsole.ShowError(msg);
|
||||
DebugConsole.LogError(msg);
|
||||
GameAnalyticsManager.AddErrorEventOnce(errorId, GameAnalyticsManager.ErrorSeverity.Error, msg);
|
||||
}
|
||||
}
|
||||
@@ -263,7 +263,7 @@ namespace Barotrauma
|
||||
}
|
||||
if (!msg.IsNullOrEmpty())
|
||||
{
|
||||
DebugConsole.ShowError(msg);
|
||||
DebugConsole.LogError(msg);
|
||||
GameAnalyticsManager.AddErrorEventOnce(errorId, GameAnalyticsManager.ErrorSeverity.Error, msg);
|
||||
}
|
||||
}
|
||||
@@ -1250,7 +1250,7 @@ namespace Barotrauma
|
||||
}
|
||||
catch (NotImplementedException e)
|
||||
{
|
||||
DebugConsole.ShowError($"Error getting item price: Uknown store tab type. {e.StackTrace.CleanupStackTrace()}");
|
||||
DebugConsole.LogError($"Error getting item price: Uknown store tab type. {e.StackTrace.CleanupStackTrace()}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1808,7 +1808,7 @@ namespace Barotrauma
|
||||
{
|
||||
string errorMsg = $"Error creating a store quantity label text: unknown store tab.\n{e.StackTrace.CleanupStackTrace()}";
|
||||
#if DEBUG
|
||||
DebugConsole.ShowError(errorMsg);
|
||||
DebugConsole.LogError(errorMsg);
|
||||
#else
|
||||
DebugConsole.AddWarning(errorMsg);
|
||||
#endif
|
||||
@@ -1882,7 +1882,7 @@ namespace Barotrauma
|
||||
}
|
||||
catch (NotImplementedException e)
|
||||
{
|
||||
DebugConsole.ShowError($"Error getting item availability: Uknown store tab type. {e.StackTrace.CleanupStackTrace()}");
|
||||
DebugConsole.LogError($"Error getting item availability: Uknown store tab type. {e.StackTrace.CleanupStackTrace()}");
|
||||
}
|
||||
if (list != null && list.Find(i => i.ItemPrefab == itemPrefab) is PurchasedItem item)
|
||||
{
|
||||
@@ -1962,7 +1962,7 @@ namespace Barotrauma
|
||||
}
|
||||
catch (NotImplementedException e)
|
||||
{
|
||||
DebugConsole.ShowError($"Error adding an item to the shopping crate: Uknown store tab type. {e.StackTrace.CleanupStackTrace()}");
|
||||
DebugConsole.LogError($"Error adding an item to the shopping crate: Uknown store tab type. {e.StackTrace.CleanupStackTrace()}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1982,7 +1982,7 @@ namespace Barotrauma
|
||||
}
|
||||
catch (NotImplementedException e)
|
||||
{
|
||||
DebugConsole.ShowError($"Error clearing the shopping crate: Uknown store tab type. {e.StackTrace.CleanupStackTrace()}");
|
||||
DebugConsole.LogError($"Error clearing the shopping crate: Uknown store tab type. {e.StackTrace.CleanupStackTrace()}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -2029,7 +2029,7 @@ namespace Barotrauma
|
||||
}
|
||||
catch (NotImplementedException e)
|
||||
{
|
||||
DebugConsole.ShowError($"Error confirming the store transaction: Uknown store tab type. {e.StackTrace.CleanupStackTrace()}");
|
||||
DebugConsole.LogError($"Error confirming the store transaction: Uknown store tab type. {e.StackTrace.CleanupStackTrace()}");
|
||||
return false;
|
||||
}
|
||||
var itemsToRemove = new List<PurchasedItem>();
|
||||
|
||||
@@ -206,9 +206,9 @@ namespace Barotrauma
|
||||
transferMenuButton.RectTransform.AbsoluteOffset = new Point(0, -pos - transferMenu.Rect.Height);
|
||||
}
|
||||
GameSession.UpdateTalentNotificationIndicator(talentPointNotification);
|
||||
if (Character.Controlled is { } controlled && talentResetButton != null && talentApplyButton != null)
|
||||
if (Character.Controlled?.Info is { } characterInfo && talentResetButton != null && talentApplyButton != null)
|
||||
{
|
||||
int talentCount = selectedTalents.Count - controlled.Info.GetUnlockedTalentsInTree().Count();
|
||||
int talentCount = selectedTalents.Count - characterInfo.GetUnlockedTalentsInTree().Count();
|
||||
talentResetButton.Enabled = talentApplyButton.Enabled = talentCount > 0;
|
||||
if (talentApplyButton.Enabled && talentApplyButton.FlashTimer <= 0.0f)
|
||||
{
|
||||
@@ -1918,14 +1918,18 @@ namespace Barotrauma
|
||||
skillListBox = new GUIListBox(new RectTransform(new Vector2(1f, 1f - skillBlock.RectTransform.RelativeSize.Y), skillLayout.RectTransform), style: null);
|
||||
CreateSkillList(controlledCharacter, info, skillListBox);
|
||||
|
||||
if (controlledCharacter != null)
|
||||
new GUIFrame(new RectTransform(new Vector2(1f, 1f), contentLayout.RectTransform), style: "HorizontalLine");
|
||||
|
||||
GUIListBox talentTreeListBox = new GUIListBox(new RectTransform(new Vector2(1f, 0.6f), contentLayout.RectTransform, Anchor.TopCenter), isHorizontal: true, style: null);
|
||||
|
||||
if (controlledCharacter == null)
|
||||
{
|
||||
talentTreeListBox.Enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!TalentTree.JobTalentTrees.TryGet(info.Job.Prefab.Identifier, out TalentTree talentTree)) { return; }
|
||||
|
||||
new GUIFrame(new RectTransform(new Vector2(1f, 1f), contentLayout.RectTransform), style: "HorizontalLine");
|
||||
|
||||
GUIListBox talentTreeListBox = new GUIListBox(new RectTransform(new Vector2(1f, 0.6f), contentLayout.RectTransform, Anchor.TopCenter), isHorizontal: true, style: null);
|
||||
|
||||
selectedTalents = info.GetUnlockedTalentsInTree().ToList();
|
||||
|
||||
List<GUITextBlock> subTreeNames = new List<GUITextBlock>();
|
||||
|
||||
@@ -874,7 +874,7 @@ namespace Barotrauma
|
||||
itemPrefab.SwappableItem.CanBeBought &&
|
||||
itemPrefab.SwappableItem.SwapIdentifier.Equals(item.Prefab.SwappableItem.SwapIdentifier, StringComparison.OrdinalIgnoreCase)).Cast<ItemPrefab>();
|
||||
|
||||
var linkedItems = Campaign.UpgradeManager.GetLinkedItemsToSwap(item) ?? new List<Item>() { item };
|
||||
var linkedItems = UpgradeManager.GetLinkedItemsToSwap(item) ?? new List<Item>() { item };
|
||||
//create the swap entry only for one of the items (the one with the smallest ID)
|
||||
if (linkedItems.Min(it => it.ID) < item.ID) { return; }
|
||||
|
||||
@@ -910,7 +910,7 @@ namespace Barotrauma
|
||||
GUILayoutGroup buttonLayout = new GUILayoutGroup(rectT(1f, 1f, toggleButton.Frame), isHorizontal: true);
|
||||
|
||||
LocalizedString slotText = "";
|
||||
if (linkedItems.Count > 1)
|
||||
if (linkedItems.Count() > 1)
|
||||
{
|
||||
slotText = TextManager.GetWithVariable("weaponslot", "[number]", string.Join(", ", linkedItems.Select(it => (swappableEntities.IndexOf(it) + 1).ToString())));
|
||||
}
|
||||
@@ -982,7 +982,7 @@ namespace Barotrauma
|
||||
|
||||
bool isPurchased = item.AvailableSwaps.Contains(replacement);
|
||||
|
||||
int price = isPurchased || replacement == item.Prefab ? 0 : replacement.SwappableItem.GetPrice(Campaign.Map?.CurrentLocation) * linkedItems.Count;
|
||||
int price = isPurchased || replacement == item.Prefab ? 0 : replacement.SwappableItem.GetPrice(Campaign.Map?.CurrentLocation) * linkedItems.Count();
|
||||
|
||||
frames.Add(CreateUpgradeEntry(rectT(1f, 0.25f, parent.Content), replacement.UpgradePreviewSprite, replacement.Name, replacement.Description,
|
||||
price, replacement,
|
||||
@@ -998,7 +998,7 @@ namespace Barotrauma
|
||||
{
|
||||
LocalizedString promptBody = TextManager.GetWithVariables(isPurchased ? "upgrades.itemswappromptbody" : "upgrades.purchaseitemswappromptbody",
|
||||
("[itemtoinstall]", replacement.Name),
|
||||
("[amount]", (replacement.SwappableItem.GetPrice(Campaign?.Map?.CurrentLocation) * linkedItems.Count).ToString()));
|
||||
("[amount]", (replacement.SwappableItem.GetPrice(Campaign?.Map?.CurrentLocation) * linkedItems.Count()).ToString()));
|
||||
currectConfirmation = EventEditorScreen.AskForConfirmation(TextManager.Get("Upgrades.PurchasePromptTitle"), promptBody, () =>
|
||||
{
|
||||
if (GameMain.NetworkMember != null)
|
||||
@@ -1042,7 +1042,7 @@ namespace Barotrauma
|
||||
}
|
||||
if (toggleButton.Selected)
|
||||
{
|
||||
var linkedItems = Campaign.UpgradeManager.GetLinkedItemsToSwap(item);
|
||||
var linkedItems = UpgradeManager.GetLinkedItemsToSwap(item);
|
||||
foreach (var itemPreview in itemPreviews)
|
||||
{
|
||||
itemPreview.Value.OutlineColor = itemPreview.Value.Color = linkedItems.Contains(itemPreview.Key) ? GUIStyle.Orange : previewWhite;
|
||||
@@ -1391,7 +1391,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (selectedUpgradeCategoryLayout != null)
|
||||
{
|
||||
var linkedItems = HoveredEntity is Item hoveredItem ? Campaign.UpgradeManager.GetLinkedItemsToSwap(hoveredItem) : new List<Item>();
|
||||
var linkedItems = HoveredEntity is Item hoveredItem ? UpgradeManager.GetLinkedItemsToSwap(hoveredItem) : new List<Item>();
|
||||
if (selectedUpgradeCategoryLayout.FindChild(c => c.UserData is Item item && (item == HoveredEntity || linkedItems.Contains(item)), recursive: true) is GUIButton itemElement)
|
||||
{
|
||||
if (!itemElement.Selected) { itemElement.OnClicked(itemElement, itemElement.UserData); }
|
||||
|
||||
@@ -139,7 +139,7 @@ namespace Barotrauma
|
||||
}
|
||||
catch (NotImplementedException e)
|
||||
{
|
||||
DebugConsole.ShowError($"Error selling items: uknown store tab type \"{sellingMode}\".\n{e.StackTrace.CleanupStackTrace()}");
|
||||
DebugConsole.LogError($"Error selling items: uknown store tab type \"{sellingMode}\".\n{e.StackTrace.CleanupStackTrace()}");
|
||||
return;
|
||||
}
|
||||
bool canAddToRemoveQueue = campaign.IsSinglePlayer && Entity.Spawner != null;
|
||||
@@ -148,7 +148,7 @@ namespace Barotrauma
|
||||
var sellValues = GetSellValuesAtCurrentLocation(storeIdentifier, itemsToSell.Select(i => i.ItemPrefab));
|
||||
if (!(Location.GetStore(storeIdentifier) is { } store))
|
||||
{
|
||||
DebugConsole.ShowError($"Error selling items at {Location}: no store with identifier \"{storeIdentifier}\" exists.\n{Environment.StackTrace.CleanupStackTrace()}");
|
||||
DebugConsole.LogError($"Error selling items at {Location}: no store with identifier \"{storeIdentifier}\" exists.\n{Environment.StackTrace.CleanupStackTrace()}");
|
||||
return;
|
||||
}
|
||||
var storeSpecificSoldItems = GetSoldItems(storeIdentifier, create: true);
|
||||
|
||||
@@ -291,29 +291,13 @@ namespace Barotrauma
|
||||
return crewArea.Rect;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove the character from the crew (and crew menus).
|
||||
/// </summary>
|
||||
/// <param name="character">The character to remove</param>
|
||||
/// <param name="removeInfo">If the character info is also removed, the character will not be visible in the round summary.</param>
|
||||
public void RemoveCharacter(Character character, bool removeInfo = false, bool resetCrewListIndex = true)
|
||||
{
|
||||
if (character == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Tried to remove a null character from CrewManager.\n" + Environment.StackTrace.CleanupStackTrace());
|
||||
return;
|
||||
}
|
||||
characters.Remove(character);
|
||||
if (removeInfo) { characterInfos.Remove(character.Info); }
|
||||
if (resetCrewListIndex) { ResetCrewListIndex(character); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add character to the list without actually adding it to the crew
|
||||
/// </summary>
|
||||
public GUIComponent AddCharacterToCrewList(Character character)
|
||||
{
|
||||
if (character == null) { return null; }
|
||||
if (crewList.Content.Children.Any(c => c.UserData as Character == character)) { return null; }
|
||||
|
||||
var background = new GUIFrame(
|
||||
new RectTransform(crewListEntrySize, parent: crewList.Content.RectTransform, anchor: Anchor.TopRight),
|
||||
@@ -509,7 +493,15 @@ namespace Barotrauma
|
||||
return background;
|
||||
}
|
||||
|
||||
private void SetCharacterComponentTooltip(GUIComponent characterComponent)
|
||||
public void RemoveCharacterFromCrewList(Character character)
|
||||
{
|
||||
if (crewList?.Content.GetChildByUserData(character) is { } component)
|
||||
{
|
||||
crewList.RemoveChild(component);
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetCharacterComponentTooltip(GUIComponent characterComponent)
|
||||
{
|
||||
if (!(characterComponent?.UserData is Character character)) { return; }
|
||||
if (character.Info?.Job?.Prefab == null) { return; }
|
||||
@@ -2821,7 +2813,7 @@ namespace Barotrauma
|
||||
return node;
|
||||
}
|
||||
|
||||
private struct MinimapNodeData
|
||||
public struct MinimapNodeData
|
||||
{
|
||||
public Order Order;
|
||||
}
|
||||
|
||||
@@ -761,6 +761,7 @@ namespace Barotrauma
|
||||
item.PendingItemSwap = null;
|
||||
}
|
||||
}
|
||||
campaign.CampaignUI?.UpgradeStore?.RequestRefresh();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+56
-24
@@ -78,7 +78,7 @@ namespace Barotrauma.Tutorials
|
||||
|
||||
public Action OnClickObjective;
|
||||
|
||||
public readonly TutorialSegmentType SegmentType;
|
||||
public TutorialSegmentType SegmentType { get; private set; }
|
||||
|
||||
public static Segment CreateInfoBoxSegment(Identifier id, Identifier objectiveTextTag, AutoPlayVideo autoPlayVideo, Text textContent = default, Video videoContent = default)
|
||||
{
|
||||
@@ -119,6 +119,12 @@ namespace Barotrauma.Tutorials
|
||||
ObjectiveText = TextManager.ParseInputTypes(TextManager.Get(objectiveTextTag));
|
||||
SegmentType = TutorialSegmentType.Objective;
|
||||
}
|
||||
|
||||
public void ConnectMessageBox(Segment messageBoxSegment)
|
||||
{
|
||||
SegmentType = TutorialSegmentType.MessageBox;
|
||||
OnClickObjective = messageBoxSegment.OnClickObjective;
|
||||
}
|
||||
}
|
||||
|
||||
private bool completed;
|
||||
@@ -144,6 +150,7 @@ namespace Barotrauma.Tutorials
|
||||
private readonly EventPrefab eventPrefab;
|
||||
|
||||
private CoroutineHandle tutorialCoroutine;
|
||||
private CoroutineHandle completedCoroutine;
|
||||
|
||||
private Character character;
|
||||
|
||||
@@ -154,7 +161,7 @@ namespace Barotrauma.Tutorials
|
||||
|
||||
private SubmarineInfo startOutpost = null;
|
||||
|
||||
public readonly List<(Entity entity, string iconStyle)> Icons = new List<(Entity entity, string iconStyle)>();
|
||||
public readonly List<(Entity entity, Identifier iconStyle)> Icons = new List<(Entity entity, Identifier iconStyle)>();
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -331,13 +338,16 @@ namespace Barotrauma.Tutorials
|
||||
{
|
||||
CoroutineManager.StopCoroutines(tutorialCoroutine);
|
||||
}
|
||||
GUI.PreventPauseMenuToggle = false;
|
||||
if (completedCoroutine == null && !CoroutineManager.IsCoroutineRunning(completedCoroutine))
|
||||
{
|
||||
GUI.PreventPauseMenuToggle = false;
|
||||
}
|
||||
ContentRunning = false;
|
||||
infoBox = null;
|
||||
}
|
||||
else if (Character.Controlled.IsDead)
|
||||
else
|
||||
{
|
||||
CoroutineManager.StartCoroutine(Dead());
|
||||
character = Character.Controlled;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -385,7 +395,7 @@ namespace Barotrauma.Tutorials
|
||||
|
||||
if (eventPrefab == null)
|
||||
{
|
||||
DebugConsole.ShowError($"No tutorial event defined for the tutorial (identifier: \"{TutorialPrefab?.Identifier.ToString() ?? "null"})\"");
|
||||
DebugConsole.LogError($"No tutorial event defined for the tutorial (identifier: \"{TutorialPrefab?.Identifier.ToString() ?? "null"})\"");
|
||||
yield return CoroutineStatus.Failure;
|
||||
}
|
||||
|
||||
@@ -399,7 +409,7 @@ namespace Barotrauma.Tutorials
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.ShowError($"Failed to create an instance for a tutorial event (identifier: \"{eventPrefab.Identifier}\"");
|
||||
DebugConsole.LogError($"Failed to create an instance for a tutorial event (identifier: \"{eventPrefab.Identifier}\"");
|
||||
yield return CoroutineStatus.Failure;
|
||||
}
|
||||
|
||||
@@ -409,10 +419,12 @@ namespace Barotrauma.Tutorials
|
||||
public void Complete()
|
||||
{
|
||||
GameAnalyticsManager.AddDesignEvent($"Tutorial:{Identifier}:Completed");
|
||||
CoroutineManager.StartCoroutine(TutorialCompleted());
|
||||
completedCoroutine = CoroutineManager.StartCoroutine(TutorialCompleted());
|
||||
|
||||
IEnumerable<CoroutineStatus> TutorialCompleted()
|
||||
{
|
||||
while (GUI.PauseMenuOpen) { yield return CoroutineStatus.Running; }
|
||||
|
||||
GUI.PreventPauseMenuToggle = true;
|
||||
Character.Controlled.ClearInputs();
|
||||
Character.Controlled = null;
|
||||
@@ -423,7 +435,7 @@ namespace Barotrauma.Tutorials
|
||||
var endCinematic = new CameraTransition(Submarine.MainSub, GameMain.GameScreen.Cam, null, Alignment.Center, panDuration: FadeOutTime);
|
||||
Completed = true;
|
||||
|
||||
while (endCinematic.Running) { yield return null; }
|
||||
while (endCinematic.Running) { yield return CoroutineStatus.Running; }
|
||||
|
||||
Stop();
|
||||
GameMain.MainMenuScreen.ReturnToMainMenu(null, null);
|
||||
@@ -432,16 +444,18 @@ namespace Barotrauma.Tutorials
|
||||
|
||||
private bool Restart(GUIButton button, object obj)
|
||||
{
|
||||
GUI.PreventPauseMenuToggle = false;
|
||||
GUIMessageBox.MessageBoxes.Clear();
|
||||
GameMain.MainMenuScreen.ReturnToMainMenu(button, obj);
|
||||
Start();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void TriggerTutorialSegment(Segment segment)
|
||||
public void TriggerTutorialSegment(Segment segment, bool connectObjective = false)
|
||||
{
|
||||
if (segment.SegmentType != TutorialSegmentType.InfoBox)
|
||||
{
|
||||
ActiveObjectives.Add(segment);
|
||||
AddToObjectiveList(segment);
|
||||
AddToObjectiveList(segment, connectObjective);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -488,11 +502,14 @@ namespace Barotrauma.Tutorials
|
||||
}
|
||||
if (GUIStyle.GetComponentStyle("ObjectiveIndicatorCompleted") is GUIComponentStyle style)
|
||||
{
|
||||
//return if already completed
|
||||
if (segment.ObjectiveStateIndicator.Style == style) { return; }
|
||||
segment.ObjectiveStateIndicator.ApplyStyle(style);
|
||||
}
|
||||
segment.ObjectiveStateIndicator.Parent.Flash(color: GUIStyle.Green, flashDuration: 0.35f, useRectangleFlash: true);
|
||||
segment.ObjectiveButton.OnClicked = null;
|
||||
segment.ObjectiveButton.CanBeFocused = false;
|
||||
GameAnalyticsManager.AddDesignEvent($"Tutorial:{Identifier}:{segmentId}:Completed");
|
||||
}
|
||||
|
||||
public void RemoveTutorialSegment(Identifier segmentId)
|
||||
@@ -568,8 +585,18 @@ namespace Barotrauma.Tutorials
|
||||
/// <summary>
|
||||
/// Adds the segment to the objective list
|
||||
/// </summary>
|
||||
private void AddToObjectiveList(Segment segment)
|
||||
private void AddToObjectiveList(Segment segment, bool connectExisting = false)
|
||||
{
|
||||
if (connectExisting)
|
||||
{
|
||||
if (ActiveObjectives.Find(o => o.Id == segment.Id) is { } existingSegment)
|
||||
{
|
||||
existingSegment.ConnectMessageBox(segment);
|
||||
SetButtonBehavior(existingSegment);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var frameRt = new RectTransform(new Vector2(1.0f, 0.1f), objectiveGroup.RectTransform)
|
||||
{
|
||||
AbsoluteOffset = GetObjectiveHiddenPosition(),
|
||||
@@ -595,15 +622,25 @@ namespace Barotrauma.Tutorials
|
||||
frame.RectTransform.IsFixedSize = true;
|
||||
|
||||
var indicatorRt = new RectTransform(new Point(objectiveGroup.AbsoluteSpacing), frame.RectTransform, isFixedSize: true);
|
||||
segment.ObjectiveStateIndicator = new GUIImage(indicatorRt, "ObjectiveIndicatorIncomplete");;
|
||||
segment.ObjectiveStateIndicator = new GUIImage(indicatorRt, "ObjectiveIndicatorIncomplete");
|
||||
|
||||
SetTransparent(segment.LinkedTextBlock);
|
||||
|
||||
segment.ObjectiveButton = new GUIButton(new RectTransform(Vector2.One, segment.LinkedTextBlock.RectTransform, Anchor.TopLeft, Pivot.TopLeft), style: null)
|
||||
{
|
||||
CanBeFocused = segment.SegmentType != TutorialSegmentType.Objective,
|
||||
ToolTip = objectiveTextTranslated,
|
||||
OnClicked = (GUIButton btn, object userdata) =>
|
||||
ToolTip = objectiveTextTranslated
|
||||
};
|
||||
SetButtonBehavior(segment);
|
||||
SetTransparent(segment.ObjectiveButton);
|
||||
|
||||
frameRt.MoveOverTime(new Point(0, frameRt.AbsoluteOffset.Y), ObjectiveComponentAnimationTime, onDoneMoving: () => objectiveGroup?.Recalculate());
|
||||
|
||||
static void SetTransparent(GUIComponent component) => component.Color = component.HoverColor = component.PressedColor = component.SelectedColor = Color.Transparent;
|
||||
|
||||
void SetButtonBehavior(Segment segment)
|
||||
{
|
||||
segment.ObjectiveButton.CanBeFocused = segment.SegmentType != TutorialSegmentType.Objective;
|
||||
segment.ObjectiveButton.OnClicked = (GUIButton btn, object userdata) =>
|
||||
{
|
||||
if (segment.SegmentType == TutorialSegmentType.InfoBox)
|
||||
{
|
||||
@@ -621,13 +658,8 @@ namespace Barotrauma.Tutorials
|
||||
segment.OnClickObjective?.Invoke();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
SetTransparent(segment.ObjectiveButton);
|
||||
|
||||
frameRt.MoveOverTime(new Point(0, frameRt.AbsoluteOffset.Y), ObjectiveComponentAnimationTime, onDoneMoving: () => objectiveGroup?.Recalculate());
|
||||
|
||||
static void SetTransparent(GUIComponent component) => component.Color = component.HoverColor = component.PressedColor = component.SelectedColor = Color.Transparent;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private void ReplaySegmentVideo(Segment segment)
|
||||
|
||||
@@ -4,6 +4,7 @@ using Barotrauma.Networking;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
@@ -177,7 +178,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, bool editing, float itemDepth = -1)
|
||||
{
|
||||
Color color = item.SpriteColor;
|
||||
Color color = item.GetSpriteColor(withHighlight: true);
|
||||
if (brokenSprite == null)
|
||||
{
|
||||
//broken doors turn black if no broken sprite has been configured
|
||||
@@ -220,11 +221,15 @@ namespace Barotrauma.Items.Components
|
||||
color, 0.0f, doorSprite.Origin, item.Scale, item.SpriteEffects, doorSprite.Depth);
|
||||
}
|
||||
|
||||
if (brokenSprite != null && item.Health < item.MaxCondition)
|
||||
float maxCondition = item.Repairables.Any() ?
|
||||
item.Repairables.Min(r => r.RepairThreshold) / 100.0f * item.MaxCondition :
|
||||
item.MaxCondition;
|
||||
float healthRatio = item.Health / maxCondition;
|
||||
if (brokenSprite != null && healthRatio < 1.0f)
|
||||
{
|
||||
Vector2 scale = scaleBrokenSprite ? new Vector2(1.0f - item.Health / item.MaxCondition) : Vector2.One;
|
||||
Vector2 scale = scaleBrokenSprite ? new Vector2(1.0f - healthRatio) : Vector2.One;
|
||||
if (IsHorizontal) { scale.X = 1; } else { scale.Y = 1; }
|
||||
float alpha = fadeBrokenSprite ? 1.0f - item.Health / item.MaxCondition : 1.0f;
|
||||
float alpha = fadeBrokenSprite ? 1.0f - healthRatio : 1.0f;
|
||||
spriteBatch.Draw(brokenSprite.Texture, pos,
|
||||
getSourceRect(brokenSprite, openState, IsHorizontal),
|
||||
color * alpha, 0.0f, brokenSprite.Origin, scale * item.Scale, item.SpriteEffects,
|
||||
|
||||
@@ -580,7 +580,7 @@ namespace Barotrauma.Items.Components
|
||||
GameMain.Instance.ResolutionChanged += OnResolutionChangedPrivate;
|
||||
}
|
||||
|
||||
protected void TryCreateDragHandle()
|
||||
protected virtual void TryCreateDragHandle()
|
||||
{
|
||||
if (GuiFrame != null && GuiFrameSource.GetAttributeBool("draggable", true))
|
||||
{
|
||||
@@ -593,6 +593,7 @@ namespace Barotrauma.Items.Components
|
||||
int iconHeight = GUIStyle.ItemFrameMargin.Y / 4;
|
||||
var dragIcon = new GUIImage(new RectTransform(new Point(GuiFrame.Rect.Width, iconHeight), handle.RectTransform, Anchor.TopCenter) { AbsoluteOffset = new Point(0, iconHeight / 2) },
|
||||
style: "GUIDragIndicatorHorizontal");
|
||||
dragIcon.RectTransform.MinSize = new Point(0, iconHeight);
|
||||
|
||||
handle.ValidatePosition = (RectTransform rectT) =>
|
||||
{
|
||||
@@ -622,7 +623,7 @@ namespace Barotrauma.Items.Components
|
||||
};
|
||||
|
||||
int buttonHeight = (int)(GUIStyle.ItemFrameMargin.Y * 0.4f);
|
||||
new GUIButton(new RectTransform(new Point(buttonHeight), handle.RectTransform, Anchor.TopLeft) { AbsoluteOffset = new Point(buttonHeight / 4) },
|
||||
new GUIButton(new RectTransform(new Point(buttonHeight), handle.RectTransform, Anchor.TopLeft) { AbsoluteOffset = new Point(buttonHeight / 4), MinSize = new Point(buttonHeight) },
|
||||
style: "GUIButtonSettings")
|
||||
{
|
||||
OnClicked = (btn, userdata) =>
|
||||
|
||||
@@ -324,6 +324,8 @@ namespace Barotrauma.Items.Components
|
||||
int i = 0;
|
||||
foreach (Item containedItem in Inventory.AllItems)
|
||||
{
|
||||
if (containedItem?.Sprite == null) { continue; }
|
||||
|
||||
if (AutoInteractWithContained)
|
||||
{
|
||||
containedItem.IsHighlighted = item.IsHighlighted;
|
||||
@@ -344,7 +346,7 @@ namespace Barotrauma.Items.Components
|
||||
containedItem.Sprite.Draw(
|
||||
spriteBatch,
|
||||
new Vector2(currentItemPos.X, -currentItemPos.Y),
|
||||
isWiringMode ? containedItem.GetSpriteColor() * 0.15f : containedItem.GetSpriteColor(),
|
||||
isWiringMode ? containedItem.GetSpriteColor(withHighlight: true) * 0.15f : containedItem.GetSpriteColor(withHighlight: true),
|
||||
origin,
|
||||
-(containedItem.body == null ? 0.0f : containedItem.body.DrawRotation ),
|
||||
containedItem.Scale,
|
||||
|
||||
+13
-7
@@ -96,6 +96,7 @@ namespace Barotrauma.Items.Components
|
||||
var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.4f, 0.8f), inputArea.RectTransform), childAnchor: Anchor.CenterLeft);
|
||||
activateButton = new GUIButton(new RectTransform(new Vector2(0.95f, 0.8f), buttonContainer.RectTransform), TextManager.Get("DeconstructorDeconstruct"), style: "DeviceButton")
|
||||
{
|
||||
UserData = UIHighlightAction.ElementId.DeconstructButton,
|
||||
TextBlock = { AutoScaleHorizontal = true },
|
||||
OnClicked = OnActivateButtonClicked
|
||||
};
|
||||
@@ -432,17 +433,22 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private bool OnActivateButtonClicked(GUIButton button, object obj)
|
||||
{
|
||||
var disallowedItem = inputContainer.Inventory.FindItem(i => !i.AllowDeconstruct, recursive: false);
|
||||
if (disallowedItem != null && !DeconstructItemsSimultaneously)
|
||||
if (!IsActive)
|
||||
{
|
||||
int index = inputContainer.Inventory.FindIndex(disallowedItem);
|
||||
if (index >= 0 && index < inputContainer.Inventory.visualSlots.Length)
|
||||
//don't allow turning on if there's non-deconstructable items in the queue
|
||||
var disallowedItem = inputContainer.Inventory.FindItem(i => !i.AllowDeconstruct, recursive: false);
|
||||
if (disallowedItem != null && !DeconstructItemsSimultaneously)
|
||||
{
|
||||
var slot = inputContainer.Inventory.visualSlots[index];
|
||||
slot?.ShowBorderHighlight(GUIStyle.Red, 0.1f, 0.9f);
|
||||
int index = inputContainer.Inventory.FindIndex(disallowedItem);
|
||||
if (index >= 0 && index < inputContainer.Inventory.visualSlots.Length)
|
||||
{
|
||||
var slot = inputContainer.Inventory.visualSlots[index];
|
||||
slot?.ShowBorderHighlight(GUIStyle.Red, 0.1f, 0.9f);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (GameMain.Client != null)
|
||||
{
|
||||
pendingState = !IsActive;
|
||||
|
||||
@@ -32,6 +32,8 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
private FabricationRecipe selectedItem;
|
||||
|
||||
public Identifier SelectedItemIdentifier => SelectedItem?.TargetItem.Identifier ?? Identifier.Empty;
|
||||
|
||||
private GUIComponent inSufficientPowerWarning;
|
||||
|
||||
private FabricationRecipe pendingFabricatedItem;
|
||||
|
||||
@@ -1013,12 +1013,14 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
else if (hullData.LinkedHulls.Any())
|
||||
{
|
||||
hullData.HullWaterAmount = 0.0f;
|
||||
float waterVolume = 0.0f;
|
||||
float totalVolume = 0.0f;
|
||||
foreach (Hull linkedHull in hullData.LinkedHulls)
|
||||
{
|
||||
hullData.HullWaterAmount += WaterDetector.GetWaterPercentage(linkedHull);
|
||||
waterVolume += linkedHull.WaterVolume;
|
||||
totalVolume += linkedHull.Volume;
|
||||
}
|
||||
hullData.HullWaterAmount /= hullData.LinkedHulls.Count;
|
||||
hullData.HullWaterAmount = MathHelper.Clamp((int)Math.Ceiling(waterVolume / totalVolume * 100), 0, 100);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
using Barotrauma.Networking;
|
||||
using Barotrauma.Particles;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
@@ -58,6 +56,7 @@ namespace Barotrauma.Items.Components
|
||||
RelativeOffset = new Vector2(0, 0.1f)
|
||||
}, style: "PowerButton")
|
||||
{
|
||||
UserData = UIHighlightAction.ElementId.PowerButton,
|
||||
OnClicked = (button, data) =>
|
||||
{
|
||||
TargetLevel = null;
|
||||
@@ -114,6 +113,7 @@ namespace Barotrauma.Items.Components
|
||||
return true;
|
||||
}
|
||||
};
|
||||
pumpSpeedSlider.Frame.UserData = UIHighlightAction.ElementId.PumpSpeedSlider;
|
||||
var textsArea = new GUIFrame(new RectTransform(new Vector2(1, 0.25f), sliderArea.RectTransform, Anchor.BottomCenter), style: null);
|
||||
var outLabel = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), textsArea.RectTransform, Anchor.CenterLeft), TextManager.Get("PumpOut"),
|
||||
textColor: GUIStyle.TextColorNormal, textAlignment: Alignment.CenterLeft, wrap: false, font: GUIStyle.SubHeadingFont);
|
||||
|
||||
@@ -234,6 +234,7 @@ namespace Barotrauma.Items.Components
|
||||
return false;
|
||||
}
|
||||
};
|
||||
FissionRateScrollBar.Frame.UserData = UIHighlightAction.ElementId.FissionRateSlider;
|
||||
|
||||
TurbineOutputScrollBar = new GUIScrollBar(new RectTransform(sliderSize, rightArea.RectTransform, Anchor.TopCenter)
|
||||
{
|
||||
@@ -252,6 +253,7 @@ namespace Barotrauma.Items.Components
|
||||
return false;
|
||||
}
|
||||
};
|
||||
TurbineOutputScrollBar.Frame.UserData = UIHighlightAction.ElementId.TurbineOutputSlider;
|
||||
|
||||
var buttonArea = new GUILayoutGroup(new RectTransform(new Vector2(1, 0.2f), columnLeft.RectTransform))
|
||||
{
|
||||
@@ -302,9 +304,10 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
new GUIFrame(new RectTransform(new Vector2(0.01f, 1.0f), topRightArea.RectTransform), style: "VerticalLine");
|
||||
|
||||
AutoTempSwitch = new GUIButton(new RectTransform(new Vector2(0.15f, 0.9f), topRightArea.RectTransform),
|
||||
AutoTempSwitch = new GUIButton(new RectTransform(new Vector2(0.15f, 0.9f), topRightArea.RectTransform),
|
||||
style: "SwitchVertical")
|
||||
{
|
||||
UserData = UIHighlightAction.ElementId.AutoTempSwitch,
|
||||
Enabled = false,
|
||||
Selected = AutoTemp,
|
||||
ClickSound = GUISoundType.UISwitch,
|
||||
@@ -347,6 +350,7 @@ namespace Barotrauma.Items.Components
|
||||
RelativeOffset = new Vector2(0, 0.1f)
|
||||
}, style: "PowerButton")
|
||||
{
|
||||
UserData = UIHighlightAction.ElementId.PowerButton,
|
||||
OnClicked = (button, data) =>
|
||||
{
|
||||
PowerOn = !PowerOn;
|
||||
|
||||
@@ -216,6 +216,7 @@ namespace Barotrauma.Items.Components
|
||||
var sonarModeArea = new GUIFrame(new RectTransform(new Vector2(1, 0.4f + extraHeight), paddedControlContainer.RectTransform, Anchor.TopCenter), style: null);
|
||||
SonarModeSwitch = new GUIButton(new RectTransform(new Vector2(0.2f, 1), sonarModeArea.RectTransform), string.Empty, style: "SwitchVertical")
|
||||
{
|
||||
UserData = UIHighlightAction.ElementId.SonarModeSwitch,
|
||||
Selected = false,
|
||||
Enabled = true,
|
||||
ClickSound = GUISoundType.UISwitch,
|
||||
@@ -238,6 +239,7 @@ namespace Barotrauma.Items.Components
|
||||
passiveTickBox = new GUITickBox(new RectTransform(new Vector2(1, 0.45f), sonarModeRightSide.RectTransform, Anchor.TopLeft),
|
||||
TextManager.Get("SonarPassive"), font: GUIStyle.SubHeadingFont, style: "IndicatorLightRedSmall")
|
||||
{
|
||||
UserData = UIHighlightAction.ElementId.PassiveSonarIndicator,
|
||||
ToolTip = TextManager.Get("SonarTipPassive"),
|
||||
Selected = true,
|
||||
Enabled = false
|
||||
@@ -245,6 +247,7 @@ namespace Barotrauma.Items.Components
|
||||
activeTickBox = new GUITickBox(new RectTransform(new Vector2(1, 0.45f), sonarModeRightSide.RectTransform, Anchor.BottomLeft),
|
||||
TextManager.Get("SonarActive"), font: GUIStyle.SubHeadingFont, style: "IndicatorLightRedSmall")
|
||||
{
|
||||
UserData = UIHighlightAction.ElementId.ActiveSonarIndicator,
|
||||
ToolTip = TextManager.Get("SonarTipActive"),
|
||||
Selected = false,
|
||||
Enabled = false
|
||||
@@ -279,9 +282,14 @@ namespace Barotrauma.Items.Components
|
||||
};
|
||||
|
||||
new GUIFrame(new RectTransform(new Vector2(0.8f, 0.01f), paddedControlContainer.RectTransform, Anchor.Center), style: "HorizontalLine")
|
||||
{ UserData = "horizontalline" };
|
||||
{
|
||||
UserData = "horizontalline"
|
||||
};
|
||||
|
||||
var directionalModeFrame = new GUIFrame(new RectTransform(new Vector2(1, 0.45f), lowerAreaFrame.RectTransform, Anchor.BottomCenter), style: null);
|
||||
var directionalModeFrame = new GUIFrame(new RectTransform(new Vector2(1, 0.45f), lowerAreaFrame.RectTransform, Anchor.BottomCenter), style: null)
|
||||
{
|
||||
UserData = UIHighlightAction.ElementId.DirectionalSonarFrame
|
||||
};
|
||||
directionalModeSwitch = new GUIButton(new RectTransform(new Vector2(0.3f, 0.8f), directionalModeFrame.RectTransform, Anchor.CenterLeft), string.Empty, style: "SwitchHorizontal")
|
||||
{
|
||||
OnClicked = (button, data) =>
|
||||
@@ -334,6 +342,18 @@ namespace Barotrauma.Items.Components
|
||||
sonarView.RectTransform.RelativeOffset = new Vector2(0.13f * GUI.RelativeHorizontalAspectRatio, 0);
|
||||
sonarView.RectTransform.SetPosition(Anchor.BottomRight);
|
||||
}
|
||||
var handle = GuiFrame.GetChild<GUIDragHandle>();
|
||||
if (handle != null)
|
||||
{
|
||||
handle.RectTransform.Parent = controlContainer.RectTransform;
|
||||
handle.RectTransform.Resize(Vector2.One);
|
||||
handle.RectTransform.SetAsFirstChild();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void TryCreateDragHandle()
|
||||
{
|
||||
base.TryCreateDragHandle();
|
||||
}
|
||||
|
||||
private void SetPingDirection(Vector2 direction)
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
using Barotrauma.Networking;
|
||||
using Barotrauma.Extensions;
|
||||
using Barotrauma.Networking;
|
||||
using FarseerPhysics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.Extensions;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
@@ -141,6 +139,7 @@ namespace Barotrauma.Items.Components
|
||||
var steeringModeArea = new GUIFrame(new RectTransform(new Vector2(1, 0.4f), paddedControlContainer.RectTransform, Anchor.TopLeft), style: null);
|
||||
steeringModeSwitch = new GUIButton(new RectTransform(new Vector2(0.2f, 1), steeringModeArea.RectTransform), string.Empty, style: "SwitchVertical")
|
||||
{
|
||||
UserData = UIHighlightAction.ElementId.SteeringModeSwitch,
|
||||
Selected = autoPilot,
|
||||
Enabled = true,
|
||||
ClickSound = GUISoundType.UISwitch,
|
||||
@@ -182,6 +181,7 @@ namespace Barotrauma.Items.Components
|
||||
maintainPosTickBox = new GUITickBox(new RectTransform(new Vector2(1, 0.333f), paddedAutoPilotControls.RectTransform, Anchor.TopCenter),
|
||||
TextManager.Get("SteeringMaintainPos"), font: GUIStyle.SmallFont, style: "GUIRadioButton")
|
||||
{
|
||||
UserData = UIHighlightAction.ElementId.MaintainPosTickBox,
|
||||
Enabled = autoPilot,
|
||||
Selected = maintainPos,
|
||||
OnSelected = tickBox =>
|
||||
|
||||
@@ -83,7 +83,8 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
};
|
||||
rechargeSpeedSlider.Bar.RectTransform.MaxSize = new Point(rechargeSpeedSlider.Bar.Rect.Height);
|
||||
|
||||
rechargeSpeedSlider.Frame.UserData = UIHighlightAction.ElementId.RechargeSpeedSlider;
|
||||
|
||||
// lower area --------------------------
|
||||
|
||||
var chargeTextContainer = new GUIFrame(new RectTransform(new Vector2(1, 0.4f), lowerArea.RectTransform), style: null);
|
||||
|
||||
@@ -165,6 +165,7 @@ namespace Barotrauma.Items.Components
|
||||
repairingText = TextManager.Get("Repairing");
|
||||
RepairButton = new GUIButton(new RectTransform(new Vector2(0.4f, 1.0f), progressBarHolder.RectTransform, Anchor.TopCenter), repairButtonText)
|
||||
{
|
||||
UserData = UIHighlightAction.ElementId.RepairButton,
|
||||
OnClicked = (btn, obj) =>
|
||||
{
|
||||
requestStartFixAction = FixActions.Repair;
|
||||
|
||||
@@ -135,7 +135,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.ShowError($"Error creating a CustomInterface component: unexpected NumberType \"{(ciElement.NumberType.HasValue ? ciElement.NumberType.Value.ToString() : "none")}\"");
|
||||
DebugConsole.LogError($"Error creating a CustomInterface component: unexpected NumberType \"{(ciElement.NumberType.HasValue ? ciElement.NumberType.Value.ToString() : "none")}\"");
|
||||
}
|
||||
if (numberInput != null)
|
||||
{
|
||||
|
||||
@@ -118,7 +118,7 @@ namespace Barotrauma
|
||||
return GetDrawDepth(SpriteDepth + DrawDepthOffset, Sprite);
|
||||
}
|
||||
|
||||
public Color GetSpriteColor()
|
||||
public Color GetSpriteColor(bool withHighlight = false)
|
||||
{
|
||||
Color color = spriteColor;
|
||||
if (Prefab.UseContainedSpriteColor && ownInventory != null)
|
||||
@@ -129,6 +129,17 @@ namespace Barotrauma
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (withHighlight)
|
||||
{
|
||||
if (IsHighlighted && !GUI.DisableItemHighlights && Screen.Selected != GameMain.GameScreen)
|
||||
{
|
||||
color = GUIStyle.Orange * Math.Max(GetSpriteColor().A / (float)byte.MaxValue, 0.1f);
|
||||
}
|
||||
else if (IsHighlighted && HighlightColor.HasValue)
|
||||
{
|
||||
color = Color.Lerp(color, HighlightColor.Value, (MathF.Sin((float)Timing.TotalTime * 3.0f) + 1.0f) / 2.0f);
|
||||
}
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
@@ -281,9 +292,7 @@ namespace Barotrauma
|
||||
else if (!ShowItems) { return; }
|
||||
}
|
||||
|
||||
Color color = IsIncludedInSelection && editing ? GUIStyle.Blue : IsHighlighted && !GUI.DisableItemHighlights && Screen.Selected != GameMain.GameScreen ? GUIStyle.Orange * Math.Max(GetSpriteColor().A / (float) byte.MaxValue, 0.1f) : GetSpriteColor();
|
||||
|
||||
//if (IsSelected && editing) color = Color.Lerp(color, Color.Gold, 0.5f);
|
||||
Color color = IsIncludedInSelection && editing ? GUIStyle.Blue : GetSpriteColor(withHighlight: true);
|
||||
|
||||
bool isWiringMode = editing && SubEditorScreen.TransparentWiringMode && SubEditorScreen.IsWiringMode() && !isWire && parentInventory == null;
|
||||
bool renderTransparent = isWiringMode && GetComponent<ConnectionPanel>() == null;
|
||||
|
||||
@@ -229,6 +229,7 @@ namespace Barotrauma
|
||||
Submarine = Submarine.MainSub
|
||||
};
|
||||
item.SetTransform(ConvertUnits.ToSimUnits(Submarine.MainSub == null ? item.Position : item.Position - Submarine.MainSub.Position), 0.0f);
|
||||
item.GetComponent<Items.Components.Door>()?.RefreshLinkedGap();
|
||||
item.FindHull();
|
||||
item.Submarine = Submarine.MainSub;
|
||||
|
||||
|
||||
@@ -264,10 +264,6 @@ namespace Barotrauma
|
||||
{
|
||||
Vector2 velocity = flowForce;
|
||||
if (!IsHorizontal)
|
||||
{
|
||||
velocity.X = Rand.Range(-100.0f, 100.0f) * open;
|
||||
}
|
||||
else
|
||||
{
|
||||
velocity.X *= Rand.Range(1.0f, 3.0f);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma.Networking
|
||||
{
|
||||
@@ -88,12 +87,13 @@ namespace Barotrauma.Networking
|
||||
TextManager.Get("BanPermanent") : TextManager.GetWithVariable("BanExpires", "[time]", bannedPlayer.ExpirationTime.Value.ToString()),
|
||||
font: GUIStyle.SmallFont);
|
||||
|
||||
LocalizedString reason = TextManager.GetServerMessage(bannedPlayer.Reason).Fallback(bannedPlayer.Reason);
|
||||
var reasonText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedPlayerFrame.RectTransform),
|
||||
TextManager.Get("BanReason") + " " +
|
||||
(string.IsNullOrEmpty(bannedPlayer.Reason) ? TextManager.Get("None") : bannedPlayer.Reason),
|
||||
(string.IsNullOrEmpty(bannedPlayer.Reason) ? TextManager.Get("None") : reason),
|
||||
font: GUIStyle.SmallFont, wrap: true)
|
||||
{
|
||||
ToolTip = bannedPlayer.Reason
|
||||
ToolTip = reason
|
||||
};
|
||||
|
||||
paddedPlayerFrame.Recalculate();
|
||||
|
||||
@@ -31,12 +31,17 @@ namespace Barotrauma.Networking
|
||||
|
||||
public bool IsOwner;
|
||||
|
||||
public bool AllowKicking;
|
||||
|
||||
public bool IsDownloading;
|
||||
|
||||
public float Karma;
|
||||
|
||||
public bool AllowKicking =>
|
||||
!IsOwner &&
|
||||
!HasPermission(ClientPermissions.Ban) &&
|
||||
!HasPermission(ClientPermissions.Kick) &&
|
||||
!HasPermission(ClientPermissions.Unban);
|
||||
|
||||
public void UpdateSoundPosition()
|
||||
{
|
||||
if (VoipSound == null) { return; }
|
||||
|
||||
@@ -362,8 +362,7 @@ namespace Barotrauma.Networking
|
||||
// When this is set to true, we are approved and ready to go
|
||||
canStart = false;
|
||||
|
||||
DateTime timeOut = DateTime.Now + new TimeSpan(0, 0, 40);
|
||||
DateTime reqAuthTime = DateTime.Now + new TimeSpan(0, 0, 0, 0, 200);
|
||||
DateTime timeOut = DateTime.Now + new TimeSpan(0, 0, 200);
|
||||
|
||||
// Loop until we are approved
|
||||
LocalizedString connectingText = TextManager.Get("Connecting");
|
||||
@@ -489,7 +488,10 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameClient.Update:CheckServerMessagesException" + e.TargetSite.ToString(), GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
|
||||
DebugConsole.ThrowError("Error while reading a message from server.", e);
|
||||
new GUIMessageBox(TextManager.Get("Error"), TextManager.GetWithVariables("MessageReadError", ("[message]", e.Message), ("[targetsite]", e.TargetSite.ToString())));
|
||||
new GUIMessageBox(TextManager.Get("Error"), TextManager.GetWithVariables("MessageReadError", ("[message]", e.Message), ("[targetsite]", e.TargetSite.ToString())))
|
||||
{
|
||||
DisplayInLoadingScreens = true
|
||||
};
|
||||
Quit();
|
||||
GameMain.ServerListScreen.Select();
|
||||
return;
|
||||
@@ -965,10 +967,10 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
AttemptReconnect(disconnectPacket);
|
||||
}
|
||||
else if (disconnectPacket.ShouldShowMessage)
|
||||
else
|
||||
{
|
||||
ReturnToPreviousMenu(null, null);
|
||||
var msgBox = new GUIMessageBox(TextManager.Get(wasConnected ? "ConnectionLost" : "CouldNotConnectToServer"), disconnectPacket.PopupMessage)
|
||||
new GUIMessageBox(TextManager.Get(wasConnected ? "ConnectionLost" : "CouldNotConnectToServer"), disconnectPacket.PopupMessage)
|
||||
{
|
||||
DisplayInLoadingScreens = true
|
||||
};
|
||||
@@ -1033,6 +1035,7 @@ namespace Barotrauma.Networking
|
||||
if (ClientPeer != null)
|
||||
{
|
||||
//restore the previous list of content packages so we can reconnect immediately without having to recheck that the packages match
|
||||
ClientPeer.ContentPackageOrderReceived = true;
|
||||
ClientPeer.ServerContentPackages = prevContentPackages;
|
||||
}
|
||||
}
|
||||
@@ -1721,6 +1724,7 @@ namespace Barotrauma.Networking
|
||||
string subName = inc.ReadString();
|
||||
string subHash = inc.ReadString();
|
||||
byte subClass = inc.ReadByte();
|
||||
bool isShuttle = inc.ReadBoolean();
|
||||
bool requiredContentPackagesInstalled = inc.ReadBoolean();
|
||||
|
||||
var matchingSub = SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.Name == subName && s.MD5Hash.StringRepresentation == subHash);
|
||||
@@ -1730,6 +1734,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
SubmarineClass = (SubmarineClass)subClass
|
||||
};
|
||||
if (isShuttle) { matchingSub.AddTag(SubmarineTag.Shuttle); }
|
||||
}
|
||||
matchingSub.RequiredContentPackagesInstalled = requiredContentPackagesInstalled;
|
||||
ServerSubmarines.Add(matchingSub);
|
||||
@@ -1780,7 +1785,6 @@ namespace Barotrauma.Networking
|
||||
AccountInfo = tc.AccountInfo,
|
||||
Muted = tc.Muted,
|
||||
InGame = tc.InGame,
|
||||
AllowKicking = tc.AllowKicking,
|
||||
IsOwner = tc.IsOwner
|
||||
};
|
||||
otherClients.Add(existingClient);
|
||||
@@ -1795,7 +1799,6 @@ namespace Barotrauma.Networking
|
||||
existingClient.Muted = tc.Muted;
|
||||
existingClient.InGame = tc.InGame;
|
||||
existingClient.IsOwner = tc.IsOwner;
|
||||
existingClient.AllowKicking = tc.AllowKicking;
|
||||
existingClient.IsDownloading = tc.IsDownloading;
|
||||
GameMain.NetLobbyScreen.SetPlayerNameAndJobPreference(existingClient);
|
||||
if (Screen.Selected != GameMain.NetLobbyScreen && tc.CharacterId > 0)
|
||||
@@ -2404,7 +2407,7 @@ namespace Barotrauma.Networking
|
||||
var subElement = subListChildren.FirstOrDefault(c =>
|
||||
((SubmarineInfo)c.UserData).Name == newSub.Name &&
|
||||
((SubmarineInfo)c.UserData).MD5Hash.StringRepresentation == newSub.MD5Hash.StringRepresentation);
|
||||
if (subElement == null) continue;
|
||||
if (subElement == null) { continue; }
|
||||
|
||||
Color newSubTextColor = new Color(subElement.GetChild<GUITextBlock>().TextColor, 1.0f);
|
||||
subElement.GetChild<GUITextBlock>().TextColor = newSubTextColor;
|
||||
@@ -2429,7 +2432,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (GameMain.NetLobbyScreen.FailedSelectedShuttle.HasValue &&
|
||||
GameMain.NetLobbyScreen.FailedSelectedShuttle.Value.Name == newSub.Name &&
|
||||
GameMain.NetLobbyScreen.FailedSelectedShuttle.Value.Name == newSub.MD5Hash.StringRepresentation)
|
||||
GameMain.NetLobbyScreen.FailedSelectedShuttle.Value.Hash == newSub.MD5Hash.StringRepresentation)
|
||||
{
|
||||
GameMain.NetLobbyScreen.TrySelectSub(newSub.Name, newSub.MD5Hash.StringRepresentation, GameMain.NetLobbyScreen.ShuttleList.ListBox);
|
||||
}
|
||||
@@ -2583,6 +2586,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
ChildServerRelay.ShutDown();
|
||||
GUIMessageBox.MessageBoxes.RemoveAll(c => c?.UserData is RoundSummary);
|
||||
|
||||
characterInfo?.Remove();
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace Barotrauma.Networking
|
||||
protected abstract void SendMsgInternal(PeerPacketHeaders headers, INetSerializableStruct? body);
|
||||
|
||||
protected ConnectionInitialization initializationStep;
|
||||
public bool ContentPackageOrderReceived { get; protected set; }
|
||||
public bool ContentPackageOrderReceived { get; set; }
|
||||
protected int passwordSalt;
|
||||
protected Steamworks.AuthTicket? steamAuthTicket;
|
||||
private GUIMessageBox? passwordMsgBox;
|
||||
|
||||
+3
@@ -36,6 +36,8 @@ namespace Barotrauma.Networking
|
||||
|
||||
public override void Start()
|
||||
{
|
||||
if (isActive) { return; }
|
||||
|
||||
ContentPackageOrderReceived = false;
|
||||
|
||||
steamAuthTicket = SteamManager.GetAuthSessionTicket();
|
||||
@@ -189,6 +191,7 @@ namespace Barotrauma.Networking
|
||||
if (packet is { SteamId: var steamId, Data: var data })
|
||||
{
|
||||
OnP2PData(steamId, data, data.Length);
|
||||
if (!isActive) { return; }
|
||||
receivedBytes += data.Length;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -391,7 +391,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
for (int i = remotePeers.Count - 1; i >= 0; i--)
|
||||
{
|
||||
DisconnectPeer(remotePeers[i], peerDisconnectPacket);
|
||||
DisconnectPeer(remotePeers[i], PeerDisconnectPacket.WithReason(DisconnectReason.ServerShutdown));
|
||||
}
|
||||
|
||||
Thread.Sleep(100);
|
||||
|
||||
@@ -37,6 +37,7 @@ namespace Barotrauma.Networking
|
||||
switch (serverInfo.Endpoint)
|
||||
{
|
||||
case LidgrenEndpoint { NetEndpoint: { Address: var address } }:
|
||||
|
||||
GetIPAddressPing(serverInfo, address, onPingDiscovered);
|
||||
break;
|
||||
case SteamP2PEndpoint steamP2PEndpoint:
|
||||
@@ -132,24 +133,30 @@ namespace Barotrauma.Networking
|
||||
|
||||
private static void GetIPAddressPing(ServerInfo serverInfo, IPAddress address, Action<ServerInfo> onPingDiscovered)
|
||||
{
|
||||
lock (activePings)
|
||||
if (IPAddress.IsLoopback(address))
|
||||
{
|
||||
if (activePings.ContainsKey(address)) { return; }
|
||||
activePings.Add(address, activePings.Any() ? activePings.Values.Max() + 1 : 0);
|
||||
serverInfo.Ping = Option<int>.Some(0);
|
||||
onPingDiscovered(serverInfo);
|
||||
}
|
||||
|
||||
serverInfo.Ping = Option<int>.None();
|
||||
|
||||
TaskPool.Add($"PingServerAsync ({address})", PingServerAsync(address, 1000),
|
||||
rtt =>
|
||||
else
|
||||
{
|
||||
lock (activePings)
|
||||
{
|
||||
if (!rtt.TryGetResult(out serverInfo.Ping)) { serverInfo.Ping = Option<int>.None(); }
|
||||
onPingDiscovered(serverInfo);
|
||||
lock (activePings)
|
||||
if (activePings.ContainsKey(address)) { return; }
|
||||
activePings.Add(address, activePings.Any() ? activePings.Values.Max() + 1 : 0);
|
||||
}
|
||||
serverInfo.Ping = Option<int>.None();
|
||||
TaskPool.Add($"PingServerAsync ({address})", PingServerAsync(address, 1000),
|
||||
rtt =>
|
||||
{
|
||||
activePings.Remove(address);
|
||||
}
|
||||
});
|
||||
if (!rtt.TryGetResult(out serverInfo.Ping)) { serverInfo.Ping = Option<int>.None(); }
|
||||
onPingDiscovered(serverInfo);
|
||||
lock (activePings)
|
||||
{
|
||||
activePings.Remove(address);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<Option<int>> PingServerAsync(IPAddress ipAddress, int timeOut)
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace Barotrauma.Networking
|
||||
[Serialize(PlayStyle.Casual, IsPropertySaveable.Yes)]
|
||||
public PlayStyle PlayStyle { get; set; }
|
||||
|
||||
public Version GameVersion { get; set; } = new Version(0,0,0,0);
|
||||
public Version GameVersion { get; set; } = new Version(0, 0, 0, 0);
|
||||
|
||||
public Option<int> Ping = Option<int>.None();
|
||||
|
||||
@@ -200,7 +200,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), frame.RectTransform),
|
||||
TextManager.AddPunctuation(':', TextManager.Get("ServerListVersion"),
|
||||
GameVersion.ToString()))
|
||||
GameVersion == new Version(0, 0, 0, 0) ? TextManager.Get("Unknown") : GameVersion.ToString()))
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
@@ -397,10 +397,10 @@ namespace Barotrauma.Networking
|
||||
public void UpdateInfo(Func<string, string?> valueGetter)
|
||||
{
|
||||
ServerMessage = valueGetter("message") ?? "";
|
||||
GameVersion = Version.TryParse(valueGetter("version"), out var version)
|
||||
? version
|
||||
: GameMain.Version;
|
||||
|
||||
if (Version.TryParse(valueGetter("version"), out var version))
|
||||
{
|
||||
GameVersion = version;
|
||||
}
|
||||
if (int.TryParse(valueGetter("playercount"), out int playerCount)) { PlayerCount = playerCount; }
|
||||
if (int.TryParse(valueGetter("maxplayernum"), out int maxPlayers)) { MaxPlayers = maxPlayers; }
|
||||
if (Enum.TryParse(valueGetter("modeselectionmode"), out SelectionMode modeSelectionMode)) { ModeSelectionMode = modeSelectionMode; }
|
||||
|
||||
@@ -346,7 +346,7 @@ namespace Barotrauma
|
||||
};
|
||||
|
||||
var missionName = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform), mission?.Name ?? TextManager.Get("NoMission"), font: GUIStyle.SubHeadingFont, wrap: true);
|
||||
// missionName.RectTransform.MinSize = new Point(0, (int)(missionName.Rect.Height * 1.5f));
|
||||
missionName.RectTransform.MinSize = new Point(0, GUI.IntScale(15));
|
||||
if (mission != null)
|
||||
{
|
||||
var tickBox = new GUITickBox(new RectTransform(Vector2.One * 0.9f, missionName.RectTransform, anchor: Anchor.CenterLeft, scaleBasis: ScaleBasis.Smallest) { AbsoluteOffset = new Point((int)missionName.Padding.X, 0) }, label: string.Empty)
|
||||
|
||||
@@ -67,7 +67,9 @@ namespace Barotrauma
|
||||
|
||||
public static readonly Queue<ulong> WorkshopItemsToUpdate = new Queue<ulong>();
|
||||
|
||||
private readonly GUIListBox tutorialList;
|
||||
private GUIImage tutorialBanner;
|
||||
private GUITextBlock tutorialHeader, tutorialDescription;
|
||||
private GUIListBox tutorialList;
|
||||
|
||||
#region Creation
|
||||
public MainMenuScreen(GameMain game)
|
||||
@@ -429,20 +431,7 @@ namespace Barotrauma
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
menuTabs[Tab.Tutorials] = new GUIFrame(new RectTransform(relativeSize, GUI.Canvas, anchor, pivot, minSize, maxSize) { RelativeOffset = relativeSpacing });
|
||||
|
||||
//PLACEHOLDER
|
||||
tutorialList = new GUIListBox(
|
||||
new RectTransform(new Vector2(0.95f, 0.85f), menuTabs[Tab.Tutorials].RectTransform, Anchor.TopCenter) { RelativeOffset = new Vector2(0.0f, 0.1f) })
|
||||
{
|
||||
PlaySoundOnSelect = true,
|
||||
};
|
||||
tutorialList.OnSelected += (component, obj) =>
|
||||
{
|
||||
(obj as Tutorial)?.Start();
|
||||
return true;
|
||||
};
|
||||
|
||||
CreateTutorialButtons();
|
||||
CreateTutorialTab();
|
||||
|
||||
this.game = game;
|
||||
|
||||
@@ -459,24 +448,68 @@ namespace Barotrauma
|
||||
creditsPlayer = new CreditsPlayer(new RectTransform(Vector2.One, creditsContainer.RectTransform), "Content/Texts/Credits.xml");
|
||||
}
|
||||
|
||||
private void CreateTutorialButtons()
|
||||
private void CreateTutorialTab()
|
||||
{
|
||||
var tutorialInnerFrame = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.9f), menuTabs[Tab.Tutorials].RectTransform, Anchor.Center), style: "InnerFrame");
|
||||
var tutorialContent = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.95f), tutorialInnerFrame.RectTransform, Anchor.Center), isHorizontal: true) { RelativeSpacing = 0.02f, Stretch = true };
|
||||
|
||||
tutorialList = new GUIListBox(new RectTransform(new Vector2(0.4f, 1.0f), tutorialContent.RectTransform))
|
||||
{
|
||||
PlaySoundOnSelect = true,
|
||||
OnSelected = (component, obj) =>
|
||||
{
|
||||
SelectTutorial(obj as Tutorial);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
var tutorialPreview = new GUILayoutGroup(new RectTransform(new Vector2(0.6f, 1.0f), tutorialContent.RectTransform)) { RelativeSpacing = 0.05f, Stretch = true };
|
||||
var imageContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.6f), tutorialPreview.RectTransform), style: "InnerFrame");
|
||||
tutorialBanner = new GUIImage(new RectTransform(Vector2.One, imageContainer.RectTransform), style: null, scaleToFit: true);
|
||||
|
||||
var infoContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.4f), tutorialPreview.RectTransform), style: "GUIFrameListBox");
|
||||
var infoContent = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.9f), infoContainer.RectTransform, Anchor.Center), childAnchor: Anchor.TopCenter);
|
||||
|
||||
tutorialHeader = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.75f), infoContent.RectTransform), string.Empty, font: GUIStyle.SubHeadingFont, textAlignment: Alignment.Center);
|
||||
|
||||
var startButton = new GUIButton(new RectTransform(new Vector2(0.5f, 0.0f), infoContent.RectTransform, Anchor.BottomRight), text: TextManager.Get("startgamebutton"))
|
||||
{
|
||||
IgnoreLayoutGroups = true,
|
||||
OnClicked = (component, obj) =>
|
||||
{
|
||||
(tutorialList.SelectedData as Tutorial)?.Start();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
Tutorial firstTutorial = null;
|
||||
foreach (var tutorialPrefab in TutorialPrefab.Prefabs.OrderBy(p => p.Order))
|
||||
{
|
||||
var tutorial = new Tutorial(tutorialPrefab);
|
||||
var tutorialText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), tutorialList.Content.RectTransform), tutorial.DisplayName, textAlignment: Alignment.Center, font: GUIStyle.LargeFont)
|
||||
firstTutorial ??= tutorial;
|
||||
var tutorialText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), tutorialList.Content.RectTransform), tutorial.DisplayName)
|
||||
{
|
||||
TextColor = GUIStyle.Green,
|
||||
Padding = new Vector4(30.0f * GUI.Scale, 0,0,0),
|
||||
UserData = tutorial
|
||||
};
|
||||
tutorialText.RectTransform.MinSize = new Point(0, (int)(tutorialText.TextSize.Y * 2));
|
||||
}
|
||||
GUITextBlock.AutoScaleAndNormalize(tutorialList.Content.Children.Select(c => c as GUITextBlock));
|
||||
tutorialList.Select(firstTutorial);
|
||||
}
|
||||
|
||||
private void SelectTutorial(Tutorial tutorial)
|
||||
{
|
||||
tutorialHeader.Text = tutorial.DisplayName;
|
||||
tutorial.TutorialPrefab.Banner?.EnsureLazyLoaded();
|
||||
tutorialBanner.Sprite = tutorial.TutorialPrefab.Banner;
|
||||
tutorialBanner.Color = tutorial.TutorialPrefab.Banner == null ? Color.Black : Color.White;
|
||||
}
|
||||
|
||||
public static void UpdateInstanceTutorialButtons()
|
||||
{
|
||||
if (GameMain.MainMenuScreen is not MainMenuScreen menuScreen) { return; }
|
||||
menuScreen.tutorialList.ClearChildren();
|
||||
menuScreen.CreateTutorialButtons();
|
||||
menuScreen.CreateTutorialTab();
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -746,12 +779,13 @@ namespace Barotrauma
|
||||
|
||||
private void UpdateTutorialList()
|
||||
{
|
||||
foreach (GUITextBlock tutorialText in menuTabs[Tab.Tutorials].GetChild<GUIListBox>().Content.Children)
|
||||
foreach (GUITextBlock tutorialText in tutorialList.Content.Children)
|
||||
{
|
||||
var tutorial = (Tutorial)tutorialText.UserData;
|
||||
tutorialText.Text = CompletedTutorials.Instance.Contains(tutorial.Identifier) ?
|
||||
TextManager.GetWithVariable("tutorialcompleted", "[tutorialname]", tutorial.DisplayName) :
|
||||
tutorial.DisplayName;
|
||||
if (CompletedTutorials.Instance.Contains(tutorial.Identifier) && tutorialText.GetChild<GUIImage>() == null)
|
||||
{
|
||||
new GUIImage(new RectTransform(new Point((int)(tutorialText.Padding.X * 0.8f)), tutorialText.RectTransform, Anchor.CenterLeft), style: "ObjectiveIndicatorCompleted");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1862,7 +1862,7 @@ namespace Barotrauma
|
||||
SubmarineType.Wreck => "Content/Map/Wrecks/{0}",
|
||||
SubmarineType.BeaconStation => "Content/Map/BeaconStations/{0}",
|
||||
SubmarineType.EnemySubmarine => "Content/Map/EnemySubmarines/{0}",
|
||||
SubmarineType.OutpostModule => "Content/Map/Outposts/{0}",
|
||||
SubmarineType.OutpostModule => MainSub.Info.FilePath.Contains("RuinModules") ? "Content/Map/RuinModules/{0}" : "Content/Map/Outposts/{0}",
|
||||
_ => throw new InvalidOperationException()
|
||||
}, savePath);
|
||||
modProject.ModVersion = "";
|
||||
|
||||
@@ -195,13 +195,13 @@ namespace Barotrauma.Sounds
|
||||
GainMultipliers[index] = gain;
|
||||
}
|
||||
}
|
||||
private Dictionary<string, CategoryModifier> categoryModifiers;
|
||||
|
||||
private readonly Dictionary<string, CategoryModifier> categoryModifiers = new Dictionary<string, CategoryModifier>();
|
||||
|
||||
public SoundManager()
|
||||
{
|
||||
loadedSounds = new List<Sound>();
|
||||
streamingThread = null;
|
||||
categoryModifiers = null;
|
||||
|
||||
sourcePools = new SoundSourcePool[2];
|
||||
playingChannels[(int)SourcePoolIndex.Default] = new SoundChannel[SOURCE_COUNT];
|
||||
@@ -235,7 +235,7 @@ namespace Barotrauma.Sounds
|
||||
CompressionDynamicRangeGain = 1.0f;
|
||||
}
|
||||
|
||||
private void SetAudioOutputDevice(string deviceName)
|
||||
private static void SetAudioOutputDevice(string deviceName)
|
||||
{
|
||||
var config = GameSettings.CurrentConfig;
|
||||
config.Audio.AudioOutputDevice = deviceName;
|
||||
@@ -249,7 +249,7 @@ namespace Barotrauma.Sounds
|
||||
DebugConsole.NewMessage($"Attempting to open ALC device \"{deviceName}\"");
|
||||
|
||||
alcDevice = IntPtr.Zero;
|
||||
int alcError = Al.NoError;
|
||||
int alcError;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
alcDevice = Alc.OpenDevice(deviceName);
|
||||
@@ -371,8 +371,10 @@ namespace Barotrauma.Sounds
|
||||
throw new System.IO.FileNotFoundException($"Sound file \"{filePath}\" doesn't exist! Content package \"{(element.ContentPackage?.Name ?? "Unknown")}\".");
|
||||
}
|
||||
|
||||
var newSound = new OggSound(this, filePath, stream, xElement: element);
|
||||
newSound.BaseGain = element.GetAttributeFloat("volume", 1.0f);
|
||||
var newSound = new OggSound(this, filePath, stream, xElement: element)
|
||||
{
|
||||
BaseGain = element.GetAttributeFloat("volume", 1.0f)
|
||||
};
|
||||
float range = element.GetAttributeFloat("range", 1000.0f);
|
||||
newSound.BaseNear = range * 0.4f;
|
||||
newSound.BaseFar = range;
|
||||
@@ -537,14 +539,16 @@ namespace Barotrauma.Sounds
|
||||
{
|
||||
if (Disabled) { return; }
|
||||
category = category.ToLower();
|
||||
if (categoryModifiers == null) categoryModifiers = new Dictionary<string, CategoryModifier>();
|
||||
if (!categoryModifiers.ContainsKey(category))
|
||||
lock (categoryModifiers)
|
||||
{
|
||||
categoryModifiers.Add(category, new CategoryModifier(index, gain, false));
|
||||
}
|
||||
else
|
||||
{
|
||||
categoryModifiers[category].SetGainMultiplier(index, gain);
|
||||
if (!categoryModifiers.ContainsKey(category))
|
||||
{
|
||||
categoryModifiers.Add(category, new CategoryModifier(index, gain, false));
|
||||
}
|
||||
else
|
||||
{
|
||||
categoryModifiers[category].SetGainMultiplier(index, gain);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < playingChannels.Length; i++)
|
||||
@@ -562,23 +566,26 @@ namespace Barotrauma.Sounds
|
||||
}
|
||||
}
|
||||
|
||||
public float GetCategoryGainMultiplier(string category, int index=-1)
|
||||
public float GetCategoryGainMultiplier(string category, int index = -1)
|
||||
{
|
||||
if (Disabled) { return 0.0f; }
|
||||
category = category.ToLower();
|
||||
if (categoryModifiers == null || !categoryModifiers.ContainsKey(category)) return 1.0f;
|
||||
if (index < 0)
|
||||
lock (categoryModifiers)
|
||||
{
|
||||
float accumulatedMultipliers = 1.0f;
|
||||
for (int i = 0; i < categoryModifiers[category].GainMultipliers.Length; i++)
|
||||
if (categoryModifiers == null || !categoryModifiers.TryGetValue(category, out CategoryModifier categoryModifier)) { return 1.0f; }
|
||||
if (index < 0)
|
||||
{
|
||||
accumulatedMultipliers *= categoryModifiers[category].GainMultipliers[i];
|
||||
float accumulatedMultipliers = 1.0f;
|
||||
for (int i = 0; i < categoryModifier.GainMultipliers.Length; i++)
|
||||
{
|
||||
accumulatedMultipliers *= categoryModifier.GainMultipliers[i];
|
||||
}
|
||||
return accumulatedMultipliers;
|
||||
}
|
||||
else
|
||||
{
|
||||
return categoryModifier.GainMultipliers[index];
|
||||
}
|
||||
return accumulatedMultipliers;
|
||||
}
|
||||
else
|
||||
{
|
||||
return categoryModifiers[category].GainMultipliers[index];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -587,15 +594,16 @@ namespace Barotrauma.Sounds
|
||||
if (Disabled) { return; }
|
||||
|
||||
category = category.ToLower();
|
||||
|
||||
if (categoryModifiers == null) { categoryModifiers = new Dictionary<string, CategoryModifier>(); }
|
||||
if (!categoryModifiers.ContainsKey(category))
|
||||
lock (categoryModifiers)
|
||||
{
|
||||
categoryModifiers.Add(category, new CategoryModifier(0, 1.0f, muffle));
|
||||
}
|
||||
else
|
||||
{
|
||||
categoryModifiers[category].Muffle = muffle;
|
||||
if (!categoryModifiers.ContainsKey(category))
|
||||
{
|
||||
categoryModifiers.Add(category, new CategoryModifier(0, 1.0f, muffle));
|
||||
}
|
||||
else
|
||||
{
|
||||
categoryModifiers[category].Muffle = muffle;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < playingChannels.Length; i++)
|
||||
@@ -618,8 +626,11 @@ namespace Barotrauma.Sounds
|
||||
if (Disabled) { return false; }
|
||||
|
||||
category = category.ToLower();
|
||||
if (categoryModifiers == null || !categoryModifiers.ContainsKey(category)) { return false; }
|
||||
return categoryModifiers[category].Muffle;
|
||||
lock (categoryModifiers)
|
||||
{
|
||||
if (categoryModifiers == null || !categoryModifiers.TryGetValue(category, out CategoryModifier categoryModifier)) { return false; }
|
||||
return categoryModifier.Muffle;
|
||||
}
|
||||
}
|
||||
|
||||
public void Update()
|
||||
|
||||
Reference in New Issue
Block a user