(98af64697) Updated readme file
This commit is contained in:
@@ -61,6 +61,14 @@ namespace Barotrauma
|
|||||||
var path = pathSteering.CurrentPath;
|
var path = pathSteering.CurrentPath;
|
||||||
if (path != null)
|
if (path != null)
|
||||||
{
|
{
|
||||||
|
if (path.CurrentNode != null)
|
||||||
|
{
|
||||||
|
GUI.DrawLine(spriteBatch, pos,
|
||||||
|
new Vector2(path.CurrentNode.DrawPosition.X, -path.CurrentNode.DrawPosition.Y),
|
||||||
|
Color.BlueViolet, 0, 3);
|
||||||
|
|
||||||
|
GUI.DrawString(spriteBatch, pos + textOffset - new Vector2(0, 20), "Path cost: " + path.Cost.FormatZeroDecimal(), Color.White, Color.Black * 0.5f);
|
||||||
|
}
|
||||||
for (int i = 1; i < path.Nodes.Count; i++)
|
for (int i = 1; i < path.Nodes.Count; i++)
|
||||||
{
|
{
|
||||||
var previousNode = path.Nodes[i - 1];
|
var previousNode = path.Nodes[i - 1];
|
||||||
@@ -75,14 +83,6 @@ namespace Barotrauma
|
|||||||
new Vector2(currentNode.DrawPosition.X - 10, -currentNode.DrawPosition.Y - 30),
|
new Vector2(currentNode.DrawPosition.X - 10, -currentNode.DrawPosition.Y - 30),
|
||||||
Color.Blue);
|
Color.Blue);
|
||||||
}
|
}
|
||||||
if (path.CurrentNode != null)
|
|
||||||
{
|
|
||||||
GUI.DrawLine(spriteBatch, pos,
|
|
||||||
new Vector2(path.CurrentNode.DrawPosition.X, -path.CurrentNode.DrawPosition.Y),
|
|
||||||
Color.BlueViolet, 0, 3);
|
|
||||||
|
|
||||||
GUI.DrawString(spriteBatch, pos + textOffset - new Vector2(0, 20), "Path cost: " + path.Cost.FormatZeroDecimal(), Color.White, Color.Black * 0.5f);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GUI.DrawLine(spriteBatch, pos, pos + ConvertUnits.ToDisplayUnits(new Vector2(Character.AnimController.TargetMovement.X, -Character.AnimController.TargetMovement.Y)), Color.SteelBlue, width: 2);
|
GUI.DrawLine(spriteBatch, pos, pos + ConvertUnits.ToDisplayUnits(new Vector2(Character.AnimController.TargetMovement.X, -Character.AnimController.TargetMovement.Y)), Color.SteelBlue, width: 2);
|
||||||
|
|||||||
@@ -152,6 +152,32 @@ namespace Barotrauma
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (character.MemLocalState.Count > 120) character.MemLocalState.RemoveRange(0, character.MemLocalState.Count - 120);
|
||||||
|
character.MemState.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
partial void ImpactProjSpecific(float impact, Body body)
|
||||||
|
{
|
||||||
|
float volume = MathHelper.Clamp(impact - 3.0f, 0.5f, 1.0f);
|
||||||
|
|
||||||
|
if (body.UserData is Limb limb && character.Stun <= 0f)
|
||||||
|
{
|
||||||
|
if (impact > 3.0f) { PlayImpactSound(limb); }
|
||||||
|
}
|
||||||
|
else if (body.UserData is Limb || body == Collider.FarseerBody)
|
||||||
|
{
|
||||||
|
if (!character.IsRemotePlayer && impact > ImpactTolerance)
|
||||||
|
{
|
||||||
|
SoundPlayer.PlayDamageSound("LimbBlunt", strongestImpact, Collider);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Character.Controlled == character)
|
||||||
|
{
|
||||||
|
GameMain.GameScreen.Cam.Shake = Math.Min(Math.Max(strongestImpact, GameMain.GameScreen.Cam.Shake), 3.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (character.MemState.Count < 1) return;
|
if (character.MemState.Count < 1) return;
|
||||||
|
|
||||||
overrideTargetMovement = Vector2.Zero;
|
overrideTargetMovement = Vector2.Zero;
|
||||||
|
|||||||
@@ -74,17 +74,12 @@ namespace Barotrauma
|
|||||||
public CrewManager(XElement element, bool isSinglePlayer)
|
public CrewManager(XElement element, bool isSinglePlayer)
|
||||||
: this(isSinglePlayer)
|
: this(isSinglePlayer)
|
||||||
{
|
{
|
||||||
if (GameMain.Client != null)
|
if (!isSinglePlayer)
|
||||||
{
|
{
|
||||||
//let the server create random conversations in MP
|
DebugConsole.ThrowError("Cannot add messages to single player chat box in multiplayer mode!\n" + Environment.StackTrace);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
List<Character> availableSpeakers = Character.CharacterList.FindAll(c =>
|
if (string.IsNullOrEmpty(text)) { return; }
|
||||||
c.AIController is HumanAIController &&
|
|
||||||
!c.IsDead &&
|
|
||||||
c.SpeechImpediment <= 100.0f);
|
|
||||||
pendingConversationLines.AddRange(NPCConversation.CreateRandom(availableSpeakers));
|
|
||||||
}
|
|
||||||
|
|
||||||
var characterInfo = new CharacterInfo(subElement);
|
var characterInfo = new CharacterInfo(subElement);
|
||||||
characterInfos.Add(characterInfo);
|
characterInfos.Add(characterInfo);
|
||||||
@@ -95,6 +90,7 @@ namespace Barotrauma
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ChatBox.AddMessage(ChatMessage.Create(senderName, text, messageType, sender));
|
||||||
}
|
}
|
||||||
|
|
||||||
partial void InitProjectSpecific()
|
partial void InitProjectSpecific()
|
||||||
@@ -243,24 +239,27 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public IEnumerable<Character> GetCharacters()
|
public IEnumerable<Character> GetCharacters()
|
||||||
{
|
{
|
||||||
if (characterInfos.Contains(characterInfo))
|
if (character?.Inventory == null) return null;
|
||||||
{
|
|
||||||
DebugConsole.ThrowError("Tried to add the same character info to CrewManager twice.\n" + Environment.StackTrace);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
characterInfos.Add(characterInfo);
|
var radioItem = character.Inventory.Items.FirstOrDefault(it => it != null && it.GetComponent<WifiComponent>() != null);
|
||||||
|
if (radioItem == null) return null;
|
||||||
|
if (requireEquipped && !character.HasEquippedItem(radioItem)) return null;
|
||||||
|
|
||||||
|
return radioItem.GetComponent<WifiComponent>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<CharacterInfo> GetCharacterInfos()
|
public IEnumerable<CharacterInfo> GetCharacterInfos()
|
||||||
{
|
{
|
||||||
if (character == null)
|
if (GameMain.Client != null)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Tried to remove a null character from CrewManager.\n" + Environment.StackTrace);
|
//let the server create random conversations in MP
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
characters.Remove(character);
|
List<Character> availableSpeakers = Character.CharacterList.FindAll(c =>
|
||||||
if (removeInfo) characterInfos.Remove(character.Info);
|
c.AIController is HumanAIController &&
|
||||||
|
!c.IsDead &&
|
||||||
|
c.SpeechImpediment <= 100.0f);
|
||||||
|
pendingConversationLines.AddRange(NPCConversation.CreateRandom(availableSpeakers));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddCharacter(Character character)
|
public void AddCharacter(Character character)
|
||||||
@@ -634,183 +633,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
characterListBox.BarScroll = roundedPos;
|
characterListBox.BarScroll = roundedPos;
|
||||||
}
|
}
|
||||||
var characterArea = new GUIButton(new RectTransform(new Point(characterInfoWidth, frame.Rect.Height), frame.RectTransform, Anchor.CenterLeft), style: "GUITextBox")
|
soundIcon.Visible = !muted && !mutedLocally;
|
||||||
{
|
soundIconDisabled.Visible = muted || mutedLocally;
|
||||||
UserData = character,
|
soundIconDisabled.ToolTip = TextManager.Get(mutedLocally ? "MutedLocally" : "MutedGlobally");
|
||||||
Color = frame.Color,
|
|
||||||
SelectedColor = frame.SelectedColor,
|
|
||||||
HoverColor = frame.HoverColor,
|
|
||||||
ToolTip = characterToolTip
|
|
||||||
};
|
|
||||||
|
|
||||||
var soundIcon = new GUIImage(new RectTransform(new Point((int)(characterArea.Rect.Height * 0.5f)), characterArea.RectTransform, Anchor.CenterRight) { AbsoluteOffset = new Point(5, 0) },
|
|
||||||
"GUISoundIcon")
|
|
||||||
{
|
|
||||||
UserData = "soundicon",
|
|
||||||
CanBeFocused = false,
|
|
||||||
Visible = true
|
|
||||||
};
|
|
||||||
soundIcon.Color = new Color(soundIcon.Color, 0.0f);
|
|
||||||
new GUIImage(new RectTransform(new Point((int)(characterArea.Rect.Height * 0.5f)), characterArea.RectTransform, Anchor.CenterRight) { AbsoluteOffset = new Point(5, 0) },
|
|
||||||
"GUISoundIconDisabled")
|
|
||||||
{
|
|
||||||
UserData = "soundicondisabled",
|
|
||||||
CanBeFocused = true,
|
|
||||||
Visible = false
|
|
||||||
};
|
|
||||||
|
|
||||||
if (isSinglePlayer)
|
|
||||||
{
|
|
||||||
characterArea.OnClicked = CharacterClicked;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
characterArea.CanBeFocused = false;
|
|
||||||
characterArea.CanBeSelected = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var characterImage = new GUICustomComponent(new RectTransform(new Point(characterArea.Rect.Height), characterArea.RectTransform, Anchor.CenterLeft),
|
|
||||||
onDraw: (sb, component) => character.Info.DrawIcon(sb, component.Rect.Center.ToVector2(), targetAreaSize: component.Rect.Size.ToVector2()))
|
|
||||||
{
|
|
||||||
CanBeFocused = false,
|
|
||||||
HoverColor = Color.White,
|
|
||||||
SelectedColor = Color.White,
|
|
||||||
ToolTip = characterToolTip
|
|
||||||
};
|
|
||||||
|
|
||||||
var characterName = new GUITextBlock(new RectTransform(new Point(characterArea.Rect.Width - characterImage.Rect.Width - soundIcon.Rect.Width - 10, characterArea.Rect.Height),
|
|
||||||
characterArea.RectTransform, Anchor.CenterRight) { AbsoluteOffset = new Point(soundIcon.Rect.Width + 10, 0) },
|
|
||||||
character.Name, textColor: frame.Color, font: GUI.SmallFont, wrap: true)
|
|
||||||
{
|
|
||||||
Color = frame.Color,
|
|
||||||
HoverColor = Color.Transparent,
|
|
||||||
SelectedColor = Color.Transparent,
|
|
||||||
CanBeFocused = false,
|
|
||||||
ToolTip = characterToolTip,
|
|
||||||
AutoScale = true
|
|
||||||
};
|
|
||||||
|
|
||||||
//---------------- order buttons ----------------
|
|
||||||
|
|
||||||
var orderButtonFrame = new GUILayoutGroup(new RectTransform(new Point(100, frame.Rect.Height), frame.RectTransform)
|
|
||||||
{ AbsoluteOffset = new Point(characterInfoWidth + spacing, 0) },
|
|
||||||
isHorizontal: true, childAnchor: Anchor.CenterLeft)
|
|
||||||
{
|
|
||||||
AbsoluteSpacing = (int)(10 * GUI.Scale),
|
|
||||||
UserData = "orderbuttons",
|
|
||||||
CanBeFocused = false
|
|
||||||
};
|
|
||||||
|
|
||||||
//listbox for holding the orders inappropriate for this character
|
|
||||||
//(so we can easily toggle their visibility)
|
|
||||||
var wrongOrderList = new GUIListBox(new RectTransform(new Point(50, orderButtonFrame.Rect.Height), orderButtonFrame.RectTransform), isHorizontal: true, style: null)
|
|
||||||
{
|
|
||||||
ScrollBarEnabled = false,
|
|
||||||
ScrollBarVisible = false,
|
|
||||||
Enabled = false,
|
|
||||||
Spacing = spacing,
|
|
||||||
ClampMouseRectToParent = false
|
|
||||||
};
|
|
||||||
wrongOrderList.Content.ClampMouseRectToParent = false;
|
|
||||||
|
|
||||||
for (int i = 0; i < orders.Count; i++)
|
|
||||||
{
|
|
||||||
var order = orders[i];
|
|
||||||
if (order.TargetAllCharacters) continue;
|
|
||||||
|
|
||||||
RectTransform btnParent = (i >= correctOrderCount + neutralOrderCount) ?
|
|
||||||
wrongOrderList.Content.RectTransform :
|
|
||||||
orderButtonFrame.RectTransform;
|
|
||||||
|
|
||||||
var btn = new GUIButton(new RectTransform(new Point(iconSize, iconSize), btnParent, Anchor.CenterLeft),
|
|
||||||
style: null)
|
|
||||||
{
|
|
||||||
UserData = order
|
|
||||||
};
|
|
||||||
|
|
||||||
new GUIFrame(new RectTransform(new Vector2(1.5f), btn.RectTransform, Anchor.Center), "OuterGlow")
|
|
||||||
{
|
|
||||||
Color = Color.Lerp(order.Color, frame.Color, 0.5f) * 0.8f,
|
|
||||||
HoverColor = Color.Lerp(order.Color, frame.Color, 0.5f) * 1.0f,
|
|
||||||
PressedColor = Color.Lerp(order.Color, frame.Color, 0.5f) * 0.6f,
|
|
||||||
UserData = "selected",
|
|
||||||
CanBeFocused = false,
|
|
||||||
Visible = false
|
|
||||||
};
|
|
||||||
|
|
||||||
var img = new GUIImage(new RectTransform(Vector2.One, btn.RectTransform), order.Prefab.SymbolSprite);
|
|
||||||
img.Scale = iconSize / (float)img.SourceRect.Width;
|
|
||||||
img.Color = Color.Lerp(order.Color, frame.Color, 0.5f);
|
|
||||||
img.ToolTip = order.Name;
|
|
||||||
img.HoverColor = Color.Lerp(img.Color, Color.White, 0.5f);
|
|
||||||
|
|
||||||
btn.OnClicked += (GUIButton button, object userData) =>
|
|
||||||
{
|
|
||||||
if (Character.Controlled == null || Character.Controlled.SpeechImpediment >= 100.0f) return false;
|
|
||||||
|
|
||||||
if (btn.GetChildByUserData("selected").Visible)
|
|
||||||
{
|
|
||||||
SetCharacterOrder(character, Order.PrefabList.Find(o => o.AITag == "dismissed"), null, Character.Controlled);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (order.ItemComponentType != null || order.ItemIdentifiers.Length > 0 || order.Options.Length > 1)
|
|
||||||
{
|
|
||||||
CreateOrderTargetFrame(button, character, order);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SetCharacterOrder(character, order, null, Character.Controlled);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
btn.UserData = order;
|
|
||||||
btn.ToolTip = order.Name;
|
|
||||||
|
|
||||||
//divider between different groups of orders
|
|
||||||
if (i == correctOrderCount - 1 || i == correctOrderCount + neutralOrderCount - 1)
|
|
||||||
{
|
|
||||||
//TODO: divider sprite
|
|
||||||
new GUIFrame(new RectTransform(new Point(8, iconSize), orderButtonFrame.RectTransform), style: "GUIButton");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var toggleWrongOrderBtn = new GUIButton(new RectTransform(new Point((int)(30 * GUI.Scale), wrongOrderList.Rect.Height), wrongOrderList.Content.RectTransform),
|
|
||||||
"", style: "UIToggleButton")
|
|
||||||
{
|
|
||||||
UserData = "togglewrongorder",
|
|
||||||
CanBeFocused = false
|
|
||||||
};
|
|
||||||
|
|
||||||
wrongOrderList.RectTransform.NonScaledSize = new Point(
|
|
||||||
wrongOrderList.Content.Children.Sum(c => c.Rect.Width + wrongOrderList.Spacing),
|
|
||||||
wrongOrderList.RectTransform.NonScaledSize.Y);
|
|
||||||
wrongOrderList.RectTransform.SetAsLastChild();
|
|
||||||
|
|
||||||
new GUIFrame(new RectTransform(new Point(
|
|
||||||
wrongOrderList.Rect.Width - toggleWrongOrderBtn.Rect.Width - wrongOrderList.Spacing * 2,
|
|
||||||
wrongOrderList.Rect.Height), wrongOrderList.Content.RectTransform),
|
|
||||||
style: null)
|
|
||||||
{
|
|
||||||
CanBeFocused = false
|
|
||||||
};
|
|
||||||
|
|
||||||
//scale to fit the content
|
|
||||||
orderButtonFrame.RectTransform.NonScaledSize = new Point(
|
|
||||||
orderButtonFrame.Children.Sum(c => c.Rect.Width + orderButtonFrame.AbsoluteSpacing),
|
|
||||||
orderButtonFrame.RectTransform.NonScaledSize.Y);
|
|
||||||
|
|
||||||
frame.RectTransform.NonScaledSize = new Point(
|
|
||||||
characterInfoWidth + spacing + (orderButtonFrame.Rect.Width - wrongOrderList.Rect.Width),
|
|
||||||
frame.RectTransform.NonScaledSize.Y);
|
|
||||||
|
|
||||||
characterListBox.RectTransform.NonScaledSize = new Point(
|
|
||||||
characterListBox.Content.Children.Max(c => c.Rect.Width) + wrongOrderList.Rect.Width,
|
|
||||||
characterListBox.RectTransform.NonScaledSize.Y);
|
|
||||||
characterListBox.Content.RectTransform.NonScaledSize = characterListBox.RectTransform.NonScaledSize;
|
|
||||||
characterListBox.UpdateScrollBarSize();
|
|
||||||
return frame;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<object> KillCharacterAnim(GUIComponent component)
|
private IEnumerable<object> KillCharacterAnim(GUIComponent component)
|
||||||
@@ -954,12 +779,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
List<Character> availableSpeakers = Character.CharacterList.FindAll(c =>
|
|
||||||
c.AIController is HumanAIController &&
|
|
||||||
!c.IsDead &&
|
|
||||||
c.SpeechImpediment <= 100.0f);
|
|
||||||
pendingConversationLines.AddRange(NPCConversation.CreateRandom(availableSpeakers));
|
|
||||||
}
|
|
||||||
|
|
||||||
character.SetOrder(order, option, orderGiver, speak: orderGiver != character);
|
character.SetOrder(order, option, orderGiver, speak: orderGiver != character);
|
||||||
if (IsSinglePlayer)
|
if (IsSinglePlayer)
|
||||||
@@ -1017,23 +836,19 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//only one target (or an order with no particular targets), just show options
|
||||||
character.SetOrder(order, option, orderGiver, speak: orderGiver != character);
|
else
|
||||||
if (IsSinglePlayer)
|
|
||||||
{
|
{
|
||||||
orderGiver?.Speak(
|
orderTargetFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.2f + order.Options.Length * 0.1f, 0.18f), GUI.Canvas)
|
||||||
order.GetChatMessage(character.Name, orderGiver.CurrentHull?.DisplayName, givingOrderToSelf: character == orderGiver, orderOption: option), null);
|
{ AbsoluteOffset = new Point(orderButton.Rect.Center.X, orderButton.Rect.Bottom) },
|
||||||
}
|
isHorizontal: true, childAnchor: Anchor.BottomLeft)
|
||||||
else if (orderGiver != null)
|
|
||||||
{
|
|
||||||
OrderChatMessage msg = new OrderChatMessage(order, option, order.TargetItemComponent?.Item, character, orderGiver);
|
|
||||||
if (GameMain.Client != null)
|
|
||||||
{
|
{
|
||||||
GameMain.Client.SendChatMessage(msg);
|
UserData = character,
|
||||||
}
|
Stretch = true
|
||||||
}
|
};
|
||||||
DisplayCharacterOrder(character, order);
|
//line connecting the order button to the option buttons
|
||||||
}
|
//TODO: sprite
|
||||||
|
new GUIFrame(new RectTransform(new Vector2(0.5f, 1.0f), orderTargetFrame.RectTransform), style: null);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create the UI panel that's used to select the target and options for a given order
|
/// Create the UI panel that's used to select the target and options for a given order
|
||||||
|
|||||||
@@ -474,6 +474,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;
|
||||||
|
|||||||
@@ -789,10 +789,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
GUI.Draw(Cam, spriteBatch);
|
GUI.Draw(Cam, spriteBatch);
|
||||||
|
|
||||||
spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, GameMain.ScissorTestEnable);
|
|
||||||
|
|
||||||
GUI.Draw(Cam, spriteBatch);
|
|
||||||
|
|
||||||
GUI.Draw(Cam, spriteBatch);
|
GUI.Draw(Cam, spriteBatch);
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
|||||||
@@ -1,21 +1,10 @@
|
|||||||
BAROTRAUMA
|
BAROTRAUMA
|
||||||
|
|
||||||
www.barotraumagame.com
|
http://www.barotraumagame.com
|
||||||
Copyright © Undertow Games 2017-2018
|
|
||||||
|
|
||||||
Default controls:
|
© 2018-2019 FakeFish Ltd. All rights reserved.
|
||||||
WASD - move
|
© 2019 Daedalic Entertainment GmbH. The Daedalic logo is a trademark of Daedalic Entertainment GmbH, Germany. All rights reserved.
|
||||||
Shift - run
|
Privacy policy: http://privacypolicy.daedalic.com
|
||||||
E - use/activate items and devices
|
|
||||||
Right click - aim with equipped item
|
|
||||||
Left click - use equipped item
|
|
||||||
C - open the crew command menu
|
|
||||||
Left control - crouch
|
|
||||||
Tab - select/deselect the chat box in multiplayer mode
|
|
||||||
Tilde - select the chat box in multiplayer mode and set
|
|
||||||
the message to be sent through the radio
|
|
||||||
Space - hold to stay in ragdoll mode
|
|
||||||
F3 - open/close the debug console
|
|
||||||
|
|
||||||
See the wiki for more detailed info and instructions:
|
See the wiki for more detailed info and instructions:
|
||||||
http://barotrauma.gamepedia.com
|
http://barotrauma.gamepedia.com
|
||||||
@@ -46,38 +35,4 @@ Query port (used to communicate with Steam)
|
|||||||
Service/Application: barotrauma
|
Service/Application: barotrauma
|
||||||
External Port: The port you have selected for your server (27016 by default)
|
External Port: The port you have selected for your server (27016 by default)
|
||||||
Internal Port: The port you have selected for your server (27016 by default)
|
Internal Port: The port you have selected for your server (27016 by default)
|
||||||
Protocol: UDP
|
Protocol: UDP
|
||||||
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
Credits:
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Programming, graphics, sounds, game design - Joonas Rikkonen ("Regalis")
|
|
||||||
Graphics - James Bear ("Moonsaber99")
|
|
||||||
Programming - Sebastian Broberg
|
|
||||||
Programming - Juan Pablo Arce ("juanjp600")
|
|
||||||
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
|
|
||||||
"Road to Hell"
|
|
||||||
Kevin MacLeod (incompetech.com)
|
|
||||||
Licensed under Creative Commons: By Attribution 3.0
|
|
||||||
http://creativecommons.org/licenses/by/3.0/
|
|
||||||
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Lidgren.Network networking library - Michael Lidgren
|
|
||||||
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Sound effects:
|
|
||||||
metal whining and screeching - ScottFerguson1
|
|
||||||
metal gate 10 - thencamenow
|
|
||||||
foil_expanding_multiple - markb
|
|
||||||
Bug Zapper_Many medium zaps - CGEffex
|
|
||||||
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Textures from the PK01, PK02 and Ancient Collection Texture packages by Philip Klevestav are used in some of the sprites in the game.
|
|
||||||
The texture packages are licensed under a Creative Commons Attribution 3.0 Unported License (https://creativecommons.org/licenses/by/3.0/).
|
|
||||||
@@ -493,23 +493,18 @@ namespace Barotrauma
|
|||||||
item.ContainedItems.Any(i => i.HasTag(containedTag) && i.ConditionPercentage > conditionPercentage)));
|
item.ContainedItems.Any(i => i.HasTag(containedTag) && i.ConditionPercentage > conditionPercentage)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DoForEachCrewMember(Character character, Action<HumanAIController> action)
|
|
||||||
{
|
|
||||||
foreach (var c in Character.CharacterList)
|
|
||||||
{
|
|
||||||
if (c.AIController is HumanAIController humanAi && humanAi.IsFriendly(character))
|
|
||||||
{
|
|
||||||
action(humanAi);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates the hull safety for all ai characters in the team.
|
/// Updates the hull safety for all ai characters in the team.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void PropagateHullSafety(Character character, Hull hull)
|
public static void PropagateHullSafety(Character character, Hull hull)
|
||||||
{
|
{
|
||||||
DoForEachCrewMember(character, (humanAi) => humanAi.RefreshHullSafety(hull));
|
foreach (var c in Character.CharacterList)
|
||||||
|
{
|
||||||
|
if (c.AIController is HumanAIController humanAi && humanAi.IsFriendly(character))
|
||||||
|
{
|
||||||
|
humanAi.RefreshHullSafety(hull);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RefreshHullSafety(Hull hull)
|
private void RefreshHullSafety(Hull hull)
|
||||||
@@ -582,26 +577,21 @@ namespace Barotrauma
|
|||||||
private static bool AddTargets<T1, T2>(Character caller, T2 target) where T1 : AIObjectiveLoop<T2>
|
private static bool AddTargets<T1, T2>(Character caller, T2 target) where T1 : AIObjectiveLoop<T2>
|
||||||
{
|
{
|
||||||
bool targetAdded = false;
|
bool targetAdded = false;
|
||||||
DoForEachCrewMember(caller, humanAI =>
|
foreach (var c in Character.CharacterList)
|
||||||
{
|
{
|
||||||
var objective = humanAI.ObjectiveManager.GetObjective<T1>();
|
if (IsFriendly(caller, c) && c.AIController is HumanAIController humanAI)
|
||||||
if (objective != null)
|
|
||||||
{
|
{
|
||||||
|
var objective = humanAI.ObjectiveManager.GetObjective<T1>();
|
||||||
|
if (objective == null) { continue; }
|
||||||
if (!targetAdded && objective.AddTarget(target))
|
if (!targetAdded && objective.AddTarget(target))
|
||||||
{
|
{
|
||||||
targetAdded = true;
|
targetAdded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
return targetAdded;
|
return targetAdded;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void RemoveTargets<T1, T2>(Character caller, T2 target) where T1 : AIObjectiveLoop<T2>
|
|
||||||
{
|
|
||||||
DoForEachCrewMember(caller, humanAI =>
|
|
||||||
humanAI.ObjectiveManager.GetObjective<T1>()?.ReportedTargets.Remove(target));
|
|
||||||
}
|
|
||||||
|
|
||||||
public float GetHullSafety(Hull hull)
|
public float GetHullSafety(Hull hull)
|
||||||
{
|
{
|
||||||
if (hull == null) { return 0; }
|
if (hull == null) { return 0; }
|
||||||
|
|||||||
@@ -71,7 +71,6 @@ namespace Barotrauma
|
|||||||
#if DEBUG
|
#if DEBUG
|
||||||
DebugConsole.NewMessage($"Removing subobjective {subObjective.DebugTag} of {DebugTag}, because it is completed.");
|
DebugConsole.NewMessage($"Removing subobjective {subObjective.DebugTag} of {DebugTag}, because it is completed.");
|
||||||
#endif
|
#endif
|
||||||
subObjective.OnCompleted();
|
|
||||||
subObjectives.Remove(subObjective);
|
subObjectives.Remove(subObjective);
|
||||||
}
|
}
|
||||||
else if (!subObjective.CanBeCompleted)
|
else if (!subObjective.CanBeCompleted)
|
||||||
@@ -94,9 +93,9 @@ namespace Barotrauma
|
|||||||
|
|
||||||
bool wasCompleted = IsCompleted();
|
bool wasCompleted = IsCompleted();
|
||||||
Act(deltaTime);
|
Act(deltaTime);
|
||||||
if (IsCompleted())
|
if (!wasCompleted && IsCompleted())
|
||||||
{
|
{
|
||||||
OnCompleted();
|
Completed?.Invoke();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,15 +213,6 @@ namespace Barotrauma
|
|||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnCompleted()
|
|
||||||
{
|
|
||||||
if (Completed != null)
|
|
||||||
{
|
|
||||||
Completed();
|
|
||||||
Completed = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void Reset() { }
|
public virtual void Reset() { }
|
||||||
|
|
||||||
protected abstract void Act(float deltaTime);
|
protected abstract void Act(float deltaTime);
|
||||||
|
|||||||
-3
@@ -65,8 +65,5 @@ namespace Barotrauma
|
|||||||
|
|
||||||
protected override AIObjective ObjectiveConstructor(PowerContainer battery)
|
protected override AIObjective ObjectiveConstructor(PowerContainer battery)
|
||||||
=> new AIObjectiveOperateItem(battery, character, objectiveManager, Option, false, priorityModifier: PriorityModifier) { IsLoop = false };
|
=> new AIObjectiveOperateItem(battery, character, objectiveManager, Option, false, priorityModifier: PriorityModifier) { IsLoop = false };
|
||||||
|
|
||||||
protected override void OnObjectiveCompleted(AIObjective objective, PowerContainer target)
|
|
||||||
=> HumanAIController.RemoveTargets<AIObjectiveChargeBatteries, PowerContainer>(character, target);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-6
@@ -1,7 +1,6 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Barotrauma.Extensions;
|
using Barotrauma.Extensions;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
@@ -21,11 +20,7 @@ namespace Barotrauma
|
|||||||
public override bool IsDuplicate(AIObjective otherObjective) => otherObjective is AIObjectiveExtinguishFires;
|
public override bool IsDuplicate(AIObjective otherObjective) => otherObjective is AIObjectiveExtinguishFires;
|
||||||
protected override IEnumerable<Hull> GetList() => Hull.hullList;
|
protected override IEnumerable<Hull> GetList() => Hull.hullList;
|
||||||
|
|
||||||
protected override AIObjective ObjectiveConstructor(Hull target)
|
protected override AIObjective ObjectiveConstructor(Hull target) => new AIObjectiveExtinguishFire(character, target, objectiveManager, PriorityModifier);
|
||||||
=> new AIObjectiveExtinguishFire(character, target, objectiveManager, PriorityModifier);
|
|
||||||
|
|
||||||
protected override void OnObjectiveCompleted(AIObjective objective, Hull target)
|
|
||||||
=> HumanAIController.RemoveTargets<AIObjectiveExtinguishFires, Hull>(character, target);
|
|
||||||
|
|
||||||
public static bool IsValidTarget(Hull hull, Character character)
|
public static bool IsValidTarget(Hull hull, Character character)
|
||||||
{
|
{
|
||||||
|
|||||||
+2
-6
@@ -21,18 +21,14 @@ namespace Barotrauma
|
|||||||
|
|
||||||
protected override IEnumerable<Character> GetList() => Character.CharacterList;
|
protected override IEnumerable<Character> GetList() => Character.CharacterList;
|
||||||
|
|
||||||
|
protected override AIObjective ObjectiveConstructor(Character target) => new AIObjectiveCombat(character, target, AIObjectiveCombat.CombatMode.Offensive, objectiveManager, PriorityModifier);
|
||||||
|
|
||||||
protected override float TargetEvaluation()
|
protected override float TargetEvaluation()
|
||||||
{
|
{
|
||||||
// TODO: sorting criteria
|
// TODO: sorting criteria
|
||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override AIObjective ObjectiveConstructor(Character target)
|
|
||||||
=> new AIObjectiveCombat(character, target, AIObjectiveCombat.CombatMode.Offensive, objectiveManager, PriorityModifier);
|
|
||||||
|
|
||||||
protected override void OnObjectiveCompleted(AIObjective objective, Character target)
|
|
||||||
=> HumanAIController.RemoveTargets<AIObjectiveFightIntruders, Character>(character, target);
|
|
||||||
|
|
||||||
public static bool IsValidTarget(Character target, Character character)
|
public static bool IsValidTarget(Character target, Character character)
|
||||||
{
|
{
|
||||||
if (target == null || target.IsDead || target.Removed) { return false; }
|
if (target == null || target.IsDead || target.Removed) { return false; }
|
||||||
|
|||||||
@@ -723,6 +723,31 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
TryAddSubObjective(ref gotoObjective, () => new AIObjectiveGoTo(ConvertUnits.ToSimUnits(GetStandPosition()), character, objectiveManager) { CloseEnough = reach * 0.75f });
|
TryAddSubObjective(ref gotoObjective, () => new AIObjectiveGoTo(ConvertUnits.ToSimUnits(GetStandPosition()), character, objectiveManager) { CloseEnough = reach * 0.75f });
|
||||||
}
|
}
|
||||||
|
var repairTool = weldingTool.GetComponent<RepairTool>();
|
||||||
|
if (repairTool == null)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
DebugConsole.ThrowError("AIObjectiveFixLeak failed - the item \"" + weldingTool + "\" has no RepairTool component but is tagged as a welding tool");
|
||||||
|
#endif
|
||||||
|
abandon = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Vector2 gapDiff = Leak.WorldPosition - character.WorldPosition;
|
||||||
|
// TODO: use the collider size/reach?
|
||||||
|
if (!character.AnimController.InWater && Math.Abs(gapDiff.X) < 100 && gapDiff.Y < 0.0f && gapDiff.Y > -150)
|
||||||
|
{
|
||||||
|
HumanAIController.AnimController.Crouching = true;
|
||||||
|
}
|
||||||
|
float reach = ConvertUnits.ToSimUnits(repairTool.Range);
|
||||||
|
bool canOperate = ConvertUnits.ToSimUnits(gapDiff.Length()) < reach;
|
||||||
|
if (canOperate)
|
||||||
|
{
|
||||||
|
TryAddSubObjective(ref operateObjective, () => new AIObjectiveOperateItem(repairTool, character, objectiveManager, option: "", requireEquip: true, operateTarget: Leak));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TryAddSubObjective(ref gotoObjective, () => new AIObjectiveGoTo(ConvertUnits.ToSimUnits(GetStandPosition()), character, objectiveManager) { CloseEnough = reach * 0.75f });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Vector2 GetStandPosition()
|
private Vector2 GetStandPosition()
|
||||||
|
|||||||
@@ -27,11 +27,7 @@ namespace Barotrauma
|
|||||||
public override bool IsDuplicate(AIObjective otherObjective) => otherObjective is AIObjectiveFixLeaks;
|
public override bool IsDuplicate(AIObjective otherObjective) => otherObjective is AIObjectiveFixLeaks;
|
||||||
protected override float TargetEvaluation() => Targets.Max(t => GetLeakSeverity(t));
|
protected override float TargetEvaluation() => Targets.Max(t => GetLeakSeverity(t));
|
||||||
protected override IEnumerable<Gap> GetList() => Gap.GapList;
|
protected override IEnumerable<Gap> GetList() => Gap.GapList;
|
||||||
protected override AIObjective ObjectiveConstructor(Gap gap)
|
protected override AIObjective ObjectiveConstructor(Gap gap) => new AIObjectiveFixLeak(gap, character, objectiveManager, PriorityModifier);
|
||||||
=> new AIObjectiveFixLeak(gap, character, objectiveManager, PriorityModifier);
|
|
||||||
|
|
||||||
protected override void OnObjectiveCompleted(AIObjective objective, Gap target)
|
|
||||||
=> HumanAIController.RemoveTargets<AIObjectiveFixLeaks, Gap>(character, target);
|
|
||||||
|
|
||||||
public static bool IsValidTarget(Gap gap, Character character)
|
public static bool IsValidTarget(Gap gap, Character character)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -271,13 +271,10 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
bool isEquipped = !equip || character.HasEquippedItem(item);
|
bool isEquipped = !equip || character.HasEquippedItem(item);
|
||||||
if (character.Inventory.Items.Contains(item) && isEquipped) { return true; }
|
if (character.Inventory.Items.Contains(item) && isEquipped) { return true; }
|
||||||
if (!equip)
|
Item rootContainer = item.GetRootContainer();
|
||||||
|
if (rootContainer != null && rootContainer.ParentInventory is CharacterInventory)
|
||||||
{
|
{
|
||||||
Item rootContainer = item.GetRootContainer();
|
return rootContainer.ParentInventory.Owner == character;
|
||||||
if (rootContainer != null && rootContainer.ParentInventory is CharacterInventory)
|
|
||||||
{
|
|
||||||
return rootContainer.ParentInventory.Owner == character;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,21 +73,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update(float deltaTime)
|
|
||||||
{
|
|
||||||
if (objectiveManager.CurrentObjective == this)
|
|
||||||
{
|
|
||||||
if (randomTimer > 0)
|
|
||||||
{
|
|
||||||
randomTimer -= deltaTime;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SetRandom();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool IsCompleted() => false;
|
public override bool IsCompleted() => false;
|
||||||
public override bool CanBeCompleted => true;
|
public override bool CanBeCompleted => true;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Barotrauma.Extensions;
|
using Barotrauma.Extensions;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
@@ -88,7 +87,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// the timer is set between 1 and 10 seconds, depending on the priority modifier and a random +-25%
|
// the timer is set between 1 and 10 seconds, depending on the priority
|
||||||
private float SetTargetUpdateTimer() => targetUpdateTimer = 1 / MathHelper.Clamp(PriorityModifier * Rand.Range(0.75f, 1.25f), 0.1f, 1);
|
private float SetTargetUpdateTimer() => targetUpdateTimer = 1 / MathHelper.Clamp(PriorityModifier * Rand.Range(0.75f, 1.25f), 0.1f, 1);
|
||||||
|
|
||||||
public override void Reset()
|
public override void Reset()
|
||||||
@@ -159,18 +158,13 @@ namespace Barotrauma
|
|||||||
if (!Objectives.TryGetValue(target, out AIObjective objective))
|
if (!Objectives.TryGetValue(target, out AIObjective objective))
|
||||||
{
|
{
|
||||||
objective = ObjectiveConstructor(target);
|
objective = ObjectiveConstructor(target);
|
||||||
objective.Completed += () => OnObjectiveCompleted(objective, target);
|
objective.Completed += () => ReportedTargets.Remove(target);
|
||||||
Objectives.Add(target, objective);
|
Objectives.Add(target, objective);
|
||||||
if (!subObjectives.Contains(objective))
|
AddSubObjective(objective);
|
||||||
{
|
|
||||||
subObjectives.Add(objective);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void OnObjectiveCompleted(AIObjective objective, T target);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// List of all possible items of the specified type. Used for filtering the removed objectives.
|
/// List of all possible items of the specified type. Used for filtering the removed objectives.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -350,6 +350,10 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
isCompleted = true;
|
isCompleted = true;
|
||||||
}
|
}
|
||||||
|
if (component.AIOperate(deltaTime, character, this))
|
||||||
|
{
|
||||||
|
isCompleted = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ namespace Barotrauma
|
|||||||
return pumpList;
|
return pumpList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override AIObjective ObjectiveConstructor(Pump pump) => new AIObjectiveOperateItem(pump, character, objectiveManager, Option, false) { IsLoop = false };
|
||||||
protected override float TargetEvaluation()
|
protected override float TargetEvaluation()
|
||||||
{
|
{
|
||||||
if (Option == "stoppumping")
|
if (Option == "stoppumping")
|
||||||
@@ -65,11 +66,5 @@ namespace Barotrauma
|
|||||||
return Targets.Max(t => MathHelper.Lerp(100, 0, Math.Abs(-t.FlowPercentage / 100)));
|
return Targets.Max(t => MathHelper.Lerp(100, 0, Math.Abs(-t.FlowPercentage / 100)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override AIObjective ObjectiveConstructor(Pump pump)
|
|
||||||
=> new AIObjectiveOperateItem(pump, character, objectiveManager, Option, false) { IsLoop = false };
|
|
||||||
|
|
||||||
protected override void OnObjectiveCompleted(AIObjective objective, Pump target)
|
|
||||||
=> HumanAIController.RemoveTargets<AIObjectivePumpWater, Pump>(character, target);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-6
@@ -54,12 +54,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
protected override float TargetEvaluation() => Targets.Max(t => 100 - t.ConditionPercentage);
|
protected override float TargetEvaluation() => Targets.Max(t => 100 - t.ConditionPercentage);
|
||||||
protected override IEnumerable<Item> GetList() => Item.ItemList;
|
protected override IEnumerable<Item> GetList() => Item.ItemList;
|
||||||
|
protected override AIObjective ObjectiveConstructor(Item item) => new AIObjectiveRepairItem(character, item, objectiveManager, PriorityModifier);
|
||||||
protected override AIObjective ObjectiveConstructor(Item item)
|
|
||||||
=> new AIObjectiveRepairItem(character, item, objectiveManager, PriorityModifier);
|
|
||||||
|
|
||||||
protected override void OnObjectiveCompleted(AIObjective objective, Item target)
|
|
||||||
=> HumanAIController.RemoveTargets<AIObjectiveRepairItems, Item>(character, target);
|
|
||||||
|
|
||||||
public static bool IsValidTarget(Item item, Character character)
|
public static bool IsValidTarget(Item item, Character character)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -22,16 +22,12 @@ namespace Barotrauma
|
|||||||
|
|
||||||
protected override IEnumerable<Character> GetList() => Character.CharacterList;
|
protected override IEnumerable<Character> GetList() => Character.CharacterList;
|
||||||
|
|
||||||
|
protected override AIObjective ObjectiveConstructor(Character target) => new AIObjectiveRescue(character, target, objectiveManager, PriorityModifier);
|
||||||
|
|
||||||
protected override float TargetEvaluation() => Targets.Max(t => GetVitalityFactor(t)) * 100;
|
protected override float TargetEvaluation() => Targets.Max(t => GetVitalityFactor(t)) * 100;
|
||||||
|
|
||||||
public static float GetVitalityFactor(Character character) => (character.MaxVitality - character.Vitality) / character.MaxVitality;
|
public static float GetVitalityFactor(Character character) => (character.MaxVitality - character.Vitality) / character.MaxVitality;
|
||||||
|
|
||||||
protected override AIObjective ObjectiveConstructor(Character target)
|
|
||||||
=> new AIObjectiveRescue(character, target, objectiveManager, PriorityModifier);
|
|
||||||
|
|
||||||
protected override void OnObjectiveCompleted(AIObjective objective, Character target)
|
|
||||||
=> HumanAIController.RemoveTargets<AIObjectiveRescueAll, Character>(character, target);
|
|
||||||
|
|
||||||
public static bool IsValidTarget(Character target, Character character)
|
public static bool IsValidTarget(Character target, Character character)
|
||||||
{
|
{
|
||||||
if (target == null || target.IsDead || target.Removed) { return false; }
|
if (target == null || target.IsDead || target.Removed) { return false; }
|
||||||
|
|||||||
@@ -696,6 +696,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);
|
||||||
|
|||||||
@@ -212,6 +212,33 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vector2? PosToMaintain
|
||||||
|
{
|
||||||
|
get { return posToMaintain; }
|
||||||
|
set { posToMaintain = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ObstacleDebugInfo
|
||||||
|
{
|
||||||
|
public Vector2 Point1;
|
||||||
|
public Vector2 Point2;
|
||||||
|
|
||||||
|
public Vector2? Intersection;
|
||||||
|
|
||||||
|
public float Dot;
|
||||||
|
|
||||||
|
public Vector2 AvoidStrength;
|
||||||
|
|
||||||
|
public ObstacleDebugInfo(GraphEdge edge, Vector2? intersection, float dot, Vector2 avoidStrength)
|
||||||
|
{
|
||||||
|
Point1 = edge.Point1;
|
||||||
|
Point2 = edge.Point2;
|
||||||
|
Intersection = intersection;
|
||||||
|
Dot = dot;
|
||||||
|
AvoidStrength = avoidStrength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//edge point 1, edge point 2, avoid strength
|
//edge point 1, edge point 2, avoid strength
|
||||||
private List<ObstacleDebugInfo> debugDrawObstacles = new List<ObstacleDebugInfo>();
|
private List<ObstacleDebugInfo> debugDrawObstacles = new List<ObstacleDebugInfo>();
|
||||||
|
|
||||||
|
|||||||
@@ -1128,10 +1128,6 @@ 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (body == null || !body.Enabled || !inWater || ParentInventory != null || Removed) { return; }
|
if (body == null || !body.Enabled || !inWater || ParentInventory != null || Removed) { return; }
|
||||||
|
|
||||||
@@ -1176,59 +1172,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateTransform()
|
|
||||||
{
|
|
||||||
Submarine prevSub = Submarine;
|
|
||||||
|
|
||||||
FindHull();
|
|
||||||
|
|
||||||
if (body == null || !body.Enabled || !inWater || ParentInventory != null || Removed) { return; }
|
|
||||||
|
|
||||||
Vector2 displayPos = ConvertUnits.ToDisplayUnits(body.SimPosition);
|
|
||||||
rect.X = (int)(displayPos.X - rect.Width / 2.0f);
|
|
||||||
rect.Y = (int)(displayPos.Y + rect.Height / 2.0f);
|
|
||||||
|
|
||||||
if (Math.Abs(body.LinearVelocity.X) > NetConfig.MaxPhysicsBodyVelocity ||
|
|
||||||
Math.Abs(body.LinearVelocity.Y) > NetConfig.MaxPhysicsBodyVelocity)
|
|
||||||
{
|
|
||||||
body.LinearVelocity = new Vector2(
|
|
||||||
MathHelper.Clamp(body.LinearVelocity.X, -NetConfig.MaxPhysicsBodyVelocity, NetConfig.MaxPhysicsBodyVelocity),
|
|
||||||
MathHelper.Clamp(body.LinearVelocity.Y, -NetConfig.MaxPhysicsBodyVelocity, NetConfig.MaxPhysicsBodyVelocity));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateTransform()
|
|
||||||
{
|
|
||||||
Submarine prevSub = Submarine;
|
|
||||||
|
|
||||||
FindHull();
|
|
||||||
|
|
||||||
if (Submarine == null && prevSub != null)
|
|
||||||
{
|
|
||||||
body.SetTransform(body.SimPosition + prevSub.SimPosition, body.Rotation);
|
|
||||||
}
|
|
||||||
else if (Submarine != null && prevSub == null)
|
|
||||||
{
|
|
||||||
body.SetTransform(body.SimPosition - Submarine.SimPosition, body.Rotation);
|
|
||||||
}
|
|
||||||
else if (Submarine != null && prevSub != null && Submarine != prevSub)
|
|
||||||
{
|
|
||||||
body.SetTransform(body.SimPosition + prevSub.SimPosition - Submarine.SimPosition, body.Rotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 displayPos = ConvertUnits.ToDisplayUnits(body.SimPosition);
|
|
||||||
rect.X = (int)(displayPos.X - rect.Width / 2.0f);
|
|
||||||
rect.Y = (int)(displayPos.Y + rect.Height / 2.0f);
|
|
||||||
|
|
||||||
if (Math.Abs(body.LinearVelocity.X) > NetConfig.MaxPhysicsBodyVelocity ||
|
|
||||||
Math.Abs(body.LinearVelocity.Y) > NetConfig.MaxPhysicsBodyVelocity)
|
|
||||||
{
|
|
||||||
body.LinearVelocity = new Vector2(
|
|
||||||
MathHelper.Clamp(body.LinearVelocity.X, -NetConfig.MaxPhysicsBodyVelocity, NetConfig.MaxPhysicsBodyVelocity),
|
|
||||||
MathHelper.Clamp(body.LinearVelocity.Y, -NetConfig.MaxPhysicsBodyVelocity, NetConfig.MaxPhysicsBodyVelocity));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateTransform()
|
public void UpdateTransform()
|
||||||
{
|
{
|
||||||
Submarine prevSub = Submarine;
|
Submarine prevSub = Submarine;
|
||||||
|
|||||||
@@ -569,6 +569,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
|
||||||
|
|||||||
@@ -4,27 +4,47 @@ v0.9.0.0
|
|||||||
|
|
||||||
Additions and changes:
|
Additions and changes:
|
||||||
- Translations to German, Russian, French, Brazilian Portuguese, Traditional Chinese and Simplified Chinese.
|
- Translations to German, Russian, French, Brazilian Portuguese, Traditional Chinese and Simplified Chinese.
|
||||||
- New logo and main menu art.
|
|
||||||
- 2 new outposts.
|
|
||||||
- New docking system.
|
|
||||||
- Numerous fixes and improvements to the crew AI. The biggest change is that the AI characters can now do
|
- Numerous fixes and improvements to the crew AI. The biggest change is that the AI characters can now do
|
||||||
tasks by themselves even when they haven't been assigned an order.
|
tasks by themselves even when they haven't been assigned an order.
|
||||||
|
- One new outpost.
|
||||||
|
- New docking system.
|
||||||
|
- New logo and main menu art.
|
||||||
|
- Added a credits tab to the main menu.
|
||||||
|
- Some new item and structure sprites.
|
||||||
|
- Some new environment sprites.
|
||||||
|
- Increased the amount of credits the player starts with in the campaign.
|
||||||
|
- Balanced location and mission distribution.
|
||||||
|
- Balanced mission rewards.
|
||||||
|
- AI characters can be ordered to fight intruders.
|
||||||
- Lock the inventory when aiming with a railgun or a coilgun.
|
- Lock the inventory when aiming with a railgun or a coilgun.
|
||||||
- Swap the order of the starting location & destination in nav terminals when playing in a mirrored sub.
|
- Swap the order of the starting location & destination in nav terminals when playing in a mirrored sub.
|
||||||
|
- Option to automatically pause the game when the window loses focus.
|
||||||
|
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
- Fixed splash screens and tutorial videos crashing the Linux version.
|
- Fixed splash screens and tutorial videos crashing the Linux version.
|
||||||
- Fixed damaged item sprites not updating client-side after being repaired.
|
- Fixed damaged item sprites not updating client-side after being repaired.
|
||||||
- Fixed characters occasionally taking impact damage when hitting walls while climbing.
|
- Fixed characters occasionally taking impact damage when hitting walls while climbing.
|
||||||
|
- Fixes crashing when attempting to use symbols such as <, > or | in the save file name.
|
||||||
|
- UI layout/scale fixes on resolutions larger than 1080p.
|
||||||
|
- Fixed crashing when loading the same sub twice in the sub editor.
|
||||||
|
- Fixed submarines occasionally being rendered at an incorrect position when viewing them in the sub editor
|
||||||
|
after they've been used in-game.
|
||||||
- Improved the syncing of ragdolled characters.
|
- Improved the syncing of ragdolled characters.
|
||||||
|
- Fixed characters not receiving impact damage when ragdolled.
|
||||||
|
- Fixed characters' arms occasionally spinning around when standing still.
|
||||||
|
- Fixed tutorial level generation parameters being used in some normal campaign levels (leading to extremely
|
||||||
|
small levels and submarines overlapping with the outposts).
|
||||||
- Fixed characters running more slowly when their torso is in a different hull than the feet (for example
|
- Fixed characters running more slowly when their torso is in a different hull than the feet (for example
|
||||||
in Humpback's bilge).
|
in Humpback's bilge).
|
||||||
|
- Fixed character's feet getting stuck to platforms when climbing ladders while holding A/D.
|
||||||
|
- Fixed monsters being able to drag characters through walls.
|
||||||
- Fixed items "vanishing" if they move directly from sub to another without going outside first.
|
- Fixed items "vanishing" if they move directly from sub to another without going outside first.
|
||||||
- Fixed content package hash calculation failing if the package is not enabled and contains new monster files.
|
- Fixed content package hash calculation failing if the package is not enabled and contains new monster files.
|
||||||
- Fixed inability to enable content packages if some of the files included in the package are already in
|
- Fixed inability to enable content packages if some of the files included in the package are already in
|
||||||
the game folder (which may happen, for example, if enabling a content package fails).
|
the game folder (which may happen, for example, if enabling a content package fails).
|
||||||
- Fixed AllowRagdollButton settings not being synced with clients, leading to strange ragdolling behavior
|
- Fixed AllowRagdollButton settings not being synced with clients, leading to strange ragdolling behavior
|
||||||
client-side if the server has disabled ragdolling.
|
client-side if the server has disabled ragdolling.
|
||||||
|
- Fixed incorrect keybinds being displayed in a couple of tutorial texts.
|
||||||
|
|
||||||
---------------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------------
|
||||||
v0.8.10.0
|
v0.8.10.0
|
||||||
|
|||||||
Reference in New Issue
Block a user