(0b88fdd81) Merge branch 'dev' of https://github.com/Regalis11/Barotrauma-development into dev
This commit is contained in:
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("0.9.0.0")]
|
||||
[assembly: AssemblyFileVersion("0.9.0.0")]
|
||||
[assembly: AssemblyVersion("0.9.0.1")]
|
||||
[assembly: AssemblyFileVersion("0.9.0.1")]
|
||||
|
||||
@@ -121,90 +121,7 @@ namespace Barotrauma
|
||||
MainLimb.PullJointWorldAnchorB = Collider.SimPosition;
|
||||
MainLimb.PullJointEnabled = true;
|
||||
}
|
||||
character.SelectedConstruction = character.MemState[0].SelectedItem;
|
||||
}
|
||||
|
||||
if (character.MemState[0].Animation == AnimController.Animation.CPR)
|
||||
{
|
||||
character.AnimController.Anim = AnimController.Animation.CPR;
|
||||
}
|
||||
else if (character.AnimController.Anim == AnimController.Animation.CPR)
|
||||
{
|
||||
character.AnimController.Anim = AnimController.Animation.None;
|
||||
}
|
||||
|
||||
Vector2 newVelocity = Collider.LinearVelocity;
|
||||
Vector2 newPosition = Collider.SimPosition;
|
||||
float newRotation = Collider.Rotation;
|
||||
float newAngularVelocity = Collider.AngularVelocity;
|
||||
Collider.CorrectPosition(character.MemState, out newPosition, out newVelocity, out newRotation, out newAngularVelocity);
|
||||
|
||||
newVelocity = newVelocity.ClampLength(100.0f);
|
||||
if (!MathUtils.IsValid(newVelocity)) { newVelocity = Vector2.Zero; }
|
||||
overrideTargetMovement = newVelocity.LengthSquared() > 0.01f ? newVelocity : Vector2.Zero;
|
||||
|
||||
Collider.LinearVelocity = newVelocity;
|
||||
Collider.AngularVelocity = newAngularVelocity;
|
||||
|
||||
float distSqrd = Vector2.DistanceSquared(newPosition, Collider.SimPosition);
|
||||
float errorTolerance = character.AllowInput ? 0.01f : 0.2f;
|
||||
if (distSqrd > errorTolerance)
|
||||
{
|
||||
if (distSqrd > 10.0f || !character.AllowInput)
|
||||
{
|
||||
Collider.TargetRotation = newRotation;
|
||||
SetPosition(newPosition, lerp: distSqrd < 5.0f, ignorePlatforms: false);
|
||||
}
|
||||
else
|
||||
{
|
||||
Collider.TargetRotation = newRotation;
|
||||
Collider.TargetPosition = newPosition;
|
||||
Collider.MoveToTargetPosition(true);
|
||||
}
|
||||
}
|
||||
|
||||
//unconscious/dead characters can't correct their position using AnimController movement
|
||||
// -> we need to correct it manually
|
||||
if (!character.AllowInput)
|
||||
{
|
||||
float mainLimbDistSqrd = Vector2.DistanceSquared(MainLimb.PullJointWorldAnchorA, Collider.SimPosition);
|
||||
float mainLimbErrorTolerance = 0.1f;
|
||||
//if the main limb is roughly at the correct position and the collider isn't moving (much at least),
|
||||
//don't attempt to correct the position.
|
||||
if (mainLimbDistSqrd > mainLimbErrorTolerance || Collider.LinearVelocity.LengthSquared() > 0.05f)
|
||||
{
|
||||
MainLimb.PullJointWorldAnchorB = Collider.SimPosition;
|
||||
MainLimb.PullJointEnabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
character.MemLocalState.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
//remove states with a timestamp (there may still timestamp-based states
|
||||
//in the list if the controlled character switches from timestamp-based interpolation to ID-based)
|
||||
character.MemState.RemoveAll(m => m.Timestamp > 0.0f);
|
||||
|
||||
for (int i = 0; i < character.MemLocalState.Count; i++)
|
||||
{
|
||||
if (character.Submarine == null)
|
||||
{
|
||||
//transform in-sub coordinates to outside coordinates
|
||||
if (character.MemLocalState[i].Position.Y > lowestSubPos)
|
||||
{
|
||||
character.MemLocalState[i].TransformInToOutside();
|
||||
}
|
||||
}
|
||||
else if (currentHull?.Submarine != null)
|
||||
{
|
||||
//transform outside coordinates to in-sub coordinates
|
||||
if (character.MemLocalState[i].Position.Y < lowestSubPos)
|
||||
{
|
||||
character.MemLocalState[i].TransformOutToInside(currentHull.Submarine);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
character.MemLocalState.Clear();
|
||||
}
|
||||
|
||||
@@ -74,12 +74,17 @@ namespace Barotrauma
|
||||
public CrewManager(XElement element, bool 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;
|
||||
}
|
||||
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);
|
||||
characterInfos.Add(characterInfo);
|
||||
@@ -90,7 +95,6 @@ namespace Barotrauma
|
||||
break;
|
||||
}
|
||||
}
|
||||
ChatBox.AddMessage(ChatMessage.Create(senderName, text, messageType, sender));
|
||||
}
|
||||
|
||||
partial void InitProjectSpecific()
|
||||
@@ -239,27 +243,24 @@ namespace Barotrauma
|
||||
|
||||
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);
|
||||
if (radioItem == null) return null;
|
||||
if (requireEquipped && !character.HasEquippedItem(radioItem)) return null;
|
||||
|
||||
return radioItem.GetComponent<WifiComponent>();
|
||||
characterInfos.Add(characterInfo);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
List<Character> availableSpeakers = Character.CharacterList.FindAll(c =>
|
||||
c.AIController is HumanAIController &&
|
||||
!c.IsDead &&
|
||||
c.SpeechImpediment <= 100.0f);
|
||||
pendingConversationLines.AddRange(NPCConversation.CreateRandom(availableSpeakers));
|
||||
characters.Remove(character);
|
||||
if (removeInfo) characterInfos.Remove(character.Info);
|
||||
}
|
||||
|
||||
public void AddCharacter(Character character)
|
||||
@@ -633,9 +634,183 @@ namespace Barotrauma
|
||||
{
|
||||
characterListBox.BarScroll = roundedPos;
|
||||
}
|
||||
soundIcon.Visible = !muted && !mutedLocally;
|
||||
soundIconDisabled.Visible = muted || mutedLocally;
|
||||
soundIconDisabled.ToolTip = TextManager.Get(mutedLocally ? "MutedLocally" : "MutedGlobally");
|
||||
var characterArea = new GUIButton(new RectTransform(new Point(characterInfoWidth, frame.Rect.Height), frame.RectTransform, Anchor.CenterLeft), style: "GUITextBox")
|
||||
{
|
||||
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)
|
||||
@@ -779,6 +954,12 @@ namespace Barotrauma
|
||||
}
|
||||
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);
|
||||
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)
|
||||
{ AbsoluteOffset = new Point(orderButton.Rect.Center.X, orderButton.Rect.Bottom) },
|
||||
isHorizontal: true, childAnchor: Anchor.BottomLeft)
|
||||
orderGiver?.Speak(
|
||||
order.GetChatMessage(character.Name, orderGiver.CurrentHull?.DisplayName, givingOrderToSelf: character == orderGiver, orderOption: option), null);
|
||||
}
|
||||
else if (orderGiver != null)
|
||||
{
|
||||
OrderChatMessage msg = new OrderChatMessage(order, option, order.TargetItemComponent?.Item, character, orderGiver);
|
||||
if (GameMain.Client != null)
|
||||
{
|
||||
UserData = character,
|
||||
Stretch = true
|
||||
};
|
||||
//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);
|
||||
GameMain.Client.SendChatMessage(msg);
|
||||
}
|
||||
}
|
||||
DisplayCharacterOrder(character, order);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create the UI panel that's used to select the target and options for a given order
|
||||
|
||||
@@ -53,9 +53,9 @@ namespace Barotrauma.Tutorials
|
||||
doctor_suppliesCabinet = Item.ItemList.Find(i => i.HasTag("doctor_suppliescabinet"))?.GetComponent<ItemContainer>();
|
||||
doctor_medBayCabinet = Item.ItemList.Find(i => i.HasTag("doctor_medbaycabinet"))?.GetComponent<ItemContainer>();
|
||||
|
||||
var patientHull1 = Hull.hullList.Find(h => h.RoomName == "Waiting room" && h.Submarine == doctor.Submarine);
|
||||
var patientHull2 = Hull.hullList.Find(h => h.RoomName == "Airlock" && h.Submarine == doctor.Submarine);
|
||||
medBay = Hull.hullList.Find(h => h.RoomName == "Med bay" && h.Submarine == doctor.Submarine);
|
||||
var patientHull1 = WayPoint.WayPointList.Find(wp => wp.IdCardDesc == "waitingroom").CurrentHull;
|
||||
var patientHull2 = WayPoint.WayPointList.Find(wp => wp.IdCardDesc == "airlock").CurrentHull;
|
||||
medBay = WayPoint.WayPointList.Find(wp => wp.IdCardDesc == "medbay").CurrentHull;
|
||||
|
||||
var assistantInfo = new CharacterInfo(Character.HumanConfigFile, "", JobPrefab.List.Find(jp => jp.Identifier == "assistant"));
|
||||
patient1 = Character.Create(assistantInfo, patientHull1.WorldPosition, "1");
|
||||
|
||||
@@ -36,6 +36,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
UserData = ciElement
|
||||
};
|
||||
tickBox.TextBlock.AutoScale = true;
|
||||
tickBox.OnSelected += (tBox) =>
|
||||
{
|
||||
if (GameMain.Client == null)
|
||||
@@ -57,6 +58,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
UserData = ciElement
|
||||
};
|
||||
btn.TextBlock.AutoScale = true;
|
||||
btn.OnClicked += (_, userdata) =>
|
||||
{
|
||||
if (GameMain.Client == null)
|
||||
|
||||
@@ -1114,8 +1114,10 @@ namespace Barotrauma
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
var itemPrefab = MapEntityPrefab.Find(itemName, itemIdentifier) as ItemPrefab;
|
||||
if (itemPrefab == null) return null;
|
||||
var itemPrefab = string.IsNullOrEmpty(itemIdentifier) ?
|
||||
MapEntityPrefab.Find(itemName, null, showErrorMessages: false) as ItemPrefab :
|
||||
MapEntityPrefab.Find(itemName, itemIdentifier, showErrorMessages: false) as ItemPrefab;
|
||||
if (itemPrefab == null) { return null; }
|
||||
|
||||
Inventory inventory = null;
|
||||
|
||||
|
||||
@@ -688,6 +688,8 @@ namespace Barotrauma
|
||||
|
||||
private GUILayoutGroup subPreviewContainer;
|
||||
|
||||
private GUILayoutGroup subPreviewContainer;
|
||||
|
||||
private GUIButton loadGameButton;
|
||||
|
||||
public Action<Submarine, string, string> StartNewGame;
|
||||
|
||||
@@ -9,7 +9,6 @@ namespace Barotrauma
|
||||
private GUIListBox listBox;
|
||||
|
||||
private readonly float scrollSpeed;
|
||||
|
||||
public CreditsPlayer(RectTransform rectT, string configFile) : base(null, rectT)
|
||||
{
|
||||
var doc = XMLExtensions.TryLoadXml(configFile);
|
||||
@@ -114,6 +113,11 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public void Restart()
|
||||
{
|
||||
listBox.BarScroll = 0.0f;
|
||||
}
|
||||
|
||||
protected override void Update(float deltaTime)
|
||||
{
|
||||
listBox.BarScroll += scrollSpeed / listBox.TotalSize * deltaTime;
|
||||
|
||||
@@ -470,6 +470,7 @@ namespace Barotrauma
|
||||
break;
|
||||
case Tab.Credits:
|
||||
titleText.Visible = false;
|
||||
creditsPlayer.Restart();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("0.9.0.0")]
|
||||
[assembly: AssemblyFileVersion("0.9.0.0")]
|
||||
[assembly: AssemblyVersion("0.9.0.1")]
|
||||
[assembly: AssemblyFileVersion("0.9.0.1")]
|
||||
|
||||
@@ -1167,6 +1167,32 @@ namespace Barotrauma
|
||||
{
|
||||
#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 * 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
|
||||
abandon = true;
|
||||
return;
|
||||
|
||||
@@ -88,6 +88,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 CanBeCompleted => true;
|
||||
|
||||
|
||||
@@ -777,6 +777,10 @@ namespace Barotrauma
|
||||
{
|
||||
isCompleted = true;
|
||||
}
|
||||
if (component.AIOperate(deltaTime, character, this))
|
||||
{
|
||||
isCompleted = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -97,11 +97,12 @@ namespace Barotrauma
|
||||
|
||||
public static string GetDefaultFileName(string speciesName, AnimationType animType) => $"{speciesName.CapitaliseFirstInvariant()}{animType.ToString()}";
|
||||
public static string GetDefaultFolder(string speciesName) => $"Content/Characters/{speciesName.CapitaliseFirstInvariant()}/Animations/";
|
||||
public static string GetDefaultFile(string speciesName, AnimationType animType) => $"{GetFolder(speciesName)}{GetDefaultFileName(speciesName, animType)}.xml";
|
||||
public static string GetDefaultFile(string speciesName, AnimationType animType, ContentPackage contentPackage = null) =>
|
||||
$"{GetFolder(speciesName, contentPackage)}{GetDefaultFileName(speciesName, animType)}.xml";
|
||||
|
||||
public static string GetFolder(string speciesName)
|
||||
public static string GetFolder(string speciesName, ContentPackage contentPackage = null)
|
||||
{
|
||||
var folder = XMLExtensions.TryLoadXml(Character.GetConfigFile(speciesName))?.Root?.Element("animations")?.GetAttributeString("folder", string.Empty);
|
||||
var folder = XMLExtensions.TryLoadXml(Character.GetConfigFile(speciesName, contentPackage))?.Root?.Element("animations")?.GetAttributeString("folder", string.Empty);
|
||||
if (string.IsNullOrEmpty(folder) || folder.ToLowerInvariant() == "default")
|
||||
{
|
||||
folder = GetDefaultFolder(speciesName);
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace Barotrauma
|
||||
|
||||
public static string GetDefaultFileName(string speciesName) => $"{speciesName.CapitaliseFirstInvariant()}DefaultRagdoll";
|
||||
public static string GetDefaultFolder(string speciesName) => $"Content/Characters/{speciesName.CapitaliseFirstInvariant()}/Ragdolls/";
|
||||
public static string GetDefaultFile(string speciesName) => $"{GetFolder(speciesName)}{GetDefaultFileName(speciesName)}.xml";
|
||||
public static string GetDefaultFile(string speciesName, ContentPackage contentPackage = null) => $"{GetFolder(speciesName, contentPackage)}{GetDefaultFileName(speciesName)}.xml";
|
||||
|
||||
private static readonly object[] dummyParams = new object[]
|
||||
{
|
||||
@@ -79,9 +79,9 @@ namespace Barotrauma
|
||||
new XAttribute("sourcerect", $"0, 0, 1, 1")))
|
||||
};
|
||||
|
||||
public static string GetFolder(string speciesName)
|
||||
public static string GetFolder(string speciesName, ContentPackage contentPackage = null)
|
||||
{
|
||||
var folder = XMLExtensions.TryLoadXml(Character.GetConfigFile(speciesName))?.Root?.Element("ragdolls")?.GetAttributeString("folder", string.Empty);
|
||||
var folder = XMLExtensions.TryLoadXml(Character.GetConfigFile(speciesName, contentPackage))?.Root?.Element("ragdolls")?.GetAttributeString("folder", string.Empty);
|
||||
if (string.IsNullOrEmpty(folder) || folder.ToLowerInvariant() == "default")
|
||||
{
|
||||
//DebugConsole.NewMessage("[RagollParams] Using the default folder.");
|
||||
|
||||
@@ -853,15 +853,26 @@ namespace Barotrauma
|
||||
{
|
||||
if (characterConfigFiles == null)
|
||||
{
|
||||
characterConfigFiles = GameMain.Instance.GetFilesOfType(ContentType.Character, searchAllContentPackages: true);
|
||||
characterConfigFiles = GameMain.Instance.GetFilesOfType(ContentType.Character);
|
||||
}
|
||||
return characterConfigFiles;
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetConfigFile(string speciesName)
|
||||
public static string GetConfigFile(string speciesName, ContentPackage contentPackage = null)
|
||||
{
|
||||
string configFile = CharacterConfigFiles.FirstOrDefault(c => Path.GetFileName(c).ToLowerInvariant() == $"{speciesName.ToLowerInvariant()}.xml");
|
||||
string configFile = null;
|
||||
if (contentPackage == null)
|
||||
{
|
||||
configFile = GameMain.Instance.GetFilesOfType(ContentType.Character, searchAllContentPackages: true)
|
||||
.FirstOrDefault(c => Path.GetFileName(c).ToLowerInvariant() == $"{speciesName.ToLowerInvariant()}.xml");
|
||||
}
|
||||
else
|
||||
{
|
||||
configFile = contentPackage.GetFilesOfType(ContentType.Character)?
|
||||
.FirstOrDefault(c => Path.GetFileName(c).ToLowerInvariant() == $"{speciesName.ToLowerInvariant()}.xml");
|
||||
}
|
||||
|
||||
if (configFile == null)
|
||||
{
|
||||
DebugConsole.ThrowError($"Couldn't find a config file for {speciesName} from the selected content packages!");
|
||||
@@ -1136,7 +1147,7 @@ namespace Barotrauma
|
||||
|
||||
if (!(this is AICharacter) || Controlled == this || IsRemotePlayer)
|
||||
{
|
||||
Vector2 targetMovement = GetTargetMovement();
|
||||
if (speedMultipliers.Count == 0) return 1f;
|
||||
|
||||
AnimController.TargetMovement = targetMovement;
|
||||
AnimController.IgnorePlatforms = AnimController.TargetMovement.Y < -0.1f;
|
||||
|
||||
@@ -362,10 +362,11 @@ namespace Barotrauma
|
||||
case ContentType.Character:
|
||||
XDocument doc = XMLExtensions.TryLoadXml(file.Path);
|
||||
string speciesName = doc.Root.GetAttributeString("name", "");
|
||||
filePaths.Add(RagdollParams.GetDefaultFile(speciesName));
|
||||
//TODO: check non-default paths if defined
|
||||
filePaths.Add(RagdollParams.GetDefaultFile(speciesName, this));
|
||||
foreach (AnimationType animationType in Enum.GetValues(typeof(AnimationType)))
|
||||
{
|
||||
filePaths.Add(AnimationParams.GetDefaultFile(speciesName, animationType));
|
||||
filePaths.Add(AnimationParams.GetDefaultFile(speciesName, animationType, this));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -491,6 +492,11 @@ namespace Barotrauma
|
||||
public ContentFile(string path, ContentType type, Workshop.Item workShopItem = null)
|
||||
{
|
||||
Path = path;
|
||||
|
||||
#if OSX
|
||||
Path = Path.Replace("\\", "/");
|
||||
#endif
|
||||
|
||||
Type = type;
|
||||
WorkShopItem = workShopItem;
|
||||
}
|
||||
|
||||
@@ -601,6 +601,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())
|
||||
{
|
||||
inputContainer.Inventory.RemoveItem(targetItem);
|
||||
|
||||
@@ -144,6 +144,17 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 SteeringInput
|
||||
{
|
||||
get { return steeringInput; }
|
||||
set
|
||||
{
|
||||
if (!MathUtils.IsValid(value)) return;
|
||||
steeringInput.X = MathHelper.Clamp(value.X, -100.0f, 100.0f);
|
||||
steeringInput.Y = MathHelper.Clamp(value.Y, -100.0f, 100.0f);
|
||||
}
|
||||
}
|
||||
|
||||
public SteeringPath SteeringPath
|
||||
{
|
||||
if (!CanBeSelected) return false;
|
||||
@@ -164,12 +175,6 @@ namespace Barotrauma.Items.Components
|
||||
set { posToMaintain = value; }
|
||||
}
|
||||
|
||||
public Vector2? PosToMaintain
|
||||
{
|
||||
get { return posToMaintain; }
|
||||
set { posToMaintain = value; }
|
||||
}
|
||||
|
||||
struct ObstacleDebugInfo
|
||||
{
|
||||
public Vector2 Point1;
|
||||
|
||||
@@ -1527,11 +1527,7 @@ namespace Barotrauma
|
||||
|
||||
if (!picked) return false;
|
||||
|
||||
if (picker.SelectedConstruction == this)
|
||||
{
|
||||
if (picker.IsKeyHit(InputType.Select) || forceSelectKey) picker.SelectedConstruction = null;
|
||||
}
|
||||
else if (selected)
|
||||
if (picker != null)
|
||||
{
|
||||
if (picker.SelectedConstruction == this)
|
||||
{
|
||||
@@ -1946,6 +1942,7 @@ namespace Barotrauma
|
||||
return Load(element, submarine, createNetworkEvent: false);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Instantiate a new item and load its data from the XML element.
|
||||
/// </summary>
|
||||
@@ -1958,30 +1955,10 @@ namespace Barotrauma
|
||||
string name = element.Attribute("name").Value;
|
||||
string identifier = element.GetAttributeString("identifier", "");
|
||||
|
||||
ItemPrefab prefab;
|
||||
if (string.IsNullOrEmpty(identifier))
|
||||
{
|
||||
//legacy support:
|
||||
//1. attempt to find a prefab with an empty identifier and a matching name
|
||||
prefab = MapEntityPrefab.Find(name, "", showErrorMessages: false) as ItemPrefab;
|
||||
//2. not found, attempt to find a prefab with a matching name
|
||||
if (prefab == null) prefab = MapEntityPrefab.Find(name) as ItemPrefab;
|
||||
}
|
||||
else
|
||||
{
|
||||
prefab = MapEntityPrefab.Find(null, identifier, showErrorMessages: false) as ItemPrefab;
|
||||
|
||||
//not found, see if we can find a prefab with a matching alias
|
||||
if (prefab == null)
|
||||
{
|
||||
string lowerCaseName = name.ToLowerInvariant();
|
||||
prefab = MapEntityPrefab.List.Find(me => me.Aliases != null && me.Aliases.Contains(lowerCaseName)) as ItemPrefab;
|
||||
}
|
||||
}
|
||||
ItemPrefab prefab = ItemPrefab.Find(name, identifier);
|
||||
|
||||
if (prefab == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Error loading item - item prefab \"" + name + "\" (identifier \"" + identifier + "\") not found.");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Xml.Linq;
|
||||
using System.Linq;
|
||||
using Barotrauma.Extensions;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -441,6 +440,7 @@ namespace Barotrauma
|
||||
configFile = filePath;
|
||||
ConfigElement = element;
|
||||
|
||||
string nonTranslatedName = element.GetAttributeString("name", "");
|
||||
identifier = element.GetAttributeString("identifier", "");
|
||||
|
||||
//nameidentifier can be used to make multiple items use the same names and descriptions
|
||||
@@ -448,20 +448,21 @@ namespace Barotrauma
|
||||
|
||||
if (string.IsNullOrEmpty(nameIdentifier))
|
||||
{
|
||||
name = TextManager.Get("EntityName." + identifier, true) ?? element.GetAttributeString("name", "");
|
||||
name = TextManager.Get("EntityName." + identifier, true) ?? nonTranslatedName;
|
||||
}
|
||||
else
|
||||
{
|
||||
name = TextManager.Get("EntityName." + nameIdentifier, true) ?? element.GetAttributeString("name", "");
|
||||
name = TextManager.Get("EntityName." + nameIdentifier, true) ?? nonTranslatedName;
|
||||
}
|
||||
|
||||
if (name == "") { DebugConsole.ThrowError("Unnamed item in " + filePath + "!"); }
|
||||
|
||||
DebugConsole.Log(" " + name);
|
||||
|
||||
Aliases =
|
||||
element.GetAttributeStringArray("aliases", null, convertToLowerInvariant: true) ??
|
||||
element.GetAttributeStringArray("Aliases", new string[0], convertToLowerInvariant: true);
|
||||
Aliases = new HashSet<string>
|
||||
(element.GetAttributeStringArray("aliases", null, convertToLowerInvariant: true) ??
|
||||
element.GetAttributeStringArray("Aliases", new string[0], convertToLowerInvariant: true));
|
||||
Aliases.Add(nonTranslatedName.ToLowerInvariant());
|
||||
|
||||
if (!Enum.TryParse(element.GetAttributeString("category", "Misc"), true, out MapEntityCategory category))
|
||||
{
|
||||
@@ -481,7 +482,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
Tags = new HashSet<string>(element.GetAttributeStringArray("tags", new string[0], convertToLowerInvariant: true));
|
||||
if (Tags.None())
|
||||
if (!Tags.Any())
|
||||
{
|
||||
Tags = new HashSet<string>(element.GetAttributeStringArray("Tags", new string[0], convertToLowerInvariant: true));
|
||||
}
|
||||
@@ -719,7 +720,42 @@ namespace Barotrauma
|
||||
return prices[location.Type.Identifier.ToLowerInvariant()];
|
||||
}
|
||||
|
||||
public static ItemPrefab Find(string name, string identifier)
|
||||
{
|
||||
ItemPrefab prefab;
|
||||
if (string.IsNullOrEmpty(identifier))
|
||||
{
|
||||
//legacy support:
|
||||
//1. attempt to find a prefab with an empty identifier and a matching name
|
||||
prefab = Find(name, "", showErrorMessages: false) as ItemPrefab;
|
||||
//2. not found, attempt to find a prefab with a matching name
|
||||
if (prefab == null) prefab = Find(name) as ItemPrefab;
|
||||
//not found, see if we can find a prefab with a matching alias
|
||||
if (prefab == null)
|
||||
{
|
||||
string lowerCaseName = name.ToLowerInvariant();
|
||||
prefab = List.Find(me => me.Aliases != null && me.Aliases.Contains(lowerCaseName)) as ItemPrefab;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
prefab = Find(null, identifier, showErrorMessages: false) as ItemPrefab;
|
||||
|
||||
//not found, see if we can find a prefab with a matching alias
|
||||
if (prefab == null)
|
||||
{
|
||||
string lowerCaseName = name.ToLowerInvariant();
|
||||
prefab = List.Find(me => me.Aliases != null && me.Aliases.Contains(lowerCaseName)) as ItemPrefab;
|
||||
}
|
||||
}
|
||||
|
||||
if (prefab == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Error loading item - item prefab \"" + name + "\" (identifier \"" + identifier + "\") not found.");
|
||||
}
|
||||
return prefab;
|
||||
}
|
||||
public IEnumerable<PriceInfo> GetPrices()
|
||||
{
|
||||
return prices?.Values;
|
||||
|
||||
@@ -83,6 +83,27 @@ namespace Barotrauma
|
||||
|
||||
public readonly List<Gap> ConnectedGaps = new List<Gap>();
|
||||
|
||||
public readonly List<Gap> ConnectedGaps = new List<Gap>();
|
||||
|
||||
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 string DisplayName
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
private string roomName;
|
||||
[Editable, Serialize("", true, translationTextTag: "RoomName.")]
|
||||
public string RoomName
|
||||
|
||||
@@ -115,6 +115,7 @@ namespace Barotrauma
|
||||
Linkable = true
|
||||
};
|
||||
ep.AllowedLinks.Add("hull");
|
||||
ep.Aliases = new HashSet<string> { "hull" };
|
||||
List.Add(ep);
|
||||
|
||||
ep = new MapEntityPrefab
|
||||
|
||||
@@ -225,12 +225,6 @@ namespace Barotrauma
|
||||
string nonTranslatedName = element.GetAttributeString("name", null) ?? element.Name.ToString();
|
||||
sp.Aliases.Add(nonTranslatedName.ToLowerInvariant());
|
||||
|
||||
SerializableProperty.DeserializeProperties(sp, element);
|
||||
if (sp.Body)
|
||||
{
|
||||
sp.Tags.Add("wall");
|
||||
}
|
||||
|
||||
SerializableProperty.DeserializeProperties(sp, element);
|
||||
if (sp.Body)
|
||||
{
|
||||
|
||||
@@ -131,7 +131,12 @@ namespace Barotrauma.Networking
|
||||
float dist = Vector2.Distance(listener.WorldPosition, sender.WorldPosition);
|
||||
if (dist > range) { return 1.0f; }
|
||||
|
||||
if (Submarine.CheckVisibility(listener.SimPosition, sender.SimPosition) != null) dist = (dist + 100f) * obstructionmult;
|
||||
Hull listenerHull = listener == null ? null : Hull.FindHull(listener.WorldPosition);
|
||||
Hull sourceHull = sender == null ? null : Hull.FindHull(sender.WorldPosition);
|
||||
if (sourceHull != listenerHull)
|
||||
{
|
||||
if (Submarine.CheckVisibility(listener.SimPosition, sender.SimPosition) != null) dist = (dist + 100f) * obstructionmult;
|
||||
}
|
||||
if (dist > range) { return 1.0f; }
|
||||
|
||||
return dist / range;
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,3 +1,19 @@
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
v0.9.0.1
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
|
||||
- Added a bunch of missing translations.
|
||||
- Fixed Steam Workshop on Mac.
|
||||
- Fixed docking interface button not working in the multiplayer.
|
||||
- Fixed medical doctor tutorial crashing on languages other than English.
|
||||
- Fixed a bug that caused AI characters to occasionally get stuck next to stairways.
|
||||
- Fixed animation and ragdoll file paths getting messed up if there are multiple content packages
|
||||
installed that include monsters with the same name.
|
||||
- Fixed crashing when a StatusEffect causes an item to be used on a target.
|
||||
- Fixed a gap between Remora and the drone.
|
||||
- Added more supplies to Remora.
|
||||
- Fixed watchman's dialogue getting muffled.
|
||||
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
v0.9.0.0
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user