(ccef21f63) Merge branch 'dev' of https://github.com/Regalis11/Barotrauma-development into dev

This commit is contained in:
Joonas Rikkonen
2019-04-06 17:49:31 +03:00
parent 45c1ed499a
commit 14d0daf16d
18 changed files with 333 additions and 180 deletions
@@ -211,22 +211,23 @@ namespace Barotrauma
Vector2 mouseSimPos = ConvertUnits.ToSimUnits(cursorPosition); Vector2 mouseSimPos = ConvertUnits.ToSimUnits(cursorPosition);
if (GUI.PauseMenuOpen) if (GUI.PauseMenuOpen)
{ {
targetOffsetAmount = 0.0f; cam.OffsetAmount = targetOffsetAmount = 0.0f;
cam.OffsetAmount = 0.0f; }
else if (Lights.LightManager.ViewTarget is Item item && item.Prefab.FocusOnSelected)
{
cam.OffsetAmount = targetOffsetAmount = item.Prefab.OffsetOnSelected;
} }
else if (SelectedConstruction != null && ViewTarget == null && else if (SelectedConstruction != null && ViewTarget == null &&
SelectedConstruction.Components.Any(ic => ic?.GuiFrame != null && ic.ShouldDrawHUD(this))) SelectedConstruction.Components.Any(ic => ic?.GuiFrame != null && ic.ShouldDrawHUD(this)))
{ {
targetOffsetAmount = 0.0f; cam.OffsetAmount = targetOffsetAmount = 0.0f;
cam.OffsetAmount = 0.0f;
cursorPosition = cursorPosition =
SelectedConstruction.Position + SelectedConstruction.Position +
new Vector2(cursorPosition.X % 10.0f, cursorPosition.Y % 10.0f); //apply a little bit of movement to the cursor pos to prevent AFK kicking new Vector2(cursorPosition.X % 10.0f, cursorPosition.Y % 10.0f); //apply a little bit of movement to the cursor pos to prevent AFK kicking
} }
else if (!GameMain.Config.EnableMouseLook) else if (!GameMain.Config.EnableMouseLook)
{ {
targetOffsetAmount = 0.0f; cam.OffsetAmount = targetOffsetAmount = 0.0f;
cam.OffsetAmount = 0.0f;
} }
else if (Lights.LightManager.ViewTarget == this && Vector2.DistanceSquared(AnimController.Limbs[0].SimPosition, mouseSimPos) > 1.0f) else if (Lights.LightManager.ViewTarget == this && Vector2.DistanceSquared(AnimController.Limbs[0].SimPosition, mouseSimPos) > 1.0f)
{ {
@@ -234,8 +235,7 @@ namespace Barotrauma
{ {
if (deltaTime > 0.0f) if (deltaTime > 0.0f)
{ {
targetOffsetAmount = 0.0f; cam.OffsetAmount = targetOffsetAmount = 0.0f;
cam.OffsetAmount = 0.0f;
} }
} }
else else
@@ -66,33 +66,6 @@ namespace Barotrauma
CanBeFocused = false CanBeFocused = false
}; };
Point scrollButtonSize = new Point((int)(200 * GUI.Scale), (int)(30 * GUI.Scale));
crewArea = new GUIFrame(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.CrewArea, guiFrame.RectTransform), "", Color.Transparent)
{
CanBeFocused = false
};
toggleCrewButton = new GUIButton(new RectTransform(new Point((int)(30 * GUI.Scale), HUDLayoutSettings.CrewArea.Height), guiFrame.RectTransform)
{ AbsoluteOffset = HUDLayoutSettings.CrewArea.Location },
"", style: "UIToggleButton");
toggleCrewButton.OnClicked += (GUIButton btn, object userdata) =>
{
toggleCrewAreaOpen = !toggleCrewAreaOpen;
foreach (GUIComponent child in btn.Children)
{
child.SpriteEffects = toggleCrewAreaOpen ? SpriteEffects.None : SpriteEffects.FlipHorizontally;
}
return true;
};
characterListBox = new GUIListBox(new RectTransform(new Point(100, (int)(crewArea.Rect.Height - scrollButtonSize.Y * 1.6f)), crewArea.RectTransform, Anchor.CenterLeft), false, Color.Transparent, null)
{
//Spacing = (int)(3 * GUI.Scale),
ScrollBarEnabled = false,
ScrollBarVisible = false,
CanBeFocused = false
};
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())
@@ -103,6 +76,50 @@ namespace Barotrauma
} }
} }
var reports = Order.PrefabList.FindAll(o => o.TargetAllCharacters && o.SymbolSprite != null);
reportButtonFrame = new GUILayoutGroup(new RectTransform(
new Point((HUDLayoutSettings.CrewArea.Height - (int)((reports.Count - 1) * 5 * GUI.Scale)) / reports.Count, HUDLayoutSettings.CrewArea.Height), guiFrame.RectTransform))
{
AbsoluteSpacing = (int)(5 * GUI.Scale),
UserData = "reportbuttons",
CanBeFocused = false
};
//report buttons
foreach (Order order in reports)
{
if (!order.TargetAllCharacters || order.SymbolSprite == null) continue;
var btn = new GUIButton(new RectTransform(new Point(reportButtonFrame.Rect.Width), reportButtonFrame.RectTransform), style: null)
{
OnClicked = (GUIButton button, object userData) =>
{
if (Character.Controlled == null || Character.Controlled.SpeechImpediment >= 100.0f) return false;
SetCharacterOrder(null, order, null, Character.Controlled);
HumanAIController.PropagateHullSafety(Character.Controlled, Character.Controlled.CurrentHull);
return true;
},
UserData = order,
ToolTip = order.Name
};
new GUIFrame(new RectTransform(new Vector2(1.5f), btn.RectTransform, Anchor.Center), "OuterGlow")
{
Color = Color.Red * 0.8f,
HoverColor = Color.Red * 1.0f,
PressedColor = Color.Red * 0.6f,
UserData = "highlighted",
CanBeFocused = false,
Visible = false
};
var img = new GUIImage(new RectTransform(Vector2.One, btn.RectTransform), order.Prefab.SymbolSprite, scaleToFit: true)
{
Color = order.Color,
HoverColor = Color.Lerp(order.Color, Color.White, 0.5f),
ToolTip = order.Name
};
}
screenResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight); screenResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
prevUIScale = GUI.Scale; prevUIScale = GUI.Scale;
@@ -175,6 +175,63 @@ namespace Barotrauma.Items.Components
} }
} }
} }
public void ApplyTo(RectTransform target)
{
if (RelativeOffset.HasValue)
{
target.RelativeOffset = RelativeOffset.Value;
}
else if (AbsoluteOffset.HasValue)
{
target.AbsoluteOffset = AbsoluteOffset.Value;
}
if (RelativeSize.HasValue)
{
target.RelativeSize = RelativeSize.Value;
}
else if (AbsoluteSize.HasValue)
{
target.NonScaledSize = AbsoluteSize.Value;
}
if (Anchor.HasValue)
{
target.Anchor = Anchor.Value;
}
if (Pivot.HasValue)
{
target.Pivot = Pivot.Value;
}
else
{
target.Pivot = RectTransform.MatchPivotToAnchor(target.Anchor);
}
target.RecalculateChildren(true, true);
}
}
public GUIFrame GuiFrame { get; protected set; }
[Serialize(false, false)]
public bool AllowUIOverlap
{
get;
set;
}
private ItemComponent linkToUIComponent;
[Serialize("", false)]
public string LinkUIToComponent
{
get;
set;
}
[Serialize(0, false)]
public int HudPriority
{
get;
private set;
} }
private bool shouldMuffleLooping; private bool shouldMuffleLooping;
@@ -339,11 +339,10 @@ namespace Barotrauma.Items.Components
} }
} }
if (crosshairSprite != null) float zoom = cam == null ? 1.0f : (float)Math.Sqrt(cam.Zoom);
{
crosshairSprite.Draw(spriteBatch, crosshairPos, readyToFire ? Color.White : Color.White * 0.2f, 0, (float)Math.Sqrt(cam.Zoom)); crosshairSprite?.Draw(spriteBatch, crosshairPos, readyToFire ? Color.White : Color.White * 0.2f, 0, zoom);
} crosshairPointerSprite?.Draw(spriteBatch, crosshairPointerPos, 0, zoom);
if (crosshairPointerSprite != null) crosshairPointerSprite.Draw(spriteBatch, crosshairPointerPos, 0, (float)Math.Sqrt(cam.Zoom));
} }
public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime) public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime)
@@ -44,12 +44,9 @@ namespace Barotrauma
public SteamWorkshopScreen() public SteamWorkshopScreen()
{ {
int width = Math.Min(GameMain.GraphicsWidth - 160, 1000);
int height = Math.Min(GameMain.GraphicsHeight - 160, 700);
tabs = new GUIFrame[Enum.GetValues(typeof(Tab)).Length]; tabs = new GUIFrame[Enum.GetValues(typeof(Tab)).Length];
menu = new GUIFrame(new RectTransform(new Vector2(0.6f, 0.7f), GUI.Canvas, Anchor.Center) { MinSize = new Point(width, height) }); menu = new GUIFrame(new RectTransform(new Vector2(0.6f, 0.8f), GUI.Canvas, Anchor.Center) { MinSize = new Point(GameMain.GraphicsHeight, 0) });
var container = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.85f), menu.RectTransform, Anchor.Center) { RelativeOffset = new Vector2(0.0f, 0.05f) }) { Stretch = true }; var container = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.85f), menu.RectTransform, Anchor.Center) { RelativeOffset = new Vector2(0.0f, 0.05f) }) { Stretch = true };
@@ -122,7 +119,8 @@ namespace Barotrauma
} }
}; };
new GUIButton(new RectTransform(new Vector2(1.0f, 0.03f), listContainer.RectTransform), TextManager.Get("FindModsButton")) var findModsButtonContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.03f), listContainer.RectTransform), style: null);
new GUIButton(new RectTransform(new Vector2(0.8f, 0.8f), findModsButtonContainer.RectTransform, Anchor.Center), TextManager.Get("FindModsButton"), style: "GUIButtonLarge")
{ {
OnClicked = (btn, userdata) => OnClicked = (btn, userdata) =>
{ {
@@ -620,7 +618,7 @@ namespace Barotrauma
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), content.RectTransform), item.Title, textAlignment: Alignment.TopLeft, font: GUI.LargeFont, wrap: true); new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), content.RectTransform), item.Title, textAlignment: Alignment.TopLeft, font: GUI.LargeFont, wrap: true);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), content.RectTransform), TextManager.Get("WorkshopItemCreator") + ": " + item.OwnerName, textAlignment: Alignment.BottomLeft, wrap: true); new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), content.RectTransform), TextManager.Get("WorkshopItemCreator") + ": " + item.OwnerName, textAlignment: Alignment.BottomLeft, wrap: true);
var headerAreaBackground = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.59f), content.RectTransform, maxSize: new Point(int.MaxValue, 235))) { Color = Color.Black }; var headerAreaBackground = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.5f), content.RectTransform, maxSize: new Point(int.MaxValue, 235))) { Color = Color.Black };
var headerArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), headerAreaBackground.RectTransform), childAnchor: Anchor.Center); var headerArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), headerAreaBackground.RectTransform), childAnchor: Anchor.Center);
@@ -693,9 +691,9 @@ namespace Barotrauma
//spacing //spacing
new GUIFrame(new RectTransform(new Vector2(0.0f, 0.015f), content.RectTransform), style: null); new GUIFrame(new RectTransform(new Vector2(0.0f, 0.015f), content.RectTransform), style: null);
var steamButtonHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.05f), content.RectTransform)); var steamButtonHolder = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.05f), content.RectTransform), style: null);
new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), steamButtonHolder.RectTransform), TextManager.Get("WorkshopShowItemInSteam")) new GUIButton(new RectTransform(new Vector2(0.8f, 1.0f), steamButtonHolder.RectTransform, Anchor.Center), TextManager.Get("WorkshopShowItemInSteam"), style: "GUIButtonLarge")
{ {
OnClicked = (btn, userdata) => OnClicked = (btn, userdata) =>
{ {
@@ -143,11 +143,16 @@ namespace Barotrauma
private void CreateUI() private void CreateUI()
{ {
TopPanel = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.04f), GUI.Canvas) { MinSize = new Point(0, 35) }, "GUIFrameTop"); TopPanel = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.05f), GUI.Canvas) { MinSize = new Point(0, 35) }, "GUIFrameTop");
GUIFrame paddedTopPanel = new GUIFrame(new RectTransform(new Vector2(0.95f, 0.55f), TopPanel.RectTransform, Anchor.Center) { RelativeOffset = new Vector2(0.0f, -0.1f) },
style: null); GUIFrame paddedTopPanel = new GUIFrame(new RectTransform(new Vector2(0.95f, 0.55f), TopPanel.RectTransform, Anchor.Center) { RelativeOffset = new Vector2(0.0f, -0.1f) }, style: null);
var button = new GUIButton(new RectTransform(new Vector2(0.07f, 0.9f), paddedTopPanel.RectTransform, Anchor.CenterLeft), TextManager.Get("OpenSubButton")) var button = new GUIButton(new RectTransform(new Vector2(0.07f, 0.9f), paddedTopPanel.RectTransform, Anchor.CenterLeft), TextManager.Get("Back"))
{
OnClicked = GameMain.MainMenuScreen.ReturnToMainMenu
};
button = new GUIButton(new RectTransform(new Vector2(0.07f, 0.9f), paddedTopPanel.RectTransform, Anchor.CenterLeft) { RelativeOffset = new Vector2(0.07f, 0.0f) }, TextManager.Get("OpenSubButton"))
{ {
OnClicked = (GUIButton btn, object data) => OnClicked = (GUIButton btn, object data) =>
{ {
@@ -158,7 +163,7 @@ namespace Barotrauma
} }
}; };
button = new GUIButton(new RectTransform(new Vector2(0.07f, 0.9f), paddedTopPanel.RectTransform, Anchor.CenterLeft) { RelativeOffset = new Vector2(0.08f, 0.0f) }, TextManager.Get("SaveSubButton")) button = new GUIButton(new RectTransform(new Vector2(0.07f, 0.9f), paddedTopPanel.RectTransform, Anchor.CenterLeft) { RelativeOffset = new Vector2(0.14f, 0.0f) }, TextManager.Get("SaveSubButton"))
{ {
OnClicked = (GUIButton btn, object data) => OnClicked = (GUIButton btn, object data) =>
{ {
@@ -169,13 +174,13 @@ namespace Barotrauma
} }
}; };
var nameLabel = new GUITextBlock(new RectTransform(new Vector2(0.1f, 0.9f), paddedTopPanel.RectTransform, Anchor.CenterLeft) { RelativeOffset = new Vector2(0.15f, 0.0f) }, var nameLabel = new GUITextBlock(new RectTransform(new Vector2(0.1f, 0.9f), paddedTopPanel.RectTransform, Anchor.CenterLeft) { RelativeOffset = new Vector2(0.21f, 0.0f) },
"", font: GUI.LargeFont, textAlignment: Alignment.CenterLeft) "", font: GUI.LargeFont, textAlignment: Alignment.CenterLeft)
{ {
TextGetter = GetSubName TextGetter = GetSubName
}; };
linkedSubBox = new GUIDropDown(new RectTransform(new Vector2(0.15f, 0.9f), paddedTopPanel.RectTransform) { RelativeOffset = new Vector2(0.4f, 0.0f) }, linkedSubBox = new GUIDropDown(new RectTransform(new Vector2(0.15f, 0.9f), paddedTopPanel.RectTransform) { RelativeOffset = new Vector2(0.385f, 0.0f) },
TextManager.Get("AddSubButton"), elementCount: 20) TextManager.Get("AddSubButton"), elementCount: 20)
{ {
ToolTip = TextManager.Get("AddSubToolTip") ToolTip = TextManager.Get("AddSubToolTip")
@@ -279,12 +284,13 @@ namespace Barotrauma
var paddedTab = new GUIFrame(new RectTransform(new Vector2(1.0f, 1.0f), EntityMenu.RectTransform, Anchor.Center), style: null); var paddedTab = new GUIFrame(new RectTransform(new Vector2(1.0f, 1.0f), EntityMenu.RectTransform, Anchor.Center), style: null);
var filterArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.1f), paddedTab.RectTransform), isHorizontal: true) var filterArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.1f), paddedTab.RectTransform) { AbsoluteOffset = new Point(0, 10) }, isHorizontal: true)
{ {
Color = secondaryColor, Color = secondaryColor,
Stretch = true, Stretch = true,
UserData = "filterarea" UserData = "filterarea"
}; };
new GUITextBlock(new RectTransform(new Vector2(0.05f, 1.0f), filterArea.RectTransform), TextManager.Get("FilterMapEntities"), font: GUI.Font); new GUITextBlock(new RectTransform(new Vector2(0.05f, 1.0f), filterArea.RectTransform), TextManager.Get("FilterMapEntities"), font: GUI.Font);
entityFilterBox = new GUITextBox(new RectTransform(new Vector2(0.8f, 1.0f), filterArea.RectTransform), font: GUI.Font); entityFilterBox = new GUITextBox(new RectTransform(new Vector2(0.8f, 1.0f), filterArea.RectTransform), font: GUI.Font);
entityFilterBox.OnTextChanged += (textBox, text) => { FilterEntities(text); return true; }; entityFilterBox.OnTextChanged += (textBox, text) => { FilterEntities(text); return true; };
@@ -293,7 +299,7 @@ namespace Barotrauma
OnClicked = (btn, userdata) => { ClearFilter(); entityFilterBox.Flash(Color.White); return true; } OnClicked = (btn, userdata) => { ClearFilter(); entityFilterBox.Flash(Color.White); return true; }
}; };
var entityListHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.85f), paddedTab.RectTransform, Anchor.Center) { RelativeOffset = new Vector2(0.0f, 0.05f) }); var entityListHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.85f), paddedTab.RectTransform, Anchor.Center) { RelativeOffset = new Vector2(0.0f, 0.06f) });
var tabButtonHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.1f), entityListHolder.RectTransform, Anchor.TopRight, Pivot.BottomRight), var tabButtonHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.1f), entityListHolder.RectTransform, Anchor.TopRight, Pivot.BottomRight),
isHorizontal: true) isHorizontal: true)
@@ -353,21 +359,24 @@ namespace Barotrauma
} }
}; };
//empty guiframe as a separator button = new GUIButton(new RectTransform(new Vector2(1.0f, 0.025f), paddedLeftPanel.RectTransform), TextManager.Get("GenerateWaypointsButton"), style: null, color: new Color(70, 100, 122, 255))
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.02f), paddedLeftPanel.RectTransform), style: null);
button = new GUIButton(new RectTransform(new Vector2(1.0f, 0.025f), paddedLeftPanel.RectTransform), TextManager.Get("GenerateWaypointsButton"))
{ {
ForceUpperCase = true,
HoverColor = new Color(33, 33, 33, 255),
TextColor = Color.White,
ToolTip = TextManager.Get("GenerateWaypointsToolTip"), ToolTip = TextManager.Get("GenerateWaypointsToolTip"),
OnClicked = GenerateWaypoints OnClicked = GenerateWaypoints
}; };
// empty guiframe as a separator //spacing
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.02f), paddedLeftPanel.RectTransform), style: null); new GUIFrame(new RectTransform(new Vector2(1.0f, 0.01f), paddedLeftPanel.RectTransform), style: null);
var showEntitiesHolder = new GUILayoutGroup(new RectTransform(new Vector2(paddedLeftPanel.RectTransform.RelativeSize.X, 0.3f), paddedLeftPanel.RectTransform)) var showEntitiesHolder = new GUILayoutGroup(new RectTransform(new Vector2(paddedLeftPanel.RectTransform.RelativeSize.X, 0.3f), paddedLeftPanel.RectTransform))
{ Color = secondaryColor, Stretch = true, RelativeSpacing = 0.05f }; { Color = secondaryColor, Stretch = true, RelativeSpacing = 0.05f };
//spacing
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.0f), showEntitiesHolder.RectTransform) { MinSize = new Point(0, 3) }, style: null);
var tickBox = new GUITickBox(new RectTransform(new Point(32, 32), showEntitiesHolder.RectTransform) { AbsoluteOffset = new Point(10, 0) }, TextManager.Get("ShowLighting")) var tickBox = new GUITickBox(new RectTransform(new Point(32, 32), showEntitiesHolder.RectTransform) { AbsoluteOffset = new Point(10, 0) }, TextManager.Get("ShowLighting"))
{ {
Selected = lightingEnabled, Selected = lightingEnabled,
@@ -431,6 +440,9 @@ namespace Barotrauma
OnSelected = (GUITickBox obj) => { Gap.ShowGaps = obj.Selected; return true; }, OnSelected = (GUITickBox obj) => { Gap.ShowGaps = obj.Selected; return true; },
}; };
//spacing
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.0f), showEntitiesHolder.RectTransform) { MinSize = new Point(0, 3) }, style: null);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.025f), paddedLeftPanel.RectTransform, Anchor.BottomCenter) { AbsoluteOffset = new Point(10, 0) }, TextManager.Get("PreviouslyUsedLabel")); new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.025f), paddedLeftPanel.RectTransform, Anchor.BottomCenter) { AbsoluteOffset = new Point(10, 0) }, TextManager.Get("PreviouslyUsedLabel"));
previouslyUsedList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.2f), paddedLeftPanel.RectTransform, Anchor.BottomCenter) { AbsoluteOffset = new Point(10, 0) }) previouslyUsedList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.2f), paddedLeftPanel.RectTransform, Anchor.BottomCenter) { AbsoluteOffset = new Point(10, 0) })
{ {
@@ -849,6 +861,8 @@ namespace Barotrauma
GUI.AddMessage(TextManager.Get("SubSavedNotification").Replace("[filepath]", Submarine.MainSub.FilePath), Color.Green); GUI.AddMessage(TextManager.Get("SubSavedNotification").Replace("[filepath]", Submarine.MainSub.FilePath), Color.Green);
Submarine.RefreshSavedSub(savePath);
linkedSubBox.ClearChildren(); linkedSubBox.ClearChildren();
foreach (Submarine sub in Submarine.SavedSubmarines) foreach (Submarine sub in Submarine.SavedSubmarines)
{ {
@@ -2210,19 +2224,19 @@ namespace Barotrauma
Sprite backgroundSprite = LevelGenerationParams.LevelParams.Find(l => l.BackgroundTopSprite != null).BackgroundTopSprite; Sprite backgroundSprite = LevelGenerationParams.LevelParams.Find(l => l.BackgroundTopSprite != null).BackgroundTopSprite;
Sprite backgroundSprite = LevelGenerationParams.LevelParams.Find(l => l.BackgroundTopSprite != null).BackgroundTopSprite; using (RenderTarget2D rt = new RenderTarget2D(
if (backgroundSprite != null) GameMain.Instance.GraphicsDevice,
width, height, false, SurfaceFormat.Color, DepthFormat.None))
using (SpriteBatch spriteBatch = new SpriteBatch(GameMain.Instance.GraphicsDevice))
{ {
spriteBatch.Begin(); GameMain.Instance.GraphicsDevice.SetRenderTarget(rt);
backgroundSprite.Draw(spriteBatch, Vector2.Zero, new Color(0.025f, 0.075f, 0.131f, 1.0f));
spriteBatch.End(); if (backgroundSprite != null)
} {
spriteBatch.Begin();
spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend, null, null, null, null, transform); backgroundSprite.Draw(spriteBatch, Vector2.Zero, new Color(0.025f, 0.075f, 0.131f, 1.0f));
Submarine.Draw(spriteBatch, false); spriteBatch.End();
Submarine.DrawFront(spriteBatch); }
Submarine.DrawDamageable(spriteBatch, null);
spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend, null, null, null, null, transform); spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend, null, null, null, null, transform);
Submarine.Draw(spriteBatch, false); Submarine.Draw(spriteBatch, false);
@@ -75,7 +75,6 @@
<Submarine file="Submarines/Bunyip.sub" /> <Submarine file="Submarines/Bunyip.sub" />
<Submarine file="Submarines/Humpback.sub" /> <Submarine file="Submarines/Humpback.sub" />
<Submarine file="Submarines/Dugong.sub" /> <Submarine file="Submarines/Dugong.sub" />
<Submarine file="Submarines/PAX.sub" />
<Submarine file="Submarines/Remora.sub" /> <Submarine file="Submarines/Remora.sub" />
<Submarine file="Submarines/RemoraDrone.sub" /> <Submarine file="Submarines/RemoraDrone.sub" />
<Text file="Content/Texts/EnglishVanilla.xml" /> <Text file="Content/Texts/EnglishVanilla.xml" />
@@ -1913,6 +1913,18 @@
<None Include="$(MSBuildThisFileDirectory)Content\Items\Misc\GuitarClown.ogg"> <None Include="$(MSBuildThisFileDirectory)Content\Items\Misc\GuitarClown.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
<None Include="$(MSBuildThisFileDirectory)Content\Items\PowerOnHeavy1.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\Items\PowerOnLight1.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\Items\PowerOnLight2.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\Items\PowerOnLight3.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\Items\Weapons\ElectricalDischarger.ogg"> <None Include="$(MSBuildThisFileDirectory)Content\Items\Weapons\ElectricalDischarger.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
@@ -2470,9 +2482,6 @@
<None Include="$(MSBuildThisFileDirectory)Content\Items\Door\DuctBreak.ogg"> <None Include="$(MSBuildThisFileDirectory)Content\Items\Door\DuctBreak.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
<None Include="$(MSBuildThisFileDirectory)Content\Items\Electricity\powerOn.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Content\Items\Electricity\Zap1.ogg"> <None Include="$(MSBuildThisFileDirectory)Content\Items\Electricity\Zap1.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
@@ -3083,9 +3092,6 @@
<None Include="$(MSBuildThisFileDirectory)Content\Items\Door\DoorBreak2.ogg"> <None Include="$(MSBuildThisFileDirectory)Content\Items\Door\DoorBreak2.ogg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
<None Include="$(MSBuildThisFileDirectory)Submarines\PAX.sub">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="$(MSBuildThisFileDirectory)Submarines\Remora.sub"> <None Include="$(MSBuildThisFileDirectory)Submarines\Remora.sub">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
@@ -289,17 +289,15 @@ namespace Barotrauma
public override void OnAttacked(Character attacker, AttackResult attackResult) public override void OnAttacked(Character attacker, AttackResult attackResult)
{ {
// Damage from falling etc.
if (Character.LastDamageSource == null) { return; }
float damage = attackResult.Damage; float damage = attackResult.Damage;
if (damage <= 0) { return; } if (damage <= 0) { return; }
if (attacker == null || attacker.IsDead || attacker.Removed) if (attacker == null || attacker.IsDead || attacker.Removed)
{ {
if (objectiveManager.CurrentOrder == null) AddCombatObjective(AIObjectiveCombat.CombatMode.Retreat, Rand.Range(0.5f, 1f, Rand.RandSync.Unsynced));
{
objectiveManager.GetObjective<AIObjectiveFindSafety>().Priority = 100;
}
return;
} }
if (IsFriendly(attacker)) else if (IsFriendly(attacker))
{ {
if (attacker.AnimController.Anim == Barotrauma.AnimController.Animation.CPR && attacker.SelectedCharacter == Character) if (attacker.AnimController.Anim == Barotrauma.AnimController.Animation.CPR && attacker.SelectedCharacter == Character)
{ {
@@ -309,51 +307,50 @@ namespace Barotrauma
} }
if (!attacker.IsRemotePlayer && Character.Controlled != attacker && attacker.AIController != null && attacker.AIController.Enabled) if (!attacker.IsRemotePlayer && Character.Controlled != attacker && attacker.AIController != null && attacker.AIController.Enabled)
{ {
// Don't react to damage done by friendly ai, because we know that it's accidental // Don't retaliate on damage done by friendly ai, because we know that it's accidental
if (objectiveManager.CurrentOrder == null) AddCombatObjective(AIObjectiveCombat.CombatMode.Retreat, Rand.Range(0.5f, 1f, Rand.RandSync.Unsynced));
{
objectiveManager.GetObjective<AIObjectiveFindSafety>().Priority = 100;
}
return;
}
float currentVitality = Character.CharacterHealth.Vitality;
float dmgPercentage = damage / currentVitality * 100;
if (dmgPercentage < currentVitality / 10)
{
// Don't react to a minor amount of (accidental) dmg done by friendly characters
if (objectiveManager.CurrentOrder == null)
{
objectiveManager.GetObjective<AIObjectiveFindSafety>().Priority = 100;
}
}
if (ObjectiveManager.CurrentObjective is AIObjectiveCombat combatObjective)
{
if (combatObjective.Enemy != attacker)
{
// Replace the old objective with the new.
ObjectiveManager.Objectives.Remove(combatObjective);
objectiveManager.AddObjective(new AIObjectiveCombat(Character, attacker));
}
} }
else else
{ {
objectiveManager.AddObjective(new AIObjectiveCombat(Character, attacker), Rand.Range(0.5f, 1f, Rand.RandSync.Unsynced)); float currentVitality = Character.CharacterHealth.Vitality;
float dmgPercentage = damage / currentVitality * 100;
if (dmgPercentage < currentVitality / 10)
{
// Don't retaliate on minor (accidental) dmg done by friendly characters
AddCombatObjective(AIObjectiveCombat.CombatMode.Retreat, Rand.Range(0.5f, 1f, Rand.RandSync.Unsynced));
}
else
{
AddCombatObjective(AIObjectiveCombat.CombatMode.Defensive, Rand.Range(0.5f, 1f, Rand.RandSync.Unsynced));
}
} }
} }
else else
{
AddCombatObjective(AIObjectiveCombat.CombatMode.Defensive);
}
void AddCombatObjective(AIObjectiveCombat.CombatMode mode, float delay = 0)
{ {
if (ObjectiveManager.CurrentObjective is AIObjectiveCombat combatObjective) if (ObjectiveManager.CurrentObjective is AIObjectiveCombat combatObjective)
{ {
if (combatObjective.Enemy != attacker) if (combatObjective.Enemy != attacker || (combatObjective.Enemy == null && attacker == null))
{ {
// Replace the old objective with the new. // Replace the old objective with the new.
ObjectiveManager.Objectives.Remove(combatObjective); ObjectiveManager.Objectives.Remove(combatObjective);
objectiveManager.AddObjective(new AIObjectiveCombat(Character, attacker)); objectiveManager.AddObjective(new AIObjectiveCombat(Character, attacker, mode));
} }
} }
else else
{ {
objectiveManager.AddObjective(new AIObjectiveCombat(Character, attacker)); if (delay > 0)
{
objectiveManager.AddObjective(new AIObjectiveCombat(Character, attacker, mode), delay);
}
else
{
objectiveManager.AddObjective(new AIObjectiveCombat(Character, attacker, mode));
}
} }
} }
} }
@@ -43,11 +43,80 @@ namespace Barotrauma
private set; private set;
} }
public bool InLadders => currentPath != null && currentPath.CurrentNode != null && currentPath.CurrentNode.Ladders != null; /// <summary>
public bool IsNextNodeLadder => currentPath.NextNode != null && currentPath.CurrentNode.Ladders != null; /// Returns true if the current or the next node is in ladders.
public bool IsNextLadderSameAsCurrent => IsNextNodeLadder && currentPath.CurrentNode.Ladders == currentPath.NextNode.Ladders; /// </summary>
public bool InLadders =>
currentPath != null &&
currentPath.CurrentNode != null && (currentPath.CurrentNode.Ladders != null ||
(currentPath.NextNode != null && currentPath.NextNode.Ladders != null));
public bool InStairs => currentPath != null && currentPath.CurrentNode != null && currentPath.CurrentNode.Stairs != null; /// <summary>
/// Returns true if the current or the next node is in stairs.
/// </summary>
public bool InStairs =>
currentPath != null &&
currentPath.CurrentNode != null && (currentPath.CurrentNode.Stairs != null ||
(currentPath.NextNode != null && currentPath.NextNode.Stairs != null));
public bool IsNextNodeLadder
{
get
{
if (currentPath == null) { return false; }
if (currentPath.NextNode == null) { return false; }
if (currentPath.NextNode.Ladders != null)
{
return true;
}
else
{
// Check if the node after the next node is ladder.
int index = currentPath.CurrentIndex + 2;
if (currentPath.Nodes.Count > index)
{
var node = currentPath.Nodes[index];
if (node == null) { return false; }
// Only applied if the node is close enough to the current node.
if (Vector2.DistanceSquared(currentPath.CurrentNode.WorldPosition, node.WorldPosition) > 100) { return false; }
return node.Ladders != null;
}
return false;
}
}
}
public bool IsNextLadderSameAsCurrent
{
get
{
if (currentPath == null) { return false; }
if (currentPath.CurrentNode == null) { return false; }
if (currentPath.NextNode == null) { return false; }
var currentLadder = currentPath.CurrentNode.Ladders;
if (currentLadder == null) { return false; }
var nextLadder = currentPath.NextNode.Ladders;
if (nextLadder != null)
{
return currentLadder == nextLadder;
}
else
{
// Check if the node after the next node is in the same ladder as the current.
int index = currentPath.CurrentIndex + 2;
if (currentPath.Nodes.Count > index)
{
var node = currentPath.Nodes[index];
if (node == null) { return false; }
// Only applied if the node is close enough to the current node.
if (Vector2.DistanceSquared(currentPath.CurrentNode.WorldPosition, node.WorldPosition) > 100) { return false; }
nextLadder = node.Ladders;
return nextLadder != null && nextLadder == currentLadder;
}
return false;
}
}
}
public IndoorsSteeringManager(ISteerable host, bool canOpenDoors, bool canBreakDoors) : base(host) public IndoorsSteeringManager(ISteerable host, bool canOpenDoors, bool canBreakDoors) : base(host)
{ {
@@ -173,7 +242,7 @@ namespace Barotrauma
Vector2 diff = currentPath.CurrentNode.SimPosition - pos; Vector2 diff = currentPath.CurrentNode.SimPosition - pos;
bool nextLadderSamesCurrent = IsNextLadderSameAsCurrent; bool nextLadderSamesCurrent = IsNextLadderSameAsCurrent;
if (IsNextLadderSameAsCurrent) if (nextLadderSamesCurrent)
{ {
//climbing ladders -> don't move horizontally //climbing ladders -> don't move horizontally
diff.X = 0.0f; diff.X = 0.0f;
@@ -191,14 +260,14 @@ namespace Barotrauma
bool aboveFloor = heightFromFloor > 0.0f && heightFromFloor < collider.height * 1.5f; bool aboveFloor = heightFromFloor > 0.0f && heightFromFloor < collider.height * 1.5f;
if (aboveFloor || IsNextNodeLadder) if (aboveFloor || IsNextNodeLadder)
{ {
if (!IsNextLadderSameAsCurrent) if (!nextLadderSamesCurrent)
{ {
character.AnimController.Anim = AnimController.Animation.None; character.AnimController.Anim = AnimController.Animation.None;
} }
currentPath.SkipToNextNode(); currentPath.SkipToNextNode();
} }
} }
else if (IsNextLadderSameAsCurrent) else if (nextLadderSamesCurrent)
{ {
//if the current node is below the character and the next one is above (or vice versa) //if the current node is below the character and the next one is above (or vice versa)
//and both are on ladders, we can skip directly to the next one //and both are on ladders, we can skip directly to the next one
@@ -47,25 +47,32 @@ namespace Barotrauma
private float coolDownTimer; private float coolDownTimer;
public AIObjectiveCombat(Character character, Character enemy) : base(character, "") public enum CombatMode
{
Defensive,
Offensive, // Not implemented
Retreat
}
public CombatMode Mode { get; private set; }
public AIObjectiveCombat(Character character, Character enemy, CombatMode mode) : base(character, "")
{ {
Enemy = enemy; Enemy = enemy;
coolDownTimer = CoolDown; coolDownTimer = CoolDown;
HumanAIController.ObjectiveManager.GetObjective<AIObjectiveFindSafety>().Priority = 0; HumanAIController.ObjectiveManager.GetObjective<AIObjectiveFindSafety>().Priority = 0;
Mode = mode;
if (Enemy == null)
{
Mode = CombatMode.Retreat;
}
} }
protected override void Act(float deltaTime) protected override void Act(float deltaTime)
{ {
coolDownTimer -= deltaTime; coolDownTimer -= deltaTime;
if (Weapon != null && character.Inventory.Items.Contains(_weapon)) if (abandon) { return; }
{ switch (Mode)
Weapon = null;
}
if (Weapon == null)
{
Weapon = GetWeapon();
}
if (Weapon == null)
{ {
case CombatMode.Defensive: case CombatMode.Defensive:
if (Weapon != null && character.Inventory.Items.Contains(_weapon)) if (Weapon != null && character.Inventory.Items.Contains(_weapon))
@@ -97,17 +104,6 @@ namespace Barotrauma
default: default:
throw new System.NotImplementedException(); throw new System.NotImplementedException();
} }
else if (Equip(deltaTime))
{
if (Reload(deltaTime))
{
Attack(deltaTime);
}
}
if (!abandon)
{
Move(deltaTime);
}
} }
private Item GetWeapon() private Item GetWeapon()
@@ -140,6 +136,21 @@ namespace Barotrauma
} }
} }
} }
// When defensive, try to retreat to safety. TODO: in offsensive mode, engage the target
Retreat(deltaTime);
break;
case CombatMode.Retreat:
Retreat(deltaTime);
break;
case CombatMode.Offensive:
default:
throw new System.NotImplementedException();
}
else if (Equip(deltaTime))
{
if (Reload(deltaTime))
{
Attack(deltaTime);
} }
} }
return weapon; return weapon;
@@ -168,20 +179,18 @@ namespace Barotrauma
else else
{ {
//couldn't equip the item, escape //couldn't equip the item, escape
Escape(deltaTime); //Abandon(deltaTime);
return false; return false;
} }
} }
return true; return true;
} }
private void Move(float deltaTime) private void Retreat(float deltaTime)
{ {
// Retreat to safety
// TODO: aggressive behaviour, chasing?
if (retreatTarget == null || (retreatObjective != null && !retreatObjective.CanBeCompleted)) if (retreatTarget == null || (retreatObjective != null && !retreatObjective.CanBeCompleted))
{ {
retreatTarget = HumanAIController.ObjectiveManager.GetObjective<AIObjectiveFindSafety>().FindBestHull(); retreatTarget = HumanAIController.ObjectiveManager.GetObjective<AIObjectiveFindSafety>().FindBestHull(new List<Hull>() { character.CurrentHull });
} }
if (retreatTarget != null) if (retreatTarget != null)
{ {
@@ -218,7 +227,7 @@ namespace Barotrauma
} }
else if (!reloadWeaponObjective.CanBeCompleted) else if (!reloadWeaponObjective.CanBeCompleted)
{ {
Escape(deltaTime); Mode = CombatMode.Retreat;
} }
else else
{ {
@@ -277,16 +286,16 @@ namespace Barotrauma
} }
} }
private void Escape(float deltaTime) private void Abandon(float deltaTime)
{ {
abandon = true; abandon = true;
SteeringManager.Reset(); SteeringManager.Reset();
HumanAIController.ObjectiveManager.GetObjective<AIObjectiveFindSafety>().Priority = 100; //HumanAIController.ObjectiveManager.GetObjective<AIObjectiveFindSafety>().Priority = 100;
} }
public override bool IsCompleted() public override bool IsCompleted()
{ {
bool completed = Enemy == null || Enemy.Removed || Enemy.IsDead || coolDownTimer <= 0; bool completed = (Enemy != null && (Enemy.Removed || Enemy.IsDead)) || coolDownTimer <= 0;
if (completed) if (completed)
{ {
if (Weapon != null) if (Weapon != null)
@@ -298,7 +307,7 @@ namespace Barotrauma
} }
public override bool CanBeCompleted => !abandon && (reloadWeaponObjective == null || reloadWeaponObjective.CanBeCompleted) && (retreatObjective == null || retreatObjective.CanBeCompleted); public override bool CanBeCompleted => !abandon && (reloadWeaponObjective == null || reloadWeaponObjective.CanBeCompleted) && (retreatObjective == null || retreatObjective.CanBeCompleted);
public override float GetPriority(AIObjectiveManager objectiveManager) => Enemy == null || Enemy.Removed || Enemy.IsDead ? 0 : 100; public override float GetPriority(AIObjectiveManager objectiveManager) => (Enemy != null && (Enemy.Removed || Enemy.IsDead)) ? 0 : 100;
public override bool IsDuplicate(AIObjective otherObjective) public override bool IsDuplicate(AIObjective otherObjective)
{ {
@@ -86,7 +86,10 @@ namespace Barotrauma
character.AIController.SteeringManager.Reset(); character.AIController.SteeringManager.Reset();
character.CursorPosition = fs.Position; character.CursorPosition = fs.Position;
character.SetInput(InputType.Aim, false, true); if (extinguisher.Item.RequireAimToUse)
{
character.SetInput(InputType.Aim, false, true);
}
extinguisher.Use(deltaTime, character); extinguisher.Use(deltaTime, character);
if (!targetHull.FireSources.Contains(fs)) if (!targetHull.FireSources.Contains(fs))
@@ -168,13 +168,14 @@ namespace Barotrauma
} }
} }
public Hull FindBestHull() public Hull FindBestHull(IEnumerable<Hull> ignoredHulls = null)
{ {
Hull bestHull = character.CurrentHull; Hull bestHull = null;
float bestValue = currenthullSafety; float bestValue = 0;
foreach (Hull hull in Hull.hullList) foreach (Hull hull in Hull.hullList)
{ {
if (hull.Submarine == null) { continue; } if (hull.Submarine == null) { continue; }
if (ignoredHulls != null && ignoredHulls.Contains(hull)) { continue; }
float hullSafety = 0; float hullSafety = 0;
if (character.Submarine != null && SteeringManager == PathSteering) if (character.Submarine != null && SteeringManager == PathSteering)
{ {
@@ -161,7 +161,7 @@ namespace Barotrauma
private void OperateRepairTool(float deltaTime) private void OperateRepairTool(float deltaTime)
{ {
character.CursorPosition = Item.Position; character.CursorPosition = Item.Position;
if (Item.RequireAimToUse) if (repairTool.Item.RequireAimToUse)
{ {
character.SetInput(InputType.Aim, false, true); character.SetInput(InputType.Aim, false, true);
} }
@@ -64,6 +64,7 @@ namespace Barotrauma.Items.Components
attack = new Attack(subElement, item.Name + ", MeleeWeapon"); attack = new Attack(subElement, item.Name + ", MeleeWeapon");
} }
item.IsShootable = true; item.IsShootable = true;
// TODO: should define this in xml if we have melee weapons that don't require aim to use
item.RequireAimToUse = true; item.RequireAimToUse = true;
} }
@@ -58,6 +58,7 @@ namespace Barotrauma.Items.Components
: base(item, element) : base(item, element)
{ {
item.IsShootable = true; item.IsShootable = true;
// TODO: should define this in xml if we have ranged weapons that don't require aim to use
item.RequireAimToUse = true; item.RequireAimToUse = true;
} }
@@ -80,6 +80,7 @@ namespace Barotrauma.Items.Components
} }
} }
item.IsShootable = true; item.IsShootable = true;
// TODO: should define this in xml if we have repair tools that don't require aim to use
item.RequireAimToUse = true; item.RequireAimToUse = true;
InitProjSpecific(element); InitProjSpecific(element);
} }
@@ -533,25 +533,6 @@ namespace Barotrauma
{ {
maxX = Math.Min(maxX, ruin.Area.X - 100.0f); maxX = Math.Min(maxX, ruin.Area.X - 100.0f);
} }
else
{
maxX = Math.Min(maxX, ruin.Area.X - 100.0f);
}
}
if (minX < 0.0f && maxX > Level.Loaded.Size.X)
{
//no walls found at either side, just use the initial spawnpos and hope for the best
}
else if (minX < 0)
{
//no wall found at the left side, spawn to the left from the right-side wall
spawnPos.X = maxX - minWidth - 100.0f + subDockingPortOffset;
}
else if (maxX > Level.Loaded.Size.X)
{
//no wall found at right side, spawn to the right from the left-side wall
spawnPos.X = minX + minWidth + 100.0f + subDockingPortOffset;
} }
if (minX < 0.0f && maxX > Level.Loaded.Size.X) if (minX < 0.0f && maxX > Level.Loaded.Size.X)