(af16ecdfa) Merge branch 'dev' into human-ai

This commit is contained in:
Joonas Rikkonen
2019-05-16 05:14:00 +03:00
parent 8be0b0676e
commit bec7aadfa9
65 changed files with 1579 additions and 1449 deletions
@@ -43,8 +43,13 @@
<Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\GameModes\MultiPlayerCampaign.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\GameModes\MultiPlayerCampaign.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\GameModes\SinglePlayerCampaign.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\GameModes\SinglePlayerCampaign.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\GameModes\Tutorials\BasicTutorial.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\GameModes\Tutorials\BasicTutorial.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\GameModes\Tutorials\CaptainTutorial.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\GameModes\Tutorials\ContextualTutorial.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\GameModes\Tutorials\ContextualTutorial.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\GameModes\Tutorials\DoctorTutorial.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\GameModes\Tutorials\EditorTutorial.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\GameModes\Tutorials\EditorTutorial.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\GameModes\Tutorials\EngineerTutorial.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\GameModes\Tutorials\MechanicTutorial.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\GameModes\Tutorials\OfficerTutorial.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\GameModes\Tutorials\ScenarioTutorial.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\GameModes\Tutorials\ScenarioTutorial.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\GameModes\Tutorials\Tutorial.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\GameModes\Tutorials\Tutorial.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\GameModes\Tutorials\TutorialMode.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Source\GameSession\GameModes\Tutorials\TutorialMode.cs" />
@@ -243,6 +243,7 @@
<None Include="System.Xml.Linq.dll"> <None Include="System.Xml.Linq.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
<None Include="barotrauma.icns" />
</ItemGroup> </ItemGroup>
<ItemGroup /> <ItemGroup />
<Import Project="ClientCode.projitems" Label="Shared" /> <Import Project="ClientCode.projitems" Label="Shared" />
@@ -440,14 +440,15 @@ namespace Barotrauma
return; return;
} }
//foreach (Limb limb in Limbs) Color? color = null;
//{ if (character.ExternalHighlight)
// limb.Draw(spriteBatch, cam); {
//} color = Color.Lerp(Color.White, Color.OrangeRed, (float)Math.Sin(Timing.TotalTime * 3.5f));
}
for (int i = 0; i < limbs.Length; i++) for (int i = 0; i < limbs.Length; i++)
{ {
inversedLimbDrawOrder[i].Draw(spriteBatch, cam); inversedLimbDrawOrder[i].Draw(spriteBatch, cam, color);
} }
LimbJoints.ForEach(j => j.Draw(spriteBatch)); LimbJoints.ForEach(j => j.Draw(spriteBatch));
} }
@@ -111,6 +111,33 @@ namespace Barotrauma
get { return gibEmitters; } get { return gibEmitters; }
} }
public class ObjectiveEntity
{
public Entity Entity;
public Sprite Sprite;
public Color Color;
public ObjectiveEntity(Entity entity, Sprite sprite, Color? color = null)
{
Entity = entity;
Sprite = sprite;
if (color.HasValue)
{
Color = color.Value;
}
else
{
Color = Color.White;
}
}
}
private List<ObjectiveEntity> activeObjectiveEntities = new List<ObjectiveEntity>();
public IEnumerable<ObjectiveEntity> ActiveObjectiveEntities
{
get { return activeObjectiveEntities; }
}
partial void InitProjSpecific(XDocument doc) partial void InitProjSpecific(XDocument doc)
{ {
soundInterval = doc.Root.GetAttributeFloat("soundinterval", 10.0f); soundInterval = doc.Root.GetAttributeFloat("soundinterval", 10.0f);
@@ -140,9 +167,6 @@ namespace Barotrauma
} }
} }
hudProgressBars = new Dictionary<object, HUDProgressBar>();
}
partial void UpdateLimbLightSource(Limb limb) partial void UpdateLimbLightSource(Limb limb)
{ {
if (limb.LightSource != null) if (limb.LightSource != null)
@@ -735,6 +759,20 @@ namespace Barotrauma
soundTimer = soundInterval; soundTimer = soundInterval;
} }
public void AddActiveObjectiveEntity(Entity entity, Sprite sprite, Color? color = null)
{
if (activeObjectiveEntities.Any(aoe => aoe.Entity == entity)) return;
ObjectiveEntity objectiveEntity = new ObjectiveEntity(entity, sprite, color);
activeObjectiveEntities.Add(objectiveEntity);
}
public void RemoveActiveObjectiveEntity(Entity entity)
{
ObjectiveEntity found = activeObjectiveEntities.Find(aoe => aoe.Entity == entity);
if (found == null) return;
activeObjectiveEntities.Remove(found);
}
partial void ImplodeFX() partial void ImplodeFX()
{ {
Vector2 centerOfMass = AnimController.GetCenterOfMass(); Vector2 centerOfMass = AnimController.GetCenterOfMass();
@@ -168,7 +168,12 @@ namespace Barotrauma
DrawOrderIndicator(spriteBatch, cam, character, character.CurrentOrder, 1.0f); DrawOrderIndicator(spriteBatch, cam, character, character.CurrentOrder, 1.0f);
} }
} }
foreach (Character.ObjectiveEntity objectiveEntity in character.ActiveObjectiveEntities)
{
DrawObjectiveIndicator(spriteBatch, cam, character, objectiveEntity, 1.0f);
}
foreach (Item brokenItem in brokenItems) foreach (Item brokenItem in brokenItems)
{ {
float dist = Vector2.Distance(character.WorldPosition, brokenItem.WorldPosition); float dist = Vector2.Distance(character.WorldPosition, brokenItem.WorldPosition);
@@ -371,5 +376,13 @@ namespace Barotrauma
orderIndicatorCount[target] = orderIndicatorCount[target] + 1; orderIndicatorCount[target] = orderIndicatorCount[target] + 1;
} }
private static void DrawObjectiveIndicator(SpriteBatch spriteBatch, Camera cam, Character character, Character.ObjectiveEntity objectiveEntity, float iconAlpha = 1.0f)
{
if (objectiveEntity == null) return;
Vector2 drawPos = objectiveEntity.Entity.WorldPosition;// + Vector2.UnitX * objectiveEntity.Sprite.size.X * 1.5f;
GUI.DrawIndicator(spriteBatch, drawPos, cam, 100.0f, objectiveEntity.Sprite, objectiveEntity.Color * iconAlpha);
}
} }
} }
@@ -136,6 +136,17 @@ namespace Barotrauma
} }
} }
public GUIButton CPRButton
{
get { return cprButton; }
}
public float HealthBarPulsateTimer
{
get { return healthBarPulsateTimer; }
set { healthBarPulsateTimer = MathHelper.Clamp(value, 0.0f, 10.0f); }
}
static CharacterHealth() static CharacterHealth()
{ {
damageOverlay = new Sprite("Content/UI/damageOverlay.png", Vector2.Zero); damageOverlay = new Sprite("Content/UI/damageOverlay.png", Vector2.Zero);
+12 -2
View File
@@ -129,6 +129,8 @@ namespace Barotrauma
get { return pauseMenuOpen; } get { return pauseMenuOpen; }
} }
public static bool PreventPauseMenuToggle = false;
public static Color ScreenOverlayColor public static Color ScreenOverlayColor
{ {
get; get;
@@ -1413,6 +1415,7 @@ namespace Barotrauma
public static void TogglePauseMenu() public static void TogglePauseMenu()
{ {
if (Screen.Selected == GameMain.MainMenuScreen) return; if (Screen.Selected == GameMain.MainMenuScreen) return;
if (PreventPauseMenuToggle) return;
settingsMenuOpen = false; settingsMenuOpen = false;
@@ -1546,9 +1549,16 @@ namespace Barotrauma
if (GameMain.GameSession != null) if (GameMain.GameSession != null)
{ {
if (ContextualTutorial.Initialized && GameMain.GameSession.GameMode is SinglePlayerCampaign) if (Tutorial.Initialized)
{ {
((SinglePlayerCampaign)GameMain.GameSession.GameMode).ContextualTutorial.Stop(); if (GameMain.GameSession.GameMode is SinglePlayerCampaign)
{
((SinglePlayerCampaign)GameMain.GameSession.GameMode).ContextualTutorial.Stop();
}
else
{
((TutorialMode)GameMain.GameSession.GameMode).Tutorial.Stop();
}
} }
if (GameSettings.SendUserStatistics) if (GameSettings.SendUserStatistics)
@@ -174,6 +174,11 @@ namespace Barotrauma
if (frame != null) frame.ApplyStyle(style); if (frame != null) frame.ApplyStyle(style);
} }
public override void Flash(Color? color = null, float flashDuration = 1.5f, bool useRectangleFlash = false, Vector2? flashRectInflate = null)
{
Frame.Flash(color, flashDuration, useRectangleFlash, flashRectInflate);
}
protected override void Draw(SpriteBatch spriteBatch) protected override void Draw(SpriteBatch spriteBatch)
{ {
//do nothing //do nothing
@@ -121,77 +121,22 @@ namespace Barotrauma
protected Color selectedColor; protected Color selectedColor;
protected Color pressedColor; protected Color pressedColor;
private CoroutineHandle pulsateCoroutine;
protected ComponentState state; protected ComponentState state;
protected Color flashColor; protected Color flashColor;
protected float flashDuration = 1.5f; protected float flashDuration = 1.5f;
private bool useRectangleFlash;
public float FlashTimer
{
get { return flashTimer; }
}
protected float flashTimer; protected float flashTimer;
private Vector2 flashRectInflate; private Vector2 flashRectInflate;
public bool IgnoreLayoutGroups; public bool IgnoreLayoutGroups;
public bool IgnoreLayoutGroups;
public bool IgnoreLayoutGroups;
public bool IgnoreLayoutGroups;
public bool IgnoreLayoutGroups;
public bool IgnoreLayoutGroups;
public bool IgnoreLayoutGroups;
public bool IgnoreLayoutGroups;
public bool IgnoreLayoutGroups;
public bool IgnoreLayoutGroups;
public bool IgnoreLayoutGroups;
public bool IgnoreLayoutGroups;
public bool IgnoreLayoutGroups;
public bool IgnoreLayoutGroups;
public bool IgnoreLayoutGroups;
public bool IgnoreLayoutGroups;
public bool IgnoreLayoutGroups;
public bool IgnoreLayoutGroups;
public bool IgnoreLayoutGroups;
public bool IgnoreLayoutGroups;
public bool IgnoreLayoutGroups;
public bool IgnoreLayoutGroups;
public bool IgnoreLayoutGroups;
public bool IgnoreLayoutGroups;
public bool IgnoreLayoutGroups;
public bool IgnoreLayoutGroups;
public bool IgnoreLayoutGroups;
public bool IgnoreLayoutGroups;
public bool IgnoreLayoutGroups;
public bool IgnoreLayoutGroups;
public bool IgnoreLayoutGroups;
public bool IgnoreLayoutGroups;
public virtual ScalableFont Font public virtual ScalableFont Font
{ {
get; get;
@@ -324,6 +269,8 @@ namespace Barotrauma
set { pressedColor = value; } set { pressedColor = value; }
} }
public bool ExternalHighlight = false;
private RectTransform rectTransform; private RectTransform rectTransform;
public RectTransform RectTransform public RectTransform RectTransform
{ {
@@ -496,11 +443,21 @@ namespace Barotrauma
int flashCycleCount = (int)Math.Max(flashDuration, 1); int flashCycleCount = (int)Math.Max(flashDuration, 1);
float flashCycleDuration = flashDuration / flashCycleCount; float flashCycleDuration = flashDuration / flashCycleCount;
Rectangle flashRect = Rect;
flashRect.Inflate(flashRectInflate.X, flashRectInflate.Y);
//MathHelper.Pi * 0.8f -> the curve goes from 144 deg to 0, //MathHelper.Pi * 0.8f -> the curve goes from 144 deg to 0,
//i.e. quickly bumps up from almost full brightness to full and then fades out //i.e. quickly bumps up from almost full brightness to full and then fades out
GUI.UIGlow.Draw(spriteBatch, if (!useRectangleFlash)
rect, {
flashColor * (float)Math.Sin(flashTimer % flashCycleDuration / flashCycleDuration * MathHelper.Pi * 0.8f)); GUI.UIGlow.Draw(spriteBatch,
flashRect,
flashColor * (float)Math.Sin(flashTimer % flashCycleDuration / flashCycleDuration * MathHelper.Pi * 0.8f));
}
else
{
GUI.DrawRectangle(spriteBatch, flashRect, flashColor * (float)Math.Sin(flashTimer % flashCycleDuration / flashCycleDuration * MathHelper.Pi * 0.8f), true);
}
} }
} }
@@ -525,6 +482,7 @@ namespace Barotrauma
toolTipBlock.WrappedText.Split('\n').Length * 18 + 7); toolTipBlock.WrappedText.Split('\n').Length * 18 + 7);
toolTipBlock.userData = toolTip; toolTipBlock.userData = toolTip;
} }
toolTipBlock.SetTextPos();
toolTipBlock.RectTransform.AbsoluteOffset = new Point(targetElement.Center.X, targetElement.Bottom); toolTipBlock.RectTransform.AbsoluteOffset = new Point(targetElement.Center.X, targetElement.Bottom);
if (toolTipBlock.Rect.Right > GameMain.GraphicsWidth - 10) if (toolTipBlock.Rect.Right > GameMain.GraphicsWidth - 10)
@@ -548,9 +506,11 @@ namespace Barotrauma
color = new Color(color.R / 255.0f, color.G / 255.0f, color.B / 255.0f, a); color = new Color(color.R / 255.0f, color.G / 255.0f, color.B / 255.0f, a);
} }
public virtual void Flash(Color? color = null, float flashDuration = 1.5f) public virtual void Flash(Color? color = null, float flashDuration = 1.5f, bool useRectangleFlash = false, Vector2? flashRectInflate = null)
{ {
flashTimer = flashDuration; flashTimer = flashDuration;
this.flashRectInflate = flashRectInflate ?? Vector2.Zero;
this.useRectangleFlash = useRectangleFlash;
this.flashDuration = flashDuration; this.flashDuration = flashDuration;
flashColor = (color == null) ? Color.Red : (Color)color; flashColor = (color == null) ? Color.Red : (Color)color;
} }
@@ -568,12 +528,9 @@ namespace Barotrauma
while (t < duration) while (t < duration)
{ {
t += CoroutineManager.DeltaTime; t += CoroutineManager.DeltaTime;
SetAlpha(MathHelper.Lerp(startA, to, t / duration)); SetAlpha(MathHelper.Lerp(startA, to, t / duration));
yield return CoroutineStatus.Running; yield return CoroutineStatus.Running;
} }
toolTipBlock.SetTextPos();
SetAlpha(to); SetAlpha(to);
@@ -584,9 +541,31 @@ namespace Barotrauma
yield return CoroutineStatus.Success; yield return CoroutineStatus.Success;
} }
public void Pulsate(Vector2 startScale, Vector2 endScale, float duration)
{
if (CoroutineManager.IsCoroutineRunning(pulsateCoroutine))
{
return;
}
pulsateCoroutine = CoroutineManager.StartCoroutine(DoPulsate(startScale, endScale, duration), "Pulsate" + ToString());
}
private IEnumerable<object> DoPulsate(Vector2 startScale, Vector2 endScale, float duration)
{
float t = 0.0f;
while (t < duration)
{
t += CoroutineManager.DeltaTime;
RectTransform.LocalScale = Vector2.Lerp(startScale, endScale, (float)Math.Sin(t / duration * MathHelper.Pi));
yield return CoroutineStatus.Running;
}
RectTransform.LocalScale = startScale;
yield return CoroutineStatus.Success;
}
#endregion #endregion
protected virtual void SetAlpha(float a) public virtual void ApplyStyle(GUIComponentStyle style)
{ {
if (style == null) return; if (style == null) return;
@@ -599,11 +578,7 @@ namespace Barotrauma
OutlineColor = style.OutlineColor; OutlineColor = style.OutlineColor;
public virtual void Flash(Color? color = null, float flashDuration = 1.5f) this.style = style;
{
flashTimer = flashDuration;
this.flashDuration = flashDuration;
flashColor = (color == null) ? Color.Red : (Color)color;
} }
} }
} }
@@ -227,6 +227,12 @@ namespace Barotrauma
Content = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.85f), InnerFrame.RectTransform, Anchor.Center)) { AbsoluteSpacing = 5 }; Content = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.85f), InnerFrame.RectTransform, Anchor.Center)) { AbsoluteSpacing = 5 };
Tag = tag; Tag = tag;
InnerFrame = new GUIFrame(new RectTransform(new Point(width, height), RectTransform, Anchor.Center) { IsFixedSize = false }, style: null);
GUI.Style.Apply(InnerFrame, "", this);
Content = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.85f), InnerFrame.RectTransform, Anchor.Center)) { AbsoluteSpacing = 5 };
Tag = tag;
if (height == 0) if (height == 0)
{ {
string wrappedText = ToolBox.WrapText(text, Content.Rect.Width, GUI.Font); string wrappedText = ToolBox.WrapText(text, Content.Rect.Width, GUI.Font);
@@ -365,9 +365,9 @@ namespace Barotrauma
OnDeselected?.Invoke(this, Keys.None); OnDeselected?.Invoke(this, Keys.None);
} }
public override void Flash(Color? color = null, float flashDuration = 1.5f) public override void Flash(Color? color = null, float flashDuration = 1.5f, bool useRectangleFlash = false, Vector2? flashRectOffset = null)
{ {
textBlock.Flash(color, flashDuration); textBlock.Flash(color, flashDuration, useRectangleFlash, flashRectOffset);
} }
protected override void Update(float deltaTime) protected override void Update(float deltaTime)
@@ -10,9 +10,10 @@ namespace Barotrauma
{ {
class VideoPlayer class VideoPlayer
{ {
public bool IsPlaying;
private Video currentVideo; private Video currentVideo;
private string filePath; private string filePath;
private bool isPlaying;
private GUIFrame background, videoFrame, textFrame; private GUIFrame background, videoFrame, textFrame;
private GUITextBlock title, textContent, objectiveTitle, objectiveText; private GUITextBlock title, textContent, objectiveTitle, objectiveText;
@@ -24,12 +25,14 @@ namespace Barotrauma
private Point scaledVideoResolution; private Point scaledVideoResolution;
private readonly int borderSize = 20; private readonly int borderSize = 20;
private readonly Point buttonSize = new Point(160, 50); private readonly Point buttonSize = new Point(120, 30);
private readonly int titleHeight = 30; private readonly int titleHeight = 30;
private readonly int objectiveFrameHeight = 60; private readonly int objectiveFrameHeight = 60;
private readonly int textHeight = 25; private readonly int textHeight = 25;
public struct TextSettings private bool useTextOnRightSide = false;
public class TextSettings
{ {
public string Text; public string Text;
public int Width; public int Width;
@@ -41,7 +44,7 @@ namespace Barotrauma
} }
} }
public struct VideoSettings public class VideoSettings
{ {
public string File; public string File;
@@ -62,7 +65,14 @@ namespace Barotrauma
background = new GUIFrame(new RectTransform(Point.Zero, GUI.Canvas, Anchor.Center), "InnerFrame", backgroundColor); background = new GUIFrame(new RectTransform(Point.Zero, GUI.Canvas, Anchor.Center), "InnerFrame", backgroundColor);
videoFrame = new GUIFrame(new RectTransform(Point.Zero, background.RectTransform, Anchor.Center, Pivot.Center), "SonarFrame"); videoFrame = new GUIFrame(new RectTransform(Point.Zero, background.RectTransform, Anchor.Center, Pivot.Center), "SonarFrame");
textFrame = new GUIFrame(new RectTransform(Point.Zero, videoFrame.RectTransform, Anchor.CenterLeft, Pivot.CenterLeft), "TextFrame"); if (useTextOnRightSide)
{
textFrame = new GUIFrame(new RectTransform(Point.Zero, videoFrame.RectTransform, Anchor.CenterLeft, Pivot.CenterLeft), "TextFrame");
}
else
{
textFrame = new GUIFrame(new RectTransform(Point.Zero, videoFrame.RectTransform, Anchor.TopCenter, Pivot.TopCenter), "TextFrame");
}
videoView = new GUICustomComponent(new RectTransform(Point.Zero, videoFrame.RectTransform, Anchor.Center), (spriteBatch, guiCustomComponent) => { DrawVideo(spriteBatch, guiCustomComponent.Rect); }); videoView = new GUICustomComponent(new RectTransform(Point.Zero, videoFrame.RectTransform, Anchor.Center), (spriteBatch, guiCustomComponent) => { DrawVideo(spriteBatch, guiCustomComponent.Rect); });
title = new GUITextBlock(new RectTransform(Point.Zero, textFrame.RectTransform, Anchor.TopLeft, Pivot.TopLeft), string.Empty, font: GUI.VideoTitleFont, textColor: new Color(253, 174, 0), textAlignment: Alignment.Left); title = new GUITextBlock(new RectTransform(Point.Zero, textFrame.RectTransform, Anchor.TopLeft, Pivot.TopLeft), string.Empty, font: GUI.VideoTitleFont, textColor: new Color(253, 174, 0), textAlignment: Alignment.Left);
@@ -70,7 +80,7 @@ namespace Barotrauma
textContent = new GUITextBlock(new RectTransform(Point.Zero, textFrame.RectTransform, Anchor.TopLeft, Pivot.TopLeft), string.Empty, font: GUI.Font, textAlignment: Alignment.TopLeft); textContent = new GUITextBlock(new RectTransform(Point.Zero, textFrame.RectTransform, Anchor.TopLeft, Pivot.TopLeft), string.Empty, font: GUI.Font, textAlignment: Alignment.TopLeft);
objectiveTitle = new GUITextBlock(new RectTransform(new Vector2(1f, 0f), textFrame.RectTransform, Anchor.TopCenter, Pivot.TopCenter), string.Empty, font: GUI.ObjectiveTitleFont, textAlignment: Alignment.CenterRight, textColor: Color.White); objectiveTitle = new GUITextBlock(new RectTransform(new Vector2(1f, 0f), textFrame.RectTransform, Anchor.TopCenter, Pivot.TopCenter), string.Empty, font: GUI.ObjectiveTitleFont, textAlignment: Alignment.CenterRight, textColor: Color.White);
objectiveTitle.Text = TextManager.Get("NewObjective"); objectiveTitle.Text = TextManager.Get("Tutorial.NewObjective");
objectiveText = new GUITextBlock(new RectTransform(Point.Zero, textFrame.RectTransform, Anchor.TopCenter, Pivot.TopCenter), string.Empty, font: GUI.ObjectiveNameFont, textColor: new Color(4, 180, 108), textAlignment: Alignment.CenterRight); objectiveText = new GUITextBlock(new RectTransform(Point.Zero, textFrame.RectTransform, Anchor.TopCenter, Pivot.TopCenter), string.Empty, font: GUI.ObjectiveNameFont, textColor: new Color(4, 180, 108), textAlignment: Alignment.CenterRight);
objectiveTitle.Visible = objectiveText.Visible = false; objectiveTitle.Visible = objectiveText.Visible = false;
@@ -78,12 +88,12 @@ namespace Barotrauma
public void Play() public void Play()
{ {
isPlaying = true; IsPlaying = true;
} }
public void Stop() public void Stop()
{ {
isPlaying = false; IsPlaying = false;
if (currentVideo == null) return; if (currentVideo == null) return;
currentVideo.Dispose(); currentVideo.Dispose();
currentVideo = null; currentVideo = null;
@@ -99,13 +109,6 @@ namespace Barotrauma
public void Update() public void Update()
{ {
if (currentVideo == null) return; if (currentVideo == null) return;
if (PlayerInput.KeyHit(Keys.Enter) || PlayerInput.KeyHit(Keys.Escape))
{
DisposeVideo(null, null);
return;
}
if (currentVideo.IsPlaying) return; if (currentVideo.IsPlaying) return;
currentVideo.Dispose(); currentVideo.Dispose();
@@ -115,7 +118,7 @@ namespace Barotrauma
public void AddToGUIUpdateList(bool ignoreChildren = false, int order = 0) public void AddToGUIUpdateList(bool ignoreChildren = false, int order = 0)
{ {
if (!isPlaying) return; if (!IsPlaying) return;
background.AddToGUIUpdateList(ignoreChildren, order); background.AddToGUIUpdateList(ignoreChildren, order);
} }
@@ -139,7 +142,7 @@ namespace Barotrauma
currentVideo = CreateVideo(scaledVideoResolution); currentVideo = CreateVideo(scaledVideoResolution);
title.Text = TextManager.Get(contentId); title.Text = TextManager.Get(contentId);
textContent.Text = textSettings.Text; textContent.Text = textSettings != null ? textSettings.Text : string.Empty;
objectiveText.Text = objective; objectiveText.Text = objective;
AdjustFrames(videoSettings, textSettings); AdjustFrames(videoSettings, textSettings);
@@ -165,7 +168,8 @@ namespace Barotrauma
title.TextScale = textContent.TextScale = objectiveText.TextScale = objectiveTitle.TextScale = GUI.Scale; title.TextScale = textContent.TextScale = objectiveText.TextScale = objectiveTitle.TextScale = GUI.Scale;
int scaledBorderSize = (int)(borderSize * GUI.Scale); int scaledBorderSize = (int)(borderSize * GUI.Scale);
int scaledTextWidth = (int)(textSettings.Width * GUI.Scale); int scaledTextWidth = 0;
if (textSettings != null) scaledTextWidth = useTextOnRightSide ? (int)(textSettings.Width * GUI.Scale) : scaledVideoResolution.X / 2;
int scaledTitleHeight = (int)(titleHeight * GUI.Scale); int scaledTitleHeight = (int)(titleHeight * GUI.Scale);
int scaledTextHeight = (int)(textHeight * GUI.Scale); int scaledTextHeight = (int)(textHeight * GUI.Scale);
int scaledObjectiveFrameHeight = (int)(objectiveFrameHeight * GUI.Scale); int scaledObjectiveFrameHeight = (int)(objectiveFrameHeight * GUI.Scale);
@@ -180,13 +184,21 @@ namespace Barotrauma
title.RectTransform.NonScaledSize += new Point(scaledTextWidth, scaledTitleHeight); title.RectTransform.NonScaledSize += new Point(scaledTextWidth, scaledTitleHeight);
title.RectTransform.AbsoluteOffset = new Point((int)(5 * GUI.Scale), (int)(10 * GUI.Scale)); title.RectTransform.AbsoluteOffset = new Point((int)(5 * GUI.Scale), (int)(10 * GUI.Scale));
if (!string.IsNullOrEmpty(textSettings.Text)) if (textSettings != null && !string.IsNullOrEmpty(textSettings.Text))
{ {
textSettings.Text = ToolBox.WrapText(textSettings.Text, scaledTextWidth, GUI.Font); textSettings.Text = ToolBox.WrapText(textSettings.Text, scaledTextWidth, GUI.Font);
int wrappedHeight = textSettings.Text.Split('\n').Length * scaledTextHeight; int wrappedHeight = textSettings.Text.Split('\n').Length * scaledTextHeight;
textFrame.RectTransform.NonScaledSize += new Point(scaledTextWidth + scaledBorderSize, wrappedHeight + scaledBorderSize + scaledButtonSize.Y + scaledTitleHeight); textFrame.RectTransform.NonScaledSize += new Point(scaledTextWidth + scaledBorderSize, wrappedHeight + scaledBorderSize + scaledButtonSize.Y + scaledTitleHeight);
textFrame.RectTransform.AbsoluteOffset = new Point(scaledVideoResolution.X + scaledBorderSize * 2, 0);
if (useTextOnRightSide)
{
textFrame.RectTransform.AbsoluteOffset = new Point(scaledVideoResolution.X + scaledBorderSize * 2, 0);
}
else
{
textFrame.RectTransform.AbsoluteOffset = new Point(0, scaledVideoResolution.Y + scaledBorderSize * 2);
}
textContent.RectTransform.NonScaledSize += new Point(scaledTextWidth, wrappedHeight); textContent.RectTransform.NonScaledSize += new Point(scaledTextWidth, wrappedHeight);
textContent.RectTransform.AbsoluteOffset = new Point(0, scaledBorderSize + scaledTitleHeight); textContent.RectTransform.AbsoluteOffset = new Point(0, scaledBorderSize + scaledTitleHeight);
@@ -209,22 +221,41 @@ namespace Barotrauma
objectiveTitle.Visible = objectiveText.Visible = false; objectiveTitle.Visible = objectiveText.Visible = false;
} }
int totalFrameWidth = videoFrame.Rect.Width + textFrame.Rect.Width + scaledBorderSize * 2;
int xOffset = videoFrame.Rect.Width / 2 + scaledBorderSize - (videoFrame.Rect.Width / 2 - textFrame.Rect.Width / 2);
videoFrame.RectTransform.AbsoluteOffset = new Point(-xOffset, (int)(50 * GUI.Scale));
if (okButton != null) if (okButton != null)
{ {
textFrame.RemoveChild(okButton); textFrame.RemoveChild(okButton);
okButton = null; okButton = null;
} }
okButton = new GUIButton(new RectTransform(scaledButtonSize, textFrame.RectTransform, Anchor.BottomRight, Pivot.BottomRight) { AbsoluteOffset = new Point(scaledBorderSize, scaledBorderSize) }, TextManager.Get("OK")) if (textSettings != null)
{ {
OnClicked = DisposeVideo if (useTextOnRightSide)
}; {
int totalFrameWidth = videoFrame.Rect.Width + textFrame.Rect.Width + scaledBorderSize * 2;
int xOffset = videoFrame.Rect.Width / 2 + scaledBorderSize - (videoFrame.Rect.Width / 2 - textFrame.Rect.Width / 2);
videoFrame.RectTransform.AbsoluteOffset = new Point(-xOffset, (int)(50 * GUI.Scale));
}
else
{
int totalFrameHeight = videoFrame.Rect.Height + textFrame.Rect.Height + scaledBorderSize * 2;
int yOffset = videoFrame.Rect.Height / 2 + scaledBorderSize - (videoFrame.Rect.Height / 2 - textFrame.Rect.Height / 2);
videoFrame.RectTransform.AbsoluteOffset = new Point(0, -yOffset);
}
okButton = new GUIButton(new RectTransform(scaledButtonSize, textFrame.RectTransform, Anchor.BottomRight, Pivot.BottomRight) { AbsoluteOffset = new Point(scaledBorderSize, scaledBorderSize) }, TextManager.Get("OK"))
{
OnClicked = DisposeVideo
};
}
else
{
videoFrame.RectTransform.AbsoluteOffset = new Point(0, (int)(100 * GUI.Scale));
okButton = new GUIButton(new RectTransform(scaledButtonSize, videoFrame.RectTransform, Anchor.TopLeft, Pivot.TopLeft) { AbsoluteOffset = new Point(scaledBorderSize, scaledBorderSize) }, TextManager.Get("Back"))
{
OnClicked = DisposeVideo
};
}
} }
private Video CreateVideo(Point resolution) private Video CreateVideo(Point resolution)
@@ -245,7 +276,7 @@ namespace Barotrauma
private void DrawVideo(SpriteBatch spriteBatch, Rectangle rect) private void DrawVideo(SpriteBatch spriteBatch, Rectangle rect)
{ {
if (!isPlaying) return; if (!IsPlaying) return;
spriteBatch.Draw(currentVideo.GetTexture(), rect, Color.White); spriteBatch.Draw(currentVideo.GetTexture(), rect, Color.White);
} }
@@ -623,8 +623,12 @@ namespace Barotrauma
{ {
((GUIMessageBox)GUIMessageBox.VisibleBox).Close(); ((GUIMessageBox)GUIMessageBox.VisibleBox).Close();
} }
else if (Tutorial.Initialized && Tutorial.ContentRunning)
{
(GameMain.GameSession.GameMode as TutorialMode).Tutorial.CloseActiveContentGUI();
}
else if ((Character.Controlled?.SelectedConstruction == null || !Character.Controlled.SelectedConstruction.ActiveHUDs.Any(ic => ic.GuiFrame != null)) else if ((Character.Controlled?.SelectedConstruction == null || !Character.Controlled.SelectedConstruction.ActiveHUDs.Any(ic => ic.GuiFrame != null))
&& Inventory.SelectedSlot == null && CharacterHealth.OpenHealthWindow == null) && Inventory.SelectedSlot == null && CharacterHealth.OpenHealthWindow == null)
{ {
// Otherwise toggle pausing, unless another window/interface is open. // Otherwise toggle pausing, unless another window/interface is open.
GUI.TogglePauseMenu(); GUI.TogglePauseMenu();
@@ -632,7 +636,7 @@ namespace Barotrauma
} }
GUI.ClearUpdateList(); GUI.ClearUpdateList();
paused = (DebugConsole.IsOpen || GUI.PauseMenuOpen || GUI.SettingsMenuOpen || ContextualTutorial.ContentRunning) && paused = (DebugConsole.IsOpen || GUI.PauseMenuOpen || GUI.SettingsMenuOpen || Tutorial.ContentRunning) &&
(NetworkMember == null || !NetworkMember.GameStarted); (NetworkMember == null || !NetworkMember.GameStarted);
Screen.Selected.AddToGUIUpdateList(); Screen.Selected.AddToGUIUpdateList();
@@ -651,9 +655,9 @@ namespace Barotrauma
{ {
Screen.Selected.Update(Timing.Step); Screen.Selected.Update(Timing.Step);
} }
else if (ContextualTutorial.Initialized && ContextualTutorial.ContentRunning && GameSession.GameMode is SinglePlayerCampaign) else if (Tutorial.Initialized && Tutorial.ContentRunning)
{ {
(GameSession.GameMode as SinglePlayerCampaign).ContextualTutorial.Update((float)Timing.Step); (GameSession.GameMode as TutorialMode).Update((float)Timing.Step);
} }
if (NetworkMember != null) if (NetworkMember != null)
@@ -49,6 +49,8 @@ namespace Barotrauma
private GUIComponent orderTargetFrame, orderTargetFrameShadow; private GUIComponent orderTargetFrame, orderTargetFrameShadow;
public bool AllowCharacterSwitch = true;
public bool ToggleCrewAreaOpen public bool ToggleCrewAreaOpen
{ {
get { return toggleCrewAreaOpen; } get { return toggleCrewAreaOpen; }
@@ -63,6 +65,8 @@ namespace Barotrauma
} }
} }
public List<GUIButton> OrderOptionButtons = new List<GUIButton>();
#endregion #endregion
#region Constructors #region Constructors
@@ -98,6 +102,20 @@ namespace Barotrauma
CanBeFocused = false CanBeFocused = false
}; };
scrollButtonUp = new GUIButton(new RectTransform(scrollButtonSize, crewArea.RectTransform, Anchor.TopLeft, Pivot.TopLeft), "", Alignment.Center, "GUIButtonVerticalArrow")
{
Visible = false,
UserData = -1,
OnClicked = ScrollCharacterList
};
scrollButtonDown = new GUIButton(new RectTransform(scrollButtonSize, crewArea.RectTransform, Anchor.BottomLeft, Pivot.BottomLeft), "", Alignment.Center, "GUIButtonVerticalArrow")
{
Visible = false,
UserData = 1,
OnClicked = ScrollCharacterList
};
scrollButtonDown.Children.ForEach(c => c.SpriteEffects = SpriteEffects.FlipVertically);
var characterInfo = new CharacterInfo(subElement); var characterInfo = new CharacterInfo(subElement);
characterInfos.Add(characterInfo); characterInfos.Add(characterInfo);
foreach (XElement invElement in subElement.Elements()) foreach (XElement invElement in subElement.Elements())
@@ -159,6 +177,16 @@ namespace Barotrauma
ToggleCrewAreaOpen = GameMain.Config.CrewMenuOpen; ToggleCrewAreaOpen = GameMain.Config.CrewMenuOpen;
} }
#endregion
#region Character list management
public Rectangle GetCharacterListArea()
{
return characterListBox.Rect;
}
partial void InitProjectSpecific() partial void InitProjectSpecific()
{ {
guiFrame = new GUIFrame(new RectTransform(Vector2.One, GUICanvas.Instance), null, Color.Transparent) guiFrame = new GUIFrame(new RectTransform(Vector2.One, GUICanvas.Instance), null, Color.Transparent)
@@ -547,7 +575,10 @@ namespace Barotrauma
orderButtonFrame.RectTransform; orderButtonFrame.RectTransform;
var btn = new GUIButton(new RectTransform(new Point(iconSize, iconSize), btnParent, Anchor.CenterLeft), var btn = new GUIButton(new RectTransform(new Point(iconSize, iconSize), btnParent, Anchor.CenterLeft),
style: null); style: null)
{
UserData = order
};
new GUIFrame(new RectTransform(new Vector2(1.5f), btn.RectTransform, Anchor.Center), "OuterGlow") new GUIFrame(new RectTransform(new Vector2(1.5f), btn.RectTransform, Anchor.Center), "OuterGlow")
{ {
@@ -639,6 +670,7 @@ namespace Barotrauma
/// </summary> /// </summary>
public bool CharacterClicked(GUIComponent component, object selection) public bool CharacterClicked(GUIComponent component, object selection)
{ {
if (!AllowCharacterSwitch) { return false; }
Character character = selection as Character; Character character = selection as Character;
if (character == null || character.IsDead || character.IsUnconscious) return false; if (character == null || character.IsDead || character.IsUnconscious) return false;
SelectCharacter(character); SelectCharacter(character);
@@ -679,8 +711,33 @@ namespace Barotrauma
{ {
characterListBox.BarScroll = roundedPos; characterListBox.BarScroll = roundedPos;
} }
}
return false; public void AddCharacterInfo(CharacterInfo characterInfo)
{
if (characterInfos.Contains(characterInfo))
{
DebugConsole.ThrowError("Tried to add the same character info to CrewManager twice.\n" + Environment.StackTrace);
return;
}
characterInfos.Add(characterInfo);
}
/// <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)
{
if (character == null)
{
DebugConsole.ThrowError("Tried to remove a null character from CrewManager.\n" + Environment.StackTrace);
return;
}
characters.Remove(character);
if (removeInfo) characterInfos.Remove(character.Info);
} }
private IEnumerable<object> KillCharacterAnim(GUIComponent component) private IEnumerable<object> KillCharacterAnim(GUIComponent component)
@@ -881,6 +938,22 @@ namespace Barotrauma
} }
} }
} }
character.SetOrder(order, option, orderGiver, speak: orderGiver != character);
if (IsSinglePlayer)
{
orderGiver?.Speak(
order.GetChatMessage(character.Name, orderGiver.CurrentHull?.DisplayName, givingOrderToSelf: character == orderGiver, orderOption: option), null);
}
else if (orderGiver != null)
{
OrderChatMessage msg = new OrderChatMessage(order, option, order.TargetItemComponent?.Item, character, orderGiver);
if (GameMain.Client != null)
{
GameMain.Client.SendChatMessage(msg);
}
}
DisplayCharacterOrder(character, order);
} }
/// <summary> /// <summary>
@@ -982,9 +1055,12 @@ namespace Barotrauma
if (Character.Controlled == null) return false; if (Character.Controlled == null) return false;
SetCharacterOrder(character, userData as Order, option, Character.Controlled); SetCharacterOrder(character, userData as Order, option, Character.Controlled);
orderTargetFrame = null; orderTargetFrame = null;
OrderOptionButtons.Clear();
return true; return true;
} }
}; };
OrderOptionButtons.Add(optionButton);
} }
} }
@@ -1017,9 +1093,13 @@ namespace Barotrauma
if (Character.Controlled == null) return false; if (Character.Controlled == null) return false;
SetCharacterOrder(character, userData as Order, option, Character.Controlled); SetCharacterOrder(character, userData as Order, option, Character.Controlled);
orderTargetFrame = null; orderTargetFrame = null;
OrderOptionButtons.Clear();
return true; return true;
} }
}; };
OrderOptionButtons.Add(optionButton);
//lines between the order buttons //lines between the order buttons
if (i < order.Options.Length - 1) if (i < order.Options.Length - 1)
{ {
@@ -1035,6 +1115,24 @@ namespace Barotrauma
color: matchingItems.Count > 1 ? Color.Black * 0.9f : Color.Black * 0.7f); color: matchingItems.Count > 1 ? Color.Black * 0.9f : Color.Black * 0.7f);
} }
public void HighlightOrderButton(Character character, string orderAiTag, Color color, Vector2? flashRectInflate = null)
{
var order = Order.PrefabList.Find(o => o.AITag == orderAiTag);
if (order == null)
{
DebugConsole.ThrowError("Could not find an order with the AI tag \"" + orderAiTag + "\".\n" + Environment.StackTrace);
return;
}
var characterElement = characterListBox.Content.FindChild(character);
GUIButton orderBtn = characterElement.FindChild(order, recursive: true) as GUIButton;
if (orderBtn.Frame.FlashTimer <= 0)
{
orderBtn.Flash(color, 1.5f, false, flashRectInflate);
}
//orderBtn.Pulsate(Vector2.One, Vector2.One * 2.0f, 1.5f);
}
#region Updating and drawing the UI #region Updating and drawing the UI
private void DrawMiniMapOverlay(SpriteBatch spriteBatch, GUICustomComponent container) private void DrawMiniMapOverlay(SpriteBatch spriteBatch, GUICustomComponent container)
@@ -1092,6 +1190,7 @@ namespace Barotrauma
public void SelectNextCharacter() public void SelectNextCharacter()
{ {
if (!AllowCharacterSwitch) { return; }
if (GameMain.IsMultiplayer) { return; } if (GameMain.IsMultiplayer) { return; }
if (characters.None()) { return; } if (characters.None()) { return; }
SelectCharacter(characters[TryAdjustIndex(1)]); SelectCharacter(characters[TryAdjustIndex(1)]);
@@ -1099,6 +1198,7 @@ namespace Barotrauma
public void SelectPreviousCharacter() public void SelectPreviousCharacter()
{ {
if (!AllowCharacterSwitch) { return; }
if (GameMain.IsMultiplayer) { return; } if (GameMain.IsMultiplayer) { return; }
if (characters.None()) { return; } if (characters.None()) { return; }
SelectCharacter(characters[TryAdjustIndex(-1)]); SelectCharacter(characters[TryAdjustIndex(-1)]);
@@ -1106,6 +1206,7 @@ namespace Barotrauma
private void SelectCharacter(Character character) private void SelectCharacter(Character character)
{ {
if (!AllowCharacterSwitch) { return; }
//make the previously selected character wait in place for some time //make the previously selected character wait in place for some time
//(so they don't immediately start idling and walking away from their station) //(so they don't immediately start idling and walking away from their station)
if (Character.Controlled?.AIController?.ObjectiveManager != null) if (Character.Controlled?.AIController?.ObjectiveManager != null)
@@ -303,7 +303,7 @@ namespace Barotrauma.Tutorials
yield return new WaitForSeconds(1.0f); yield return new WaitForSeconds(1.0f);
infoBox = CreateInfoFrame("Uh-oh... Something enormous just appeared on the sonar."); infoBox = CreateInfoFrame("", "Uh-oh... Something enormous just appeared on the sonar.");
List<Structure> windows = new List<Structure>(); List<Structure> windows = new List<Structure>();
foreach (Structure s in Structure.WallList) foreach (Structure s in Structure.WallList)
@@ -4,22 +4,12 @@ using System;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Barotrauma.Items.Components; using Barotrauma.Items.Components;
using System.Linq; using System.Linq;
using Microsoft.Xna.Framework.Input;
namespace Barotrauma.Tutorials namespace Barotrauma.Tutorials
{ {
class ContextualTutorial : Tutorial class ContextualTutorial : Tutorial
{ {
public static bool Selected = false; public static bool Selected = false;
public static bool ContentRunning = false;
public static bool Initialized = false;
private enum ContentTypes { None = 0, Video = 1, TextOnly = 2 };
private TutorialSegment activeSegment;
private List<TutorialSegment> segments;
private VideoPlayer videoPlayer;
private Steering navConsole; private Steering navConsole;
private Reactor reactor; private Reactor reactor;
@@ -33,83 +23,29 @@ namespace Barotrauma.Tutorials
private List<Pair<Character, float>> characterTimeOnSonar; private List<Pair<Character, float>> characterTimeOnSonar;
private float requiredTimeOnSonar = 5f; private float requiredTimeOnSonar = 5f;
private bool started = false;
private string playableContentPath;
private float tutorialTimer; private float tutorialTimer;
private bool disableTutorialOnDeficiencyFound = true; private bool disableTutorialOnDeficiencyFound = true;
private GUIFrame holderFrame, objectiveFrame;
private List<TutorialSegment> activeObjectives = new List<TutorialSegment>();
private string objectiveTranslated;
private float floodTutorialTimer = 0.0f; private float floodTutorialTimer = 0.0f;
private const float floodTutorialDelay = 2.0f; private const float floodTutorialDelay = 2.0f;
private float medicalTutorialTimer = 0.0f; private float medicalTutorialTimer = 0.0f;
private const float medicalTutorialDelay = 2.0f; private const float medicalTutorialDelay = 2.0f;
private Point screenResolution;
private float prevUIScale;
private class TutorialSegment
{
public string Id;
public string Objective;
public ContentTypes ContentType;
public XElement TextContent;
public XElement VideoContent;
public bool IsTriggered;
public GUIButton ReplayButton;
public GUITextBlock LinkedTitle, LinkedText;
public TutorialSegment(XElement config)
{
Id = config.GetAttributeString("id", "Missing ID");
Objective = TextManager.Get(config.GetAttributeString("objective", string.Empty), true);
Enum.TryParse(config.GetAttributeString("contenttype", "None"), true, out ContentType);
IsTriggered = config.GetAttributeBool("istriggered", false);
switch (ContentType)
{
case ContentTypes.None:
break;
case ContentTypes.Video:
VideoContent = config.Element("Video");
TextContent = config.Element("Text");
break;
case ContentTypes.TextOnly:
TextContent = config.Element("Text");
break;
}
}
}
public ContextualTutorial(XElement element) : base(element) public ContextualTutorial(XElement element) : base(element)
{ {
playableContentPath = element.GetAttributeString("playablecontentpath", "");
segments = new List<TutorialSegment>();
foreach (var segment in element.Elements("Segment"))
{
segments.Add(new TutorialSegment(segment));
}
Name = "ContextualTutorial"; Name = "ContextualTutorial";
} }
public override void Initialize() public override void Initialize()
{ {
base.Initialize();
for (int i = 0; i < segments.Count; i++) for (int i = 0; i < segments.Count; i++)
{ {
segments[i].IsTriggered = false; segments[i].IsTriggered = false;
} }
if (Initialized) return;
Initialized = true;
base.Initialize();
videoPlayer = new VideoPlayer();
characterTimeOnSonar = new List<Pair<Character, float>>(); characterTimeOnSonar = new List<Pair<Character, float>>();
} }
@@ -167,10 +103,7 @@ namespace Barotrauma.Tutorials
base.Start(); base.Start();
injuredMember = null; injuredMember = null;
activeObjectives.Clear(); activeContentSegment = null;
objectiveTranslated = TextManager.Get("Objective");
CreateObjectiveFrame();
activeSegment = null;
tutorialTimer = floodTutorialTimer = medicalTutorialTimer = 0.0f; tutorialTimer = floodTutorialTimer = medicalTutorialTimer = 0.0f;
subStartingPosition = Vector2.Zero; subStartingPosition = Vector2.Zero;
characterTimeOnSonar.Clear(); characterTimeOnSonar.Clear();
@@ -183,10 +116,10 @@ namespace Barotrauma.Tutorials
#if DEBUG #if DEBUG
if (reactor == null || navConsole == null || sonar == null) if (reactor == null || navConsole == null || sonar == null)
{ {
infoBox = CreateInfoFrame("Submarine not compatible with the tutorial:" infoBox = CreateInfoFrame("Error", "Submarine not compatible with the tutorial:"
+ "\nReactor - " + (reactor != null ? "OK" : "Tag 'reactor' not found") + "\nReactor - " + (reactor != null ? "OK" : "Tag 'reactor' not found")
+ "\nNavigation Console - " + (navConsole != null ? "OK" : "Tag 'command' not found") + "\nNavigation Console - " + (navConsole != null ? "OK" : "Tag 'command' not found")
+ "\nSonar - " + (sonar != null ? "OK" : "Not found under Navigation Console"), true); + "\nSonar - " + (sonar != null ? "OK" : "Not found under Navigation Console"), hasButton: true);
CoroutineManager.StartCoroutine(WaitForErrorClosed()); CoroutineManager.StartCoroutine(WaitForErrorClosed());
return; return;
} }
@@ -222,62 +155,15 @@ namespace Barotrauma.Tutorials
} }
#endif #endif
public void Stop() public override void Stop()
{ {
started = ContentRunning = Initialized = false; base.Stop();
videoPlayer.Remove();
videoPlayer = null;
characterTimeOnSonar = null; characterTimeOnSonar = null;
} }
private void CreateObjectiveFrame()
{
holderFrame = new GUIFrame(new RectTransform(new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight), GUI.Canvas, Anchor.Center));
objectiveFrame = new GUIFrame(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.ObjectiveAnchor, holderFrame.RectTransform), style: null);
for (int i = 0; i < activeObjectives.Count; i++)
{
CreateObjectiveGUI(activeObjectives[i], i);
}
screenResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
prevUIScale = GUI.Scale;
}
public override void AddToGUIUpdateList()
{
if (videoPlayer != null)
{
videoPlayer.AddToGUIUpdateList(order: 100);
}
if (GUI.DisableHUD) return;
if (GameMain.GraphicsWidth != screenResolution.X || GameMain.GraphicsHeight != screenResolution.Y || prevUIScale != GUI.Scale)
{
CreateObjectiveFrame();
}
if (objectiveFrame != null && activeObjectives.Count > 0)
{
objectiveFrame.AddToGUIUpdateList(order: -1);
}
base.AddToGUIUpdateList();
}
public override void Update(float deltaTime) public override void Update(float deltaTime)
{ {
if (videoPlayer != null) base.Update(deltaTime);
{
videoPlayer.Update();
}
if (infoBox != null)
{
if (PlayerInput.KeyHit(Keys.Enter) || PlayerInput.KeyHit(Keys.Escape))
{
CloseInfoFrame(null, null);
}
}
if (!started || ContentRunning) return; if (!started || ContentRunning) return;
@@ -285,93 +171,12 @@ namespace Barotrauma.Tutorials
for (int i = 0; i < segments.Count; i++) for (int i = 0; i < segments.Count; i++)
{ {
if (segments[i].IsTriggered || activeObjectives.Contains(segments[i])) continue; if (segments[i].IsTriggered || HasObjective(segments[i])) continue;
if (CheckContextualTutorials(i, deltaTime)) // Found a relevant tutorial, halt finding new ones if (CheckContextualTutorials(i, deltaTime)) // Found a relevant tutorial, halt finding new ones
{ {
break; break;
} }
} }
for (int i = 0; i < activeObjectives.Count; i++)
{
CheckActiveObjectives(activeObjectives[i], deltaTime);
}
}
private void ClosePreTextAndTriggerVideoCallback()
{
videoPlayer.LoadContent(playableContentPath, new VideoPlayer.VideoSettings(activeSegment.VideoContent), new VideoPlayer.TextSettings(activeSegment.VideoContent), activeSegment.Id, true, activeSegment.Objective, CurrentSegmentStopCallback);
}
private void CurrentSegmentStopCallback()
{
if (!string.IsNullOrEmpty(activeSegment.Objective))
{
AddNewObjective(activeSegment);
}
activeSegment = null;
ContentRunning = false;
}
private void AddNewObjective(TutorialSegment segment)
{
activeObjectives.Add(segment);
CreateObjectiveGUI(segment, activeObjectives.Count - 1);
}
private void CreateObjectiveGUI(TutorialSegment segment, int index)
{
Point replayButtonSize = new Point((int)(GUI.ObjectiveNameFont.MeasureString(segment.Objective).X * GUI.Scale), (int)(GUI.ObjectiveNameFont.MeasureString(segment.Objective).Y * 1.45f * GUI.Scale));
segment.ReplayButton = new GUIButton(new RectTransform(replayButtonSize, objectiveFrame.RectTransform, Anchor.TopRight, Pivot.TopRight) { AbsoluteOffset = new Point(0, (replayButtonSize.Y + (int)(20f * GUI.Scale)) * index) }, style: null);
segment.ReplayButton.OnClicked += (GUIButton btn, object userdata) =>
{
ReplaySegmentVideo(segment);
return true;
};
int yOffset = (int)((GUI.ObjectiveNameFont.MeasureString(objectiveTranslated).Y / 2f + 5) * GUI.Scale);
segment.LinkedTitle = new GUITextBlock(new RectTransform(new Point(replayButtonSize.X, yOffset), segment.ReplayButton.RectTransform, Anchor.Center, Pivot.BottomCenter) { AbsoluteOffset = new Point((int)(10 * GUI.Scale), 0) }, objectiveTranslated, textColor: Color.White, font: GUI.ObjectiveTitleFont, textAlignment: Alignment.CenterRight);
segment.LinkedText = new GUITextBlock(new RectTransform(new Point(replayButtonSize.X, yOffset), segment.ReplayButton.RectTransform, Anchor.Center, Pivot.TopCenter) { AbsoluteOffset = new Point((int)(10 * GUI.Scale), 0) }, segment.Objective, textColor: new Color(4, 180, 108), font: GUI.ObjectiveNameFont, textAlignment: Alignment.CenterRight);
segment.LinkedTitle.TextScale = segment.LinkedText.TextScale = GUI.Scale;
segment.LinkedTitle.Color = segment.LinkedTitle.HoverColor = segment.LinkedTitle.PressedColor = segment.LinkedTitle.SelectedColor = Color.Transparent;
segment.LinkedText.Color = segment.LinkedText.HoverColor = segment.LinkedText.PressedColor = segment.LinkedText.SelectedColor = Color.Transparent;
segment.ReplayButton.Color = segment.ReplayButton.HoverColor = segment.ReplayButton.PressedColor = segment.ReplayButton.SelectedColor = Color.Transparent;
}
private void RemoveCompletedObjective(TutorialSegment objective)
{
objective.IsTriggered = true;
int checkMarkHeight = (int)(objective.ReplayButton.Rect.Height * 1.2f);
int checkMarkWidth = (int)(checkMarkHeight * 0.93f);
Color color = new Color(4, 180, 108);
RectTransform rectTA = new RectTransform(new Point(checkMarkWidth, checkMarkHeight), objective.ReplayButton.RectTransform, Anchor.BottomLeft, Pivot.BottomLeft);
rectTA.AbsoluteOffset = new Point(-rectTA.Rect.Width - 5, 0);
GUIImage checkmark = new GUIImage(rectTA, "CheckMark");
checkmark.Color = color;
RectTransform rectTB = new RectTransform(new Vector2(1.1f, .8f), objective.LinkedText.RectTransform, Anchor.Center, Pivot.Center);
GUIImage stroke = new GUIImage(rectTB, "Stroke");
stroke.Color = color;
CoroutineManager.StartCoroutine(WaitForObjectiveEnd(objective));
}
private IEnumerable<object> WaitForObjectiveEnd(TutorialSegment objective)
{
yield return new WaitForSeconds(2.0f);
objectiveFrame.RemoveChild(objective.ReplayButton);
activeObjectives.Remove(objective);
for (int i = 0; i < activeObjectives.Count; i++)
{
activeObjectives[i].ReplayButton.RectTransform.AbsoluteOffset = new Point(0, (activeObjectives[i].ReplayButton.Rect.Height + 20) * i);
}
} }
private bool CheckContextualTutorials(int index, float deltaTime) private bool CheckContextualTutorials(int index, float deltaTime)
@@ -526,17 +331,7 @@ namespace Barotrauma.Tutorials
return true; return true;
} }
private bool HasObjective(string objectiveName) protected override void CheckActiveObjectives(TutorialSegment objective, float deltaTime)
{
for (int i = 0; i < activeObjectives.Count; i++)
{
if (activeObjectives[i].Id == objectiveName) return true;
}
return false;
}
private void CheckActiveObjectives(TutorialSegment objective, float deltaTime)
{ {
switch(objective.Id) switch(objective.Id)
{ {
@@ -704,50 +499,9 @@ namespace Barotrauma.Tutorials
return characterTimeOnSonar.Find(ct => ct.Second >= requiredTimeOnSonar && !ct.First.IsDead) != null; return characterTimeOnSonar.Find(ct => ct.Second >= requiredTimeOnSonar && !ct.First.IsDead) != null;
} }
private void TriggerTutorialSegment(int index, params object[] args) protected override void TriggerTutorialSegment(int index, params object[] args)
{ {
Inventory.draggingItem = null; base.TriggerTutorialSegment(index, args);
ContentRunning = true;
activeSegment = segments[index];
string tutorialText = TextManager.GetFormatted(activeSegment.TextContent.GetAttributeString("tag", ""), true, args);
string objectiveText = string.Empty;
if (!string.IsNullOrEmpty(activeSegment.Objective))
{
if (args.Length == 0)
{
objectiveText = activeSegment.Objective;
}
else
{
objectiveText = string.Format(activeSegment.Objective, args);
}
activeSegment.Objective = objectiveText;
}
else
{
activeSegment.IsTriggered = true; // Complete at this stage only if no related objective
}
switch (activeSegment.ContentType)
{
case ContentTypes.None:
break;
case ContentTypes.Video:
infoBox = CreateInfoFrame(TextManager.Get(activeSegment.Id), tutorialText,
activeSegment.TextContent.GetAttributeInt("width", 300),
activeSegment.TextContent.GetAttributeInt("height", 80),
activeSegment.TextContent.GetAttributeString("anchor", "Center"), true, ClosePreTextAndTriggerVideoCallback);
break;
case ContentTypes.TextOnly:
infoBox = CreateInfoFrame(TextManager.Get(activeSegment.Id), tutorialText,
activeSegment.TextContent.GetAttributeInt("width", 300),
activeSegment.TextContent.GetAttributeInt("height", 80),
activeSegment.TextContent.GetAttributeString("anchor", "Center"), true, CurrentSegmentStopCallback);
break;
}
for (int i = 0; i < segments.Count; i++) for (int i = 0; i < segments.Count; i++)
{ {
@@ -757,13 +511,6 @@ namespace Barotrauma.Tutorials
CoroutineManager.StartCoroutine(WaitToStop()); // Completed CoroutineManager.StartCoroutine(WaitToStop()); // Completed
} }
private void ReplaySegmentVideo(TutorialSegment segment)
{
if (ContentRunning) return;
ContentRunning = true;
videoPlayer.LoadContent(playableContentPath, new VideoPlayer.VideoSettings(segment.VideoContent), new VideoPlayer.TextSettings(segment.VideoContent), segment.Id, true, callback: () => ContentRunning = false);
}
private IEnumerable<object> WaitToStop() private IEnumerable<object> WaitToStop()
{ {
while (ContentRunning) yield return null; while (ContentRunning) yield return null;
@@ -170,7 +170,7 @@ namespace Barotrauma.Tutorials
yield return new WaitForSeconds(2.0f); yield return new WaitForSeconds(2.0f);
}*/ }*/
TriggerTutorialSegment(0, GameMain.Config.KeyBind(InputType.Select), GameMain.Config.KeyBind(InputType.Deselect)); // Medical supplies objective TriggerTutorialSegment(0, GameMain.Config.KeyBind(InputType.Use), GameMain.Config.KeyBind(InputType.Deselect)); // Medical supplies objective
do do
{ {
@@ -508,7 +508,7 @@ namespace Barotrauma.Tutorials
mechanic.AddActiveObjectiveEntity(mechanic_brokenWall_2, mechanic_repairIcon, mechanic_repairIconColor); mechanic.AddActiveObjectiveEntity(mechanic_brokenWall_2, mechanic_repairIcon, mechanic_repairIconColor);
do { yield return null; } while (WallHasDamagedSections(mechanic_brokenWall_2)); do { yield return null; } while (WallHasDamagedSections(mechanic_brokenWall_2));
mechanic.RemoveActiveObjectiveEntity(mechanic_brokenWall_2); mechanic.RemoveActiveObjectiveEntity(mechanic_brokenWall_2);
TriggerTutorialSegment(9, GameMain.Config.KeyBind(InputType.Use)); // Repairing machinery (pump) TriggerTutorialSegment(9, GameMain.Config.KeyBind(InputType.Select)); // Repairing machinery (pump)
SetHighlight(mechanic_brokenPump.Item, true); SetHighlight(mechanic_brokenPump.Item, true);
Repairable repairablePumpComponent = mechanic_brokenPump.Item.GetComponent<Repairable>(); Repairable repairablePumpComponent = mechanic_brokenPump.Item.GetComponent<Repairable>();
do do
@@ -1,44 +1,118 @@
using System; using Barotrauma.Items.Components;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq; using System.Xml.Linq;
namespace Barotrauma.Tutorials namespace Barotrauma.Tutorials
{ {
class ScenarioTutorial : Tutorial class ScenarioTutorial : Tutorial
{ {
private CoroutineHandle tutorialCoroutine;
private Character character; private Character character;
private string spawnSub;
private SpawnType spawnPointType; private SpawnType spawnPointType;
private string submarinePath; private string submarinePath;
private string startOutpostPath;
private string endOutpostPath;
private string levelSeed; private string levelSeed;
private string levelParams;
private Submarine startOutpost = null;
private Submarine endOutpost = null;
private bool currentTutorialCompleted = false;
private float fadeOutTime = 3f;
protected float waitBeforeFade = 4f;
// Colors
protected Color highlightColor = Color.OrangeRed;
protected Color uiHighlightColor = new Color(150, 50, 0);
protected Color buttonHighlightColor = new Color(255, 100, 0);
protected Color inaccessibleColor = Color.Red;
protected Color accessibleColor = Color.Green;
public ScenarioTutorial(XElement element) : base(element) public ScenarioTutorial(XElement element) : base(element)
{ {
submarinePath = element.GetAttributeString("submarinepath", ""); submarinePath = element.GetAttributeString("submarinepath", "");
startOutpostPath = element.GetAttributeString("startoutpostpath", "");
endOutpostPath = element.GetAttributeString("endoutpostpath", "");
levelSeed = element.GetAttributeString("levelseed", "tuto"); levelSeed = element.GetAttributeString("levelseed", "tuto");
Enum.TryParse(element.GetAttributeString("spawnpointtype", "Human"), true, out spawnPointType); levelParams = element.GetAttributeString("levelparams", "");
spawnSub = element.GetAttributeString("spawnsub", "");
Enum.TryParse(element.GetAttributeString("spawnpointtype", "Human"), true, out spawnPointType);
} }
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
currentTutorialCompleted = false;
GameMain.Instance.ShowLoading(Loading()); GameMain.Instance.ShowLoading(Loading());
} }
private IEnumerable<object> Loading()
{
Submarine.MainSub = Submarine.Load(submarinePath, "", true);
LevelGenerationParams generationParams = LevelGenerationParams.LevelParams.Find(p => p.Name == levelParams);
yield return CoroutineStatus.Running;
GameMain.GameSession = new GameSession(Submarine.MainSub, "",
GameModePreset.List.Find(g => g.Identifier == "tutorial"));
(GameMain.GameSession.GameMode as TutorialMode).Tutorial = this;
if (generationParams != null)
{
Biome biome = LevelGenerationParams.GetBiomes().Find(b => generationParams.AllowedBiomes.Contains(b));
if (startOutpostPath != string.Empty)
{
startOutpost = Submarine.Load(startOutpostPath, "", false);
}
if (endOutpostPath != string.Empty)
{
endOutpost = Submarine.Load(endOutpostPath, "", false);
}
Level tutorialLevel = new Level(levelSeed, 0, 0, generationParams, biome, startOutpost, endOutpost);
GameMain.GameSession.StartRound(tutorialLevel);
}
else
{
GameMain.GameSession.StartRound(levelSeed);
}
GameMain.GameSession.EventManager.Events.Clear();
GameMain.GameSession.EventManager.Enabled = false;
GameMain.GameScreen.Select();
yield return CoroutineStatus.Success;
}
public override void Start() public override void Start()
{ {
base.Start(); base.Start();
WayPoint wayPoint = WayPoint.GetRandom(spawnPointType, null); Submarine.MainSub.GodMode = true;
CharacterInfo charInfo = configElement.Element("Character") == null ?
new CharacterInfo(Character.HumanConfigFile, "", JobPrefab.List.Find(jp => jp.Identifier == "engineer")) :
new CharacterInfo(configElement.Element("Character"));
WayPoint wayPoint = GetSpawnPoint(charInfo);
if (wayPoint == null) if (wayPoint == null)
{ {
DebugConsole.ThrowError("A waypoint with the spawntype \"" + spawnPointType + "\" is required for the tutorial event"); DebugConsole.ThrowError("A waypoint with the spawntype \"" + spawnPointType + "\" is required for the tutorial event");
return; return;
} }
CharacterInfo charInfo = configElement.Element("Character") == null ?
new CharacterInfo(Character.HumanConfigFile, "", JobPrefab.List.Find(jp => jp.Identifier == "engineer")) :
new CharacterInfo(configElement.Element("Character"));
character = Character.Create(charInfo, wayPoint.WorldPosition, "", false, false); character = Character.Create(charInfo, wayPoint.WorldPosition, "", false, false);
Character.Controlled = character; Character.Controlled = character;
character.GiveJobItems(null); character.GiveJobItems(null);
@@ -52,22 +126,82 @@ namespace Barotrauma.Tutorials
idCard.AddTag("com"); idCard.AddTag("com");
idCard.AddTag("eng"); idCard.AddTag("eng");
CoroutineManager.StartCoroutine(UpdateState()); tutorialCoroutine = CoroutineManager.StartCoroutine(UpdateState());
} }
private IEnumerable<object> Loading() public override void AddToGUIUpdateList()
{ {
Submarine.MainSub = Submarine.Load(submarinePath, "", true); if (!currentTutorialCompleted)
yield return CoroutineStatus.Running; {
base.AddToGUIUpdateList();
}
}
GameMain.GameSession = new GameSession(Submarine.MainSub, "", private WayPoint GetSpawnPoint(CharacterInfo charInfo)
GameModePreset.List.Find(g => g.Identifier == "tutorial")); {
(GameMain.GameSession.GameMode as TutorialMode).tutorial = this; Submarine spawnSub = null;
GameMain.GameSession.StartRound(levelSeed);
GameMain.GameSession.EventManager.Events.Clear();
GameMain.GameScreen.Select();
yield return CoroutineStatus.Success; if (this.spawnSub != string.Empty)
{
switch (this.spawnSub)
{
case "startoutpost":
spawnSub = startOutpost;
break;
case "endoutpost":
spawnSub = endOutpost;
break;
default:
spawnSub = Submarine.MainSub;
break;
}
}
return WayPoint.GetRandom(spawnPointType, charInfo.Job, spawnSub);
}
protected bool HasOrder(Character character, string aiTag, string option = null)
{
if (character.CurrentOrder?.AITag == aiTag)
{
if (option == null)
{
return true;
}
else
{
HumanAIController humanAI = character.AIController as HumanAIController;
return humanAI.CurrentOrderOption == option;
}
}
return false;
}
protected void SetHighlight(Item item, bool state)
{
if (item.ExternalHighlight == state) return;
item.SpriteColor = (state) ? highlightColor : Color.White;
item.ExternalHighlight = state;
}
protected void SetHighlight(Structure structure, bool state)
{
structure.SpriteColor = (state) ? highlightColor : Color.White;
structure.ExternalHighlight = state;
}
protected void SetHighlight(Character character, bool state)
{
character.ExternalHighlight = state;
}
protected void SetDoorAccess(Door door, LightComponent light, bool state)
{
if (state && door != null) door.requiredItems.Clear();
if (light != null) light.LightColor = (state) ? accessibleColor : inaccessibleColor;
} }
public override void Update(float deltaTime) public override void Update(float deltaTime)
@@ -75,27 +209,47 @@ namespace Barotrauma.Tutorials
base.Update(deltaTime); base.Update(deltaTime);
if (character != null) if (character != null)
{ {
if (Character.Controlled == null) if (character.Oxygen < 1)
{ {
CoroutineManager.StopCoroutines("TutorialMode.UpdateState"); character.Oxygen = 1;
}
if (character.IsDead)
{
CoroutineManager.StartCoroutine(Dead());
}
else if (Character.Controlled == null)
{
if (tutorialCoroutine != null)
{
CoroutineManager.StopCoroutines(tutorialCoroutine);
}
infoBox = null; infoBox = null;
} }
else if (Character.Controlled.IsDead) else if (Character.Controlled.IsDead)
{ {
Character.Controlled = null;
CoroutineManager.StopCoroutines("TutorialMode.UpdateState");
infoBox = null;
CoroutineManager.StartCoroutine(Dead()); CoroutineManager.StartCoroutine(Dead());
} }
} }
} }
public override void Stop()
{
if (tutorialCoroutine != null)
{
CoroutineManager.StopCoroutines(tutorialCoroutine);
}
base.Stop();
}
private IEnumerable<object> Dead() private IEnumerable<object> Dead()
{ {
GUI.PreventPauseMenuToggle = true;
Character.Controlled = character = null;
Stop();
yield return new WaitForSeconds(3.0f); yield return new WaitForSeconds(3.0f);
var messageBox = new GUIMessageBox("You have died", "Do you want to try again?", new string[] { "Yes", "No" }); var messageBox = new GUIMessageBox(TextManager.Get("Tutorial.TryAgainHeader"), TextManager.Get("Tutorial.TryAgain"), new string[] { TextManager.Get("Yes"), TextManager.Get("No") });
messageBox.Buttons[0].OnClicked += Restart; messageBox.Buttons[0].OnClicked += Restart;
messageBox.Buttons[0].OnClicked += messageBox.Close; messageBox.Buttons[0].OnClicked += messageBox.Close;
@@ -106,5 +260,29 @@ namespace Barotrauma.Tutorials
yield return CoroutineStatus.Success; yield return CoroutineStatus.Success;
} }
protected IEnumerable<object> TutorialCompleted()
{
GUI.PreventPauseMenuToggle = true;
Character.Controlled.ClearInputs();
Character.Controlled = null;
yield return new WaitForSeconds(waitBeforeFade);
var endCinematic = new RoundEndCinematic(Submarine.MainSub, GameMain.GameScreen.Cam, fadeOutTime);
currentTutorialCompleted = Completed = true;
while (endCinematic.Running) yield return null;
Stop();
GameMain.MainMenuScreen.ReturnToMainMenu(null, null);
}
protected void Heal(Character character)
{
character.SetAllDamage(0.0f, 0.0f, 0.0f);
character.Oxygen = 100.0f;
character.Bloodloss = 0.0f;
character.SetStun(0.0f, true);
}
} }
} }
@@ -1,15 +1,23 @@
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using System.Linq;
using System.Xml.Linq; using System.Xml.Linq;
using Barotrauma.Items.Components;
using Barotrauma.Extensions;
namespace Barotrauma.Tutorials namespace Barotrauma.Tutorials
{ {
abstract class Tutorial abstract class Tutorial
{ {
#region Tutorial variables
public static bool Initialized = false;
public static bool ContentRunning = false;
public static List<Tutorial> Tutorials; public static List<Tutorial> Tutorials;
protected bool started = false;
protected GUIComponent infoBox; protected GUIComponent infoBox;
private Action infoBoxClosedCallback; private Action infoBoxClosedCallback;
protected XElement configElement; protected XElement configElement;
@@ -17,6 +25,54 @@ namespace Barotrauma.Tutorials
private enum TutorialType { None, Scenario, Contextual }; private enum TutorialType { None, Scenario, Contextual };
private TutorialType tutorialType = TutorialType.None; private TutorialType tutorialType = TutorialType.None;
protected VideoPlayer videoPlayer;
protected enum TutorialContentTypes { None = 0, Video = 1, ManualVideo = 2, TextOnly = 3 };
protected string playableContentPath;
protected Point screenResolution;
protected float prevUIScale;
private GUIFrame holderFrame, objectiveFrame;
private List<TutorialSegment> activeObjectives = new List<TutorialSegment>();
private string objectiveTranslated;
protected TutorialSegment activeContentSegment;
protected List<TutorialSegment> segments;
protected class TutorialSegment
{
public string Id;
public string Objective;
public TutorialContentTypes ContentType;
public XElement TextContent;
public XElement VideoContent;
public bool IsTriggered;
public GUIButton ReplayButton;
public GUITextBlock LinkedTitle, LinkedText;
public object[] Args;
public TutorialSegment(XElement config)
{
Id = config.GetAttributeString("id", "Missing ID");
Objective = TextManager.Get(config.GetAttributeString("objective", string.Empty), true);
Enum.TryParse(config.GetAttributeString("contenttype", "None"), true, out ContentType);
IsTriggered = config.GetAttributeBool("istriggered", false);
switch (ContentType)
{
case TutorialContentTypes.None:
break;
case TutorialContentTypes.Video:
case TutorialContentTypes.ManualVideo:
VideoContent = config.Element("Video");
TextContent = config.Element("Text");
break;
case TutorialContentTypes.TextOnly:
TextContent = config.Element("Text");
break;
}
}
}
public string Name public string Name
{ {
get; get;
@@ -34,7 +90,9 @@ namespace Barotrauma.Tutorials
GameMain.Config.SaveNewPlayerConfig(); GameMain.Config.SaveNewPlayerConfig();
} }
} }
#endregion
#region Tutorial Controls
public static void Init() public static void Init()
{ {
Tutorials = new List<Tutorial>(); Tutorials = new List<Tutorial>();
@@ -107,26 +165,85 @@ namespace Barotrauma.Tutorials
Name = element.GetAttributeString("name", "Unnamed"); Name = element.GetAttributeString("name", "Unnamed");
completed = GameMain.Config.CompletedTutorialNames.Contains(Name); completed = GameMain.Config.CompletedTutorialNames.Contains(Name);
Enum.TryParse(element.GetAttributeString("tutorialtype", "Scenario"), true, out tutorialType); Enum.TryParse(element.GetAttributeString("tutorialtype", "Scenario"), true, out tutorialType);
playableContentPath = element.GetAttributeString("playablecontentpath", "");
segments = new List<TutorialSegment>();
foreach (var segment in element.Elements("Segment"))
{
segments.Add(new TutorialSegment(segment));
}
} }
public virtual void Initialize() public virtual void Initialize()
{ {
if (Initialized) return;
Initialized = true;
videoPlayer = new VideoPlayer();
} }
public virtual void Start() public virtual void Start()
{ {
activeObjectives.Clear();
objectiveTranslated = TextManager.Get("Tutorial.Objective");
CreateObjectiveFrame();
// Setup doors: Clear all requirements, unless the door is setup as locked.
foreach (var item in Item.ItemList)
{
var door = item.GetComponent<Door>();
if (door != null)
{
if (door.requiredItems.Values.None(ris => ris.None(ri => ri.Identifiers.None(i => i == "locked"))))
{
door.requiredItems.Clear();
}
}
}
} }
public virtual void AddToGUIUpdateList() public virtual void AddToGUIUpdateList()
{ {
if (GameMain.GraphicsWidth != screenResolution.X || GameMain.GraphicsHeight != screenResolution.Y || prevUIScale != GUI.Scale)
{
CreateObjectiveFrame();
}
if (objectiveFrame != null && activeObjectives.Count > 0)
{
objectiveFrame.AddToGUIUpdateList(order: -1);
}
if (infoBox != null) infoBox.AddToGUIUpdateList(order: 100); if (infoBox != null) infoBox.AddToGUIUpdateList(order: 100);
if (videoPlayer != null) videoPlayer.AddToGUIUpdateList(order: 100);
} }
public virtual void Update(float deltaTime) public virtual void Update(float deltaTime)
{ {
if (videoPlayer != null)
{
videoPlayer.Update();
}
if (activeObjectives != null)
{
for (int i = 0; i < activeObjectives.Count; i++)
{
CheckActiveObjectives(activeObjectives[i], deltaTime);
}
}
}
public void CloseActiveContentGUI()
{
if (videoPlayer.IsPlaying)
{
videoPlayer.Stop();
}
else if (infoBox != null)
{
CloseInfoFrame(null, null);
}
} }
public virtual IEnumerable<object> UpdateState() public virtual IEnumerable<object> UpdateState()
@@ -134,6 +251,233 @@ namespace Barotrauma.Tutorials
yield return CoroutineStatus.Success; yield return CoroutineStatus.Success;
} }
protected bool Restart(GUIButton button, object obj)
{
GUI.PreventPauseMenuToggle = false;
TutorialMode.StartTutorial(this);
return true;
}
protected virtual void TriggerTutorialSegment(int index, params object[] args)
{
Inventory.draggingItem = null;
ContentRunning = true;
activeContentSegment = segments[index];
segments[index].Args = args;
string tutorialText = TextManager.GetFormatted(activeContentSegment.TextContent.GetAttributeString("tag", ""), true, args);
tutorialText = TextManager.ParseInputTypes(tutorialText);
string objectiveText = string.Empty;
if (!string.IsNullOrEmpty(activeContentSegment.Objective))
{
if (args.Length == 0)
{
objectiveText = activeContentSegment.Objective;
}
else
{
objectiveText = string.Format(activeContentSegment.Objective, args);
}
objectiveText = TextManager.ParseInputTypes(objectiveText);
activeContentSegment.Objective = objectiveText;
}
else
{
activeContentSegment.IsTriggered = true; // Complete at this stage only if no related objective
}
switch (activeContentSegment.ContentType)
{
case TutorialContentTypes.None:
break;
case TutorialContentTypes.Video:
infoBox = CreateInfoFrame(TextManager.Get(activeContentSegment.Id), tutorialText,
activeContentSegment.TextContent.GetAttributeInt("width", 300),
activeContentSegment.TextContent.GetAttributeInt("height", 80),
activeContentSegment.TextContent.GetAttributeString("anchor", "Center"), true, () => LoadVideo(activeContentSegment));
break;
case TutorialContentTypes.ManualVideo:
infoBox = CreateInfoFrame(TextManager.Get(activeContentSegment.Id), tutorialText,
activeContentSegment.TextContent.GetAttributeInt("width", 300),
activeContentSegment.TextContent.GetAttributeInt("height", 80),
activeContentSegment.TextContent.GetAttributeString("anchor", "Center"), true, StopCurrentContentSegment, () => LoadVideo(activeContentSegment, false));
break;
case TutorialContentTypes.TextOnly:
infoBox = CreateInfoFrame(TextManager.Get(activeContentSegment.Id), tutorialText,
activeContentSegment.TextContent.GetAttributeInt("width", 300),
activeContentSegment.TextContent.GetAttributeInt("height", 80),
activeContentSegment.TextContent.GetAttributeString("anchor", "Center"), true, StopCurrentContentSegment);
break;
}
}
public virtual void Stop()
{
started = ContentRunning = Initialized = false;
infoBox = null;
if (videoPlayer != null)
{
videoPlayer.Remove();
videoPlayer = null;
}
}
#endregion
#region Objectives
private void CreateObjectiveFrame()
{
holderFrame = new GUIFrame(new RectTransform(new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight), GUI.Canvas, Anchor.Center));
objectiveFrame = new GUIFrame(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.ObjectiveAnchor, holderFrame.RectTransform), style: null);
for (int i = 0; i < activeObjectives.Count; i++)
{
CreateObjectiveGUI(activeObjectives[i], i, activeObjectives[i].ContentType);
}
screenResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
prevUIScale = GUI.Scale;
}
protected void StopCurrentContentSegment()
{
if (!string.IsNullOrEmpty(activeContentSegment.Objective))
{
AddNewObjective(activeContentSegment, activeContentSegment.ContentType);
}
activeContentSegment = null;
ContentRunning = false;
}
protected virtual void CheckActiveObjectives(TutorialSegment objective, float deltaTime)
{
}
protected bool HasObjective(TutorialSegment segment)
{
return activeObjectives.Contains(segment);
}
protected void AddNewObjective(TutorialSegment segment, TutorialContentTypes type)
{
activeObjectives.Add(segment);
CreateObjectiveGUI(segment, activeObjectives.Count - 1, type);
}
private void CreateObjectiveGUI(TutorialSegment segment, int index, TutorialContentTypes type)
{
Point replayButtonSize = new Point((int)(GUI.ObjectiveNameFont.MeasureString(segment.Objective).X * GUI.Scale), (int)(GUI.ObjectiveNameFont.MeasureString(segment.Objective).Y * 1.45f * GUI.Scale));
segment.ReplayButton = new GUIButton(new RectTransform(replayButtonSize, objectiveFrame.RectTransform, Anchor.TopRight, Pivot.TopRight) { AbsoluteOffset = new Point(0, (replayButtonSize.Y + (int)(20f * GUI.Scale)) * index) }, style: null);
segment.ReplayButton.OnClicked += (GUIButton btn, object userdata) =>
{
if (type == TutorialContentTypes.Video)
{
ReplaySegmentVideo(segment);
}
else
{
ShowSegmentText(segment);
}
return true;
};
string objectiveText = TextManager.ParseInputTypes(objectiveTranslated);
int yOffset = (int)((GUI.ObjectiveNameFont.MeasureString(objectiveText).Y / 2f + 5) * GUI.Scale);
segment.LinkedTitle = new GUITextBlock(new RectTransform(new Point((int)GUI.ObjectiveNameFont.MeasureString(objectiveText).X, yOffset), segment.ReplayButton.RectTransform, Anchor.CenterRight, Pivot.BottomRight) { AbsoluteOffset = new Point((int)(-10 * GUI.Scale), 0) },
objectiveText, textColor: Color.White, font: GUI.ObjectiveTitleFont, textAlignment: Alignment.CenterRight);
segment.LinkedText = new GUITextBlock(new RectTransform(new Point(replayButtonSize.X, yOffset), segment.ReplayButton.RectTransform, Anchor.Center, Pivot.TopCenter) { AbsoluteOffset = new Point((int)(10 * GUI.Scale), 0) },
TextManager.ParseInputTypes(segment.Objective), textColor: new Color(4, 180, 108), font: GUI.ObjectiveNameFont, textAlignment: Alignment.CenterRight);
segment.LinkedTitle.TextScale = segment.LinkedText.TextScale = GUI.Scale;
segment.LinkedTitle.Color = segment.LinkedTitle.HoverColor = segment.LinkedTitle.PressedColor = segment.LinkedTitle.SelectedColor = Color.Transparent;
segment.LinkedText.Color = segment.LinkedText.HoverColor = segment.LinkedText.PressedColor = segment.LinkedText.SelectedColor = Color.Transparent;
segment.ReplayButton.Color = segment.ReplayButton.HoverColor = segment.ReplayButton.PressedColor = segment.ReplayButton.SelectedColor = Color.Transparent;
}
private void ReplaySegmentVideo(TutorialSegment segment)
{
if (ContentRunning) return;
ContentRunning = true;
videoPlayer.LoadContent(playableContentPath, new VideoPlayer.VideoSettings(segment.VideoContent), new VideoPlayer.TextSettings(segment.VideoContent), segment.Id, true, callback: () => ContentRunning = false);
}
private void ShowSegmentText(TutorialSegment segment)
{
if (ContentRunning) return;
Inventory.draggingItem = null;
ContentRunning = true;
string tutorialText = TextManager.GetFormatted(segment.TextContent.GetAttributeString("tag", ""), true, segment.Args);
Action videoAction = null;
if (segment.ContentType != TutorialContentTypes.TextOnly)
{
videoAction = () => LoadVideo(segment, false);
}
infoBox = CreateInfoFrame(TextManager.Get(segment.Id), tutorialText,
segment.TextContent.GetAttributeInt("width", 300),
segment.TextContent.GetAttributeInt("height", 80),
segment.TextContent.GetAttributeString("anchor", "Center"), true, () => ContentRunning = false, videoAction);
}
protected void RemoveCompletedObjective(TutorialSegment segment)
{
if (!HasObjective(segment)) return;
segment.IsTriggered = true;
segment.ReplayButton.OnClicked = null;
int checkMarkHeight = (int)(segment.ReplayButton.Rect.Height * 1.2f);
int checkMarkWidth = (int)(checkMarkHeight * 0.93f);
Color color = new Color(4, 180, 108);
int objectiveTextWidth = segment.LinkedText.Rect.Width;
int objectiveTitleWidth = segment.LinkedTitle.Rect.Width;
RectTransform rectTA;
if (objectiveTextWidth > objectiveTitleWidth)
{
rectTA = new RectTransform(new Point(checkMarkWidth, checkMarkHeight), segment.ReplayButton.RectTransform, Anchor.BottomLeft, Pivot.BottomLeft);
rectTA.AbsoluteOffset = new Point(-rectTA.Rect.Width - 5, 0);
}
else
{
rectTA = new RectTransform(new Point(checkMarkWidth, checkMarkHeight), segment.ReplayButton.RectTransform, Anchor.BottomLeft, Pivot.BottomLeft);
rectTA.AbsoluteOffset = new Point(-rectTA.Rect.Width - 5 - (objectiveTitleWidth), 0);
}
GUIImage checkmark = new GUIImage(rectTA, "CheckMark");
checkmark.Color = checkmark.SelectedColor = checkmark.HoverColor = checkmark.PressedColor = color;
RectTransform rectTB = new RectTransform(new Vector2(1.1f, .8f), segment.LinkedText.RectTransform, Anchor.Center, Pivot.Center);
GUIImage stroke = new GUIImage(rectTB, "Stroke");
stroke.Color = stroke.SelectedColor = stroke.HoverColor = stroke.PressedColor = color;
CoroutineManager.StartCoroutine(WaitForObjectiveEnd(segment));
}
private IEnumerable<object> WaitForObjectiveEnd(TutorialSegment objective)
{
yield return new WaitForSeconds(2.0f);
objectiveFrame.RemoveChild(objective.ReplayButton);
activeObjectives.Remove(objective);
for (int i = 0; i < activeObjectives.Count; i++)
{
activeObjectives[i].ReplayButton.RectTransform.AbsoluteOffset = new Point(0, (activeObjectives[i].ReplayButton.Rect.Height + 20) * i);
}
}
#endregion
#region InfoFrame
protected bool CloseInfoFrame(GUIButton button, object userData) protected bool CloseInfoFrame(GUIButton button, object userData)
{ {
infoBox = null; infoBox = null;
@@ -141,73 +485,71 @@ namespace Barotrauma.Tutorials
return true; return true;
} }
protected GUIComponent CreateInfoFrame(string text, bool hasButton = false, Action callback = null) protected GUIComponent CreateInfoFrame(string title, string text, int width = 300, int height = 80, string anchorStr = "", bool hasButton = false, Action callback = null, Action showVideo = null)
{ {
int width = 300; if (hasButton) height += 60;
int height = hasButton ? 110 : 80;
string wrappedText = ToolBox.WrapText(text, width, GUI.Font); float textScale = GUI.Scale;
string wrappedText = ToolBox.WrapText(text, width, GUI.Font, textScale);
height += wrappedText.Split('\n').Length * 25;
var infoBlock = new GUIFrame(new RectTransform(new Point(width, height), GUI.Canvas, Anchor.TopRight) { AbsoluteOffset = new Point(20) });
infoBlock.Flash(Color.Green);
var textBlock = new GUITextBlock(new RectTransform(new Vector2(0.9f, 0.7f), infoBlock.RectTransform, Anchor.Center),
text, wrap: true);
infoBoxClosedCallback = callback;
if (hasButton)
{
var okButton = new GUIButton(new RectTransform(new Point(160, 50), infoBlock.RectTransform, Anchor.BottomCenter, Pivot.TopCenter) { AbsoluteOffset = new Point(0, -10) },
TextManager.Get("OK"))
{
OnClicked = CloseInfoFrame
};
}
GUI.PlayUISound(GUISoundType.UIMessage);
return infoBlock;
}
protected GUIComponent CreateInfoFrame(string title, string text, int width, int height, string anchorStr, bool hasButton = false, Action callback = null)
{
if (hasButton) height += 30;
string wrappedText = ToolBox.WrapText(text, width, GUI.Font);
height += wrappedText.Split('\n').Length * 25;
height += (int)(GUI.Font.MeasureString(wrappedText).Y * textScale + 50);
if (title.Length > 0) if (title.Length > 0)
{ {
height += 35; height += 35;
} }
Anchor anchor = Anchor.TopRight; Anchor anchor = Anchor.TopRight;
Enum.TryParse(anchorStr, out anchor);
var infoBlock = new GUIFrame(new RectTransform(new Point((int)(width * GUI.Scale), (int)(height * GUI.Scale)), GUI.Canvas, anchor) { AbsoluteOffset = new Point(20) }); if (anchorStr != string.Empty)
{
Enum.TryParse(anchorStr, out anchor);
}
var background = new GUIFrame(new RectTransform(new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight), GUI.Canvas, Anchor.Center), "InnerFrame", new Color(0, 0, 0, 1f));
var infoBlock = new GUIFrame(new RectTransform(new Point((int)(width * GUI.Scale), (int)(height * GUI.Scale)), background.RectTransform, anchor) { AbsoluteOffset = new Point(20) });
infoBlock.Flash(Color.Green); infoBlock.Flash(Color.Green);
var infoContent = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.8f), infoBlock.RectTransform, Anchor.Center))
{
Stretch = true,
RelativeSpacing = 0.02f
};
if (title.Length > 0) if (title.Length > 0)
{ {
var titleBlock = new GUITextBlock(new RectTransform(new Vector2(1f, .35f), infoBlock.RectTransform, Anchor.TopCenter, var titleBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.3f), infoContent.RectTransform),
Pivot.TopCenter), title, font: GUI.VideoTitleFont, textAlignment: Alignment.Center, textColor: new Color(253, 174, 0)); title, font: GUI.VideoTitleFont, textAlignment: Alignment.Center, textColor: new Color(253, 174, 0));
titleBlock.TextScale = GUI.Scale; titleBlock.TextScale = textScale;
} }
var textBlock = new GUITextBlock(new RectTransform(new Vector2(0.9f, 1f), infoBlock.RectTransform, Anchor.BottomCenter), var textBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 1.0f), infoContent.RectTransform), text, wrap: true);
text, wrap: true);
textBlock.TextScale = GUI.Scale;
infoBoxClosedCallback = callback; infoBoxClosedCallback = callback;
if (hasButton) if (hasButton)
{ {
var okButton = new GUIButton(new RectTransform(new Point(160, 50), infoBlock.RectTransform, Anchor.BottomCenter, Pivot.TopCenter) { AbsoluteOffset = new Point(0, -10) }, var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.3f), infoContent.RectTransform) { MinSize = new Point(0, 30), MaxSize = new Point((int) infoContent.Rect.X, 60) }, isHorizontal: true)
TextManager.Get("OK")) {
Stretch = true,
RelativeSpacing = 0.1f
};
if (showVideo != null)
{
var videoButton = new GUIButton(new RectTransform(new Vector2(0.4f, 1.0f), buttonContainer.RectTransform),
TextManager.Get("Video"), style: "GUIButtonLarge")
{
OnClicked = (GUIButton button, object obj) =>
{
showVideo();
return true;
}
};
}
var okButton = new GUIButton(new RectTransform(new Vector2(0.6f, 1.0f), buttonContainer.RectTransform),
TextManager.Get("OK"), style: "GUIButtonLarge")
{ {
OnClicked = CloseInfoFrame OnClicked = CloseInfoFrame
}; };
@@ -215,13 +557,55 @@ namespace Barotrauma.Tutorials
GUI.PlayUISound(GUISoundType.UIMessage); GUI.PlayUISound(GUISoundType.UIMessage);
return infoBlock; return background;
}
#endregion
#region Video
protected void LoadVideo(TutorialSegment segment, bool showText = true)
{
if (videoPlayer == null) videoPlayer = new VideoPlayer();
if (showText)
{
videoPlayer.LoadContent(playableContentPath, new VideoPlayer.VideoSettings(segment.VideoContent), new VideoPlayer.TextSettings(segment.VideoContent), segment.Id, true, segment.Objective, StopCurrentContentSegment);
}
else
{
videoPlayer.LoadContent(playableContentPath, new VideoPlayer.VideoSettings(segment.VideoContent), null, segment.Id, true, segment.Objective, null);
}
}
#endregion
#region Highlights
protected void HighlightInventorySlot(Inventory inventory, string identifier, Color color, float fadeInDuration, float fadeOutDuration, float scaleUpAmount)
{
if (inventory.slots == null) { return; }
for (int i = 0; i < inventory.Items.Length; i++)
{
if (inventory.Items[i] != null && inventory.Items[i].Prefab.Identifier == identifier)
{
HighlightInventorySlot(inventory, i, color, fadeInDuration, fadeOutDuration, scaleUpAmount);
}
}
} }
protected bool Restart(GUIButton button, object obj) protected void HighlightInventorySlotWithTag(Inventory inventory, string tag, Color color, float fadeInDuration, float fadeOutDuration, float scaleUpAmount)
{ {
TutorialMode.StartTutorial(this); if (inventory.slots == null) { return; }
return true; for (int i = 0; i < inventory.Items.Length; i++)
{
if (inventory.Items[i] != null && inventory.Items[i].HasTag(tag))
{
HighlightInventorySlot(inventory, i, color, fadeInDuration, fadeOutDuration, scaleUpAmount);
}
}
} }
protected void HighlightInventorySlot(Inventory inventory, int index, Color color, float fadeInDuration, float fadeOutDuration, float scaleUpAmount)
{
if (inventory.slots == null || index < 0 || inventory.slots[index].HighlightTimer > 0) return;
inventory.slots[index].ShowBorderHighlight(color, fadeInDuration, fadeOutDuration, scaleUpAmount);
}
#endregion
} }
} }
@@ -4,7 +4,7 @@ namespace Barotrauma
{ {
class TutorialMode : GameMode class TutorialMode : GameMode
{ {
public Tutorial tutorial; public Tutorial Tutorial;
public static void StartTutorial(Tutorial tutorial) public static void StartTutorial(Tutorial tutorial)
{ {
@@ -19,18 +19,20 @@ namespace Barotrauma
public override void Start() public override void Start()
{ {
base.Start(); base.Start();
tutorial.Start(); GameMain.GameSession.CrewManager = new CrewManager(true);
Tutorial.Start();
} }
public override void AddToGUIUpdateList() public override void AddToGUIUpdateList()
{ {
tutorial.AddToGUIUpdateList(); base.AddToGUIUpdateList();
Tutorial.AddToGUIUpdateList();
} }
public override void Update(float deltaTime) public override void Update(float deltaTime)
{ {
base.Update(deltaTime); base.Update(deltaTime);
tutorial.Update(deltaTime); Tutorial.Update(deltaTime);
} }
} }
} }
@@ -100,6 +100,7 @@ namespace Barotrauma
limbSlotIcons.Add(InvSlotType.Head, new Sprite("Content/UI/IconAtlas.png", new Rectangle(896 + margin, 128 + margin, 128 - margin * 2, 128 - margin * 2))); limbSlotIcons.Add(InvSlotType.Head, new Sprite("Content/UI/IconAtlas.png", new Rectangle(896 + margin, 128 + margin, 128 - margin * 2, 128 - margin * 2)));
limbSlotIcons.Add(InvSlotType.LeftHand, new Sprite("Content/UI/IconAtlas.png", new Rectangle(640 + margin, 383 + margin, 128 - margin * 2, 128 - margin * 2))); limbSlotIcons.Add(InvSlotType.LeftHand, new Sprite("Content/UI/IconAtlas.png", new Rectangle(640 + margin, 383 + margin, 128 - margin * 2, 128 - margin * 2)));
limbSlotIcons.Add(InvSlotType.RightHand, new Sprite("Content/UI/IconAtlas.png", new Rectangle(768 + margin, 383 + margin, 128 - margin * 2, 128 - margin * 2))); limbSlotIcons.Add(InvSlotType.RightHand, new Sprite("Content/UI/IconAtlas.png", new Rectangle(768 + margin, 383 + margin, 128 - margin * 2, 128 - margin * 2)));
limbSlotIcons.Add(InvSlotType.OuterClothes, new Sprite("Content/UI/IconAtlas.png", new Rectangle(768 + margin, 896 + margin, 128 - margin * 2, 128 - margin * 2)));
} }
SlotPositions = new Vector2[SlotTypes.Length]; SlotPositions = new Vector2[SlotTypes.Length];
CurrentLayout = Layout.Default; CurrentLayout = Layout.Default;
@@ -23,7 +23,7 @@ namespace Barotrauma.Items.Components
{ {
if (light.LightSprite != null && (item.body == null || item.body.Enabled) && lightBrightness > 0.0f) if (light.LightSprite != null && (item.body == null || item.body.Enabled) && lightBrightness > 0.0f)
{ {
light.LightSprite.Draw(spriteBatch, new Vector2(item.DrawPosition.X, -item.DrawPosition.Y), lightColor * lightBrightness, 0.0f, 1.0f, Microsoft.Xna.Framework.Graphics.SpriteEffects.None, item.SpriteDepth - 0.0001f); light.LightSprite.Draw(spriteBatch, new Vector2(item.DrawPosition.X, -item.DrawPosition.Y), lightColor * lightBrightness, 0.0f, item.Scale, SpriteEffects.None, item.SpriteDepth - 0.0001f);
} }
} }
@@ -9,6 +9,10 @@ namespace Barotrauma.Items.Components
{ {
partial class Deconstructor : Powered, IServerSerializable, IClientSerializable partial class Deconstructor : Powered, IServerSerializable, IClientSerializable
{ {
public GUIButton ActivateButton
{
get { return activateButton; }
}
private GUIButton activateButton; private GUIButton activateButton;
private GUIComponent inputInventoryHolder, outputInventoryHolder; private GUIComponent inputInventoryHolder, outputInventoryHolder;
private GUICustomComponent inputInventoryOverlay; private GUICustomComponent inputInventoryOverlay;
@@ -44,7 +48,6 @@ namespace Barotrauma.Items.Components
Visible = false, Visible = false,
CanBeFocused = false CanBeFocused = false
}; };
outputInventoryHolder = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.3f), paddedFrame.RectTransform), style: null); outputInventoryHolder = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.3f), paddedFrame.RectTransform), style: null);
} }
@@ -71,7 +74,7 @@ namespace Barotrauma.Items.Components
public override void UpdateHUD(Character character, float deltaTime, Camera cam) public override void UpdateHUD(Character character, float deltaTime, Camera cam)
{ {
inSufficientPowerWarning.Visible = powerConsumption > 0 && voltage < minVoltage; inSufficientPowerWarning.Visible = powerConsumption > 0 && voltage < minVoltage;
activateButton.Enabled = !inSufficientPowerWarning.Visible; //activateButton.Enabled = !inSufficientPowerWarning.Visible;
} }
private bool ToggleActive(GUIButton button, object obj) private bool ToggleActive(GUIButton button, object obj)
@@ -15,6 +15,10 @@ namespace Barotrauma.Items.Components
private GUIFrame selectedItemFrame; private GUIFrame selectedItemFrame;
public GUIButton ActivateButton
{
get { return activateButton; }
}
private GUIButton activateButton; private GUIButton activateButton;
private GUITextBox itemFilterBox; private GUITextBox itemFilterBox;
@@ -22,6 +26,10 @@ namespace Barotrauma.Items.Components
private GUIComponent inputInventoryHolder, outputInventoryHolder; private GUIComponent inputInventoryHolder, outputInventoryHolder;
private GUICustomComponent inputInventoryOverlay, outputInventoryOverlay; private GUICustomComponent inputInventoryOverlay, outputInventoryOverlay;
public FabricationRecipe SelectedItem
{
get { return selectedItem; }
}
private FabricationRecipe selectedItem; private FabricationRecipe selectedItem;
private GUIComponent inSufficientPowerWarning; private GUIComponent inSufficientPowerWarning;
@@ -73,7 +81,31 @@ namespace Barotrauma.Items.Components
{ {
CanBeFocused = false CanBeFocused = false
}; };
CreateRecipes();
activateButton = new GUIButton(new RectTransform(new Vector2(0.8f, 0.07f), paddedFrame.RectTransform),
TextManager.Get("FabricatorCreate"), style: "GUIButtonLarge")
{
OnClicked = StartButtonClicked,
UserData = selectedItem,
Enabled = false
};
inSufficientPowerWarning = new GUITextBlock(new RectTransform(Vector2.One, activateButton.RectTransform), TextManager.Get("FabricatorNoPower"),
textColor: Color.Orange, textAlignment: Alignment.Center, color: Color.Black, style: "OuterGlow")
{
HoverColor = Color.Black,
IgnoreLayoutGroups = true,
Visible = false,
CanBeFocused = false
};
}
partial void CreateRecipes()
{
itemList.Content.RectTransform.ClearChildren();
foreach (FabricationRecipe fi in fabricationRecipes) foreach (FabricationRecipe fi in fabricationRecipes)
{ {
GUIFrame frame = new GUIFrame(new RectTransform(new Point(itemList.Rect.Width, 30), itemList.Content.RectTransform), style: null) GUIFrame frame = new GUIFrame(new RectTransform(new Point(itemList.Rect.Width, 30), itemList.Content.RectTransform), style: null)
@@ -101,23 +133,6 @@ namespace Barotrauma.Items.Components
}; };
} }
} }
activateButton = new GUIButton(new RectTransform(new Vector2(0.8f, 0.07f), paddedFrame.RectTransform),
TextManager.Get("FabricatorCreate"), style: "GUIButtonLarge")
{
OnClicked = StartButtonClicked,
UserData = selectedItem,
Enabled = false
};
inSufficientPowerWarning = new GUITextBlock(new RectTransform(Vector2.One, activateButton.RectTransform), TextManager.Get("FabricatorNoPower"),
textColor: Color.Orange, textAlignment: Alignment.Center, color: Color.Black, style: "OuterGlow")
{
HoverColor = Color.Black,
IgnoreLayoutGroups = true,
Visible = false,
CanBeFocused = false
};
} }
partial void OnItemLoadedProjSpecific() partial void OnItemLoadedProjSpecific()
@@ -241,6 +256,7 @@ namespace Barotrauma.Items.Components
} }
} }
} }
private void DrawOutputOverLay(SpriteBatch spriteBatch, GUICustomComponent overlayComponent) private void DrawOutputOverLay(SpriteBatch spriteBatch, GUICustomComponent overlayComponent)
{ {
overlayComponent.RectTransform.SetAsLastChild(); overlayComponent.RectTransform.SetAsLastChild();
@@ -363,6 +379,29 @@ namespace Barotrauma.Items.Components
return true; return true;
} }
public void HighlightRecipe(string identifier, Color color)
{
foreach (GUIComponent child in itemList.Content.Children)
{
FabricationRecipe recipe = child.UserData as FabricationRecipe;
if (recipe?.DisplayName == null) { continue; }
if (recipe.TargetItem.Identifier == identifier)
{
if (child.FlashTimer > 0.0f) return;
child.Flash(color, 1.5f, false);
for (int i = 0; i < child.CountChildren; i++)
{
var grandChild = child.GetChild(i);
if (grandChild is GUITextBlock) continue;
grandChild.Flash(color, 1.5f, false);
}
return;
}
}
}
private bool StartButtonClicked(GUIButton button, object obj) private bool StartButtonClicked(GUIButton button, object obj)
{ {
if (selectedItem == null) { return false; } if (selectedItem == null) { return false; }
@@ -10,6 +10,10 @@ namespace Barotrauma.Items.Components
{ {
partial class Pump : Powered, IServerSerializable, IClientSerializable partial class Pump : Powered, IServerSerializable, IClientSerializable
{ {
public GUIScrollBar IsActiveSlider
{
get { return isActiveSlider; }
}
private GUIScrollBar isActiveSlider; private GUIScrollBar isActiveSlider;
private GUIScrollBar pumpSpeedSlider; private GUIScrollBar pumpSpeedSlider;
private GUITickBox powerIndicator; private GUITickBox powerIndicator;
@@ -49,7 +53,6 @@ namespace Barotrauma.Items.Components
}; };
var sliderHandle = isActiveSlider.GetChild<GUIButton>(); var sliderHandle = isActiveSlider.GetChild<GUIButton>();
sliderHandle.RectTransform.NonScaledSize = new Point(84, sliderHandle.Rect.Height); sliderHandle.RectTransform.NonScaledSize = new Point(84, sliderHandle.Rect.Height);
isActiveSlider.OnMoved = (GUIScrollBar scrollBar, float barScroll) => isActiveSlider.OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
{ {
bool active = scrollBar.BarScroll < 0.5f; bool active = scrollBar.BarScroll < 0.5f;
@@ -11,7 +11,16 @@ namespace Barotrauma.Items.Components
{ {
partial class Reactor : Powered, IServerSerializable, IClientSerializable partial class Reactor : Powered, IServerSerializable, IClientSerializable
{ {
public GUIScrollBar AutoTempSlider
{
get { return autoTempSlider; }
}
private GUIScrollBar autoTempSlider; private GUIScrollBar autoTempSlider;
public GUIScrollBar OnOffSwitch
{
get { return onOffSwitch; }
}
private GUIScrollBar onOffSwitch; private GUIScrollBar onOffSwitch;
private const int GraphSize = 25; private const int GraphSize = 25;
@@ -27,7 +36,16 @@ namespace Barotrauma.Items.Components
private Sprite graphLine; private Sprite graphLine;
public GUIScrollBar FissionRateScrollBar
{
get { return fissionRateScrollBar; }
}
private GUIScrollBar fissionRateScrollBar; private GUIScrollBar fissionRateScrollBar;
public GUIScrollBar TurbineOutputScrollBar
{
get { return turbineOutputScrollBar; }
}
private GUIScrollBar turbineOutputScrollBar; private GUIScrollBar turbineOutputScrollBar;
private float[] outputGraph = new float[GraphSize]; private float[] outputGraph = new float[GraphSize];
@@ -20,6 +20,10 @@ namespace Barotrauma.Items.Components
private bool unsentChanges; private bool unsentChanges;
private float networkUpdateTimer; private float networkUpdateTimer;
public GUITickBox ActiveTickBox
{
get { return activeTickBox; }
}
private GUITickBox activeTickBox, passiveTickBox; private GUITickBox activeTickBox, passiveTickBox;
private GUITextBlock signalWarningText; private GUITextBlock signalWarningText;
@@ -10,6 +10,10 @@ namespace Barotrauma.Items.Components
{ {
partial class Repairable : ItemComponent, IDrawableComponent partial class Repairable : ItemComponent, IDrawableComponent
{ {
public GUIButton RepairButton
{
get { return repairButton; }
}
private GUIButton repairButton; private GUIButton repairButton;
private GUIProgressBar progressBar; private GUIProgressBar progressBar;
@@ -18,6 +18,14 @@ namespace Barotrauma.Items.Components
private static Wire draggingConnected; private static Wire draggingConnected;
private Color flashColor;
private float flashDuration = 1.5f;
public float FlashTimer
{
get { return flashTimer; }
}
private float flashTimer;
public static void DrawConnections(SpriteBatch spriteBatch, ConnectionPanel panel, Character character) public static void DrawConnections(SpriteBatch spriteBatch, ConnectionPanel panel, Character character)
{ {
Rectangle panelRect = panel.GuiFrame.Rect; Rectangle panelRect = panel.GuiFrame.Rect;
@@ -174,14 +182,38 @@ namespace Barotrauma.Items.Components
} }
} }
} }
if (flashTimer > 0.0f)
{
//the number of flashes depends on the duration, 1 flash per 1 full second
int flashCycleCount = (int)Math.Max(flashDuration, 1);
float flashCycleDuration = flashDuration / flashCycleCount;
//MathHelper.Pi * 0.8f -> the curve goes from 144 deg to 0,
//i.e. quickly bumps up from almost full brightness to full and then fades out
connectionSpriteHighlight.Draw(spriteBatch, position, flashColor * (float)Math.Sin(flashTimer % flashCycleDuration / flashCycleDuration * MathHelper.Pi * 0.8f));
}
if (Wires.Any(w => w != null && w != draggingConnected)) if (Wires.Any(w => w != null && w != draggingConnected))
{ {
int screwIndex = (int)Math.Floor(position.Y / 30.0f) % screwSprites.Count; int screwIndex = (int)Math.Floor(position.Y / 30.0f) % screwSprites.Count;
screwSprites[screwIndex].Draw(spriteBatch, position); screwSprites[screwIndex].Draw(spriteBatch, position);
} }
} }
public void Flash(Color? color = null, float flashDuration = 1.5f)
{
flashTimer = flashDuration;
this.flashDuration = flashDuration;
flashColor = (color == null) ? Color.Red : (Color)color;
}
public void UpdateFlashTimer(float deltaTime)
{
if (flashTimer <= 0) return;
flashTimer -= deltaTime;
}
private static void DrawWire(SpriteBatch spriteBatch, Wire wire, Item item, Vector2 end, Vector2 start, bool mouseIn, Wire equippedWire, ConnectionPanel panel, string label) private static void DrawWire(SpriteBatch spriteBatch, Wire wire, Item item, Vector2 end, Vector2 start, bool mouseIn, Wire equippedWire, ConnectionPanel panel, string label)
{ {
if (draggingConnected == wire) if (draggingConnected == wire)
@@ -92,6 +92,25 @@ namespace Barotrauma.Items.Components
} }
} }
public void HighlightElement(int index, Color color, float duration, float pulsateAmount = 0.0f)
{
if (index < 0 || index >= uiElements.Count) { return; }
uiElements[index].Flash(color, duration);
if (pulsateAmount > 0.0f)
{
if (uiElements[index] is GUIButton button)
{
button.Frame.Pulsate(Vector2.One, Vector2.One * (1.0f + pulsateAmount), duration);
button.Frame.RectTransform.SetPosition(Anchor.Center);
}
else
{
uiElements[index].Pulsate(Vector2.One, Vector2.One * (1.0f + pulsateAmount), duration);
}
}
}
partial void UpdateLabelsProjSpecific() partial void UpdateLabelsProjSpecific()
{ {
for (int i = 0; i < labels.Length && i < uiElements.Count; i++) for (int i = 0; i < labels.Length && i < uiElements.Count; i++)
@@ -26,6 +26,7 @@ namespace Barotrauma
public Color Color; public Color Color;
public Color HighlightColor; public Color HighlightColor;
public float HighlightScaleUpAmount;
private CoroutineHandle highlightCoroutine; private CoroutineHandle highlightCoroutine;
public float HighlightTimer; public float HighlightTimer;
@@ -80,7 +81,7 @@ namespace Barotrauma
return rect.Contains(PlayerInput.MousePosition); return rect.Contains(PlayerInput.MousePosition);
} }
public void ShowBorderHighlight(Color color, float fadeInDuration, float fadeOutDuration) public void ShowBorderHighlight(Color color, float fadeInDuration, float fadeOutDuration, float scaleUpAmount = 0.5f)
{ {
if (highlightCoroutine != null) if (highlightCoroutine != null)
{ {
@@ -88,6 +89,7 @@ namespace Barotrauma
highlightCoroutine = null; highlightCoroutine = null;
} }
HighlightScaleUpAmount = scaleUpAmount;
highlightCoroutine = CoroutineManager.StartCoroutine(UpdateBorderHighlight(color, fadeInDuration, fadeOutDuration)); highlightCoroutine = CoroutineManager.StartCoroutine(UpdateBorderHighlight(color, fadeInDuration, fadeOutDuration));
} }
@@ -800,8 +802,7 @@ namespace Barotrauma
if (slot.HighlightColor.A > 0) if (slot.HighlightColor.A > 0)
{ {
float scaleUpAmount = 0.5f; float inflateAmount = (slot.HighlightColor.A / 255.0f) * slot.HighlightScaleUpAmount * 0.5f;
float inflateAmount = (slot.HighlightColor.A / 255.0f) * scaleUpAmount * 0.5f;
rect.Inflate(rect.Width * inflateAmount, rect.Height * inflateAmount); rect.Inflate(rect.Width * inflateAmount, rect.Height * inflateAmount);
} }
@@ -184,7 +184,7 @@ namespace Barotrauma
if (!Visible || (!editing && hiddenInGame)) return; if (!Visible || (!editing && hiddenInGame)) return;
if (editing && !ShowItems) return; if (editing && !ShowItems) return;
Color color = isHighlighted && !GUI.DisableItemHighlights && Screen.Selected != GameMain.GameScreen ? Color.Orange : GetSpriteColor(); Color color = IsHighlighted && !GUI.DisableItemHighlights && Screen.Selected != GameMain.GameScreen ? Color.Orange : GetSpriteColor();
//if (IsSelected && editing) color = Color.Lerp(color, Color.Gold, 0.5f); //if (IsSelected && editing) color = Color.Lerp(color, Color.Gold, 0.5f);
BrokenItemSprite fadeInBrokenSprite = null; BrokenItemSprite fadeInBrokenSprite = null;
@@ -326,843 +326,6 @@ namespace Barotrauma
Color.Green, width: 2); Color.Green, width: 2);
} }
} }
foreach (MapEntity e in linkedTo)
{
if (e is Hull)
{
Hull linkedHull = (Hull)e;
Rectangle connectedHullRect = e.Submarine == null ?
linkedHull.rect :
new Rectangle(
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
//center of the hull
Rectangle currentHullRect = Submarine == null ?
WorldRect :
new Rectangle(
(int)(Submarine.DrawPosition.X + WorldPosition.X),
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
WorldRect.Width, WorldRect.Height);
GUI.DrawLine(spriteBatch,
new Vector2(currentHullRect.X, -currentHullRect.Y),
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
Color.Green, width: 2);
}
}
foreach (MapEntity e in linkedTo)
{
if (e is Hull)
{
Hull linkedHull = (Hull)e;
Rectangle connectedHullRect = e.Submarine == null ?
linkedHull.rect :
new Rectangle(
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
//center of the hull
Rectangle currentHullRect = Submarine == null ?
WorldRect :
new Rectangle(
(int)(Submarine.DrawPosition.X + WorldPosition.X),
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
WorldRect.Width, WorldRect.Height);
GUI.DrawLine(spriteBatch,
new Vector2(currentHullRect.X, -currentHullRect.Y),
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
Color.Green, width: 2);
}
}
foreach (MapEntity e in linkedTo)
{
if (e is Hull)
{
Hull linkedHull = (Hull)e;
Rectangle connectedHullRect = e.Submarine == null ?
linkedHull.rect :
new Rectangle(
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
//center of the hull
Rectangle currentHullRect = Submarine == null ?
WorldRect :
new Rectangle(
(int)(Submarine.DrawPosition.X + WorldPosition.X),
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
WorldRect.Width, WorldRect.Height);
GUI.DrawLine(spriteBatch,
new Vector2(currentHullRect.X, -currentHullRect.Y),
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
Color.Green, width: 2);
}
}
foreach (MapEntity e in linkedTo)
{
if (e is Hull)
{
Hull linkedHull = (Hull)e;
Rectangle connectedHullRect = e.Submarine == null ?
linkedHull.rect :
new Rectangle(
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
//center of the hull
Rectangle currentHullRect = Submarine == null ?
WorldRect :
new Rectangle(
(int)(Submarine.DrawPosition.X + WorldPosition.X),
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
WorldRect.Width, WorldRect.Height);
GUI.DrawLine(spriteBatch,
new Vector2(currentHullRect.X, -currentHullRect.Y),
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
Color.Green, width: 2);
}
}
foreach (MapEntity e in linkedTo)
{
if (e is Hull)
{
Hull linkedHull = (Hull)e;
Rectangle connectedHullRect = e.Submarine == null ?
linkedHull.rect :
new Rectangle(
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
//center of the hull
Rectangle currentHullRect = Submarine == null ?
WorldRect :
new Rectangle(
(int)(Submarine.DrawPosition.X + WorldPosition.X),
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
WorldRect.Width, WorldRect.Height);
GUI.DrawLine(spriteBatch,
new Vector2(currentHullRect.X, -currentHullRect.Y),
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
Color.Green, width: 2);
}
}
foreach (MapEntity e in linkedTo)
{
if (e is Hull)
{
Hull linkedHull = (Hull)e;
Rectangle connectedHullRect = e.Submarine == null ?
linkedHull.rect :
new Rectangle(
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
//center of the hull
Rectangle currentHullRect = Submarine == null ?
WorldRect :
new Rectangle(
(int)(Submarine.DrawPosition.X + WorldPosition.X),
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
WorldRect.Width, WorldRect.Height);
GUI.DrawLine(spriteBatch,
new Vector2(currentHullRect.X, -currentHullRect.Y),
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
Color.Green, width: 2);
}
}
foreach (MapEntity e in linkedTo)
{
if (e is Hull)
{
Hull linkedHull = (Hull)e;
Rectangle connectedHullRect = e.Submarine == null ?
linkedHull.rect :
new Rectangle(
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
//center of the hull
Rectangle currentHullRect = Submarine == null ?
WorldRect :
new Rectangle(
(int)(Submarine.DrawPosition.X + WorldPosition.X),
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
WorldRect.Width, WorldRect.Height);
GUI.DrawLine(spriteBatch,
new Vector2(currentHullRect.X, -currentHullRect.Y),
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
Color.Green, width: 2);
}
}
foreach (MapEntity e in linkedTo)
{
if (e is Hull)
{
Hull linkedHull = (Hull)e;
Rectangle connectedHullRect = e.Submarine == null ?
linkedHull.rect :
new Rectangle(
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
//center of the hull
Rectangle currentHullRect = Submarine == null ?
WorldRect :
new Rectangle(
(int)(Submarine.DrawPosition.X + WorldPosition.X),
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
WorldRect.Width, WorldRect.Height);
GUI.DrawLine(spriteBatch,
new Vector2(currentHullRect.X, -currentHullRect.Y),
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
Color.Green, width: 2);
}
}
foreach (MapEntity e in linkedTo)
{
if (e is Hull)
{
Hull linkedHull = (Hull)e;
Rectangle connectedHullRect = e.Submarine == null ?
linkedHull.rect :
new Rectangle(
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
//center of the hull
Rectangle currentHullRect = Submarine == null ?
WorldRect :
new Rectangle(
(int)(Submarine.DrawPosition.X + WorldPosition.X),
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
WorldRect.Width, WorldRect.Height);
GUI.DrawLine(spriteBatch,
new Vector2(currentHullRect.X, -currentHullRect.Y),
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
Color.Green, width: 2);
}
}
foreach (MapEntity e in linkedTo)
{
if (e is Hull)
{
Hull linkedHull = (Hull)e;
Rectangle connectedHullRect = e.Submarine == null ?
linkedHull.rect :
new Rectangle(
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
//center of the hull
Rectangle currentHullRect = Submarine == null ?
WorldRect :
new Rectangle(
(int)(Submarine.DrawPosition.X + WorldPosition.X),
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
WorldRect.Width, WorldRect.Height);
GUI.DrawLine(spriteBatch,
new Vector2(currentHullRect.X, -currentHullRect.Y),
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
Color.Green, width: 2);
}
}
foreach (MapEntity e in linkedTo)
{
if (e is Hull)
{
Hull linkedHull = (Hull)e;
Rectangle connectedHullRect = e.Submarine == null ?
linkedHull.rect :
new Rectangle(
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
//center of the hull
Rectangle currentHullRect = Submarine == null ?
WorldRect :
new Rectangle(
(int)(Submarine.DrawPosition.X + WorldPosition.X),
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
WorldRect.Width, WorldRect.Height);
GUI.DrawLine(spriteBatch,
new Vector2(currentHullRect.X, -currentHullRect.Y),
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
Color.Green, width: 2);
}
}
foreach (MapEntity e in linkedTo)
{
if (e is Hull)
{
Hull linkedHull = (Hull)e;
Rectangle connectedHullRect = e.Submarine == null ?
linkedHull.rect :
new Rectangle(
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
//center of the hull
Rectangle currentHullRect = Submarine == null ?
WorldRect :
new Rectangle(
(int)(Submarine.DrawPosition.X + WorldPosition.X),
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
WorldRect.Width, WorldRect.Height);
GUI.DrawLine(spriteBatch,
new Vector2(currentHullRect.X, -currentHullRect.Y),
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
Color.Green, width: 2);
}
}
foreach (MapEntity e in linkedTo)
{
if (e is Hull)
{
Hull linkedHull = (Hull)e;
Rectangle connectedHullRect = e.Submarine == null ?
linkedHull.rect :
new Rectangle(
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
//center of the hull
Rectangle currentHullRect = Submarine == null ?
WorldRect :
new Rectangle(
(int)(Submarine.DrawPosition.X + WorldPosition.X),
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
WorldRect.Width, WorldRect.Height);
GUI.DrawLine(spriteBatch,
new Vector2(currentHullRect.X, -currentHullRect.Y),
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
Color.Green, width: 2);
}
}
foreach (MapEntity e in linkedTo)
{
if (e is Hull)
{
Hull linkedHull = (Hull)e;
Rectangle connectedHullRect = e.Submarine == null ?
linkedHull.rect :
new Rectangle(
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
//center of the hull
Rectangle currentHullRect = Submarine == null ?
WorldRect :
new Rectangle(
(int)(Submarine.DrawPosition.X + WorldPosition.X),
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
WorldRect.Width, WorldRect.Height);
GUI.DrawLine(spriteBatch,
new Vector2(currentHullRect.X, -currentHullRect.Y),
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
Color.Green, width: 2);
}
}
foreach (MapEntity e in linkedTo)
{
if (e is Hull)
{
Hull linkedHull = (Hull)e;
Rectangle connectedHullRect = e.Submarine == null ?
linkedHull.rect :
new Rectangle(
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
//center of the hull
Rectangle currentHullRect = Submarine == null ?
WorldRect :
new Rectangle(
(int)(Submarine.DrawPosition.X + WorldPosition.X),
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
WorldRect.Width, WorldRect.Height);
GUI.DrawLine(spriteBatch,
new Vector2(currentHullRect.X, -currentHullRect.Y),
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
Color.Green, width: 2);
}
}
foreach (MapEntity e in linkedTo)
{
if (e is Hull)
{
Hull linkedHull = (Hull)e;
Rectangle connectedHullRect = e.Submarine == null ?
linkedHull.rect :
new Rectangle(
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
//center of the hull
Rectangle currentHullRect = Submarine == null ?
WorldRect :
new Rectangle(
(int)(Submarine.DrawPosition.X + WorldPosition.X),
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
WorldRect.Width, WorldRect.Height);
GUI.DrawLine(spriteBatch,
new Vector2(currentHullRect.X, -currentHullRect.Y),
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
Color.Green, width: 2);
}
}
foreach (MapEntity e in linkedTo)
{
if (e is Hull)
{
Hull linkedHull = (Hull)e;
Rectangle connectedHullRect = e.Submarine == null ?
linkedHull.rect :
new Rectangle(
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
//center of the hull
Rectangle currentHullRect = Submarine == null ?
WorldRect :
new Rectangle(
(int)(Submarine.DrawPosition.X + WorldPosition.X),
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
WorldRect.Width, WorldRect.Height);
GUI.DrawLine(spriteBatch,
new Vector2(currentHullRect.X, -currentHullRect.Y),
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
Color.Green, width: 2);
}
}
foreach (MapEntity e in linkedTo)
{
if (e is Hull)
{
Hull linkedHull = (Hull)e;
Rectangle connectedHullRect = e.Submarine == null ?
linkedHull.rect :
new Rectangle(
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
//center of the hull
Rectangle currentHullRect = Submarine == null ?
WorldRect :
new Rectangle(
(int)(Submarine.DrawPosition.X + WorldPosition.X),
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
WorldRect.Width, WorldRect.Height);
GUI.DrawLine(spriteBatch,
new Vector2(currentHullRect.X, -currentHullRect.Y),
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
Color.Green, width: 2);
}
}
foreach (MapEntity e in linkedTo)
{
if (e is Hull)
{
Hull linkedHull = (Hull)e;
Rectangle connectedHullRect = e.Submarine == null ?
linkedHull.rect :
new Rectangle(
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
//center of the hull
Rectangle currentHullRect = Submarine == null ?
WorldRect :
new Rectangle(
(int)(Submarine.DrawPosition.X + WorldPosition.X),
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
WorldRect.Width, WorldRect.Height);
GUI.DrawLine(spriteBatch,
new Vector2(currentHullRect.X, -currentHullRect.Y),
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
Color.Green, width: 2);
}
}
foreach (MapEntity e in linkedTo)
{
if (e is Hull)
{
Hull linkedHull = (Hull)e;
Rectangle connectedHullRect = e.Submarine == null ?
linkedHull.rect :
new Rectangle(
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
//center of the hull
Rectangle currentHullRect = Submarine == null ?
WorldRect :
new Rectangle(
(int)(Submarine.DrawPosition.X + WorldPosition.X),
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
WorldRect.Width, WorldRect.Height);
GUI.DrawLine(spriteBatch,
new Vector2(currentHullRect.X, -currentHullRect.Y),
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
Color.Green, width: 2);
}
}
foreach (MapEntity e in linkedTo)
{
if (e is Hull)
{
Hull linkedHull = (Hull)e;
Rectangle connectedHullRect = e.Submarine == null ?
linkedHull.rect :
new Rectangle(
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
//center of the hull
Rectangle currentHullRect = Submarine == null ?
WorldRect :
new Rectangle(
(int)(Submarine.DrawPosition.X + WorldPosition.X),
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
WorldRect.Width, WorldRect.Height);
GUI.DrawLine(spriteBatch,
new Vector2(currentHullRect.X, -currentHullRect.Y),
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
Color.Green, width: 2);
}
}
foreach (MapEntity e in linkedTo)
{
if (e is Hull)
{
Hull linkedHull = (Hull)e;
Rectangle connectedHullRect = e.Submarine == null ?
linkedHull.rect :
new Rectangle(
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
//center of the hull
Rectangle currentHullRect = Submarine == null ?
WorldRect :
new Rectangle(
(int)(Submarine.DrawPosition.X + WorldPosition.X),
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
WorldRect.Width, WorldRect.Height);
GUI.DrawLine(spriteBatch,
new Vector2(currentHullRect.X, -currentHullRect.Y),
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
Color.Green, width: 2);
}
}
foreach (MapEntity e in linkedTo)
{
if (e is Hull)
{
Hull linkedHull = (Hull)e;
Rectangle connectedHullRect = e.Submarine == null ?
linkedHull.rect :
new Rectangle(
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
//center of the hull
Rectangle currentHullRect = Submarine == null ?
WorldRect :
new Rectangle(
(int)(Submarine.DrawPosition.X + WorldPosition.X),
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
WorldRect.Width, WorldRect.Height);
GUI.DrawLine(spriteBatch,
new Vector2(currentHullRect.X, -currentHullRect.Y),
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
Color.Green, width: 2);
}
}
foreach (MapEntity e in linkedTo)
{
if (e is Hull)
{
Hull linkedHull = (Hull)e;
Rectangle connectedHullRect = e.Submarine == null ?
linkedHull.rect :
new Rectangle(
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
//center of the hull
Rectangle currentHullRect = Submarine == null ?
WorldRect :
new Rectangle(
(int)(Submarine.DrawPosition.X + WorldPosition.X),
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
WorldRect.Width, WorldRect.Height);
GUI.DrawLine(spriteBatch,
new Vector2(currentHullRect.X, -currentHullRect.Y),
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
Color.Green, width: 2);
}
}
foreach (MapEntity e in linkedTo)
{
if (e is Hull)
{
Hull linkedHull = (Hull)e;
Rectangle connectedHullRect = e.Submarine == null ?
linkedHull.rect :
new Rectangle(
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
//center of the hull
Rectangle currentHullRect = Submarine == null ?
WorldRect :
new Rectangle(
(int)(Submarine.DrawPosition.X + WorldPosition.X),
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
WorldRect.Width, WorldRect.Height);
GUI.DrawLine(spriteBatch,
new Vector2(currentHullRect.X, -currentHullRect.Y),
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
Color.Green, width: 2);
}
}
foreach (MapEntity e in linkedTo)
{
if (e is Hull)
{
Hull linkedHull = (Hull)e;
Rectangle connectedHullRect = e.Submarine == null ?
linkedHull.rect :
new Rectangle(
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
//center of the hull
Rectangle currentHullRect = Submarine == null ?
WorldRect :
new Rectangle(
(int)(Submarine.DrawPosition.X + WorldPosition.X),
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
WorldRect.Width, WorldRect.Height);
GUI.DrawLine(spriteBatch,
new Vector2(currentHullRect.X, -currentHullRect.Y),
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
Color.Green, width: 2);
}
}
foreach (MapEntity e in linkedTo)
{
if (e is Hull)
{
Hull linkedHull = (Hull)e;
Rectangle connectedHullRect = e.Submarine == null ?
linkedHull.rect :
new Rectangle(
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
//center of the hull
Rectangle currentHullRect = Submarine == null ?
WorldRect :
new Rectangle(
(int)(Submarine.DrawPosition.X + WorldPosition.X),
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
WorldRect.Width, WorldRect.Height);
GUI.DrawLine(spriteBatch,
new Vector2(currentHullRect.X, -currentHullRect.Y),
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
Color.Green, width: 2);
}
}
foreach (MapEntity e in linkedTo)
{
if (e is Hull)
{
Hull linkedHull = (Hull)e;
Rectangle connectedHullRect = e.Submarine == null ?
linkedHull.rect :
new Rectangle(
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
//center of the hull
Rectangle currentHullRect = Submarine == null ?
WorldRect :
new Rectangle(
(int)(Submarine.DrawPosition.X + WorldPosition.X),
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
WorldRect.Width, WorldRect.Height);
GUI.DrawLine(spriteBatch,
new Vector2(currentHullRect.X, -currentHullRect.Y),
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
Color.Green, width: 2);
}
}
foreach (MapEntity e in linkedTo)
{
if (e is Hull)
{
Hull linkedHull = (Hull)e;
Rectangle connectedHullRect = e.Submarine == null ?
linkedHull.rect :
new Rectangle(
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
//center of the hull
Rectangle currentHullRect = Submarine == null ?
WorldRect :
new Rectangle(
(int)(Submarine.DrawPosition.X + WorldPosition.X),
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
WorldRect.Width, WorldRect.Height);
GUI.DrawLine(spriteBatch,
new Vector2(currentHullRect.X, -currentHullRect.Y),
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
Color.Green, width: 2);
}
}
foreach (MapEntity e in linkedTo)
{
if (e is Hull)
{
Hull linkedHull = (Hull)e;
Rectangle connectedHullRect = e.Submarine == null ?
linkedHull.rect :
new Rectangle(
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
//center of the hull
Rectangle currentHullRect = Submarine == null ?
WorldRect :
new Rectangle(
(int)(Submarine.DrawPosition.X + WorldPosition.X),
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
WorldRect.Width, WorldRect.Height);
GUI.DrawLine(spriteBatch,
new Vector2(currentHullRect.X, -currentHullRect.Y),
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
Color.Green, width: 2);
}
}
foreach (MapEntity e in linkedTo)
{
if (e is Hull)
{
Hull linkedHull = (Hull)e;
Rectangle connectedHullRect = e.Submarine == null ?
linkedHull.rect :
new Rectangle(
(int)(Submarine.DrawPosition.X + linkedHull.WorldPosition.X),
(int)(Submarine.DrawPosition.Y + linkedHull.WorldPosition.Y),
linkedHull.WorldRect.Width, linkedHull.WorldRect.Height);
//center of the hull
Rectangle currentHullRect = Submarine == null ?
WorldRect :
new Rectangle(
(int)(Submarine.DrawPosition.X + WorldPosition.X),
(int)(Submarine.DrawPosition.Y + WorldPosition.Y),
WorldRect.Width, WorldRect.Height);
GUI.DrawLine(spriteBatch,
new Vector2(currentHullRect.X, -currentHullRect.Y),
new Vector2(connectedHullRect.X, -connectedHullRect.Y),
Color.Green, width: 2);
}
}
} }
public static void UpdateVertices(GraphicsDevice graphicsDevice, Camera cam, WaterRenderer renderer) public static void UpdateVertices(GraphicsDevice graphicsDevice, Camera cam, WaterRenderer renderer)
@@ -42,7 +42,21 @@ namespace Barotrauma
MathHelper.Clamp(value.Y, 0.01f, 10)); MathHelper.Clamp(value.Y, 0.01f, 10));
} }
} }
private string specialTag;
[Editable, Serialize("", true)]
public string SpecialTag
{
get { return specialTag; }
set { specialTag = value; }
}
// Only for testing in the debug build. Not saved.
#if DEBUG
[Editable, Serialize(true, false)]
#endif
public bool DrawTiled { get; protected set; } = true;
protected Vector2 textureOffset = Vector2.Zero; protected Vector2 textureOffset = Vector2.Zero;
[Editable(MinValueFloat = -1000f, MaxValueFloat = 1000f, ValueStep = 10f), Serialize("0.0, 0.0", true)] [Editable(MinValueFloat = -1000f, MaxValueFloat = 1000f, ValueStep = 10f), Serialize("0.0, 0.0", true)]
public Vector2 TextureOffset public Vector2 TextureOffset
@@ -187,7 +201,7 @@ namespace Barotrauma
if (HasBody && !ShowWalls) return; if (HasBody && !ShowWalls) return;
} }
Color color = isHighlighted ? Color.Orange : spriteColor; Color color = IsHighlighted ? Color.Orange : spriteColor;
if (IsSelected && editing) if (IsSelected && editing)
{ {
//color = Color.Lerp(color, Color.Gold, 0.5f); //color = Color.Lerp(color, Color.Gold, 0.5f);
@@ -20,6 +20,8 @@ namespace Barotrauma
private GUILayoutGroup subPreviewContainer; private GUILayoutGroup subPreviewContainer;
private GUILayoutGroup subPreviewContainer;
private GUIButton loadGameButton; private GUIButton loadGameButton;
public Action<Submarine, string, string> StartNewGame; public Action<Submarine, string, string> StartNewGame;
@@ -68,25 +70,20 @@ namespace Barotrauma
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.02f), leftColumn.RectTransform) { MinSize = new Point(0, 20) }, TextManager.Get("MapSeed") + ":"); new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.02f), leftColumn.RectTransform) { MinSize = new Point(0, 20) }, TextManager.Get("MapSeed") + ":");
seedBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform) { MinSize = new Point(0, 20) }, ToolBox.RandomSeed(8)); seedBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform) { MinSize = new Point(0, 20) }, ToolBox.RandomSeed(8));
if (!isMultiplayer)
{
contextualTutorialBox = new GUITickBox(new RectTransform(new Point(32, 32), leftColumn.RectTransform), TextManager.Get("TutorialActive"));
UpdateTutorialSelection();
}
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.02f), leftColumn.RectTransform) { MinSize = new Point(0, 20) }, TextManager.Get("SelectedSub") + ":"); new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.02f), leftColumn.RectTransform) { MinSize = new Point(0, 20) }, TextManager.Get("SelectedSub") + ":");
var filterContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform), isHorizontal: true)
{
Stretch = true
};
subList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.65f), leftColumn.RectTransform)) { ScrollBarVisible = true }; subList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.65f), leftColumn.RectTransform)) { ScrollBarVisible = true };
var filterContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.07f), leftColumn.RectTransform), isHorizontal: true) var searchTitle = new GUITextBlock(new RectTransform(new Vector2(0.001f, 1.0f), filterContainer.RectTransform), TextManager.Get("FilterMapEntities"), textAlignment: Alignment.CenterLeft, font: GUI.Font);
{ var searchBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 1.0f), filterContainer.RectTransform, Anchor.CenterRight), font: GUI.Font);
Stretch = true, searchBox.OnSelected += (sender, userdata) => { searchTitle.Visible = false; };
RelativeSpacing = 0.02f searchBox.OnDeselected += (sender, userdata) => { searchTitle.Visible = true; };
};
new GUITextBlock(new RectTransform(new Vector2(0.3f, 1.0f), filterContainer.RectTransform), TextManager.Get("FilterMapEntities"), textAlignment: Alignment.CenterLeft, font: GUI.Font);
var searchBox = new GUITextBox(new RectTransform(new Vector2(0.9f, 1.0f), filterContainer.RectTransform), font: GUI.Font);
searchBox.OnTextChanged += (textBox, text) => { FilterSubs(subList, text); return true; }; searchBox.OnTextChanged += (textBox, text) => { FilterSubs(subList, text); return true; };
var clearButton = new GUIButton(new RectTransform(new Vector2(0.15f, 1.0f), filterContainer.RectTransform), "x") var clearButton = new GUIButton(new RectTransform(new Vector2(0.075f, 1.0f), filterContainer.RectTransform), "x")
{ {
OnClicked = (btn, userdata) => { searchBox.Text = ""; FilterSubs(subList, ""); searchBox.Flash(Color.White); return true; } OnClicked = (btn, userdata) => { searchBox.Text = ""; FilterSubs(subList, ""); searchBox.Flash(Color.White); return true; }
}; };
@@ -399,14 +396,7 @@ namespace Barotrauma
}, },
Enabled = false Enabled = false
}; };
} }
public void UpdateTutorialSelection()
{
if (isMultiplayer) return;
Tutorial contextualTutorial = Tutorial.Tutorials.Find(t => t is ContextualTutorial);
contextualTutorialBox.Selected = (contextualTutorial != null) ? !GameMain.Config.CompletedTutorialNames.Contains(contextualTutorial.Name) : true;
}
private bool SelectSaveFile(GUIComponent component, object obj) private bool SelectSaveFile(GUIComponent component, object obj)
{ {
@@ -182,23 +182,24 @@ namespace Barotrauma
{ {
TextGetter = GetMoney TextGetter = GetMoney
}; };
var filterContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 0.5f), storeContentTop.RectTransform), isHorizontal: true) var filterContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 0.4f), storeContentTop.RectTransform), isHorizontal: true)
{ {
Stretch = true, Stretch = true
RelativeSpacing = 0.02f
}; };
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), filterContainer.RectTransform), TextManager.Get("FilterMapEntities"), textAlignment: Alignment.CenterRight, font: GUI.Font); var searchTitle = new GUITextBlock(new RectTransform(new Vector2(0.001f, 1.0f), filterContainer.RectTransform), TextManager.Get("FilterMapEntities"), textAlignment: Alignment.CenterLeft, font: GUI.Font);
searchBox = new GUITextBox(new RectTransform(new Vector2(0.8f, 1.0f), filterContainer.RectTransform), font: GUI.Font); searchBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 1.0f), filterContainer.RectTransform), font: GUI.Font);
searchBox.OnSelected += (sender, userdata) => { searchTitle.Visible = false; };
searchBox.OnDeselected += (sender, userdata) => { searchTitle.Visible = true; };
searchBox.OnTextChanged += (textBox, text) => { FilterStoreItems(null, text); return true; }; searchBox.OnTextChanged += (textBox, text) => { FilterStoreItems(null, text); return true; };
var clearButton = new GUIButton(new RectTransform(new Vector2(0.2f, 1.0f), filterContainer.RectTransform), "x") var clearButton = new GUIButton(new RectTransform(new Vector2(0.1f, 1.0f), filterContainer.RectTransform), "x")
{ {
OnClicked = (btn, userdata) => { searchBox.Text = ""; FilterStoreItems(selectedItemCategory, ""); searchBox.Flash(Color.White); return true; } OnClicked = (btn, userdata) => { searchBox.Text = ""; FilterStoreItems(selectedItemCategory, ""); searchBox.Flash(Color.White); return true; }
}; };
var storeItemLists = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.8f), storeContent.RectTransform), isHorizontal: true) var storeItemLists = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.8f), storeContent.RectTransform), isHorizontal: true)
{ {
Stretch = true, Stretch = true
RelativeSpacing = 0.02f
}; };
myItemList = new GUIListBox(new RectTransform(new Vector2(0.5f, 1.0f), storeItemLists.RectTransform)); myItemList = new GUIListBox(new RectTransform(new Vector2(0.5f, 1.0f), storeItemLists.RectTransform));
storeItemList = new GUIListBox(new RectTransform(new Vector2(0.5f, 1.0f), storeItemLists.RectTransform)) storeItemList = new GUIListBox(new RectTransform(new Vector2(0.5f, 1.0f), storeItemLists.RectTransform))
@@ -59,10 +59,10 @@ namespace Barotrauma
Stretch = true, Stretch = true,
RelativeSpacing = 0.02f RelativeSpacing = 0.02f
}; };
// === CAMPAIGN // === CAMPAIGN
var campaignHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 1.0f), parent: buttonsParent.RectTransform) { RelativeOffset = new Vector2(0.1f, 0.0f) }, isHorizontal: true); var campaignHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 1.0f), parent: buttonsParent.RectTransform) { RelativeOffset = new Vector2(0.1f, 0.0f) }, isHorizontal: true);
new GUIImage(new RectTransform(new Vector2(0.2f, 0.7f), campaignHolder.RectTransform), "MainMenuCampaignIcon") new GUIImage(new RectTransform(new Vector2(0.2f, 0.7f), campaignHolder.RectTransform), "MainMenuCampaignIcon")
{ {
CanBeFocused = false CanBeFocused = false
@@ -84,6 +84,17 @@ namespace Barotrauma
RelativeSpacing = 0.035f RelativeSpacing = 0.035f
}; };
new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), campaignList.RectTransform), "Tutorial", textAlignment: Alignment.Left, style: "MainMenuGUIButton")
{
ForceUpperCase = true,
UserData = Tab.Tutorials,
OnClicked = (tb, userdata) =>
{
SelectTab(tb, userdata);
return true;
}
};
new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), campaignList.RectTransform), TextManager.Get("LoadGameButton"), textAlignment: Alignment.Left, style: "MainMenuGUIButton") new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), campaignList.RectTransform), TextManager.Get("LoadGameButton"), textAlignment: Alignment.Left, style: "MainMenuGUIButton")
{ {
ForceUpperCase = true, ForceUpperCase = true,
@@ -184,6 +195,10 @@ namespace Barotrauma
UserData = Tab.SteamWorkshop, UserData = Tab.SteamWorkshop,
OnClicked = SelectTab OnClicked = SelectTab
}; };
#if OSX && !DEBUG
steamWorkshopButton.Text += " (Not yet available on MacOS)";
#endif
} }
new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), customizeList.RectTransform), TextManager.Get("SubEditorButton"), textAlignment: Alignment.Left, style: "MainMenuGUIButton") new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), customizeList.RectTransform), TextManager.Get("SubEditorButton"), textAlignment: Alignment.Left, style: "MainMenuGUIButton")
@@ -309,6 +324,7 @@ namespace Barotrauma
false, null, ""); false, null, "");
foreach (Tutorial tutorial in Tutorial.Tutorials) foreach (Tutorial tutorial in Tutorial.Tutorials)
{ {
if (tutorial is ContextualTutorial) continue;
var tutorialText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), tutorialList.Content.RectTransform), tutorial.Name, textAlignment: Alignment.Center, font: GUI.LargeFont) var tutorialText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), tutorialList.Content.RectTransform), tutorial.Name, textAlignment: Alignment.Center, font: GUI.LargeFont)
{ {
UserData = tutorial UserData = tutorial
@@ -320,8 +336,6 @@ namespace Barotrauma
return true; return true;
}; };
UpdateTutorialList();
this.game = game; this.game = game;
menuTabs[(int)Tab.Credits] = new GUIFrame(new RectTransform(Vector2.One, GUI.Canvas), style: null, color: Color.Black * 0.5f) menuTabs[(int)Tab.Credits] = new GUIFrame(new RectTransform(Vector2.One, GUI.Canvas), style: null, color: Color.Black * 0.5f)
@@ -331,9 +345,9 @@ namespace Barotrauma
var creditsContainer = new GUIFrame(new RectTransform(new Vector2(0.75f, 1.5f), menuTabs[(int)Tab.Credits].RectTransform, Anchor.CenterRight), style: "OuterGlow", color: Color.Black * 0.8f); var creditsContainer = new GUIFrame(new RectTransform(new Vector2(0.75f, 1.5f), menuTabs[(int)Tab.Credits].RectTransform, Anchor.CenterRight), style: "OuterGlow", color: Color.Black * 0.8f);
creditsPlayer = new CreditsPlayer(new RectTransform(Vector2.One, creditsContainer.RectTransform), "Content/Texts/Credits.xml"); creditsPlayer = new CreditsPlayer(new RectTransform(Vector2.One, creditsContainer.RectTransform), "Content/Texts/Credits.xml");
} }
#endregion #endregion
#region Selection #region Selection
public override void Select() public override void Select()
{ {
base.Select(); base.Select();
@@ -348,10 +362,6 @@ namespace Barotrauma
ResetButtonStates(null); ResetButtonStates(null);
UpdateTutorialList();
ResetButtonStates(null);
GameAnalyticsManager.SetCustomDimension01(""); GameAnalyticsManager.SetCustomDimension01("");
} }
@@ -397,7 +407,6 @@ namespace Barotrauma
case Tab.NewGame: case Tab.NewGame:
campaignSetupUI.CreateDefaultSaveName(); campaignSetupUI.CreateDefaultSaveName();
campaignSetupUI.RandomizeSeed(); campaignSetupUI.RandomizeSeed();
campaignSetupUI.UpdateTutorialSelection();
campaignSetupUI.UpdateSubList(Submarine.SavedSubmarines); campaignSetupUI.UpdateSubList(Submarine.SavedSubmarines);
break; break;
case Tab.LoadGame: case Tab.LoadGame:
@@ -414,6 +423,7 @@ namespace Barotrauma
case Tab.HostServer: case Tab.HostServer:
break; break;
case Tab.Tutorials: case Tab.Tutorials:
UpdateTutorialList();
break; break;
case Tab.CharacterEditor: case Tab.CharacterEditor:
Submarine.MainSub = null; Submarine.MainSub = null;
@@ -444,6 +454,8 @@ namespace Barotrauma
public bool ReturnToMainMenu(GUIButton button, object obj) public bool ReturnToMainMenu(GUIButton button, object obj)
{ {
GUI.PreventPauseMenuToggle = false;
if (Selected != this) if (Selected != this)
{ {
Select(); Select();
@@ -468,7 +480,7 @@ namespace Barotrauma
otherButton.Selected = false; otherButton.Selected = false;
} }
} }
#endregion #endregion
private void QuickStart() private void QuickStart()
{ {
@@ -646,6 +658,7 @@ namespace Barotrauma
FileName = filename, FileName = filename,
Arguments = arguments Arguments = arguments
#if !DEBUG #if !DEBUG
,
WindowStyle = ProcessWindowStyle.Hidden WindowStyle = ProcessWindowStyle.Hidden
#endif #endif
}; };
@@ -685,6 +698,7 @@ namespace Barotrauma
GameMain.TitleScreen.TitleSize.Y / 2.0f * GameMain.TitleScreen.Scale + 30.0f), GameMain.TitleScreen.TitleSize.Y / 2.0f * GameMain.TitleScreen.Scale + 30.0f),
0.1f); 0.1f);
#if !DEBUG #if !DEBUG
#if !OSX
if (Steam.SteamManager.USE_STEAM) if (Steam.SteamManager.USE_STEAM)
{ {
if (GameMain.Config.UseSteamMatchmaking) if (GameMain.Config.UseSteamMatchmaking)
@@ -694,6 +708,16 @@ namespace Barotrauma
} }
steamWorkshopButton.Enabled = Steam.SteamManager.IsInitialized; steamWorkshopButton.Enabled = Steam.SteamManager.IsInitialized;
} }
#else
if (Steam.SteamManager.USE_STEAM)
{
if (GameMain.Config.UseSteamMatchmaking)
{
joinServerButton.Enabled = Steam.SteamManager.IsInitialized;
hostServerButton.Enabled = Steam.SteamManager.IsInitialized;
}
}
#endif
#else #else
joinServerButton.Enabled = true; joinServerButton.Enabled = true;
hostServerButton.Enabled = true; hostServerButton.Enabled = true;
@@ -804,8 +828,7 @@ namespace Barotrauma
} }
selectedSub = new Submarine(Path.Combine(SaveUtil.TempPath, selectedSub.Name + ".sub"), ""); selectedSub = new Submarine(Path.Combine(SaveUtil.TempPath, selectedSub.Name + ".sub"), "");
ContextualTutorial.Selected = campaignSetupUI.TutorialSelected;
GameMain.GameSession = new GameSession(selectedSub, saveName, GameMain.GameSession = new GameSession(selectedSub, saveName,
GameModePreset.List.Find(g => g.Identifier == "singleplayercampaign")); GameModePreset.List.Find(g => g.Identifier == "singleplayercampaign"));
(GameMain.GameSession.GameMode as CampaignMode).GenerateMap(mapSeed); (GameMain.GameSession.GameMode as CampaignMode).GenerateMap(mapSeed);
@@ -832,7 +855,7 @@ namespace Barotrauma
GameMain.LobbyScreen.Select(); GameMain.LobbyScreen.Select();
} }
#region UI Methods #region UI Methods
private void CreateHostServerFields() private void CreateHostServerFields()
{ {
Vector2 textLabelSize = new Vector2(1.0f, 0.1f); Vector2 textLabelSize = new Vector2(1.0f, 0.1f);
@@ -913,7 +936,7 @@ namespace Barotrauma
OnClicked = HostServerClicked OnClicked = HostServerClicked
}; };
} }
#endregion #endregion
} }
} }
@@ -1301,6 +1301,12 @@ namespace Barotrauma
var paddedLoadFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.9f), innerFrame.RectTransform, Anchor.Center)) { Stretch = true, RelativeSpacing = 0.02f }; var paddedLoadFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.9f), innerFrame.RectTransform, Anchor.Center)) { Stretch = true, RelativeSpacing = 0.02f };
var deleteButtonHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.1f), paddedLoadFrame.RectTransform, Anchor.Center)); var deleteButtonHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.1f), paddedLoadFrame.RectTransform, Anchor.Center));
var filterContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.1f), paddedLoadFrame.RectTransform), isHorizontal: true)
{
Stretch = true
};
var subList = new GUIListBox(new RectTransform(new Vector2(1.0f, 1.0f), paddedLoadFrame.RectTransform)) var subList = new GUIListBox(new RectTransform(new Vector2(1.0f, 1.0f), paddedLoadFrame.RectTransform))
{ {
ScrollBarVisible = true, ScrollBarVisible = true,
@@ -1311,15 +1317,13 @@ namespace Barotrauma
} }
}; };
var filterContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.1f), paddedLoadFrame.RectTransform), isHorizontal: true) var searchTitle = new GUITextBlock(new RectTransform(new Vector2(0.001f, 1.0f), filterContainer.RectTransform), TextManager.Get("FilterMapEntities"), textAlignment: Alignment.CenterLeft, font: GUI.Font);
{ var searchBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 1.0f), filterContainer.RectTransform), font: GUI.Font);
Stretch = true, searchBox.OnSelected += (sender, userdata) => { searchTitle.Visible = false; };
RelativeSpacing = 0.02f searchBox.OnDeselected += (sender, userdata) => { searchTitle.Visible = true; };
};
new GUITextBlock(new RectTransform(new Vector2(0.3f, 1.0f), filterContainer.RectTransform), TextManager.Get("FilterMapEntities"), textAlignment: Alignment.CenterLeft, font: GUI.Font);
var searchBox = new GUITextBox(new RectTransform(new Vector2(0.9f, 1.0f), filterContainer.RectTransform), font: GUI.Font);
searchBox.OnTextChanged += (textBox, text) => { FilterSubs(subList, text); return true; }; searchBox.OnTextChanged += (textBox, text) => { FilterSubs(subList, text); return true; };
var clearButton = new GUIButton(new RectTransform(new Vector2(0.15f, 1.0f), filterContainer.RectTransform), "x") var clearButton = new GUIButton(new RectTransform(new Vector2(0.1f, 1.0f), filterContainer.RectTransform), "x")
{ {
OnClicked = (btn, userdata) => { searchBox.Text = ""; FilterSubs(subList, ""); searchBox.Flash(Color.White); return true; } OnClicked = (btn, userdata) => { searchBox.Text = ""; FilterSubs(subList, ""); searchBox.Flash(Color.White); return true; }
}; };
@@ -12,6 +12,7 @@
<Item file="Content/Items/Jobgear/Assistant/assistant_gear.xml" /> <Item file="Content/Items/Jobgear/Assistant/assistant_gear.xml" />
<Item file="Content/Items/Jobgear/Watchman/watchman_gear.xml" /> <Item file="Content/Items/Jobgear/Watchman/watchman_gear.xml" />
<Item file="Content/Items/Jobgear/Security/securityofficer_gear.xml" /> <Item file="Content/Items/Jobgear/Security/securityofficer_gear.xml" />
<Item file="Content/Items/Jobgear/Clown/clown.xml" />
<Item file="Content/Items/Jobgear/misc.xml" /> <Item file="Content/Items/Jobgear/misc.xml" />
<Item file="Content/Items/CreatureLoot/creatureloot.xml" /> <Item file="Content/Items/CreatureLoot/creatureloot.xml" />
<Item file="Content/Items/Diving/divinggear.xml" /> <Item file="Content/Items/Diving/divinggear.xml" />
@@ -181,6 +181,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Source\Map\Entity.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Source\Map\Entity.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\Map\EntityGrid.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Source\Map\EntityGrid.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\Map\Explosion.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Source\Map\Explosion.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\Map\DummyFireSource.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\Map\FireSource.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Source\Map\FireSource.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\Map\Gap.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Source\Map\Gap.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\Map\Hull.cs" /> <Compile Include="$(MSBuildThisFileDirectory)Source\Map\Hull.cs" />
@@ -379,6 +379,18 @@
<Content Include="$(MSBuildThisFileDirectory)Content\Items\Jobgear\Assistant\assistant_gear.xml"> <Content Include="$(MSBuildThisFileDirectory)Content\Items\Jobgear\Assistant\assistant_gear.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Items\Jobgear\Clown\clown_legs_female.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Items\Jobgear\Clown\clown_legs_male.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Items\Jobgear\Clown\clown_torso_female.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Items\Jobgear\Clown\clown_torso_male.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Items\Jobgear\Engineer\engineer_gear.xml"> <Content Include="$(MSBuildThisFileDirectory)Content\Items\Jobgear\Engineer\engineer_gear.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
@@ -409,6 +421,12 @@
<Content Include="$(MSBuildThisFileDirectory)Content\Items\Jobgear\Mechanic\mechanic_torso_male_2.png"> <Content Include="$(MSBuildThisFileDirectory)Content\Items\Jobgear\Mechanic\mechanic_torso_male_2.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Items\Jobgear\Clown\clown.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Items\Jobgear\Old\clownshirt.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Items\Jobgear\Watchman\watchman_gear.xml"> <Content Include="$(MSBuildThisFileDirectory)Content\Items\Jobgear\Watchman\watchman_gear.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
@@ -445,9 +463,24 @@
<Content Include="$(MSBuildThisFileDirectory)Content\Map\LabelLetters.png"> <Content Include="$(MSBuildThisFileDirectory)Content\Map\LabelLetters.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Map\OpbgMaintenanceBay.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Map\OpbgShop.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Map\OpbgSocialCenter.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Map\OutpostWall_A.png"> <Content Include="$(MSBuildThisFileDirectory)Content\Map\OutpostWall_A.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Map\OutpostWall_B.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Map\OutpostWall_C.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\ContextualTutorial\1_CommandReactor\BaroTutorial_CommandReactor.mp4"> <Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\ContextualTutorial\1_CommandReactor\BaroTutorial_CommandReactor.mp4">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
@@ -475,6 +508,54 @@
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\ContextualTutorial\9_SwitchCharacter\BaroTutorial_SwitchCharacter.mp4"> <Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\ContextualTutorial\9_SwitchCharacter\BaroTutorial_SwitchCharacter.mp4">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\TutorialVideos\tutorial_command.mp4">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\TutorialVideos\tutorial_cpr.mp4">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\TutorialVideos\tutorial_deconstruct.mp4">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\TutorialVideos\tutorial_equip.mp4">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\TutorialVideos\tutorial_fabricate.mp4">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\TutorialVideos\tutorial_inventory.mp4">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\TutorialVideos\tutorial_leaks.mp4">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\TutorialVideos\tutorial_loaders.mp4">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\TutorialVideos\tutorial_medinterface1.mp4">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\TutorialVideos\tutorial_medinterface2.mp4">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\TutorialVideos\tutorial_navigation.mp4">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\TutorialVideos\tutorial_ranged.mp4">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\TutorialVideos\tutorial_reactor.mp4">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\TutorialVideos\tutorial_undock.mp4">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\TutorialVideos\tutorial_unequip.mp4">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\TutorialVideos\tutorial_wiring.mp4">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\UI\tutorialAtlas.png"> <Content Include="$(MSBuildThisFileDirectory)Content\UI\tutorialAtlas.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
@@ -1144,6 +1225,9 @@
<Content Include="$(MSBuildThisFileDirectory)Content\Lights\pointlight_falloff.png"> <Content Include="$(MSBuildThisFileDirectory)Content\Lights\pointlight_falloff.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Lights\light_fluorescent_L2.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Map\AlienBackground1.png"> <Content Include="$(MSBuildThisFileDirectory)Content\Map\AlienBackground1.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
@@ -1635,15 +1719,6 @@
<Content Include="$(MSBuildThisFileDirectory)Content\Items\Jobgear\Captain\captain_gear.xml"> <Content Include="$(MSBuildThisFileDirectory)Content\Items\Jobgear\Captain\captain_gear.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Items\Jobgear\clownmask.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Items\Jobgear\clownpants.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Items\Jobgear\clownshirt.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="$(MSBuildThisFileDirectory)Content\Items\Jobgear\Medic\medic_gear.xml"> <Content Include="$(MSBuildThisFileDirectory)Content\Items\Jobgear\Medic\medic_gear.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
@@ -2109,9 +2184,19 @@
<None Include="$(MSBuildThisFileDirectory)Content\Sounds\Impact\SoftImpact3.ogg"> <None Include="$(MSBuildThisFileDirectory)Content\Sounds\Impact\SoftImpact3.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
<None Include="$(MSBuildThisFileDirectory)Content\Tutorials\Dugong_Tutorial.sub">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\Tutorials\TutorialOutpost.sub">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Submarines\Berilia.sub"> <None Include="$(MSBuildThisFileDirectory)Submarines\Berilia.sub">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
<None Include="$(MSBuildThisFileDirectory)Submarines\Dugong_Tutorial.sub">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Submarines\TutorialOutpost.sub" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="$(MSBuildThisFileDirectory)Content\Characters\Carrier\CARRIER_alarmLoop.ogg"> <None Include="$(MSBuildThisFileDirectory)Content\Characters\Carrier\CARRIER_alarmLoop.ogg">
@@ -1110,6 +1110,8 @@ namespace Barotrauma
private bool IsProperlyLatchedOnSub => LatchOntoAI != null && LatchOntoAI.IsAttachedToSub && SelectedAiTarget?.Entity == wallTarget?.Structure; private bool IsProperlyLatchedOnSub => LatchOntoAI != null && LatchOntoAI.IsAttachedToSub && SelectedAiTarget?.Entity == wallTarget?.Structure;
private bool IsProperlyLatchedOnSub => LatchOntoAI != null && LatchOntoAI.IsAttachedToSub && SelectedAiTarget?.Entity == wallTarget?.Structure;
//goes through all the AItargets, evaluates how preferable it is to attack the target, //goes through all the AItargets, evaluates how preferable it is to attack the target,
//whether the Character can see/hear the target and chooses the most preferable target within //whether the Character can see/hear the target and chooses the most preferable target within
//sight/hearing range //sight/hearing range
@@ -426,7 +426,7 @@ namespace Barotrauma
} }
} }
private bool canSpeak; public bool CanSpeak;
private bool speechImpedimentSet; private bool speechImpedimentSet;
@@ -436,7 +436,7 @@ namespace Barotrauma
{ {
get get
{ {
if (!canSpeak || IsUnconscious || Stun > 0.0f || IsDead) return 100.0f; if (!CanSpeak || IsUnconscious || Stun > 0.0f || IsDead) return 100.0f;
return speechImpediment; return speechImpediment;
} }
set set
@@ -710,7 +710,7 @@ namespace Barotrauma
displayName = TextManager.Get($"Character.{Path.GetFileName(Path.GetDirectoryName(file))}", true); displayName = TextManager.Get($"Character.{Path.GetFileName(Path.GetDirectoryName(file))}", true);
IsHumanoid = doc.Root.GetAttributeBool("humanoid", false); IsHumanoid = doc.Root.GetAttributeBool("humanoid", false);
canSpeak = doc.Root.GetAttributeBool("canspeak", false); CanSpeak = doc.Root.GetAttributeBool("canspeak", false);
needsAir = doc.Root.GetAttributeBool("needsair", false); needsAir = doc.Root.GetAttributeBool("needsair", false);
Noise = doc.Root.GetAttributeFloat("noise", 100f); Noise = doc.Root.GetAttributeFloat("noise", 100f);
@@ -1588,9 +1588,8 @@ namespace Barotrauma
} }
} }
} }
if (item.InteractDistance == 0.0f && !item.Prefab.Triggers.Any()) { return false; }
if (item.InteractDistance == 0.0f && !item.Prefab.Triggers.Any()) return false;
Pickable pickableComponent = item.GetComponent<Pickable>(); Pickable pickableComponent = item.GetComponent<Pickable>();
if (pickableComponent != null && (pickableComponent.Picker != null && !pickableComponent.Picker.IsDead)) { return false; } if (pickableComponent != null && (pickableComponent.Picker != null && !pickableComponent.Picker.IsDead)) { return false; }
@@ -2718,6 +2717,10 @@ namespace Barotrauma
GameMain.GameSession?.CrewManager?.RemoveCharacter(this); GameMain.GameSession?.CrewManager?.RemoveCharacter(this);
#endif #endif
#if CLIENT
GameMain.GameSession?.CrewManager?.RemoveCharacter(this);
#endif
#if CLIENT #if CLIENT
GameMain.GameSession?.CrewManager?.RemoveCharacter(this); GameMain.GameSession?.CrewManager?.RemoveCharacter(this);
#endif #endif
@@ -399,7 +399,7 @@ namespace Barotrauma
{ {
ID = idCounter; ID = idCounter;
idCounter++; idCounter++;
Name = element.GetAttributeString("name", "unnamed"); Name = element.GetAttributeString("name", "");
string genderStr = element.GetAttributeString("gender", "male").ToLowerInvariant(); string genderStr = element.GetAttributeString("gender", "male").ToLowerInvariant();
File = element.GetAttributeString("file", ""); File = element.GetAttributeString("file", "");
SourceElement = GetConfig(File).Root; SourceElement = GetConfig(File).Root;
@@ -423,6 +423,29 @@ namespace Barotrauma
element.GetAttributeInt("beardindex", -1), element.GetAttributeInt("beardindex", -1),
element.GetAttributeInt("moustacheindex", -1), element.GetAttributeInt("moustacheindex", -1),
element.GetAttributeInt("faceattachmentindex", -1)); element.GetAttributeInt("faceattachmentindex", -1));
if (string.IsNullOrEmpty(Name))
{
if (SourceElement.Element("name") != null)
{
string firstNamePath = SourceElement.Element("name").GetAttributeString("firstname", "");
if (firstNamePath != "")
{
firstNamePath = firstNamePath.Replace("[GENDER]", (Head.gender == Gender.Female) ? "female" : "male");
Name = ToolBox.GetRandomLine(firstNamePath);
}
string lastNamePath = SourceElement.Element("name").GetAttributeString("lastname", "");
if (lastNamePath != "")
{
lastNamePath = lastNamePath.Replace("[GENDER]", (Head.gender == Gender.Female) ? "female" : "male");
if (Name != "") Name += " ";
Name += ToolBox.GetRandomLine(lastNamePath);
}
}
}
StartItemsGiven = element.GetAttributeBool("startitemsgiven", false); StartItemsGiven = element.GetAttributeBool("startitemsgiven", false);
string personalityName = element.GetAttributeString("personality", ""); string personalityName = element.GetAttributeString("personality", "");
ragdollFileName = element.GetAttributeString("ragdoll", string.Empty); ragdollFileName = element.GetAttributeString("ragdoll", string.Empty);
@@ -801,10 +801,7 @@ namespace Barotrauma.Items.Components
string msg = TextManager.Get(Msg, true); string msg = TextManager.Get(Msg, true);
if (msg != null) if (msg != null)
{ {
foreach (InputType inputType in Enum.GetValues(typeof(InputType))) msg = TextManager.ParseInputTypes(msg);
{
msg = msg.Replace("[" + inputType.ToString().ToLowerInvariant() + "]", GameMain.Config.KeyBind(inputType).ToString());
}
DisplayMsg = msg; DisplayMsg = msg;
} }
else else
@@ -13,6 +13,11 @@ namespace Barotrauma.Items.Components
private ItemContainer inputContainer, outputContainer; private ItemContainer inputContainer, outputContainer;
public ItemContainer InputContainer
{
get { return inputContainer; }
}
public ItemContainer OutputContainer public ItemContainer OutputContainer
{ {
get { return outputContainer; } get { return outputContainer; }
@@ -102,6 +107,25 @@ namespace Barotrauma.Items.Components
} }
} }
if (targetItem.Prefab.DeconstructItems.Any())
{
inputContainer.Inventory.RemoveItem(targetItem);
Entity.Spawner.AddToRemoveQueue(targetItem);
MoveInputQueue();
PutItemsToLinkedContainer();
}
else
{
if (outputContainer.Inventory.Items.All(i => i != null))
{
targetItem.Drop(dropper: null);
}
else
{
outputContainer.Inventory.TryPutItem(targetItem, user: null, createNetworkEvent: true);
}
}
if (targetItem.Prefab.DeconstructItems.Any()) if (targetItem.Prefab.DeconstructItems.Any())
{ {
inputContainer.Inventory.RemoveItem(targetItem); inputContainer.Inventory.RemoveItem(targetItem);
@@ -23,6 +23,16 @@ namespace Barotrauma.Items.Components
private ItemContainer inputContainer, outputContainer; private ItemContainer inputContainer, outputContainer;
public ItemContainer InputContainer
{
get { return inputContainer; }
}
public ItemContainer OutputContainer
{
get { return outputContainer; }
}
private float progressState; private float progressState;
public Fabricator(Item item, XElement element) public Fabricator(Item item, XElement element)
@@ -98,7 +108,23 @@ namespace Barotrauma.Items.Components
{ {
return (picker != null); return (picker != null);
} }
public void RemoveFabricationRecipes(List<string> allowedIdentifiers)
{
for (int i = 0; i < fabricationRecipes.Count; i++)
{
if (!allowedIdentifiers.Contains(fabricationRecipes[i].TargetItem.Identifier))
{
fabricationRecipes.RemoveAt(i);
i--;
}
}
CreateRecipes();
}
partial void CreateRecipes();
private void StartFabricating(FabricationRecipe selectedItem, Character user) private void StartFabricating(FabricationRecipe selectedItem, Character user)
{ {
if (selectedItem == null) return; if (selectedItem == null) return;
@@ -259,7 +259,7 @@ namespace Barotrauma.Items.Components
int clockDir = (int)Math.Round((angle / MathHelper.TwoPi) * 12); int clockDir = (int)Math.Round((angle / MathHelper.TwoPi) * 12);
if (clockDir == 0) clockDir = 12; if (clockDir == 0) clockDir = 12;
return TextManager.Get("SubDirOClock").Replace("[dir]", clockDir.ToString()); return TextManager.Get("roomname.subdiroclock").Replace("[dir]", clockDir.ToString());
} }
private Vector2 GetTransducerCenter() private Vector2 GetTransducerCenter()
@@ -575,6 +575,19 @@ namespace Barotrauma.Items.Components
return true; return true;
} }
public override void OnItemLoaded()
{
sonar = item.GetComponent<Sonar>();
}
public override bool Select(Character character)
{
if (!CanBeSelected) return false;
user = character;
return true;
}
public override void Update(float deltaTime, Camera cam) public override void Update(float deltaTime, Camera cam)
{ {
networkUpdateTimer -= deltaTime; networkUpdateTimer -= deltaTime;
@@ -206,6 +206,16 @@ namespace Barotrauma
return true; return true;
} }
public bool IsFull()
{
for (int i = 0; i < capacity; i++)
{
if (Items[i] == null) return false;
}
return true;
}
protected bool TrySwapping(int index, Item item, Character user, bool createNetworkEvent) protected bool TrySwapping(int index, Item item, Character user, bool createNetworkEvent)
{ {
if (item?.ParentInventory == null || Items[index] == null) return false; if (item?.ParentInventory == null || Items[index] == null) return false;
@@ -1200,6 +1200,10 @@ namespace Barotrauma
{ {
ApplyStatusEffects(!waterProof && inWater ? ActionType.InWater : ActionType.NotInWater, deltaTime); ApplyStatusEffects(!waterProof && inWater ? ActionType.InWater : ActionType.NotInWater, deltaTime);
} }
if (!broken)
{
ApplyStatusEffects(!waterProof && inWater ? ActionType.InWater : ActionType.NotInWater, deltaTime);
}
ApplyStatusEffects(!waterProof && inWater ? ActionType.InWater : ActionType.NotInWater, deltaTime); ApplyStatusEffects(!waterProof && inWater ? ActionType.InWater : ActionType.NotInWater, deltaTime);
if (body == null || !body.Enabled || !inWater || ParentInventory != null || Removed) { return; } if (body == null || !body.Enabled || !inWater || ParentInventory != null || Removed) { return; }
@@ -132,14 +132,16 @@ namespace Barotrauma
//default size //default size
protected Vector2 size; protected Vector2 size;
private float impactTolerance; private List<XElement> fabricationRecipeElements = new List<XElement>();
private bool canSpriteFlipX, canSpriteFlipY; private bool canSpriteFlipX, canSpriteFlipY;
private Dictionary<string, PriceInfo> prices; private Dictionary<string, PriceInfo> prices;
//an area next to the construction /// <summary>
//the construction can be Activated() by a Character inside the area /// Defines areas where the item can be interacted with. If RequireBodyInsideTrigger is set to true, the character
/// has to be within the trigger to interact. If it's set to false, having the cursor within the trigger is enough.
/// </summary>
public List<Rectangle> Triggers; public List<Rectangle> Triggers;
private List<XElement> fabricationRecipeElements = new List<XElement>(); private List<XElement> fabricationRecipeElements = new List<XElement>();
@@ -40,7 +40,7 @@ namespace Barotrauma
flames = true; flames = true;
underwaterBubble = true; underwaterBubble = true;
} }
public Explosion(XElement element, string parentDebugName) public Explosion(XElement element, string parentDebugName)
{ {
attack = new Attack(element, parentDebugName + ", Explosion"); attack = new Attack(element, parentDebugName + ", Explosion");
@@ -62,6 +62,16 @@ namespace Barotrauma
CameraShake = element.GetAttributeFloat("camerashake", attack.Range * 0.1f); CameraShake = element.GetAttributeFloat("camerashake", attack.Range * 0.1f);
} }
public void DisableParticles()
{
sparks = false;
shockwave = false;
smoke = false;
flash = false;
flames = false;
underwaterBubble = false;
}
public List<Triplet<Explosion, Vector2, float>> GetRecentExplosions(float maxSecondsAgo) public List<Triplet<Explosion, Vector2, float>> GetRecentExplosions(float maxSecondsAgo)
{ {
return prevExplosions.FindAll(e => e.Third >= Timing.TotalTime - maxSecondsAgo); return prevExplosions.FindAll(e => e.Third >= Timing.TotalTime - maxSecondsAgo);
@@ -15,14 +15,15 @@ namespace Barotrauma
{ {
const float OxygenConsumption = 50.0f; const float OxygenConsumption = 50.0f;
const float GrowSpeed = 5.0f; const float GrowSpeed = 5.0f;
private Hull hull; protected Hull hull;
protected Vector2 position;
protected Vector2 size;
private bool removed; private bool removed;
private bool removed; protected bool removed;
private bool removed;
#if CLIENT #if CLIENT
private List<Decal> burnDecals = new List<Decal>(); private List<Decal> burnDecals = new List<Decal>();
@@ -184,6 +185,16 @@ namespace Barotrauma
} }
} }
protected virtual void ReduceOxygen(float deltaTime)
{
hull.Oxygen -= size.X * deltaTime * OxygenConsumption;
}
protected virtual void AdjustXPos(float growModifier, float deltaTime)
{
position.X -= GrowSpeed * growModifier * 0.5f * deltaTime;
}
partial void UpdateProjSpecific(float growModifier); partial void UpdateProjSpecific(float growModifier);
private void OnChangeHull(Vector2 pos, Hull particleHull) private void OnChangeHull(Vector2 pos, Hull particleHull)
@@ -660,6 +660,25 @@ namespace Barotrauma
} }
} }
public string DisplayName
{
get;
private set;
}
private string roomName;
[Editable, Serialize("", true, translationTextTag: "RoomName.")]
public string RoomName
{
get { return roomName; }
set
{
if (roomName == value) { return; }
roomName = value;
DisplayName = TextManager.Get(roomName, returnNull: true) ?? roomName;
}
}
public override Rectangle Rect public override Rectangle Rect
{ {
get get
@@ -138,6 +138,9 @@ namespace Barotrauma
public Submarine StartOutpost { get; private set; } public Submarine StartOutpost { get; private set; }
public Submarine EndOutpost { get; private set; } public Submarine EndOutpost { get; private set; }
private Submarine preSelectedStartOutpost;
private Submarine preSelectedEndOutpost;
public string Seed public string Seed
{ {
get { return seed; } get { return seed; }
@@ -209,7 +212,7 @@ namespace Barotrauma
/// </summary> /// </summary>
/// <param name="difficulty">A scalar between 0-100</param> /// <param name="difficulty">A scalar between 0-100</param>
/// <param name="sizeFactor">A scalar between 0-1 (0 = the minimum width defined in the generation params is used, 1 = the max width is used)</param> /// <param name="sizeFactor">A scalar between 0-1 (0 = the minimum width defined in the generation params is used, 1 = the max width is used)</param>
public Level(string seed, float difficulty, float sizeFactor, LevelGenerationParams generationParams, Biome biome) public Level(string seed, float difficulty, float sizeFactor, LevelGenerationParams generationParams, Biome biome, Submarine startOutpost = null, Submarine endOutPost = null)
: base(null) : base(null)
{ {
@@ -225,6 +228,9 @@ namespace Barotrauma
(width / GridCellSize) * GridCellSize, (width / GridCellSize) * GridCellSize,
(generationParams.Height / GridCellSize) * GridCellSize); (generationParams.Height / GridCellSize) * GridCellSize);
preSelectedStartOutpost = startOutpost;
preSelectedEndOutpost = endOutPost;
//remove from entity dictionary //remove from entity dictionary
base.Remove(); base.Remove();
} }
@@ -1510,14 +1516,24 @@ namespace Barotrauma
continue; continue;
} }
//only create a starting outpost in campaign mode //only create a starting outpost in campaign and tutorial modes
if (GameMain.GameSession?.GameMode as CampaignMode == null && ((i == 0) == !Mirrored)) if (!IsModeStartOutpostCompatible() && ((i == 0) == !Mirrored))
{ {
continue; continue;
} }
string outpostFile = outpostFiles.GetRandom(Rand.RandSync.Server); Submarine outpost = null;
var outpost = new Submarine(outpostFile, tryLoad: false);
if (i == 0 && preSelectedStartOutpost == null || i == 1 && preSelectedEndOutpost == null)
{
string outpostFile = outpostFiles.GetRandom(Rand.RandSync.Server);
outpost = new Submarine(outpostFile, tryLoad: false);
}
else
{
outpost = (i == 0) ? preSelectedStartOutpost : preSelectedEndOutpost;
}
outpost.Load(unloadPrevious: false); outpost.Load(unloadPrevious: false);
outpost.MakeOutpost(); outpost.MakeOutpost();
@@ -1569,6 +1585,15 @@ namespace Barotrauma
} }
} }
private bool IsModeStartOutpostCompatible()
{
#if CLIENT
return GameMain.GameSession?.GameMode as CampaignMode != null || GameMain.GameSession?.GameMode as TutorialMode != null;
#else
return GameMain.GameSession?.GameMode as CampaignMode != null;
#endif
}
public override void Remove() public override void Remove()
{ {
base.Remove(); base.Remove();
@@ -431,6 +431,12 @@ namespace Barotrauma
else if (ic is Pickable pickable) else if (ic is Pickable pickable)
{ {
//prevent picking up (or deattaching) items //prevent picking up (or deattaching) items
#if CLIENT
if (GameMain.GameSession.GameMode is TutorialMode)
{
continue;
}
#endif
pickable.CanBePicked = false; pickable.CanBePicked = false;
pickable.CanBeSelected = false; pickable.CanBeSelected = false;
} }
@@ -1426,7 +1432,7 @@ namespace Barotrauma
doc.Root.Add(new XAttribute("md5hash", hash.Hash)); doc.Root.Add(new XAttribute("md5hash", hash.Hash));
if (previewImage != null) if (previewImage != null)
{ {
doc.Root.Add(new XAttribute("previewimage", Convert.ToBase64String(previewImage.ToArray()))); //doc.Root.Add(new XAttribute("previewimage", Convert.ToBase64String(previewImage.ToArray())));
} }
try try
@@ -162,21 +162,6 @@ namespace Barotrauma
get { return binding; } get { return binding; }
} }
public void SetState()
{
hit = binding.IsHit();
if (hit) hitQueue = true;
held = binding.IsDown();
if (held) heldQueue = true;
}
#endif
public KeyOrMouse State
{
get { return binding; }
}
public void SetState() public void SetState()
{ {
hit = binding.IsHit(); hit = binding.IsHit();
@@ -46,7 +46,15 @@ namespace Barotrauma
if (File.Exists(filePath)) if (File.Exists(filePath))
{ {
doc = XDocument.Load(filePath, LoadOptions.SetBaseUri); try
{
doc = XDocument.Load(filePath, LoadOptions.SetBaseUri);
}
catch
{
return null;
}
if (doc.Root == null) return null; if (doc.Root == null) return null;
} }
@@ -79,6 +79,40 @@ namespace Barotrauma
} }
public static string Get(string textTag, bool returnNull = false) public static string Get(string textTag, bool returnNull = false)
{
if (!textPacks.ContainsKey(Language))
{
DebugConsole.ThrowError("No text packs available for the selected language (" + Language + ")! Switching to English...");
Language = "English";
if (!textPacks.ContainsKey(Language))
{
throw new Exception("No text packs available in English!");
}
}
}
public static string GetFormatted(string textTag, bool returnNull = false, params object[] args)
{
string text = Get(textTag, returnNull);
if (text == null || text.Length == 0)
{
if (returnNull)
{
return null;
}
else
{
DebugConsole.ThrowError("Text \"" + textTag + "\" not found.");
return textTag;
}
}
return string.Format(text, args);
}
// Format: ServerMessage.Identifier1/ServerMessage.Indentifier2~[variable1]=value~[variable2]=value
public static string GetServerMessage(string serverMessage)
{ {
if (!textPacks.ContainsKey(Language)) if (!textPacks.ContainsKey(Language))
{ {
@@ -118,6 +152,16 @@ namespace Barotrauma
} }
} }
public static string ParseInputTypes(string text)
{
foreach (InputType inputType in Enum.GetValues(typeof(InputType)))
{
text = text.Replace("[" + inputType.ToString().ToLowerInvariant() + "]", GameMain.Config.KeyBind(inputType).ToString());
text = text.Replace("[InputType." + inputType.ToString() + "]", GameMain.Config.KeyBind(inputType).ToString());
}
return text;
}
public static string GetFormatted(string textTag, bool returnNull = false, params object[] args) public static string GetFormatted(string textTag, bool returnNull = false, params object[] args)
{ {
string text = Get(textTag, returnNull); string text = Get(textTag, returnNull);
Binary file not shown.
Binary file not shown.
Binary file not shown.