(de26bb46c) AutoScale CustomInterface texts to prevent overflows
This commit is contained in:
@@ -108,6 +108,61 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//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.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
|
//unconscious/dead characters can't correct their position using AnimController movement
|
||||||
// -> we need to correct it manually
|
// -> we need to correct it manually
|
||||||
if (!character.AllowInput)
|
if (!character.AllowInput)
|
||||||
@@ -151,32 +206,34 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
character.MemLocalState.Clear();
|
||||||
if (character.MemLocalState.Count > 120) character.MemLocalState.RemoveRange(0, character.MemLocalState.Count - 120);
|
|
||||||
character.MemState.Clear();
|
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
|
|
||||||
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); }
|
//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)
|
||||||
else if (body.UserData is Limb || body == Collider.FarseerBody)
|
character.MemState.RemoveAll(m => m.Timestamp > 0.0f);
|
||||||
{
|
|
||||||
if (!character.IsRemotePlayer && impact > ImpactTolerance)
|
for (int i = 0; i < character.MemLocalState.Count; i++)
|
||||||
{
|
{
|
||||||
SoundPlayer.PlayDamageSound("LimbBlunt", strongestImpact, Collider);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
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;
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
UserData = ciElement
|
UserData = ciElement
|
||||||
};
|
};
|
||||||
|
tickBox.TextBlock.AutoScale = true;
|
||||||
tickBox.OnSelected += (tBox) =>
|
tickBox.OnSelected += (tBox) =>
|
||||||
{
|
{
|
||||||
if (GameMain.Client == null)
|
if (GameMain.Client == null)
|
||||||
@@ -57,6 +58,7 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
UserData = ciElement
|
UserData = ciElement
|
||||||
};
|
};
|
||||||
|
btn.TextBlock.AutoScale = true;
|
||||||
btn.OnClicked += (_, userdata) =>
|
btn.OnClicked += (_, userdata) =>
|
||||||
{
|
{
|
||||||
if (GameMain.Client == null)
|
if (GameMain.Client == null)
|
||||||
|
|||||||
@@ -1114,8 +1114,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
//----------------------------------------
|
//----------------------------------------
|
||||||
|
|
||||||
var itemPrefab = MapEntityPrefab.Find(itemName, itemIdentifier) as ItemPrefab;
|
var itemPrefab = string.IsNullOrEmpty(itemIdentifier) ?
|
||||||
if (itemPrefab == null) return null;
|
MapEntityPrefab.Find(itemName, null, showErrorMessages: false) as ItemPrefab :
|
||||||
|
MapEntityPrefab.Find(itemName, itemIdentifier, showErrorMessages: false) as ItemPrefab;
|
||||||
|
if (itemPrefab == null) { return null; }
|
||||||
|
|
||||||
Inventory inventory = null;
|
Inventory inventory = null;
|
||||||
|
|
||||||
|
|||||||
@@ -650,6 +650,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;
|
||||||
|
|||||||
@@ -169,15 +169,7 @@ namespace Barotrauma
|
|||||||
bool highPressure = Character.CurrentHull == null || Character.CurrentHull.LethalPressure > 0 && Character.PressureProtection <= 0;
|
bool highPressure = Character.CurrentHull == null || Character.CurrentHull.LethalPressure > 0 && Character.PressureProtection <= 0;
|
||||||
bool shouldKeepTheGearOn = !ObjectiveManager.IsCurrentObjective<AIObjectiveIdle>();
|
bool shouldKeepTheGearOn = !ObjectiveManager.IsCurrentObjective<AIObjectiveIdle>();
|
||||||
|
|
||||||
// Don't allow to drop the diving suit in water or while climbing or if the current path has stairs
|
bool removeDivingSuit = (oxygenLow && !highPressure) || (!shouldKeepTheGearOn && Character.CurrentHull.WaterPercentage < 1 && !Character.IsClimbing && steeringManager == insideSteering && !PathSteering.InStairs);
|
||||||
bool removeDivingSuit =
|
|
||||||
(oxygenLow && !highPressure) ||
|
|
||||||
(!shouldKeepTheGearOn &&
|
|
||||||
Character.CurrentHull.WaterPercentage < 1 &&
|
|
||||||
!Character.IsClimbing &&
|
|
||||||
steeringManager == insideSteering &&
|
|
||||||
!PathSteering.InStairs);
|
|
||||||
|
|
||||||
if (removeDivingSuit)
|
if (removeDivingSuit)
|
||||||
{
|
{
|
||||||
var divingSuit = Character.Inventory.FindItemByIdentifier("divingsuit") ?? Character.Inventory.FindItemByTag("divingsuit");
|
var divingSuit = Character.Inventory.FindItemByIdentifier("divingsuit") ?? Character.Inventory.FindItemByTag("divingsuit");
|
||||||
|
|||||||
@@ -53,9 +53,13 @@ namespace Barotrauma
|
|||||||
(currentPath.NextNode != null && currentPath.NextNode.Ladders != null));
|
(currentPath.NextNode != null && currentPath.NextNode.Ladders != null));
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns true if any node in the path is in stairs
|
/// Returns true if the previous, current or the next node is in stairs.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool InStairs => currentPath != null && currentPath.Nodes.Any(n => n.Stairs != null);
|
public bool InStairs =>
|
||||||
|
currentPath != null && (
|
||||||
|
currentPath.PrevNode != null && currentPath.PrevNode.Stairs != null ||
|
||||||
|
currentPath.CurrentNode != null && currentPath.CurrentNode.Stairs != null ||
|
||||||
|
currentPath.NextNode != null && currentPath.NextNode.Stairs != null);
|
||||||
|
|
||||||
public bool IsNextNodeLadder
|
public bool IsNextNodeLadder
|
||||||
{
|
{
|
||||||
@@ -300,9 +304,7 @@ namespace Barotrauma
|
|||||||
float horizontalDistance = Math.Abs(collider.SimPosition.X - currentPath.CurrentNode.SimPosition.X);
|
float horizontalDistance = Math.Abs(collider.SimPosition.X - currentPath.CurrentNode.SimPosition.X);
|
||||||
bool isAboveFeet = currentPath.CurrentNode.SimPosition.Y > colliderBottom.Y;
|
bool isAboveFeet = currentPath.CurrentNode.SimPosition.Y > colliderBottom.Y;
|
||||||
bool isNotTooHigh = currentPath.CurrentNode.SimPosition.Y < colliderBottom.Y + characterHeight;
|
bool isNotTooHigh = currentPath.CurrentNode.SimPosition.Y < colliderBottom.Y + characterHeight;
|
||||||
float margin = MathHelper.Lerp(1, 10, MathHelper.Clamp(Math.Abs(velocity.X) / 10, 0, 1));
|
if (currentPath.CurrentNode != null && currentPath.CurrentNode.Stairs != null)
|
||||||
float targetDistance = collider.radius * margin;
|
|
||||||
if (horizontalDistance < targetDistance && isAboveFeet && isNotTooHigh)
|
|
||||||
{
|
{
|
||||||
float multiplierX = MathHelper.Lerp(1, 10, MathHelper.Clamp(Math.Abs(velocity.X) / 10, 0, 1));
|
float multiplierX = MathHelper.Lerp(1, 10, MathHelper.Clamp(Math.Abs(velocity.X) / 10, 0, 1));
|
||||||
float multiplierY = MathHelper.Lerp(1, 10, MathHelper.Clamp(Math.Abs(velocity.Y) / 10, 0, 1));
|
float multiplierY = MathHelper.Lerp(1, 10, MathHelper.Clamp(Math.Abs(velocity.Y) / 10, 0, 1));
|
||||||
|
|||||||
@@ -673,6 +673,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;
|
||||||
|
|
||||||
|
|||||||
@@ -701,6 +701,10 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
isCompleted = true;
|
isCompleted = true;
|
||||||
}
|
}
|
||||||
|
if (component.AIOperate(deltaTime, character, this))
|
||||||
|
{
|
||||||
|
isCompleted = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
+4
-3
@@ -97,11 +97,12 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public static string GetDefaultFileName(string speciesName, AnimationType animType) => $"{speciesName.CapitaliseFirstInvariant()}{animType.ToString()}";
|
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 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")
|
if (string.IsNullOrEmpty(folder) || folder.ToLowerInvariant() == "default")
|
||||||
{
|
{
|
||||||
folder = GetDefaultFolder(speciesName);
|
folder = GetDefaultFolder(speciesName);
|
||||||
|
|||||||
+3
-3
@@ -64,7 +64,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public static string GetDefaultFileName(string speciesName) => $"{speciesName.CapitaliseFirstInvariant()}DefaultRagdoll";
|
public static string GetDefaultFileName(string speciesName) => $"{speciesName.CapitaliseFirstInvariant()}DefaultRagdoll";
|
||||||
public static string GetDefaultFolder(string speciesName) => $"Content/Characters/{speciesName.CapitaliseFirstInvariant()}/Ragdolls/";
|
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[]
|
private static readonly object[] dummyParams = new object[]
|
||||||
{
|
{
|
||||||
@@ -79,9 +79,9 @@ namespace Barotrauma
|
|||||||
new XAttribute("sourcerect", $"0, 0, 1, 1")))
|
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")
|
if (string.IsNullOrEmpty(folder) || folder.ToLowerInvariant() == "default")
|
||||||
{
|
{
|
||||||
//DebugConsole.NewMessage("[RagollParams] Using the default folder.");
|
//DebugConsole.NewMessage("[RagollParams] Using the default folder.");
|
||||||
|
|||||||
@@ -853,15 +853,26 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (characterConfigFiles == null)
|
if (characterConfigFiles == null)
|
||||||
{
|
{
|
||||||
characterConfigFiles = GameMain.Instance.GetFilesOfType(ContentType.Character, searchAllContentPackages: true);
|
characterConfigFiles = GameMain.Instance.GetFilesOfType(ContentType.Character);
|
||||||
}
|
}
|
||||||
return characterConfigFiles;
|
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)
|
if (configFile == null)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError($"Couldn't find a config file for {speciesName} from the selected content packages!");
|
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)
|
if (!(this is AICharacter) || Controlled == this || IsRemotePlayer)
|
||||||
{
|
{
|
||||||
Vector2 targetMovement = GetTargetMovement();
|
if (speedMultipliers.Count == 0) return 1f;
|
||||||
|
|
||||||
AnimController.TargetMovement = targetMovement;
|
AnimController.TargetMovement = targetMovement;
|
||||||
AnimController.IgnorePlatforms = AnimController.TargetMovement.Y < -0.1f;
|
AnimController.IgnorePlatforms = AnimController.TargetMovement.Y < -0.1f;
|
||||||
|
|||||||
@@ -362,10 +362,11 @@ namespace Barotrauma
|
|||||||
case ContentType.Character:
|
case ContentType.Character:
|
||||||
XDocument doc = XMLExtensions.TryLoadXml(file.Path);
|
XDocument doc = XMLExtensions.TryLoadXml(file.Path);
|
||||||
string speciesName = doc.Root.GetAttributeString("name", "");
|
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)))
|
foreach (AnimationType animationType in Enum.GetValues(typeof(AnimationType)))
|
||||||
{
|
{
|
||||||
filePaths.Add(AnimationParams.GetDefaultFile(speciesName, animationType));
|
filePaths.Add(AnimationParams.GetDefaultFile(speciesName, animationType, this));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -491,6 +492,11 @@ namespace Barotrauma
|
|||||||
public ContentFile(string path, ContentType type, Workshop.Item workShopItem = null)
|
public ContentFile(string path, ContentType type, Workshop.Item workShopItem = null)
|
||||||
{
|
{
|
||||||
Path = path;
|
Path = path;
|
||||||
|
|
||||||
|
#if OSX
|
||||||
|
Path = Path.Replace("\\", "/");
|
||||||
|
#endif
|
||||||
|
|
||||||
Type = type;
|
Type = type;
|
||||||
WorkShopItem = workShopItem;
|
WorkShopItem = workShopItem;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -772,6 +772,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);
|
||||||
|
|||||||
@@ -144,17 +144,6 @@ 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
|
public SteeringPath SteeringPath
|
||||||
{
|
{
|
||||||
if (!CanBeSelected) return false;
|
if (!CanBeSelected) return false;
|
||||||
@@ -175,6 +164,12 @@ namespace Barotrauma.Items.Components
|
|||||||
set { posToMaintain = value; }
|
set { posToMaintain = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vector2? PosToMaintain
|
||||||
|
{
|
||||||
|
get { return posToMaintain; }
|
||||||
|
set { posToMaintain = value; }
|
||||||
|
}
|
||||||
|
|
||||||
struct ObstacleDebugInfo
|
struct ObstacleDebugInfo
|
||||||
{
|
{
|
||||||
public Vector2 Point1;
|
public Vector2 Point1;
|
||||||
|
|||||||
@@ -1127,6 +1127,10 @@ 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; }
|
||||||
|
|
||||||
@@ -1171,6 +1175,27 @@ 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()
|
public void UpdateTransform()
|
||||||
{
|
{
|
||||||
Submarine prevSub = Submarine;
|
Submarine prevSub = Submarine;
|
||||||
@@ -2003,6 +2028,7 @@ namespace Barotrauma
|
|||||||
return Load(element, submarine, createNetworkEvent: false);
|
return Load(element, submarine, createNetworkEvent: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Instantiate a new item and load its data from the XML element.
|
/// Instantiate a new item and load its data from the XML element.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -2015,30 +2041,10 @@ namespace Barotrauma
|
|||||||
string name = element.Attribute("name").Value;
|
string name = element.Attribute("name").Value;
|
||||||
string identifier = element.GetAttributeString("identifier", "");
|
string identifier = element.GetAttributeString("identifier", "");
|
||||||
|
|
||||||
ItemPrefab prefab;
|
ItemPrefab prefab = ItemPrefab.Find(name, identifier);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prefab == null)
|
if (prefab == null)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Error loading item - item prefab \"" + name + "\" (identifier \"" + identifier + "\") not found.");
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -441,6 +441,7 @@ namespace Barotrauma
|
|||||||
configFile = filePath;
|
configFile = filePath;
|
||||||
ConfigElement = element;
|
ConfigElement = element;
|
||||||
|
|
||||||
|
string nonTranslatedName = element.GetAttributeString("name", "");
|
||||||
identifier = element.GetAttributeString("identifier", "");
|
identifier = element.GetAttributeString("identifier", "");
|
||||||
|
|
||||||
//nameidentifier can be used to make multiple items use the same names and descriptions
|
//nameidentifier can be used to make multiple items use the same names and descriptions
|
||||||
@@ -448,11 +449,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (string.IsNullOrEmpty(nameIdentifier))
|
if (string.IsNullOrEmpty(nameIdentifier))
|
||||||
{
|
{
|
||||||
name = TextManager.Get("EntityName." + identifier, true) ?? element.GetAttributeString("name", "");
|
name = TextManager.Get("EntityName." + identifier, true) ?? nonTranslatedName;
|
||||||
}
|
}
|
||||||
else
|
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 + "!"); }
|
if (name == "") { DebugConsole.ThrowError("Unnamed item in " + filePath + "!"); }
|
||||||
@@ -460,8 +461,10 @@ namespace Barotrauma
|
|||||||
DebugConsole.Log(" " + name);
|
DebugConsole.Log(" " + name);
|
||||||
|
|
||||||
Aliases =
|
Aliases =
|
||||||
element.GetAttributeStringArray("aliases", null, convertToLowerInvariant: true) ??
|
(element.GetAttributeStringArray("aliases", null, convertToLowerInvariant: true) ??
|
||||||
element.GetAttributeStringArray("Aliases", new string[0], convertToLowerInvariant: true);
|
element.GetAttributeStringArray("Aliases", new string[0], convertToLowerInvariant: true)).ToHashSet();
|
||||||
|
Aliases.Add(nonTranslatedName.ToLowerInvariant());
|
||||||
|
|
||||||
|
|
||||||
if (!Enum.TryParse(element.GetAttributeString("category", "Misc"), true, out MapEntityCategory category))
|
if (!Enum.TryParse(element.GetAttributeString("category", "Misc"), true, out MapEntityCategory category))
|
||||||
{
|
{
|
||||||
@@ -719,7 +722,42 @@ namespace Barotrauma
|
|||||||
return prices[location.Type.Identifier.ToLowerInvariant()];
|
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()
|
public IEnumerable<PriceInfo> GetPrices()
|
||||||
{
|
{
|
||||||
return prices?.Values;
|
return prices?.Values;
|
||||||
|
|||||||
@@ -79,7 +79,26 @@ namespace Barotrauma
|
|||||||
private float[] leftDelta;
|
private float[] leftDelta;
|
||||||
private float[] rightDelta;
|
private float[] rightDelta;
|
||||||
|
|
||||||
public readonly List<Gap> ConnectedGaps = new List<Gap>();
|
public List<Gap> ConnectedGaps;
|
||||||
|
|
||||||
|
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;
|
private string roomName;
|
||||||
[Editable, Serialize("", true, translationTextTag: "RoomName.")]
|
[Editable, Serialize("", true, translationTextTag: "RoomName.")]
|
||||||
@@ -494,6 +513,9 @@ namespace Barotrauma
|
|||||||
OxygenPercentage = 100.0f;
|
OxygenPercentage = 100.0f;
|
||||||
|
|
||||||
FireSources = new List<FireSource>();
|
FireSources = new List<FireSource>();
|
||||||
|
linkedTo = new System.Collections.ObjectModel.ObservableCollection<MapEntity>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
properties = SerializableProperty.GetProperties(this);
|
properties = SerializableProperty.GetProperties(this);
|
||||||
|
|
||||||
@@ -858,7 +880,7 @@ namespace Barotrauma
|
|||||||
FireSources.Remove(fire);
|
FireSources.Remove(fire);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Hull> GetConnectedHulls(int? searchDepth = null)
|
public IEnumerable<Hull> GetConnectedHulls(int? searchDepth)
|
||||||
{
|
{
|
||||||
return GetAdjacentHulls(new HashSet<Hull>(), 0, searchDepth);
|
return GetAdjacentHulls(new HashSet<Hull>(), 0, searchDepth);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace Barotrauma
|
|||||||
protected List<ushort> linkedToID;
|
protected List<ushort> linkedToID;
|
||||||
|
|
||||||
//observable collection because some entities may need to be notified when the collection is modified
|
//observable collection because some entities may need to be notified when the collection is modified
|
||||||
public readonly ObservableCollection<MapEntity> linkedTo = new ObservableCollection<MapEntity>();
|
public ObservableCollection<MapEntity> linkedTo;
|
||||||
|
|
||||||
private bool flippedX, flippedY;
|
private bool flippedX, flippedY;
|
||||||
public bool FlippedX { get { return flippedX; } }
|
public bool FlippedX { get { return flippedX; } }
|
||||||
@@ -409,7 +409,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MethodInfo loadMethod = t.GetMethod("Load", new[] { typeof(XElement), typeof(Submarine) });
|
MethodInfo loadMethod = t.GetMethod("Load", new [] { typeof(XElement), typeof(Submarine) });
|
||||||
if (loadMethod == null)
|
if (loadMethod == null)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Could not find the method \"Load\" in " + t + ".");
|
DebugConsole.ThrowError("Could not find the method \"Load\" in " + t + ".");
|
||||||
@@ -499,37 +499,6 @@ namespace Barotrauma
|
|||||||
if (linkedTo.Contains(e)) linkedTo.Remove(e);
|
if (linkedTo.Contains(e)) linkedTo.Remove(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets all linked entities of specific type.
|
|
||||||
/// </summary>
|
|
||||||
public HashSet<T> GetLinkedEntities<T>(HashSet<T> list = null, int? maxDepth = null) where T : MapEntity
|
|
||||||
{
|
|
||||||
list = list ?? new HashSet<T>();
|
|
||||||
int startDepth = 0;
|
|
||||||
GetLinkedEntitiesRecursive<T>(this, list, ref startDepth, maxDepth);
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets all linked entities of specific type.
|
|
||||||
/// </summary>
|
|
||||||
private static void GetLinkedEntitiesRecursive<T>(MapEntity mapEntity, HashSet<T> linkedTargets, ref int depth, int? maxDepth = null) where T : MapEntity
|
|
||||||
{
|
|
||||||
if (depth > maxDepth) { return; }
|
|
||||||
foreach (var linkedEntity in mapEntity.linkedTo)
|
|
||||||
{
|
|
||||||
if (linkedEntity is T linkedTarget)
|
|
||||||
{
|
|
||||||
if (!linkedTargets.Contains(linkedTarget))
|
|
||||||
{
|
|
||||||
linkedTargets.Add(linkedTarget);
|
|
||||||
depth++;
|
|
||||||
GetLinkedEntitiesRecursive(linkedEntity, linkedTargets, ref depth, maxDepth);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Serialized properties
|
#region Serialized properties
|
||||||
// We could use NaN or nullables, but in this case the first is not preferable, because it needs to be checked every time the value is used.
|
// We could use NaN or nullables, but in this case the first is not preferable, because it needs to be checked every time the value is used.
|
||||||
// Nullable on the other requires boxing that we don't want to do too often, since it generates garbage.
|
// Nullable on the other requires boxing that we don't want to do too often, since it generates garbage.
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ namespace Barotrauma
|
|||||||
Linkable = true
|
Linkable = true
|
||||||
};
|
};
|
||||||
ep.AllowedLinks.Add("hull");
|
ep.AllowedLinks.Add("hull");
|
||||||
|
ep.Aliases = new HashSet<string> { "hull" };
|
||||||
List.Add(ep);
|
List.Add(ep);
|
||||||
|
|
||||||
ep = new MapEntityPrefab
|
ep = new MapEntityPrefab
|
||||||
|
|||||||
@@ -225,12 +225,6 @@ namespace Barotrauma
|
|||||||
string nonTranslatedName = element.GetAttributeString("name", null) ?? element.Name.ToString();
|
string nonTranslatedName = element.GetAttributeString("name", null) ?? element.Name.ToString();
|
||||||
sp.Aliases.Add(nonTranslatedName.ToLowerInvariant());
|
sp.Aliases.Add(nonTranslatedName.ToLowerInvariant());
|
||||||
|
|
||||||
SerializableProperty.DeserializeProperties(sp, element);
|
|
||||||
if (sp.Body)
|
|
||||||
{
|
|
||||||
sp.Tags.Add("wall");
|
|
||||||
}
|
|
||||||
|
|
||||||
SerializableProperty.DeserializeProperties(sp, element);
|
SerializableProperty.DeserializeProperties(sp, element);
|
||||||
if (sp.Body)
|
if (sp.Body)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -131,7 +131,12 @@ namespace Barotrauma.Networking
|
|||||||
float dist = Vector2.Distance(listener.WorldPosition, sender.WorldPosition);
|
float dist = Vector2.Distance(listener.WorldPosition, sender.WorldPosition);
|
||||||
if (dist > range) { return 1.0f; }
|
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; }
|
if (dist > range) { return 1.0f; }
|
||||||
|
|
||||||
return dist / range;
|
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.
Reference in New Issue
Block a user