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

This commit is contained in:
Joonas Rikkonen
2019-05-16 06:19:27 +03:00
parent e8ee3f9d18
commit 69494dcde8
15 changed files with 358 additions and 157 deletions
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.8.10.0")] [assembly: AssemblyVersion("0.9.0.0")]
[assembly: AssemblyFileVersion("0.8.10.0")] [assembly: AssemblyFileVersion("0.9.0.0")]
@@ -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,12 +74,17 @@ namespace Barotrauma
public CrewManager(XElement element, bool isSinglePlayer) public CrewManager(XElement element, bool isSinglePlayer)
: this(isSinglePlayer) : this(isSinglePlayer)
{ {
if (!isSinglePlayer) if (GameMain.Client != null)
{ {
DebugConsole.ThrowError("Cannot add messages to single player chat box in multiplayer mode!\n" + Environment.StackTrace); //let the server create random conversations in MP
return; return;
} }
if (string.IsNullOrEmpty(text)) { return; } List<Character> availableSpeakers = Character.CharacterList.FindAll(c =>
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);
@@ -90,7 +95,6 @@ namespace Barotrauma
break; break;
} }
} }
ChatBox.AddMessage(ChatMessage.Create(senderName, text, messageType, sender));
} }
partial void InitProjectSpecific() partial void InitProjectSpecific()
@@ -239,27 +243,24 @@ namespace Barotrauma
public IEnumerable<Character> GetCharacters() public IEnumerable<Character> GetCharacters()
{ {
if (character?.Inventory == null) return null; if (characterInfos.Contains(characterInfo))
{
DebugConsole.ThrowError("Tried to add the same character info to CrewManager twice.\n" + Environment.StackTrace);
return;
}
var radioItem = character.Inventory.Items.FirstOrDefault(it => it != null && it.GetComponent<WifiComponent>() != null); characterInfos.Add(characterInfo);
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 (GameMain.Client != null) if (character == null)
{ {
//let the server create random conversations in MP DebugConsole.ThrowError("Tried to remove a null character from CrewManager.\n" + Environment.StackTrace);
return; return;
} }
List<Character> availableSpeakers = Character.CharacterList.FindAll(c => characters.Remove(character);
c.AIController is HumanAIController && if (removeInfo) characterInfos.Remove(character.Info);
!c.IsDead &&
c.SpeechImpediment <= 100.0f);
pendingConversationLines.AddRange(NPCConversation.CreateRandom(availableSpeakers));
} }
public void AddCharacter(Character character) public void AddCharacter(Character character)
@@ -633,9 +634,183 @@ namespace Barotrauma
{ {
characterListBox.BarScroll = roundedPos; characterListBox.BarScroll = roundedPos;
} }
soundIcon.Visible = !muted && !mutedLocally; var characterArea = new GUIButton(new RectTransform(new Point(characterInfoWidth, frame.Rect.Height), frame.RectTransform, Anchor.CenterLeft), style: "GUITextBox")
soundIconDisabled.Visible = muted || mutedLocally; {
soundIconDisabled.ToolTip = TextManager.Get(mutedLocally ? "MutedLocally" : "MutedGlobally"); UserData = character,
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)
@@ -779,6 +954,12 @@ 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)
@@ -836,19 +1017,23 @@ namespace Barotrauma
} }
} }
} }
//only one target (or an order with no particular targets), just show options
else character.SetOrder(order, option, orderGiver, speak: orderGiver != character);
if (IsSinglePlayer)
{ {
orderTargetFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.2f + order.Options.Length * 0.1f, 0.18f), GUI.Canvas) orderGiver?.Speak(
{ AbsoluteOffset = new Point(orderButton.Rect.Center.X, orderButton.Rect.Bottom) }, order.GetChatMessage(character.Name, orderGiver.CurrentHull?.DisplayName, givingOrderToSelf: character == orderGiver, orderOption: option), null);
isHorizontal: true, childAnchor: Anchor.BottomLeft) }
else if (orderGiver != null)
{
OrderChatMessage msg = new OrderChatMessage(order, option, order.TargetItemComponent?.Item, character, orderGiver);
if (GameMain.Client != null)
{ {
UserData = character, GameMain.Client.SendChatMessage(msg);
Stretch = true }
}; }
//line connecting the order button to the option buttons DisplayCharacterOrder(character, order);
//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
@@ -480,6 +480,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,6 +789,10 @@ 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
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.8.10.0")] [assembly: AssemblyVersion("0.9.0.0")]
[assembly: AssemblyFileVersion("0.8.10.0")] [assembly: AssemblyFileVersion("0.9.0.0")]
-35
View File
@@ -31,41 +31,6 @@ Game port (used to communicate with clients)
Internal Port: The port you have selected for your server (27015 by default) Internal Port: The port you have selected for your server (27015 by default)
Protocol: UDP Protocol: UDP
Query port (used to communicate with Steam)
Service/Application: barotrauma
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)
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
Query port (used to communicate with Steam) 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)
@@ -779,6 +779,32 @@ namespace Barotrauma
{ {
#if DEBUG #if DEBUG
DebugConsole.ThrowError("AIObjectiveFixLeak failed - the item \"" + weldingTool + "\" has no RepairTool component but is tagged as a welding tool"); 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 * 1.5f;
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 });
}
if (subObjectives.Any()) { return; }
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 #endif
abandon = true; abandon = true;
return; return;
@@ -73,6 +73,21 @@ 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;
@@ -362,6 +362,10 @@ namespace Barotrauma
{ {
isCompleted = true; isCompleted = true;
} }
if (component.AIOperate(deltaTime, character, this))
{
isCompleted = true;
}
} }
else else
{ {
@@ -753,6 +753,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,33 +212,6 @@ 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;
@@ -626,6 +626,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
+23 -3
View File
@@ -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