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

This commit is contained in:
Joonas Rikkonen
2019-05-18 17:35:10 +03:00
parent 65a914e5ed
commit f1d794cb39
21 changed files with 241 additions and 162 deletions
@@ -332,7 +332,6 @@ namespace Barotrauma
CharacterInventory.Layout.Right; CharacterInventory.Layout.Right;
} }
} }
}
if (!character.IsUnconscious && character.Stun <= 0.0f) if (!character.IsUnconscious && character.Stun <= 0.0f)
{ {
@@ -371,7 +370,13 @@ namespace Barotrauma
private static void DrawOrderIndicator(SpriteBatch spriteBatch, Camera cam, Character character, Order order, float iconAlpha = 1.0f) private static void DrawOrderIndicator(SpriteBatch spriteBatch, Camera cam, Character character, Order order, float iconAlpha = 1.0f)
{ {
if (order.TargetAllCharacters && !order.HasAppropriateJob(character)) { return; } if (order.TargetAllCharacters)
{
if (order.OrderGiver != character && !order.HasAppropriateJob(character))
{
return;
}
}
Entity target = order.ConnectedController != null ? order.ConnectedController.Item : order.TargetEntity; Entity target = order.ConnectedController != null ? order.ConnectedController.Item : order.TargetEntity;
if (target == null) { return; } if (target == null) { return; }
@@ -331,8 +331,11 @@ namespace Barotrauma
if (!string.IsNullOrEmpty(text)) if (!string.IsNullOrEmpty(text))
{ {
Vector2 pos = rect.Location.ToVector2() + textPos + TextOffset; Vector2 pos = rect.Location.ToVector2() + textPos + TextOffset;
pos.X = (int)pos.X; if (RoundToNearestPixel)
pos.Y = (int)pos.Y; {
pos.X = (int)pos.X;
pos.Y = (int)pos.Y;
}
Font.DrawString(spriteBatch, Font.DrawString(spriteBatch,
Wrap ? wrappedText : text, Wrap ? wrappedText : text,
@@ -334,7 +334,7 @@ namespace Barotrauma
SoundManager.SetCategoryGainMultiplier("ui", Config.SoundVolume); SoundManager.SetCategoryGainMultiplier("ui", Config.SoundVolume);
SoundManager.SetCategoryGainMultiplier("waterambience", Config.SoundVolume); SoundManager.SetCategoryGainMultiplier("waterambience", Config.SoundVolume);
SoundManager.SetCategoryGainMultiplier("music", Config.MusicVolume); SoundManager.SetCategoryGainMultiplier("music", Config.MusicVolume);
SoundManager.SetCategoryGainMultiplier("voip", Config.VoiceChatVolume); SoundManager.SetCategoryGainMultiplier("voip", Config.VoiceChatVolume * 5.0f);
if (Config.EnableSplashScreen) if (Config.EnableSplashScreen)
{ {
var pendingSplashScreens = TitleScreen.PendingSplashScreens; var pendingSplashScreens = TitleScreen.PendingSplashScreens;
@@ -747,7 +747,7 @@ namespace Barotrauma
{ {
if (orderGiver == null || orderGiver.CurrentHull == null) { return; } if (orderGiver == null || orderGiver.CurrentHull == null) { return; }
var hull = orderGiver.CurrentHull; var hull = orderGiver.CurrentHull;
AddOrder(new Order(order.Prefab, hull, null), order.Prefab.FadeOutTime); AddOrder(new Order(order.Prefab, hull, null, orderGiver), order.Prefab.FadeOutTime);
if (IsSinglePlayer) if (IsSinglePlayer)
{ {
orderGiver.Speak( orderGiver.Speak(
@@ -1350,7 +1350,7 @@ namespace Barotrauma
bool hasFires = Character.Controlled.CurrentHull.FireSources.Count > 0; bool hasFires = Character.Controlled.CurrentHull.FireSources.Count > 0;
ToggleReportButton("reportfire", hasFires); ToggleReportButton("reportfire", hasFires);
bool hasLeaks = Character.Controlled.CurrentHull.ConnectedGaps.Any(g => !g.IsRoomToRoom && g.Open > 0.0f); bool hasLeaks = Character.Controlled.CurrentHull.Submarine != null && Character.Controlled.CurrentHull.ConnectedGaps.Any(g => !g.IsRoomToRoom && g.Open > 0.0f);
ToggleReportButton("reportbreach", hasLeaks); ToggleReportButton("reportbreach", hasLeaks);
bool hasIntruders = Character.CharacterList.Any(c => c.CurrentHull == Character.Controlled.CurrentHull && AIObjectiveFightIntruders.IsValidTarget(Character.Controlled, c)); bool hasIntruders = Character.CharacterList.Any(c => c.CurrentHull == Character.Controlled.CurrentHull && AIObjectiveFightIntruders.IsValidTarget(Character.Controlled, c));
@@ -233,9 +233,9 @@ namespace Barotrauma.Tutorials
//patient 1 requests first aid //patient 1 requests first aid
patient1.CanSpeak = true; patient1.CanSpeak = true;
var newOrder = new Order(Order.PrefabList.Find(o => o.AITag == "requestfirstaid"), patient1.CurrentHull, null); var newOrder = new Order(Order.PrefabList.Find(o => o.AITag == "requestfirstaid"), patient1.CurrentHull, null, orderGiver: patient1);
GameMain.GameSession.CrewManager.AddOrder(newOrder, newOrder.FadeOutTime); GameMain.GameSession.CrewManager.AddOrder(newOrder, newOrder.FadeOutTime);
patient1.Speak(newOrder.GetChatMessage("", patient1.CurrentHull?.RoomName, givingOrderToSelf: false), ChatMessageType.Order); patient1.Speak(newOrder.GetChatMessage("", patient1.CurrentHull?.DisplayName, givingOrderToSelf: false), ChatMessageType.Order);
patient1.AIController.Enabled = true; patient1.AIController.Enabled = true;
while (doctor.CurrentHull != patient1.CurrentHull) while (doctor.CurrentHull != patient1.CurrentHull)
@@ -317,9 +317,9 @@ namespace Barotrauma.Tutorials
//patient calls for help //patient calls for help
patient2.CanSpeak = true; patient2.CanSpeak = true;
newOrder = new Order(Order.PrefabList.Find(o => o.AITag == "requestfirstaid"), patient2.CurrentHull, null); newOrder = new Order(Order.PrefabList.Find(o => o.AITag == "requestfirstaid"), patient2.CurrentHull, null, orderGiver: patient2);
GameMain.GameSession.CrewManager.AddOrder(newOrder, newOrder.FadeOutTime); GameMain.GameSession.CrewManager.AddOrder(newOrder, newOrder.FadeOutTime);
patient2.Speak(newOrder.GetChatMessage("", patient1.CurrentHull?.RoomName, givingOrderToSelf: false), ChatMessageType.Order); patient2.Speak(newOrder.GetChatMessage("", patient1.CurrentHull?.DisplayName, givingOrderToSelf: false), ChatMessageType.Order);
patient2.AIController.Enabled = true; patient2.AIController.Enabled = true;
patient2.Oxygen = -50; patient2.Oxygen = -50;
CoroutineManager.StartCoroutine(KeepPatientAlive(patient2), "KeepPatient2Alive"); CoroutineManager.StartCoroutine(KeepPatientAlive(patient2), "KeepPatient2Alive");
@@ -378,10 +378,10 @@ namespace Barotrauma.Tutorials
//(within 1 minute intervals of entering the sub) //(within 1 minute intervals of entering the sub)
if (!patientCalledHelp[i] && Timing.TotalTime > subEnterTime + 60 * (i + 1)) if (!patientCalledHelp[i] && Timing.TotalTime > subEnterTime + 60 * (i + 1))
{ {
newOrder = new Order(Order.PrefabList.Find(o => o.AITag == "requestfirstaid"), subPatients[i].CurrentHull, null); newOrder = new Order(Order.PrefabList.Find(o => o.AITag == "requestfirstaid"), subPatients[i].CurrentHull, null, orderGiver: subPatients[i]);
GameMain.GameSession.CrewManager.AddOrder(newOrder, newOrder.FadeOutTime); GameMain.GameSession.CrewManager.AddOrder(newOrder, newOrder.FadeOutTime);
string message = newOrder.GetChatMessage("", subPatients[i].CurrentHull?.RoomName, givingOrderToSelf: false); string message = newOrder.GetChatMessage("", subPatients[i].CurrentHull?.DisplayName, givingOrderToSelf: false);
if (subPatients[i].CanSpeak) if (subPatients[i].CanSpeak)
{ {
subPatients[i].Speak(message, ChatMessageType.Order); subPatients[i].Speak(message, ChatMessageType.Order);
@@ -105,7 +105,8 @@ namespace Barotrauma.Items.Components
textBlock = new GUITextBlock(new RectTransform(item.Rect.Size), "", textBlock = new GUITextBlock(new RectTransform(item.Rect.Size), "",
textColor: textColor, font: GUI.UnscaledSmallFont, textAlignment: Alignment.Center, wrap: true, style: null) textColor: textColor, font: GUI.UnscaledSmallFont, textAlignment: Alignment.Center, wrap: true, style: null)
{ {
TextDepth = item.SpriteDepth - 0.0001f, TextDepth = item.SpriteDepth - 0.00001f,
RoundToNearestPixel = false,
TextScale = TextScale TextScale = TextScale
}; };
} }
@@ -441,8 +441,8 @@ namespace Barotrauma.Items.Components
{ {
Vector2 sector1 = MathUtils.RotatePointAroundTarget(pingDirection * DisplayRadius, Vector2.Zero, DirectionalPingSector * 0.5f); Vector2 sector1 = MathUtils.RotatePointAroundTarget(pingDirection * DisplayRadius, Vector2.Zero, DirectionalPingSector * 0.5f);
Vector2 sector2 = MathUtils.RotatePointAroundTarget(pingDirection * DisplayRadius, Vector2.Zero, -DirectionalPingSector * 0.5f); Vector2 sector2 = MathUtils.RotatePointAroundTarget(pingDirection * DisplayRadius, Vector2.Zero, -DirectionalPingSector * 0.5f);
DrawLine(spriteBatch, center, center + sector1, Color.LightCyan * 0.2f * directionalPingVisibility, width: 3); DrawLine(spriteBatch, Vector2.Zero, sector1, Color.LightCyan * 0.2f * directionalPingVisibility, width: 3);
DrawLine(spriteBatch, center, center + sector2, Color.LightCyan * 0.2f * directionalPingVisibility, width: 3); DrawLine(spriteBatch, Vector2.Zero, sector2, Color.LightCyan * 0.2f * directionalPingVisibility, width: 3);
} }
if (GameMain.DebugDraw) if (GameMain.DebugDraw)
@@ -66,13 +66,13 @@ namespace Barotrauma.Networking
if (order.TargetAllCharacters) if (order.TargetAllCharacters)
{ {
GameMain.GameSession?.CrewManager?.AddOrder( GameMain.GameSession?.CrewManager?.AddOrder(
new Order(order.Prefab, targetEntity, (targetEntity as Item)?.Components.FirstOrDefault(ic => ic.GetType() == order.ItemComponentType)), new Order(order.Prefab, targetEntity, (targetEntity as Item)?.Components.FirstOrDefault(ic => ic.GetType() == order.ItemComponentType), orderGiver: senderCharacter),
order.Prefab.FadeOutTime); order.Prefab.FadeOutTime);
} }
else if (targetCharacter != null) else if (targetCharacter != null)
{ {
targetCharacter.SetOrder( targetCharacter.SetOrder(
new Order(order.Prefab, targetEntity, (targetEntity as Item)?.Components.FirstOrDefault(ic => ic.GetType() == order.ItemComponentType)), new Order(order.Prefab, targetEntity, (targetEntity as Item)?.Components.FirstOrDefault(ic => ic.GetType() == order.ItemComponentType), orderGiver: senderCharacter),
orderOption, senderCharacter); orderOption, senderCharacter);
} }
@@ -27,6 +27,9 @@ namespace Barotrauma
case "text": case "text":
AddTextElement(subElement, listBox.Content.RectTransform); AddTextElement(subElement, listBox.Content.RectTransform);
break; break;
case "gridtext":
AddGridTextElement(subElement, listBox.Content.RectTransform);
break;
case "spacing": case "spacing":
AddSpacingElement(subElement, listBox.Content.RectTransform); AddSpacingElement(subElement, listBox.Content.RectTransform);
break; break;
@@ -38,9 +41,9 @@ namespace Barotrauma
listBox.UpdateScrollBarSize(); listBox.UpdateScrollBarSize();
} }
private void AddTextElement(XElement element, RectTransform parent) private GUIComponent AddTextElement(XElement element, RectTransform parent, string overrideText = null, Anchor anchor = Anchor.Center)
{ {
var text = element.ElementInnerText().Replace(@"\n", "\n"); var text = overrideText ?? element.ElementInnerText().Replace(@"\n", "\n");
Color color = element.GetAttributeColor("color", Color.White); Color color = element.GetAttributeColor("color", Color.White);
float scale = element.GetAttributeFloat("scale", 1.0f); float scale = element.GetAttributeFloat("scale", 1.0f);
Alignment alignment = Alignment.Center; Alignment alignment = Alignment.Center;
@@ -69,7 +72,7 @@ namespace Barotrauma
} }
var textHolder = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.0f), parent), style: null); var textHolder = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.0f), parent), style: null);
var textBlock = new GUITextBlock(new RectTransform(new Vector2(0.5f, 0.0f), textHolder.RectTransform, Anchor.Center), var textBlock = new GUITextBlock(new RectTransform(new Vector2(0.5f, 0.0f), textHolder.RectTransform, anchor),
text, text,
color, color,
font, font,
@@ -81,6 +84,32 @@ namespace Barotrauma
textBlock.RectTransform.IsFixedSize = textHolder.RectTransform.IsFixedSize = true; textBlock.RectTransform.IsFixedSize = textHolder.RectTransform.IsFixedSize = true;
textBlock.RectTransform.NonScaledSize = new Point(textBlock.Rect.Width, textBlock.Rect.Height); textBlock.RectTransform.NonScaledSize = new Point(textBlock.Rect.Width, textBlock.Rect.Height);
textHolder.RectTransform.NonScaledSize = new Point(textHolder.Rect.Width, textBlock.Rect.Height); textHolder.RectTransform.NonScaledSize = new Point(textHolder.Rect.Width, textBlock.Rect.Height);
return textHolder;
}
private void AddGridTextElement(XElement element, RectTransform parent)
{
var text = element.ElementInnerText().Replace(@"\n", "\n");
string[] elements = text.Split(',');
RectTransform lineContainer = null;
for (int i = 0; i < elements.Length; i++)
{
switch (i % 3)
{
case 0:
lineContainer = AddTextElement(element, parent, elements[i], Anchor.CenterLeft).RectTransform;
lineContainer.Anchor = Anchor.TopCenter;
lineContainer.Pivot = Pivot.TopCenter;
lineContainer.NonScaledSize = new Point((int)(parent.NonScaledSize.X * 0.7f), lineContainer.NonScaledSize.Y);
break;
case 1:
AddTextElement(element, lineContainer, elements[i], Anchor.Center).GetChild<GUITextBlock>().TextAlignment = Alignment.Center;
break;
case 2:
AddTextElement(element, lineContainer, elements[i], Anchor.CenterRight).GetChild<GUITextBlock>().TextAlignment = Alignment.CenterRight;
break;
}
}
} }
private void AddSpacingElement(XElement element, RectTransform parent) private void AddSpacingElement(XElement element, RectTransform parent)
@@ -440,9 +440,21 @@ namespace Barotrauma
GameMain.Config.SettingsFrame.RectTransform.RelativeSize = Vector2.One; GameMain.Config.SettingsFrame.RectTransform.RelativeSize = Vector2.One;
break; break;
case Tab.JoinServer: case Tab.JoinServer:
if (!GameMain.Config.CampaignDisclaimerShown)
{
selectedTab = 0;
GameMain.Instance.ShowCampaignDisclaimer(() => { SelectTab(null, Tab.JoinServer); });
return true;
}
GameMain.ServerListScreen.Select(); GameMain.ServerListScreen.Select();
break; break;
case Tab.HostServer: case Tab.HostServer:
if (!GameMain.Config.CampaignDisclaimerShown)
{
selectedTab = 0;
GameMain.Instance.ShowCampaignDisclaimer(() => { SelectTab(null, Tab.HostServer); });
return true;
}
break; break;
case Tab.Tutorials: case Tab.Tutorials:
if (!GameMain.Config.CampaignDisclaimerShown) if (!GameMain.Config.CampaignDisclaimerShown)
@@ -2408,7 +2408,10 @@ namespace Barotrauma.Networking
if (senderCharacter != null && if (senderCharacter != null &&
client.Character != null && !client.Character.IsDead) client.Character != null && !client.Character.IsDead)
{ {
modifiedMessage = ChatMessage.ApplyDistanceEffect(message, (ChatMessageType)type, senderCharacter, client.Character); if (senderCharacter != client.Character)
{
modifiedMessage = ChatMessage.ApplyDistanceEffect(message, (ChatMessageType)type, senderCharacter, client.Character);
}
//too far to hear the msg -> don't send //too far to hear the msg -> don't send
if (string.IsNullOrWhiteSpace(modifiedMessage)) continue; if (string.IsNullOrWhiteSpace(modifiedMessage)) continue;
@@ -2457,13 +2460,16 @@ namespace Barotrauma.Networking
if (message.Sender != null && if (message.Sender != null &&
client.Character != null && !client.Character.IsDead) client.Character != null && !client.Character.IsDead)
{ {
modifiedMessage = ChatMessage.ApplyDistanceEffect(message.Text, messageType, message.Sender, client.Character); if (message.Sender != client.Character)
{
modifiedMessage = ChatMessage.ApplyDistanceEffect(message.Text, messageType, message.Sender, client.Character);
}
//too far to hear the msg -> don't send //too far to hear the msg -> don't send
if (string.IsNullOrWhiteSpace(modifiedMessage)) continue; if (string.IsNullOrWhiteSpace(modifiedMessage)) continue;
} }
SendDirectChatMessage(message, client); SendDirectChatMessage(new OrderChatMessage(message.Order, message.OrderOption, message.TargetEntity, message.TargetCharacter, message.Sender), client);
} }
string myReceivedMessage = message.Text; string myReceivedMessage = message.Text;
@@ -85,12 +85,18 @@ namespace Barotrauma
if (Character.Submarine != null || SelectedAiTarget?.Entity?.Submarine != null) if (Character.Submarine != null || SelectedAiTarget?.Entity?.Submarine != null)
{ {
if (steeringManager != insideSteering) insideSteering.Reset(); if (steeringManager != insideSteering)
{
insideSteering.Reset();
}
steeringManager = insideSteering; steeringManager = insideSteering;
} }
else else
{ {
if (steeringManager != outsideSteering) outsideSteering.Reset(); if (steeringManager != outsideSteering)
{
outsideSteering.Reset();
}
steeringManager = outsideSteering; steeringManager = outsideSteering;
} }
@@ -295,7 +301,7 @@ namespace Barotrauma
if (newOrder == null) if (newOrder == null)
{ {
var orderPrefab = Order.PrefabList.Find(o => o.AITag == "reportintruders"); var orderPrefab = Order.PrefabList.Find(o => o.AITag == "reportintruders");
newOrder = new Order(orderPrefab, c.CurrentHull, null); newOrder = new Order(orderPrefab, c.CurrentHull, null, orderGiver: Character);
} }
} }
} }
@@ -305,7 +311,7 @@ namespace Barotrauma
if (newOrder == null) if (newOrder == null)
{ {
var orderPrefab = Order.PrefabList.Find(o => o.AITag == "reportfire"); var orderPrefab = Order.PrefabList.Find(o => o.AITag == "reportfire");
newOrder = new Order(orderPrefab, hull, null); newOrder = new Order(orderPrefab, hull, null, orderGiver: Character);
} }
} }
foreach (Character c in Character.CharacterList) foreach (Character c in Character.CharacterList)
@@ -317,7 +323,7 @@ namespace Barotrauma
if (newOrder == null) if (newOrder == null)
{ {
var orderPrefab = Order.PrefabList.Find(o => o.AITag == "requestfirstaid"); var orderPrefab = Order.PrefabList.Find(o => o.AITag == "requestfirstaid");
newOrder = new Order(orderPrefab, c.CurrentHull, null); newOrder = new Order(orderPrefab, c.CurrentHull, null, orderGiver: Character);
} }
} }
} }
@@ -329,7 +335,7 @@ namespace Barotrauma
if (newOrder == null) if (newOrder == null)
{ {
var orderPrefab = Order.PrefabList.Find(o => o.AITag == "reportbreach"); var orderPrefab = Order.PrefabList.Find(o => o.AITag == "reportbreach");
newOrder = new Order(orderPrefab, hull, null); newOrder = new Order(orderPrefab, hull, null, orderGiver: Character);
} }
} }
} }
@@ -343,7 +349,7 @@ namespace Barotrauma
if (newOrder == null) if (newOrder == null)
{ {
var orderPrefab = Order.PrefabList.Find(o => o.AITag == "reportbrokendevices"); var orderPrefab = Order.PrefabList.Find(o => o.AITag == "reportbrokendevices");
newOrder = new Order(orderPrefab, item.CurrentHull, item.Repairables?.FirstOrDefault()); newOrder = new Order(orderPrefab, item.CurrentHull, item.Repairables?.FirstOrDefault(), orderGiver: Character);
} }
} }
} }
@@ -354,6 +360,9 @@ namespace Barotrauma
if (GameMain.GameSession?.CrewManager != null && GameMain.GameSession.CrewManager.AddOrder(newOrder, newOrder.FadeOutTime)) if (GameMain.GameSession?.CrewManager != null && GameMain.GameSession.CrewManager.AddOrder(newOrder, newOrder.FadeOutTime))
{ {
Character.Speak(newOrder.GetChatMessage("", Character.CurrentHull?.DisplayName, givingOrderToSelf: false), ChatMessageType.Order); Character.Speak(newOrder.GetChatMessage("", Character.CurrentHull?.DisplayName, givingOrderToSelf: false), ChatMessageType.Order);
#if SERVER
GameMain.Server.SendOrderChatMessage(new OrderChatMessage(newOrder, "", Character.CurrentHull, null, Character));
#endif
} }
} }
} }
@@ -657,7 +666,7 @@ namespace Barotrauma
{ {
CurrentHullSafety = 0; CurrentHullSafety = 0;
} }
return 0; return CurrentHullSafety;
} }
if (character == Character) if (character == Character)
{ {
@@ -144,9 +144,9 @@ namespace Barotrauma
protected override Vector2 DoSteeringSeek(Vector2 target, float weight) protected override Vector2 DoSteeringSeek(Vector2 target, float weight)
{ {
bool isDifferentTarget = Vector2.DistanceSquared(target, currentTarget) > 1; bool needsNewPath = currentPath != null && currentPath.Unreachable || Vector2.DistanceSquared(target, currentTarget) > 1;
//find a new path if one hasn't been found yet or the target is different from the current target //find a new path if one hasn't been found yet or the target is different from the current target
if (currentPath == null || isDifferentTarget || findPathTimer < -1.0f) if (currentPath == null || needsNewPath || findPathTimer < -1.0f)
{ {
IsPathDirty = true; IsPathDirty = true;
@@ -164,7 +164,7 @@ namespace Barotrauma
} }
var newPath = pathFinder.FindPath(pos, target, "(Character: " + character.Name + ")"); var newPath = pathFinder.FindPath(pos, target, "(Character: " + character.Name + ")");
if (currentPath == null || isDifferentTarget || newPath.Cost < currentPath.Cost) if (currentPath == null || needsNewPath || !newPath.Unreachable && newPath.Cost < currentPath.Cost)
{ {
currentPath = newPath; currentPath = newPath;
} }
@@ -424,7 +424,7 @@ namespace Barotrauma
// It's possible that we could reach another buttons. // It's possible that we could reach another buttons.
// If this becomes an issue, we could go through them here and check if any of them are reachable // If this becomes an issue, we could go through them here and check if any of them are reachable
// (would have to cache a collection of buttons instead of a single reference in the CanAccess filter method above) // (would have to cache a collection of buttons instead of a single reference in the CanAccess filter method above)
currentPath.Unreachable = true; //currentPath.Unreachable = true;
return; return;
} }
} }
@@ -46,7 +46,7 @@ namespace Barotrauma
if (character.CurrentHull == null) if (character.CurrentHull == null)
{ {
currenthullSafety = 0; currenthullSafety = 0;
Priority = 100; Priority = objectiveManager.CurrentOrder is AIObjectiveGoTo ? 0 : 100;
return; return;
} }
if (character.OxygenAvailable < CharacterHealth.LowOxygenThreshold) { Priority = 100; } if (character.OxygenAvailable < CharacterHealth.LowOxygenThreshold) { Priority = 100; }
@@ -68,6 +68,8 @@ namespace Barotrauma
} }
} }
private Hull currentSafeHull;
private Hull previousSafeHull;
protected override void Act(float deltaTime) protected override void Act(float deltaTime)
{ {
var currentHull = character.AnimController.CurrentHull; var currentHull = character.AnimController.CurrentHull;
@@ -107,15 +109,20 @@ namespace Barotrauma
else else
{ {
searchHullTimer = SearchHullInterval; searchHullTimer = SearchHullInterval;
var bestHull = FindBestHull(); previousSafeHull = currentSafeHull;
if (bestHull != null && bestHull != currentHull) currentSafeHull = FindBestHull();
if (currentSafeHull == null)
{ {
if (goToObjective?.Target != bestHull) currentSafeHull = previousSafeHull;
}
if (currentSafeHull != null && currentSafeHull != currentHull)
{
if (goToObjective?.Target != currentSafeHull)
{ {
goToObjective = null; goToObjective = null;
} }
TryAddSubObjective(ref goToObjective, TryAddSubObjective(ref goToObjective,
constructor: () => new AIObjectiveGoTo(bestHull, character, objectiveManager, getDivingGearIfNeeded: false) constructor: () => new AIObjectiveGoTo(currentSafeHull, character, objectiveManager, getDivingGearIfNeeded: false)
{ {
// If we need diving gear, we should already have it, if possible. // If we need diving gear, we should already have it, if possible.
AllowGoingOutside = HumanAIController.HasDivingSuit(character) AllowGoingOutside = HumanAIController.HasDivingSuit(character)
@@ -127,7 +134,15 @@ namespace Barotrauma
goToObjective = null; goToObjective = null;
} }
} }
if (goToObjective != null) { return; } if (goToObjective != null)
{
if (goToObjective.IsCompleted())
{
objectiveManager.GetObjective<AIObjectiveIdle>()?.Wander(deltaTime);
}
Priority = 0;
return;
}
if (currentHull == null) { return; } if (currentHull == null) { return; }
//goto objective doesn't exist (a safe hull not found, or a path to a safe hull not found) //goto objective doesn't exist (a safe hull not found, or a path to a safe hull not found)
// -> attempt to manually steer away from hazards // -> attempt to manually steer away from hazards
@@ -166,7 +181,8 @@ namespace Barotrauma
} }
else else
{ {
character.AIController.SteeringManager.Reset(); Priority = 0;
objectiveManager.GetObjective<AIObjectiveIdle>()?.Wander(deltaTime);
} }
} }
} }
@@ -179,11 +195,11 @@ namespace Barotrauma
{ {
if (hull.Submarine == null) { continue; } if (hull.Submarine == null) { continue; }
if (ignoredHulls != null && ignoredHulls.Contains(hull)) { continue; } if (ignoredHulls != null && ignoredHulls.Contains(hull)) { continue; }
if (unreachable.Contains(hull)) { continue; }
float hullSafety = 0; float hullSafety = 0;
if (character.Submarine != null && SteeringManager == PathSteering) if (character.CurrentHull != null)
{ {
// Inside or outside near the sub // Inside
if (unreachable.Contains(hull)) { continue; }
if (!character.Submarine.IsConnectedTo(hull.Submarine)) { continue; } if (!character.Submarine.IsConnectedTo(hull.Submarine)) { continue; }
hullSafety = HumanAIController.GetHullSafety(hull, character); hullSafety = HumanAIController.GetHullSafety(hull, character);
// Vertical distance matters more than horizontal (climbing up/down is harder than moving horizontally) // Vertical distance matters more than horizontal (climbing up/down is harder than moving horizontally)
@@ -212,7 +228,7 @@ namespace Barotrauma
else else
{ {
// Outside // Outside
if (hull.RoomName?.ToLowerInvariant() == "airlock") if (hull.RoomName != null && hull.RoomName.ToLowerInvariant().Contains("airlock"))
{ {
hullSafety = 100; hullSafety = 100;
} }
@@ -221,13 +237,14 @@ namespace Barotrauma
// TODO: could also target gaps that get us inside? // TODO: could also target gaps that get us inside?
foreach (Item item in Item.ItemList) foreach (Item item in Item.ItemList)
{ {
if (item.CurrentHull == hull && item.HasTag("airlock")) if (item.CurrentHull != hull && item.HasTag("airlock"))
{ {
hullSafety = 100; hullSafety = 100;
break; break;
} }
} }
} }
// TODO: could we get a closest door to the outside and target the flowing hull if no airlock is found?
// Huge preference for closer targets // Huge preference for closer targets
float distance = Vector2.DistanceSquared(character.WorldPosition, hull.WorldPosition); float distance = Vector2.DistanceSquared(character.WorldPosition, hull.WorldPosition);
float distanceFactor = MathHelper.Lerp(1, 0.2f, MathUtils.InverseLerp(0, MathUtils.Pow(100000, 2), distance)); float distanceFactor = MathHelper.Lerp(1, 0.2f, MathUtils.InverseLerp(0, MathUtils.Pow(100000, 2), distance));
@@ -117,7 +117,7 @@ namespace Barotrauma
// Take the sub position into account in the sim pos // Take the sub position into account in the sim pos
if (character.Submarine == null && Target.Submarine != null) if (character.Submarine == null && Target.Submarine != null)
{ {
currTargetSimPos += Target.Submarine.SimPosition; //currTargetSimPos += Target.Submarine.SimPosition;
} }
else if (character.Submarine != null && Target.Submarine == null) else if (character.Submarine != null && Target.Submarine == null)
{ {
@@ -159,7 +159,6 @@ namespace Barotrauma
// First check the distance // First check the distance
// Then the custom condition // Then the custom condition
// And finally check if can interact (heaviest) // And finally check if can interact (heaviest)
if (repeat) { return false; }
if (isCompleted) { return true; } if (isCompleted) { return true; }
if (Target == null) if (Target == null)
{ {
@@ -167,7 +166,16 @@ namespace Barotrauma
return false; return false;
} }
bool closeEnough = Vector2.DistanceSquared(Target.WorldPosition, character.WorldPosition) < CloseEnough * CloseEnough; bool closeEnough = Vector2.DistanceSquared(Target.WorldPosition, character.WorldPosition) < CloseEnough * CloseEnough;
if (closeEnough) if (repeat)
{
if (closeEnough)
{
character.AIController.SteeringManager.Reset();
character.AnimController.TargetDir = Target.WorldPosition.X > character.WorldPosition.X ? Direction.Right : Direction.Left;
}
return false;
}
else if (closeEnough)
{ {
if (customCondition == null || customCondition()) if (customCondition == null || customCondition())
{ {
@@ -175,7 +183,7 @@ namespace Barotrauma
{ {
if (character.CanInteractWith(item, out _, checkLinked: false)) { isCompleted = true; } if (character.CanInteractWith(item, out _, checkLinked: false)) { isCompleted = true; }
} }
else if (Target is Character targetCharacter && !FollowControlledCharacter) else if (Target is Character targetCharacter)
{ {
if (character.CanInteractWith(targetCharacter, CloseEnough)) { isCompleted = true; } if (character.CanInteractWith(targetCharacter, CloseEnough)) { isCompleted = true; }
} }
@@ -81,7 +81,11 @@ namespace Barotrauma
Item.ItemList.FindAll(it => it.Components.Any(ic => ic.GetType() == orderPrefab.ItemComponentType)); Item.ItemList.FindAll(it => it.Components.Any(ic => ic.GetType() == orderPrefab.ItemComponentType));
matchingItems.RemoveAll(it => it.Submarine != character.Submarine); matchingItems.RemoveAll(it => it.Submarine != character.Submarine);
var item = matchingItems.GetRandom(); var item = matchingItems.GetRandom();
var order = new Order(orderPrefab, item ?? character.CurrentHull as Entity, item?.Components.FirstOrDefault(ic => ic.GetType() == orderPrefab.ItemComponentType)); var order = new Order(
orderPrefab,
item ?? character.CurrentHull as Entity,
item?.Components.FirstOrDefault(ic => ic.GetType() == orderPrefab.ItemComponentType),
orderGiver: character);
if (order == null) { continue; } if (order == null) { continue; }
var objective = CreateObjective(order, automaticOrder.option, character, automaticOrder.priorityModifier); var objective = CreateObjective(order, automaticOrder.option, character, automaticOrder.priorityModifier);
if (objective != null) if (objective != null)
@@ -198,6 +202,10 @@ namespace Barotrauma
{ {
CurrentObjective?.TryComplete(deltaTime); CurrentObjective?.TryComplete(deltaTime);
} }
else
{
character.AIController.SteeringManager.Reset();
}
} }
public void SetOrder(AIObjective objective) public void SetOrder(AIObjective objective)
@@ -39,7 +39,9 @@ namespace Barotrauma
public Entity TargetEntity; public Entity TargetEntity;
public ItemComponent TargetItemComponent; public ItemComponent TargetItemComponent;
public readonly bool UseController; public readonly bool UseController;
public Controller ConnectedController; public Controller ConnectedController;
public Character OrderGiver;
public readonly string[] AppropriateJobs; public readonly string[] AppropriateJobs;
public readonly string[] Options; public readonly string[] Options;
@@ -120,7 +122,7 @@ namespace Barotrauma
} }
} }
public Order(Order prefab, Entity targetEntity, ItemComponent targetItem) public Order(Order prefab, Entity targetEntity, ItemComponent targetItem, Character orderGiver = null)
{ {
Prefab = prefab; Prefab = prefab;
@@ -134,6 +136,7 @@ namespace Barotrauma
TargetAllCharacters = prefab.TargetAllCharacters; TargetAllCharacters = prefab.TargetAllCharacters;
AppropriateJobs = prefab.AppropriateJobs; AppropriateJobs = prefab.AppropriateJobs;
FadeOutTime = prefab.FadeOutTime; FadeOutTime = prefab.FadeOutTime;
OrderGiver = orderGiver;
TargetEntity = targetEntity; TargetEntity = targetEntity;
if (targetItem != null) if (targetItem != null)
@@ -165,8 +165,8 @@ namespace Barotrauma
{ {
Vector2 nodePos = node.Position; Vector2 nodePos = node.Position;
float xDiff = System.Math.Abs(start.X - nodePos.X); float xDiff = Math.Abs(start.X - nodePos.X);
float yDiff = System.Math.Abs(start.Y - nodePos.Y); float yDiff = Math.Abs(start.Y - nodePos.Y);
if (yDiff > 1.0f && node.Waypoint.Ladders == null && node.Waypoint.Stairs == null) if (yDiff > 1.0f && node.Waypoint.Ladders == null && node.Waypoint.Stairs == null)
{ {
@@ -190,7 +190,7 @@ namespace Barotrauma
if (body != null) if (body != null)
{ {
if (body.UserData is Submarine) continue; //if (body.UserData is Submarine) continue;
if (body.UserData is Structure && !((Structure)body.UserData).IsPlatform) continue; if (body.UserData is Structure && !((Structure)body.UserData).IsPlatform) continue;
if (body.UserData is Item && body.FixtureList[0].CollisionCategories.HasFlag(Physics.CollisionWall)) continue; if (body.UserData is Item && body.FixtureList[0].CollisionCategories.HasFlag(Physics.CollisionWall)) continue;
} }
@@ -216,8 +216,7 @@ namespace Barotrauma
{ {
Vector2 nodePos = node.Position; Vector2 nodePos = node.Position;
// TODO: use squared distance float dist = Vector2.DistanceSquared(end, nodePos);
float dist = Vector2.Distance(end, nodePos);
if (insideSubmarine) if (insideSubmarine)
{ {
//much higher cost to waypoints that are outside //much higher cost to waypoints that are outside
@@ -235,7 +234,7 @@ namespace Barotrauma
if (body != null) if (body != null)
{ {
if (body.UserData is Submarine) continue; //if (body.UserData is Submarine) continue;
if (body.UserData is Structure && !((Structure)body.UserData).IsPlatform) continue; if (body.UserData is Structure && !((Structure)body.UserData).IsPlatform) continue;
if (body.UserData is Item && body.FixtureList[0].CollisionCategories.HasFlag(Physics.CollisionWall)) continue; if (body.UserData is Item && body.FixtureList[0].CollisionCategories.HasFlag(Physics.CollisionWall)) continue;
@@ -206,7 +206,7 @@ namespace Barotrauma
{ {
voiceChatVolume = MathHelper.Clamp(value, 0.0f, 1.0f); voiceChatVolume = MathHelper.Clamp(value, 0.0f, 1.0f);
#if CLIENT #if CLIENT
GameMain.SoundManager?.SetCategoryGainMultiplier("voip", voiceChatVolume); GameMain.SoundManager?.SetCategoryGainMultiplier("voip", voiceChatVolume * 5.0f);
#endif #endif
} }
} }
@@ -424,6 +424,79 @@ namespace Barotrauma
{ {
Language = doc.Root.GetAttributeString("language", "English"); Language = doc.Root.GetAttributeString("language", "English");
} }
}
public void CheckBindings(bool useDefaults)
{
foreach (InputType inputType in Enum.GetValues(typeof(InputType)))
{
var binding = keyMapping[(int)inputType];
if (binding == null)
{
switch (inputType)
{
case InputType.Deselect:
if (useDefaults)
{
binding = new KeyOrMouse(1);
}
else
{
// Legacy support
var selectKey = keyMapping[(int)InputType.Select];
if (selectKey != null && selectKey.Key != Keys.None)
{
binding = new KeyOrMouse(selectKey.Key);
}
}
break;
case InputType.Shoot:
if (useDefaults)
{
binding = new KeyOrMouse(0);
}
else
{
// Legacy support
var useKey = keyMapping[(int)InputType.Use];
if (useKey != null && useKey.MouseButton.HasValue)
{
binding = new KeyOrMouse(useKey.MouseButton.Value);
}
}
break;
default:
break;
}
if (binding == null)
{
DebugConsole.ThrowError("Key binding for the input type \"" + inputType + " not set!");
binding = new KeyOrMouse(Keys.D1);
}
keyMapping[(int)inputType] = binding;
}
}
}
#region Load DefaultConfig
private void LoadDefaultConfig(bool setLanguage = true)
{
XDocument doc = XMLExtensions.TryLoadXml(savePath);
if (setLanguage || string.IsNullOrEmpty(Language))
{
Language = doc.Root.GetAttributeString("language", "English");
}
MasterServerUrl = doc.Root.GetAttributeString("masterserverurl", "");
AutoCheckUpdates = doc.Root.GetAttributeBool("autocheckupdates", true);
WasGameUpdated = doc.Root.GetAttributeBool("wasgameupdated", false);
VerboseLogging = doc.Root.GetAttributeBool("verboselogging", false);
SaveDebugConsoleLogs = doc.Root.GetAttributeBool("savedebugconsolelogs", false);
QuickStartSubmarineName = doc.Root.GetAttributeString("quickstartsub", "");
MasterServerUrl = doc.Root.GetAttributeString("masterserverurl", ""); MasterServerUrl = doc.Root.GetAttributeString("masterserverurl", "");
@@ -821,54 +894,6 @@ namespace Barotrauma
VoiceSetting = voiceSetting; VoiceSetting = voiceSetting;
} }
} }
if (!SelectedContentPackages.Any())
{
var availablePackage = ContentPackage.List.FirstOrDefault(cp => cp.IsCompatible() && cp.CorePackage);
if (availablePackage != null)
{
SelectedContentPackages.Add(availablePackage);
}
}
//save to get rid of the invalid selected packages in the config file
if (missingPackagePaths.Count > 0 || incompatiblePackages.Count > 0) { SaveNewPlayerConfig(); }
}
#endregion
#region Save DefaultConfig
private void SaveNewDefaultConfig()
{
XDocument doc = new XDocument();
if (doc.Root == null)
{
doc.Add(new XElement("config"));
}
doc.Root.Add(
new XAttribute("language", TextManager.Language),
new XAttribute("masterserverurl", MasterServerUrl),
new XAttribute("autocheckupdates", AutoCheckUpdates),
new XAttribute("musicvolume", musicVolume),
new XAttribute("soundvolume", soundVolume),
new XAttribute("voicechatvolume", voiceChatVolume),
new XAttribute("verboselogging", VerboseLogging),
new XAttribute("savedebugconsolelogs", SaveDebugConsoleLogs),
new XAttribute("enablesplashscreen", EnableSplashScreen),
new XAttribute("usesteammatchmaking", useSteamMatchmaking),
new XAttribute("quickstartsub", QuickStartSubmarineName),
new XAttribute("requiresteamauthentication", requireSteamAuthentication),
new XAttribute("aimassistamount", aimAssistAmount));
if (!ShowUserStatisticsPrompt)
{
doc.Root.Add(new XAttribute("senduserstatistics", sendUserStatistics));
}
if (WasGameUpdated)
{
doc.Root.Add(new XAttribute("wasgameupdated", true));
}
useSteamMatchmaking = doc.Root.GetAttributeBool("usesteammatchmaking", useSteamMatchmaking); useSteamMatchmaking = doc.Root.GetAttributeBool("usesteammatchmaking", useSteamMatchmaking);
requireSteamAuthentication = doc.Root.GetAttributeBool("requiresteamauthentication", requireSteamAuthentication); requireSteamAuthentication = doc.Root.GetAttributeBool("requiresteamauthentication", requireSteamAuthentication);
@@ -934,55 +959,6 @@ namespace Barotrauma
selectedContentPackagePaths = new HashSet<string>(); selectedContentPackagePaths = new HashSet<string>();
foreach (XElement subElement in doc.Root.Elements())
{
switch (subElement.Name.ToString().ToLowerInvariant())
{
case "keymapping":
LoadKeyBinds(subElement);
break;
case "gameplay":
jobPreferences = new List<string>();
foreach (XElement ele in subElement.Element("jobpreferences").Elements("job"))
{
string jobIdentifier = ele.GetAttributeString("identifier", "");
if (string.IsNullOrEmpty(jobIdentifier)) continue;
jobPreferences.Add(jobIdentifier);
}
break;
case "player":
defaultPlayerName = subElement.GetAttributeString("name", defaultPlayerName);
CharacterHeadIndex = subElement.GetAttributeInt("headindex", CharacterHeadIndex);
if (Enum.TryParse(subElement.GetAttributeString("gender", "none"), true, out Gender g))
{
CharacterGender = g;
}
if (Enum.TryParse(subElement.GetAttributeString("race", "white"), true, out Race r))
{
CharacterRace = r;
}
else
{
CharacterRace = Race.White;
}
CharacterHairIndex = subElement.GetAttributeInt("hairindex", CharacterHairIndex);
CharacterBeardIndex = subElement.GetAttributeInt("beardindex", CharacterBeardIndex);
CharacterMoustacheIndex = subElement.GetAttributeInt("moustacheindex", CharacterMoustacheIndex);
CharacterFaceAttachmentIndex = subElement.GetAttributeInt("faceattachmentindex", CharacterFaceAttachmentIndex);
break;
case "tutorials":
foreach (XElement tutorialElement in subElement.Elements())
{
CompletedTutorialNames.Add(tutorialElement.GetAttributeString("name", ""));
}
break;
}
}
UnsavedSettings = false;
selectedContentPackagePaths = new HashSet<string>();
foreach (XElement subElement in doc.Root.Elements()) foreach (XElement subElement in doc.Root.Elements())
{ {
gSettings = new XElement("graphicssettings"); gSettings = new XElement("graphicssettings");
@@ -168,7 +168,11 @@ namespace Barotrauma.Items.Components
} }
else else
{ {
FixBody(user, deltaTime, degreeOfSuccess, Submarine.PickBody(rayStart, rayEnd, ignoredBodies, collisionCategories, ignoreSensors: false, allowInsideFixture: true)); FixBody(user, deltaTime, degreeOfSuccess,
Submarine.PickBody(rayStart, rayEnd,
ignoredBodies, collisionCategories, ignoreSensors: false,
customPredicate: (Fixture f) => { return f?.Body?.UserData != null; },
allowInsideFixture: true));
} }
if (ExtinguishAmount > 0.0f && item.CurrentHull != null) if (ExtinguishAmount > 0.0f && item.CurrentHull != null)
@@ -609,8 +609,7 @@ namespace Barotrauma
foreach (InterestingPosition pos in positionsOfInterest) foreach (InterestingPosition pos in positionsOfInterest)
{ {
if (pos.PositionType != PositionType.MainPath || pos.Position.X < 5000 || pos.Position.X > Size.X - 5000) continue; if (pos.PositionType != PositionType.MainPath || pos.Position.X < 5000 || pos.Position.X > Size.X - 5000) continue;
if (Math.Abs(pos.Position.X - StartPosition.X) < 10000) continue; if (Math.Abs(pos.Position.X - StartPosition.X) < minWidth * 2 || Math.Abs(pos.Position.X - EndPosition.X) < minWidth * 2) continue;
if (Math.Abs(pos.Position.Y - StartPosition.Y) < 10000) continue;
if (GetTooCloseCells(pos.Position.ToVector2(), minWidth * 0.7f).Count > 0) continue; if (GetTooCloseCells(pos.Position.ToVector2(), minWidth * 0.7f).Count > 0) continue;
iceChunkPositions.Add(pos.Position); iceChunkPositions.Add(pos.Position);
} }