Unstable v0.9.707.0
This commit is contained in:
@@ -535,6 +535,17 @@ namespace Barotrauma
|
||||
return closestCharacter;
|
||||
}
|
||||
|
||||
public bool ShouldLockHud()
|
||||
{
|
||||
if (this != controlled) { return false; }
|
||||
|
||||
//lock if using a controller, except if we're also using a connection panel in the same item
|
||||
return
|
||||
SelectedConstruction != null &&
|
||||
SelectedConstruction?.GetComponent<Controller>()?.User == this &&
|
||||
SelectedConstruction?.GetComponent<ConnectionPanel>()?.User != this;
|
||||
}
|
||||
|
||||
|
||||
partial void UpdateProjSpecific(float deltaTime, Camera cam)
|
||||
{
|
||||
|
||||
@@ -92,7 +92,7 @@ namespace Barotrauma
|
||||
|
||||
if (!character.IsUnconscious && character.Stun <= 0.0f)
|
||||
{
|
||||
if (character.Info != null)
|
||||
if (character.Info != null && !character.ShouldLockHud())
|
||||
{
|
||||
bool mouseOnPortrait = HUDLayoutSettings.PortraitArea.Contains(PlayerInput.MousePosition) && GUI.MouseOn == null;
|
||||
if (mouseOnPortrait && PlayerInput.PrimaryMouseButtonClicked())
|
||||
@@ -170,11 +170,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (GUI.DisableHUD) { return; }
|
||||
|
||||
character.CharacterHealth.Alignment = Alignment.Right;
|
||||
/*if (Screen.Selected == GameMain.GameScreen)
|
||||
{
|
||||
GUI.InfoAreaBackground.Draw(spriteBatch, Vector2.Zero, scale: GUI.Scale);
|
||||
}*/
|
||||
character.CharacterHealth.Alignment = Alignment.Right;
|
||||
|
||||
if (GameMain.GameSession?.CrewManager != null)
|
||||
{
|
||||
@@ -309,7 +305,7 @@ namespace Barotrauma
|
||||
character.Info.DrawPortrait(spriteBatch, HUDLayoutSettings.PortraitArea.Location.ToVector2(), targetWidth: HUDLayoutSettings.PortraitArea.Width);
|
||||
character.Info.DrawJobIcon(spriteBatch);
|
||||
}
|
||||
mouseOnPortrait = HUDLayoutSettings.PortraitArea.Contains(PlayerInput.MousePosition);
|
||||
mouseOnPortrait = HUDLayoutSettings.PortraitArea.Contains(PlayerInput.MousePosition) && !character.ShouldLockHud();
|
||||
if (mouseOnPortrait)
|
||||
{
|
||||
GUI.UIGlow.Draw(spriteBatch, HUDLayoutSettings.PortraitArea, GUI.Style.Green * 0.5f);
|
||||
@@ -318,7 +314,7 @@ namespace Barotrauma
|
||||
if (ShouldDrawInventory(character))
|
||||
{
|
||||
character.Inventory.Locked = LockInventory(character);
|
||||
character.Inventory.DrawThis(spriteBatch);
|
||||
character.Inventory.DrawOwn(spriteBatch);
|
||||
character.Inventory.CurrentLayout = CharacterHealth.OpenHealthWindow == null && character.SelectedCharacter == null ?
|
||||
CharacterInventory.Layout.Default :
|
||||
CharacterInventory.Layout.Right;
|
||||
@@ -333,7 +329,7 @@ namespace Barotrauma
|
||||
{
|
||||
///character.Inventory.CurrentLayout = Alignment.Left;
|
||||
character.SelectedCharacter.Inventory.CurrentLayout = CharacterInventory.Layout.Left;
|
||||
character.SelectedCharacter.Inventory.DrawThis(spriteBatch);
|
||||
character.SelectedCharacter.Inventory.DrawOwn(spriteBatch);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -417,11 +413,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (character?.Inventory == null || !character.AllowInput || character.LockHands) { return true; }
|
||||
|
||||
//lock if using a controller, except if we're also using a connection panel in the same item
|
||||
return
|
||||
character.SelectedConstruction != null &&
|
||||
character.SelectedConstruction?.GetComponent<Controller>()?.User == character &&
|
||||
character.SelectedConstruction?.GetComponent<ConnectionPanel>()?.User != character;
|
||||
return character.ShouldLockHud();
|
||||
}
|
||||
|
||||
private static void DrawOrderIndicator(SpriteBatch spriteBatch, Camera cam, Character character, Order order, float iconAlpha = 1.0f)
|
||||
|
||||
@@ -276,7 +276,7 @@ namespace Barotrauma
|
||||
};
|
||||
healthShadowSize = 1.0f;
|
||||
|
||||
healthInterfaceFrame = new GUIFrame(new RectTransform(new Vector2(0.85f * 1.1f, 0.66f * 0.85f * 1.1f), GUI.Canvas, anchor: Anchor.Center, scaleBasis: ScaleBasis.Smallest), style: "ItemUI");
|
||||
healthInterfaceFrame = new GUIFrame(new RectTransform(new Vector2(0.7f, 0.55f), GUI.Canvas, anchor: Anchor.Center, scaleBasis: ScaleBasis.Smallest), style: "ItemUI");
|
||||
|
||||
var healthInterfaceLayout = new GUILayoutGroup(new RectTransform(Vector2.One / 1.05f, healthInterfaceFrame.RectTransform, anchor: Anchor.Center), true);
|
||||
|
||||
@@ -331,16 +331,15 @@ namespace Barotrauma
|
||||
},
|
||||
(dt, component) =>
|
||||
{
|
||||
medUIExtraAnimState += dt * 10.0f;
|
||||
while (medUIExtraAnimState >= 16.0f)
|
||||
if (!GameMain.Instance.Paused)
|
||||
{
|
||||
medUIExtraAnimState -= 16.0f;
|
||||
medUIExtraAnimState = (medUIExtraAnimState + dt * 10.0f) % 16.0f;
|
||||
}
|
||||
});
|
||||
|
||||
GUILayoutGroup selectedLimbLayout = new GUILayoutGroup(new RectTransform(Vector2.One, rightSide.RectTransform));
|
||||
|
||||
selectedLimbText = new GUITextBlock(new RectTransform(new Vector2(0.8f, 0.08f), selectedLimbLayout.RectTransform), "", font: GUI.LargeFont, textAlignment: Alignment.Center)
|
||||
selectedLimbText = new GUITextBlock(new RectTransform(new Vector2(0.8f, 0.08f), selectedLimbLayout.RectTransform), "", font: GUI.SubHeadingFont, textAlignment: Alignment.Center)
|
||||
{
|
||||
AutoScaleHorizontal = true
|
||||
};
|
||||
@@ -454,11 +453,16 @@ namespace Barotrauma
|
||||
OnClicked = (button, userData) =>
|
||||
{
|
||||
Character selectedCharacter = Character.Controlled?.SelectedCharacter;
|
||||
if (selectedCharacter == null || (!selectedCharacter.IsUnconscious && selectedCharacter.Stun <= 0.0f)) return false;
|
||||
if (selectedCharacter == null || (!selectedCharacter.IsUnconscious && selectedCharacter.Stun <= 0.0f))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Character.Controlled.AnimController.Anim = (Character.Controlled.AnimController.Anim == AnimController.Animation.CPR) ?
|
||||
AnimController.Animation.None : AnimController.Animation.CPR;
|
||||
|
||||
button.Selected = Character.Controlled.AnimController.Anim == AnimController.Animation.CPR;
|
||||
|
||||
selectedCharacter.AnimController.ResetPullJoints();
|
||||
|
||||
if (GameMain.Client != null)
|
||||
@@ -468,6 +472,7 @@ namespace Barotrauma
|
||||
|
||||
return true;
|
||||
},
|
||||
ToolTip = TextManager.Get("doctor.cprobjective"),
|
||||
Visible = false
|
||||
};
|
||||
|
||||
@@ -540,12 +545,10 @@ namespace Barotrauma
|
||||
switch (alignment)
|
||||
{
|
||||
case Alignment.Left:
|
||||
healthInterfaceFrame.RectTransform.Anchor = Anchor.CenterLeft;
|
||||
healthInterfaceFrame.RectTransform.Pivot = Pivot.CenterLeft;
|
||||
healthInterfaceFrame.RectTransform.SetPosition(Anchor.CenterLeft);
|
||||
break;
|
||||
case Alignment.Right:
|
||||
healthInterfaceFrame.RectTransform.Anchor = Anchor.CenterRight;
|
||||
healthInterfaceFrame.RectTransform.Pivot = Pivot.CenterRight;
|
||||
healthInterfaceFrame.RectTransform.SetPosition(Anchor.CenterRight);
|
||||
break;
|
||||
}
|
||||
healthInterfaceFrame.RectTransform.RecalculateChildren(false);
|
||||
@@ -833,7 +836,7 @@ namespace Barotrauma
|
||||
|
||||
treatmentLayout.Recalculate();
|
||||
|
||||
lowSkillIndicator.Color = new Color(lowSkillIndicator.Color, MathHelper.Lerp(0.1f, 1.0f, (float)(Math.Sin(Timing.TotalTime * 5.0f) + 1.0f) / 2.0f));
|
||||
lowSkillIndicator.Color = new Color(lowSkillIndicator.Color, MathHelper.Lerp(0.5f, 1.0f, (float)(Math.Sin(Timing.TotalTime * 5.0f) + 1.0f) / 2.0f));
|
||||
|
||||
if (Inventory.draggingItem != null)
|
||||
{
|
||||
@@ -868,8 +871,8 @@ namespace Barotrauma
|
||||
|
||||
Rectangle hoverArea = Rectangle.Union(HUDLayoutSettings.AfflictionAreaLeft, HUDLayoutSettings.HealthBarAreaLeft);
|
||||
|
||||
if (Character.AllowInput && UseHealthWindow &&
|
||||
Character.SelectedConstruction?.GetComponent<Controller>()?.User != Character &&
|
||||
healthBar.CanBeFocused = healthBarShadow.CanBeFocused = !Character.ShouldLockHud();
|
||||
if (Character.AllowInput && UseHealthWindow && healthBar.Enabled && healthBar.CanBeFocused &&
|
||||
hoverArea.Contains(PlayerInput.MousePosition) && Inventory.SelectedSlot == null)
|
||||
{
|
||||
healthBar.State = GUIComponent.ComponentState.Hover;
|
||||
@@ -983,7 +986,7 @@ namespace Barotrauma
|
||||
AfflictionPrefab afflictionPrefab = affliction.Prefab;
|
||||
|
||||
Rectangle afflictionIconRect = new Rectangle(pos, new Point(iconSize));
|
||||
if (afflictionIconRect.Contains(PlayerInput.MousePosition))
|
||||
if (afflictionIconRect.Contains(PlayerInput.MousePosition) && !Character.ShouldLockHud())
|
||||
{
|
||||
highlightedIcon = statusIcon;
|
||||
highlightedIconPos = afflictionIconRect.Center.ToVector2();
|
||||
@@ -1023,7 +1026,7 @@ namespace Barotrauma
|
||||
if (highlightedIcon != null)
|
||||
{
|
||||
GUI.DrawString(spriteBatch,
|
||||
alignment == Alignment.Left ? highlightedIconPos + new Vector2(60 * GUI.Scale, 5) : highlightedIconPos + new Vector2(-iconSize / 2, iconSize / 2),
|
||||
alignment == Alignment.Left ? highlightedIconPos + new Vector2(60 * GUI.Scale, 5) : highlightedIconPos + new Vector2(iconSize * 0.4f, 0.0f),
|
||||
highlightedIcon.Second,
|
||||
Color.White * 0.8f, Color.Black * 0.5f);
|
||||
}
|
||||
@@ -1127,6 +1130,7 @@ namespace Barotrauma
|
||||
{
|
||||
var child = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.25f), afflictionIconContainer.Content.RectTransform, Anchor.TopCenter))
|
||||
{
|
||||
Stretch = true,
|
||||
UserData = affliction
|
||||
};
|
||||
|
||||
@@ -1145,7 +1149,7 @@ namespace Barotrauma
|
||||
buttonToSelect = button;
|
||||
}
|
||||
|
||||
var afflictionIcon = new GUIImage(new RectTransform(Vector2.One * 0.9f, button.RectTransform, Anchor.Center), affliction.Prefab.Icon, scaleToFit: true)
|
||||
var afflictionIcon = new GUIImage(new RectTransform(Vector2.One * 0.8f, button.RectTransform, Anchor.Center), affliction.Prefab.Icon, scaleToFit: true)
|
||||
{
|
||||
Color = GetAfflictionIconColor(affliction.Prefab, affliction),
|
||||
CanBeFocused = false
|
||||
@@ -1166,7 +1170,11 @@ namespace Barotrauma
|
||||
afflictionEffectColor = GUI.Style.Green;
|
||||
}
|
||||
|
||||
new GUIProgressBar(new RectTransform(new Vector2(1.0f, 0.1f), child.RectTransform), 0.0f, afflictionEffectColor, style: "CharacterHealthBar")
|
||||
var nameText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), child.RectTransform),
|
||||
affliction.Prefab.Name, font: GUI.SmallFont, textAlignment: Alignment.Center, style: "GUIToolTip");
|
||||
nameText.Text = ToolBox.LimitString(nameText.Text, nameText.Font, nameText.Rect.Width);
|
||||
|
||||
new GUIProgressBar(new RectTransform(new Vector2(1.0f, 0.1f), child.RectTransform), 0.0f, afflictionEffectColor, style: "GUIAfflictionBar")
|
||||
{
|
||||
UserData = "afflictionstrength"
|
||||
};
|
||||
@@ -1240,14 +1248,14 @@ namespace Barotrauma
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
var afflictionStrength = new GUITextBlock(new RectTransform(new Vector2(0.35f, 0.6f), labelContainer.RectTransform), "", textAlignment: Alignment.TopRight, font: GUI.LargeFont)
|
||||
var afflictionStrength = new GUITextBlock(new RectTransform(new Vector2(0.35f, 0.6f), labelContainer.RectTransform), "", textAlignment: Alignment.TopRight, font: GUI.SubHeadingFont)
|
||||
{
|
||||
Padding = Vector4.Zero,
|
||||
UserData = "strength",
|
||||
CanBeFocused = false
|
||||
};
|
||||
var vitality = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.4f), labelContainer.RectTransform, Anchor.BottomRight), "", textAlignment: Alignment.BottomRight)
|
||||
{
|
||||
Padding = afflictionStrength.Padding,
|
||||
IgnoreLayoutGroups = true,
|
||||
UserData = "vitality",
|
||||
CanBeFocused = false
|
||||
@@ -1557,7 +1565,10 @@ namespace Barotrauma
|
||||
|
||||
private void UpdateLimbIndicators(float deltaTime, Rectangle drawArea)
|
||||
{
|
||||
limbIndicatorOverlayAnimState += deltaTime * 8.0f;
|
||||
if (!GameMain.Instance.Paused)
|
||||
{
|
||||
limbIndicatorOverlayAnimState += deltaTime * 8.0f;
|
||||
}
|
||||
|
||||
highlightedLimbIndex = -1;
|
||||
int i = 0;
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Barotrauma
|
||||
{
|
||||
public GUIButton CreateInfoFrame(int variant)
|
||||
{
|
||||
int width = 500, height = 450;
|
||||
int width = 500, height = 400;
|
||||
|
||||
GUIButton backFrame = new GUIButton(new RectTransform(Vector2.One, GUI.Canvas), style: "GUIBackgroundBlocker");
|
||||
GUIFrame frame = new GUIFrame(new RectTransform(new Point(width, height), backFrame.RectTransform, Anchor.Center));
|
||||
@@ -32,7 +32,7 @@ namespace Barotrauma
|
||||
font: GUI.SmallFont);
|
||||
}
|
||||
|
||||
if (!ItemIdentifiers.TryGetValue(variant, out var itemIdentifiers)) { return backFrame; }
|
||||
/*if (!ItemIdentifiers.TryGetValue(variant, out var itemIdentifiers)) { return backFrame; }
|
||||
var itemContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.45f, 0.5f), paddedFrame.RectTransform, Anchor.TopRight)
|
||||
{ RelativeOffset = new Vector2(0.0f, 0.2f + descriptionBlock.RectTransform.RelativeSize.Y) })
|
||||
{
|
||||
@@ -47,7 +47,7 @@ namespace Barotrauma
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), itemContainer.RectTransform),
|
||||
" - " + (count == 1 ? itemPrefab.Name : itemPrefab.Name + " x" + count),
|
||||
font: GUI.SmallFont);
|
||||
}
|
||||
}*/
|
||||
|
||||
return backFrame;
|
||||
}
|
||||
|
||||
@@ -397,7 +397,7 @@ namespace Barotrauma
|
||||
Submarine.Load(string.Join(" ", args), true);
|
||||
}
|
||||
GameMain.SubEditorScreen.Select();
|
||||
}));
|
||||
}, isCheat: true));
|
||||
|
||||
commands.Add(new Command("editparticles|particleeditor", "editparticles/particleeditor: Switch to the Particle Editor to edit particle effects.", (string[] args) =>
|
||||
{
|
||||
@@ -1099,6 +1099,22 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Submarine sub in Submarine.SavedSubmarines)
|
||||
{
|
||||
string nameIdentifier = "submarine.name." + sub.Name.ToLowerInvariant();
|
||||
if (!tags[language].Contains(nameIdentifier))
|
||||
{
|
||||
if (!missingTags.ContainsKey(nameIdentifier)) { missingTags[nameIdentifier] = new HashSet<string>(); }
|
||||
missingTags[nameIdentifier].Add(language);
|
||||
}
|
||||
string descriptionIdentifier = "submarine.description." + sub.Name.ToLowerInvariant();
|
||||
if (!tags[language].Contains(descriptionIdentifier))
|
||||
{
|
||||
if (!missingTags.ContainsKey(descriptionIdentifier)) { missingTags[descriptionIdentifier] = new HashSet<string>(); }
|
||||
missingTags[descriptionIdentifier].Add(language);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (AfflictionPrefab affliction in AfflictionPrefab.List)
|
||||
{
|
||||
string nameIdentifier = "afflictionname." + affliction.Identifier;
|
||||
|
||||
@@ -29,10 +29,6 @@ namespace Barotrauma
|
||||
{
|
||||
_toggleOpen = GameMain.Config.ChatOpen = value;
|
||||
if (value) hideableElements.Visible = true;
|
||||
foreach (GUIComponent child in ToggleButton.Children)
|
||||
{
|
||||
child.SpriteEffects = _toggleOpen ? SpriteEffects.FlipHorizontally : SpriteEffects.None;
|
||||
}
|
||||
}
|
||||
}
|
||||
private float openState;
|
||||
@@ -56,7 +52,7 @@ namespace Barotrauma
|
||||
|
||||
public GUITextBox InputBox { get; private set; }
|
||||
|
||||
public GUIButton ToggleButton { get; private set; }
|
||||
public GUIButton ToggleButton;
|
||||
|
||||
private GUIButton showNewMessagesButton;
|
||||
|
||||
@@ -79,18 +75,10 @@ namespace Barotrauma
|
||||
var chatBoxHolder = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.875f), hideableElements.RectTransform), style: "ChatBox");
|
||||
chatBox = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.95f), chatBoxHolder.RectTransform, Anchor.CenterRight), style: null);
|
||||
|
||||
ToggleButton = new GUIButton(new RectTransform(new Point(toggleButtonWidth, HUDLayoutSettings.ChatBoxArea.Height), parent.RectTransform),
|
||||
style: "UIToggleButton");
|
||||
|
||||
ToggleButton.OnClicked += (GUIButton btn, object userdata) =>
|
||||
{
|
||||
ToggleOpen = !ToggleOpen;
|
||||
return true;
|
||||
};
|
||||
|
||||
InputBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.125f), hideableElements.RectTransform, Anchor.BottomLeft),
|
||||
style: "ChatTextBox")
|
||||
{
|
||||
OverflowClip = true,
|
||||
Font = GUI.SmallFont,
|
||||
MaxTextLength = ChatMessage.MaxLength
|
||||
};
|
||||
@@ -110,7 +98,8 @@ namespace Barotrauma
|
||||
return true;
|
||||
};
|
||||
chatSendButton.RectTransform.AbsoluteOffset = new Point((int)(InputBox.Rect.Height * 0.15f), 0);
|
||||
InputBox.TextBlock.RectTransform.MaxSize = new Point((int)(InputBox.Rect.Width - chatSendButton.Rect.Width * 1.25f), int.MaxValue);
|
||||
InputBox.TextBlock.RectTransform.MaxSize
|
||||
= new Point((int)(InputBox.Rect.Width - chatSendButton.Rect.Width * 1.25f - InputBox.TextBlock.Padding.Z), int.MaxValue);
|
||||
|
||||
showNewMessagesButton = new GUIButton(new RectTransform(new Vector2(1f, 0.125f), GUIFrame.RectTransform, Anchor.BottomCenter) { RelativeOffset = new Vector2(0.0f, -0.125f) }, TextManager.Get("chat.shownewmessages"));
|
||||
showNewMessagesButton.OnClicked += (GUIButton btn, object userdata) =>
|
||||
@@ -317,10 +306,7 @@ namespace Barotrauma
|
||||
GUIFrame.RectTransform.NonScaledSize -= new Point(toggleButtonWidth, 0);
|
||||
GUIFrame.RectTransform.AbsoluteOffset += new Point(toggleButtonWidth, 0);
|
||||
|
||||
ToggleButton.RectTransform.NonScaledSize = new Point(toggleButtonWidth, HUDLayoutSettings.ChatBoxArea.Height);
|
||||
ToggleButton.RectTransform.AbsoluteOffset = new Point(HUDLayoutSettings.ChatBoxArea.Left - toggleButtonWidth, HUDLayoutSettings.ChatBoxArea.Y);
|
||||
|
||||
popupMessageOffset = ToggleButton.Rect.Width + GameMain.GameSession.CrewManager.ReportButtonFrame.Rect.Width + GUIFrame.Rect.Width;
|
||||
popupMessageOffset = GameMain.GameSession.CrewManager.ReportButtonFrame.Rect.Width + GUIFrame.Rect.Width;
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
@@ -348,6 +334,11 @@ namespace Barotrauma
|
||||
showNewMessagesButton.Visible = false;
|
||||
}
|
||||
|
||||
if (ToggleButton != null)
|
||||
{
|
||||
ToggleButton.RectTransform.AbsoluteOffset = new Point(GUIFrame.Rect.Right, GUIFrame.Rect.Y + HUDLayoutSettings.ChatBoxArea.Height - ToggleButton.Rect.Height);
|
||||
}
|
||||
|
||||
if (ToggleOpen)
|
||||
{
|
||||
openState += deltaTime * 5.0f;
|
||||
|
||||
@@ -133,7 +133,6 @@ namespace Barotrauma
|
||||
public static ScalableFont LargeFont => Style?.LargeFont;
|
||||
public static ScalableFont SubHeadingFont => Style?.SubHeadingFont;
|
||||
public static ScalableFont DigitalFont => Style?.DigitalFont;
|
||||
public static ScalableFont HotkeyFont => Style?.HotkeyFont;
|
||||
|
||||
public static ScalableFont CJKFont { get; private set; }
|
||||
|
||||
@@ -163,8 +162,6 @@ namespace Barotrauma
|
||||
get { return arrow; }
|
||||
}
|
||||
|
||||
public static Sprite InfoAreaBackground;
|
||||
|
||||
public static bool SettingsMenuOpen
|
||||
{
|
||||
get { return settingsMenuOpen; }
|
||||
@@ -260,7 +257,6 @@ namespace Barotrauma
|
||||
arrow = new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(392, 393, 49, 45), new Vector2(0.5f, 0.5f));
|
||||
SpeechBubbleIcon = new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(385, 449, 66, 60), new Vector2(0.5f, 0.5f));
|
||||
BrokenIcon = new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(898, 386, 123, 123), new Vector2(0.5f, 0.5f));
|
||||
InfoAreaBackground = new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(290, 320, 400, 300), new Vector2(0.0f, 0.0f));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -782,9 +778,21 @@ namespace Barotrauma
|
||||
if (GUIScrollBar.DraggingBar != null) { return GUIScrollBar.DraggingBar.Bar.HoverCursor; }
|
||||
|
||||
// Wire cursors
|
||||
if (ConnectionPanel.HighlightedWire != null) { return CursorState.Hand; }
|
||||
if (Wire.DraggingWire != null) { return CursorState.Dragging; }
|
||||
if (Connection.DraggingConnected != null) { return CursorState.Dragging; }
|
||||
if (Character.Controlled != null)
|
||||
{
|
||||
if (Character.Controlled.SelectedConstruction?.GetComponent<ConnectionPanel>() != null)
|
||||
{
|
||||
if (Connection.DraggingConnected != null)
|
||||
{
|
||||
return CursorState.Dragging;
|
||||
}
|
||||
else if (ConnectionPanel.HighlightedWire != null)
|
||||
{
|
||||
return CursorState.Hand;
|
||||
}
|
||||
}
|
||||
if (Wire.DraggingWire != null) { return CursorState.Dragging; }
|
||||
}
|
||||
|
||||
if (c == null || c is GUICustomComponent)
|
||||
{
|
||||
@@ -794,7 +802,7 @@ namespace Barotrauma
|
||||
case CharacterEditorScreen editor:
|
||||
return editor.GetMouseCursorState();
|
||||
// Portrait area during gameplay
|
||||
case GameScreen _ when HUDLayoutSettings.PortraitArea.Contains(PlayerInput.MousePosition):
|
||||
case GameScreen _ when HUDLayoutSettings.PortraitArea.Contains(PlayerInput.MousePosition) && !(Character.Controlled?.ShouldLockHud() ?? true):
|
||||
return CursorState.Hand;
|
||||
// Sub editor drag and highlight
|
||||
case SubEditorScreen editor:
|
||||
@@ -989,7 +997,6 @@ namespace Barotrauma
|
||||
Debug.Assert(updateList.Count == updateListSet.Count);
|
||||
updateList.ForEach(c => c.UpdateAuto(deltaTime));
|
||||
UpdateMessages(deltaTime);
|
||||
UpdateInput();
|
||||
}
|
||||
|
||||
private static void UpdateMessages(float deltaTime)
|
||||
@@ -1029,32 +1036,6 @@ namespace Barotrauma
|
||||
messages.RemoveAll(m => m.Timer <= 0.0f);
|
||||
}
|
||||
|
||||
private static void UpdateInput()
|
||||
{
|
||||
if (PlayerInput.KeyHit(InputType.ToggleInventory))
|
||||
{
|
||||
if (Character.Controlled?.Inventory != null)
|
||||
{
|
||||
Character.Controlled.Inventory.ToggleInventory();
|
||||
}
|
||||
}
|
||||
|
||||
if (PlayerInput.KeyHit(Keys.Escape) && GameMain.WindowActive)
|
||||
{
|
||||
HandleEscFunctionality();
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
if (GameMain.NetworkMember == null)
|
||||
{
|
||||
if (PlayerInput.KeyHit(Keys.P) && !(KeyboardDispatcher.Subscriber is GUITextBox))
|
||||
{
|
||||
DebugConsole.Paused = !DebugConsole.Paused;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#region Element drawing
|
||||
|
||||
public static void DrawIndicator(SpriteBatch spriteBatch, Vector2 worldPosition, Camera cam, float hideDist, Sprite sprite, Color color)
|
||||
@@ -1860,50 +1841,6 @@ namespace Barotrauma
|
||||
#endregion
|
||||
|
||||
#region Misc
|
||||
private static void HandleEscFunctionality()
|
||||
{
|
||||
// Check if a text input is selected.
|
||||
if (KeyboardDispatcher.Subscriber != null)
|
||||
{
|
||||
if (KeyboardDispatcher.Subscriber is GUITextBox textBox)
|
||||
{
|
||||
textBox.Deselect();
|
||||
}
|
||||
KeyboardDispatcher.Subscriber = null;
|
||||
}
|
||||
//if a verification prompt (are you sure you want to x) is open, close it
|
||||
else if (GUIMessageBox.VisibleBox as GUIMessageBox != null &&
|
||||
GUIMessageBox.VisibleBox.UserData as string == "verificationprompt")
|
||||
{
|
||||
((GUIMessageBox)GUIMessageBox.VisibleBox).Close();
|
||||
}
|
||||
else if (Tutorials.Tutorial.Initialized && Tutorials.Tutorial.ContentRunning)
|
||||
{
|
||||
(GameMain.GameSession.GameMode as TutorialMode).Tutorial.CloseActiveContentGUI();
|
||||
}
|
||||
else if (PauseMenuOpen)
|
||||
{
|
||||
TogglePauseMenu();
|
||||
}
|
||||
//open the pause menu if not controlling a character OR if the character has no UIs active that can be closed with ESC
|
||||
else if ((Character.Controlled == null || !itemHudActive())
|
||||
//TODO: do we need to check Inventory.SelectedSlot?
|
||||
&& Inventory.SelectedSlot == null && CharacterHealth.OpenHealthWindow == null
|
||||
&& !CrewManager.IsCommandInterfaceOpen)
|
||||
{
|
||||
// Otherwise toggle pausing, unless another window/interface is open.
|
||||
TogglePauseMenu();
|
||||
}
|
||||
|
||||
bool itemHudActive()
|
||||
{
|
||||
if (Character.Controlled?.SelectedConstruction == null) { return false; }
|
||||
return
|
||||
Character.Controlled.SelectedConstruction.ActiveHUDs.Any(ic => ic.GuiFrame != null) ||
|
||||
((Character.Controlled.ViewTarget as Item)?.Prefab?.FocusOnSelected ?? false);
|
||||
}
|
||||
}
|
||||
|
||||
public static void TogglePauseMenu()
|
||||
{
|
||||
if (Screen.Selected == GameMain.MainMenuScreen) return;
|
||||
@@ -2102,6 +2039,12 @@ namespace Barotrauma
|
||||
|
||||
sounds[soundIndex]?.Play(null, "ui");
|
||||
}
|
||||
|
||||
public static bool IsFourByThree()
|
||||
{
|
||||
float aspectRatio = HorizontalAspectRatio;
|
||||
return aspectRatio > 1.3f && aspectRatio < 1.4f;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,23 +5,20 @@ namespace Barotrauma
|
||||
public class GUIColorSettings
|
||||
{
|
||||
// Inventory
|
||||
public static readonly Color InventorySlotColor = new Color(27, 140, 132);
|
||||
public static readonly Color InventorySlotEquippedColor = new Color(211, 227, 217);
|
||||
public static readonly Color EquipmentSlotEmptyColor = new Color(152, 148, 128);
|
||||
public static readonly Color EquipmentSlotColor = new Color(225, 211, 189);
|
||||
public static readonly Color EquipmentSlotIconColor = new Color(99, 70, 64);
|
||||
public static Color EquipmentSlotIconColor = new Color(99, 70, 64);
|
||||
|
||||
// Health HUD
|
||||
public static readonly Color BuffColorLow = Color.LightGreen;
|
||||
public static readonly Color BuffColorMedium = Color.Green;
|
||||
public static readonly Color BuffColorHigh = Color.DarkGreen;
|
||||
public static Color BuffColorLow = Color.LightGreen;
|
||||
public static Color BuffColorMedium = Color.Green;
|
||||
public static Color BuffColorHigh = Color.DarkGreen;
|
||||
|
||||
public static readonly Color DebuffColorLow = Color.DarkSalmon;
|
||||
public static readonly Color DebuffColorMedium = Color.Red;
|
||||
public static readonly Color DebuffColorHigh = Color.DarkRed;
|
||||
public static Color DebuffColorLow = Color.DarkSalmon;
|
||||
public static Color DebuffColorMedium = Color.Red;
|
||||
public static Color DebuffColorHigh = Color.DarkRed;
|
||||
|
||||
public static Color HealthBarColorLow = Color.Red;
|
||||
public static Color HealthBarColorMedium = Color.Orange;
|
||||
public static Color HealthBarColorHigh = new Color(78, 114, 88);
|
||||
|
||||
public static readonly Color HealthBarColorLow = Color.Red;
|
||||
public static readonly Color HealthBarColorMedium = Color.Orange;
|
||||
public static readonly Color HealthBarColorHigh = new Color(78, 114, 88);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -772,24 +772,29 @@ namespace Barotrauma
|
||||
|
||||
if (rectTransform != null)
|
||||
{
|
||||
if (style.Width.HasValue)
|
||||
{
|
||||
RectTransform.MinSize = new Point(style.Width.Value, RectTransform.MinSize.Y);
|
||||
RectTransform.MaxSize = new Point(style.Width.Value, RectTransform.MaxSize.Y);
|
||||
if (rectTransform.IsFixedSize) { RectTransform.Resize(new Point(style.Width.Value, rectTransform.NonScaledSize.Y)); }
|
||||
}
|
||||
if (style.Height.HasValue)
|
||||
{
|
||||
RectTransform.MinSize = new Point(RectTransform.MinSize.X, style.Height.Value);
|
||||
RectTransform.MaxSize = new Point(RectTransform.MaxSize.X, style.Height.Value);
|
||||
if (rectTransform.IsFixedSize) { RectTransform.Resize(new Point(rectTransform.NonScaledSize.X, style.Height.Value)); }
|
||||
}
|
||||
ApplySizeRestrictions(style);
|
||||
}
|
||||
|
||||
|
||||
this.style = style;
|
||||
}
|
||||
|
||||
public void ApplySizeRestrictions(GUIComponentStyle style)
|
||||
{
|
||||
if (style.Width.HasValue)
|
||||
{
|
||||
RectTransform.MinSize = new Point(style.Width.Value, RectTransform.MinSize.Y);
|
||||
RectTransform.MaxSize = new Point(style.Width.Value, RectTransform.MaxSize.Y);
|
||||
if (rectTransform.IsFixedSize) { RectTransform.Resize(new Point(style.Width.Value, rectTransform.NonScaledSize.Y)); }
|
||||
}
|
||||
if (style.Height.HasValue)
|
||||
{
|
||||
RectTransform.MinSize = new Point(RectTransform.MinSize.X, style.Height.Value);
|
||||
RectTransform.MaxSize = new Point(RectTransform.MaxSize.X, style.Height.Value);
|
||||
if (rectTransform.IsFixedSize) { RectTransform.Resize(new Point(rectTransform.NonScaledSize.X, style.Height.Value)); }
|
||||
}
|
||||
}
|
||||
|
||||
public static GUIComponent FromXML(XElement element, RectTransform parent)
|
||||
{
|
||||
GUIComponent component = null;
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
public class GUIProgressBar : GUIComponent
|
||||
{
|
||||
private bool isHorizontal;
|
||||
|
||||
private GUIFrame frame, slider;
|
||||
private readonly GUIFrame frame, slider;
|
||||
private float barSize;
|
||||
private bool showFrame;
|
||||
private readonly bool showFrame;
|
||||
|
||||
public delegate float ProgressGetterHandler();
|
||||
public ProgressGetterHandler ProgressGetter;
|
||||
@@ -55,6 +55,45 @@ namespace Barotrauma
|
||||
Enabled = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the area the slider should be drawn inside
|
||||
/// </summary>
|
||||
/// <param name="fillAmount">0 = empty, 1 = full</param>
|
||||
public Rectangle GetSliderRect(float fillAmount)
|
||||
{
|
||||
Rectangle sliderArea = new Rectangle(
|
||||
frame.Rect.X + (int)style.Padding.X,
|
||||
frame.Rect.Y + (int)style.Padding.Y,
|
||||
(int)(frame.Rect.Width - style.Padding.X - style.Padding.Z),
|
||||
(int)(frame.Rect.Height - style.Padding.Y - style.Padding.W));
|
||||
|
||||
Vector4 sliceBorderSizes = Vector4.Zero;
|
||||
if (slider.sprites.ContainsKey(slider.State) && (slider.sprites[slider.State].First()?.Slice ?? false))
|
||||
{
|
||||
var slices = slider.sprites[slider.State].First().Slices;
|
||||
sliceBorderSizes = new Vector4(slices[0].Width, slices[0].Height, slices[8].Width, slices[8].Height);
|
||||
sliceBorderSizes *= slider.sprites[slider.State].First().GetSliceBorderScale(sliderArea.Size);
|
||||
}
|
||||
|
||||
Rectangle sliderRect = IsHorizontal ?
|
||||
new Rectangle(
|
||||
sliderArea.X + (int)sliceBorderSizes.X,
|
||||
sliderArea.Y,
|
||||
(int)((sliderArea.Width - sliceBorderSizes.X - sliceBorderSizes.Z) * fillAmount),
|
||||
sliderArea.Height)
|
||||
:
|
||||
new Rectangle(
|
||||
sliderArea.X,
|
||||
(int)(sliderArea.Bottom - (sliderArea.Height - sliceBorderSizes.Y - sliceBorderSizes.W) * fillAmount - sliceBorderSizes.W),
|
||||
sliderArea.Width,
|
||||
(int)((sliderArea.Height - sliceBorderSizes.Y - sliceBorderSizes.W) * fillAmount));
|
||||
|
||||
sliderRect.Width = Math.Max(sliderRect.Width, 1);
|
||||
sliderRect.Height = Math.Max(sliderRect.Height, 1);
|
||||
|
||||
return sliderRect;
|
||||
}
|
||||
|
||||
protected override void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
if (!Visible) { return; }
|
||||
@@ -75,14 +114,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle sliderRect = new Rectangle(
|
||||
frame.Rect.X + (int)style.Padding.X,
|
||||
(int)(frame.Rect.Y + (int)style.Padding.Y + (isHorizontal ? 0 : frame.Rect.Height * (1.0f - barSize))),
|
||||
isHorizontal ? (int)((frame.Rect.Width - style.Padding.X - style.Padding.Z) * barSize) : frame.Rect.Width,
|
||||
isHorizontal ? (int)(frame.Rect.Height - style.Padding.Y - style.Padding.W) : (int)(frame.Rect.Height * barSize));
|
||||
|
||||
sliderRect.Width = Math.Max(sliderRect.Width, 1);
|
||||
sliderRect.Height = Math.Max(sliderRect.Height, 1);
|
||||
var sliderRect = GetSliderRect(barSize);
|
||||
|
||||
slider.RectTransform.AbsoluteOffset = new Point((int)style.Padding.X, (int)style.Padding.Y);
|
||||
slider.RectTransform.MaxSize = new Point(
|
||||
|
||||
@@ -24,7 +24,6 @@ namespace Barotrauma
|
||||
public ScalableFont LargeFont { get; private set; }
|
||||
public ScalableFont SubHeadingFont { get; private set; }
|
||||
public ScalableFont DigitalFont { get; private set; }
|
||||
public ScalableFont HotkeyFont { get; private set; }
|
||||
|
||||
public Dictionary<ScalableFont, bool> ForceFontUpperCase
|
||||
{
|
||||
@@ -149,10 +148,6 @@ namespace Barotrauma
|
||||
DigitalFont = LoadFont(subElement, graphicsDevice);
|
||||
ForceFontUpperCase[DigitalFont] = subElement.GetAttributeBool("forceuppercase", false);
|
||||
break;
|
||||
case "hotkeyfont":
|
||||
HotkeyFont = LoadFont(subElement, graphicsDevice);
|
||||
ForceFontUpperCase[HotkeyFont] = subElement.GetAttributeBool("forceuppercase", false);
|
||||
break;
|
||||
case "objectivetitle":
|
||||
case "subheading":
|
||||
SubHeadingFont = LoadFont(subElement, graphicsDevice);
|
||||
|
||||
@@ -132,18 +132,17 @@ namespace Barotrauma
|
||||
int messageAreaWidth = GameMain.GraphicsWidth / 3;
|
||||
MessageAreaTop = new Rectangle((GameMain.GraphicsWidth - messageAreaWidth) / 2, ButtonAreaTop.Bottom, messageAreaWidth, ButtonAreaTop.Height);
|
||||
|
||||
int toggleButtonWidth = (int)(ChatBox.ToggleButtonWidthRaw * GUI.Scale);
|
||||
int chatBoxWidth = (int)(475 * GUI.Scale);
|
||||
bool isFourByThree = GUI.IsFourByThree();
|
||||
int chatBoxWidth = !isFourByThree ? (int)(475 * GUI.Scale) : (int)(375 * GUI.Scale);
|
||||
int chatBoxHeight = (int)Math.Max(GameMain.GraphicsHeight * 0.22f, 150);
|
||||
ChatBoxArea = new Rectangle(Padding + toggleButtonWidth, GameMain.GraphicsHeight - Padding - chatBoxHeight, chatBoxWidth, chatBoxHeight);
|
||||
ChatBoxArea = new Rectangle(Padding, GameMain.GraphicsHeight - Padding - chatBoxHeight, chatBoxWidth, chatBoxHeight);
|
||||
|
||||
int objectiveAnchorWidth = (int)(250 * GUI.Scale);
|
||||
int objectiveAnchorOffsetY = (int)(150 * GUI.Scale);
|
||||
ObjectiveAnchor = new Rectangle(Padding, ChatBoxArea.Y - objectiveAnchorOffsetY, objectiveAnchorWidth, 0);
|
||||
|
||||
var crewAreaY = AfflictionAreaLeft.Bottom + Padding;
|
||||
var crewAreaHeight = ObjectiveAnchor.Top - Padding - crewAreaY;
|
||||
CrewArea = new Rectangle(Padding, crewAreaY, (int)Math.Max(400 * GUI.Scale, 150), crewAreaHeight);
|
||||
CrewArea = new Rectangle(Padding, crewAreaY, (int)Math.Max(400 * GUI.Scale, 220), ObjectiveAnchor.Top - Padding - crewAreaY);
|
||||
|
||||
InventoryAreaLower = new Rectangle(Padding, inventoryTopY, GameMain.GraphicsWidth - Padding * 2, GameMain.GraphicsHeight - inventoryTopY);
|
||||
|
||||
|
||||
@@ -52,9 +52,9 @@ namespace Barotrauma
|
||||
{
|
||||
parent.children.Add(this);
|
||||
RecalculateAll(false, true, true);
|
||||
ParentChanged?.Invoke(parent);
|
||||
Parent.ChildrenChanged?.Invoke(this);
|
||||
}
|
||||
ParentChanged?.Invoke(parent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -512,7 +512,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private bool RemoveFromHierarchy(bool displayErrors = true, bool recalculate = true)
|
||||
private bool RemoveFromHierarchy(bool displayErrors = true)
|
||||
{
|
||||
if (Parent == null)
|
||||
{
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace Barotrauma
|
||||
/// How much the borders of a sliced sprite are allowed to scale
|
||||
/// You may for example want to prevent a 1-pixel border from scaling down (and disappearing) on small resolutions
|
||||
/// </summary>
|
||||
private float minBorderScale = 0.1f, maxBorderScale = 10.0f;
|
||||
private readonly float minBorderScale = 0.1f, maxBorderScale = 10.0f;
|
||||
|
||||
public bool CrossFadeIn { get; private set; } = true;
|
||||
public bool CrossFadeOut { get; private set; } = true;
|
||||
@@ -95,6 +95,19 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the scale of the sliced sprite's borders when it's draw inside an area of a specific size
|
||||
/// </summary>
|
||||
public float GetSliceBorderScale(Point drawSize)
|
||||
{
|
||||
if (!Slice) { return 1.0f; }
|
||||
|
||||
Vector2 scale = new Vector2(
|
||||
MathHelper.Clamp((float)drawSize.X / (Slices[0].Height + Slices[6].Height), 0, 1),
|
||||
MathHelper.Clamp((float)drawSize.Y / (Slices[0].Width + Slices[2].Width), 0, 1));
|
||||
return MathHelper.Clamp(Math.Min(Math.Min(scale.X, scale.Y), GUI.SlicedSpriteScale), minBorderScale, maxBorderScale);
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, Rectangle rect, Color color, SpriteEffects spriteEffects = SpriteEffects.None)
|
||||
{
|
||||
if (Sprite.Texture == null)
|
||||
@@ -107,23 +120,17 @@ namespace Barotrauma
|
||||
{
|
||||
Vector2 pos = new Vector2(rect.X, rect.Y);
|
||||
|
||||
Vector2 scale = Vector2.One;
|
||||
|
||||
scale.Y = MathHelper.Clamp((float)rect.Height / (Slices[0].Height + Slices[6].Height), 0, 1);
|
||||
scale.X = MathHelper.Clamp((float)rect.Width / (Slices[0].Width + Slices[2].Width), 0, 1);
|
||||
|
||||
scale.X = scale.Y =
|
||||
MathHelper.Clamp(Math.Min(Math.Min(scale.X, scale.Y), GUI.SlicedSpriteScale), minBorderScale, maxBorderScale);
|
||||
int centerHeight = rect.Height - (int)((Slices[0].Height + Slices[6].Height) * scale.Y);
|
||||
int centerWidth = rect.Width - (int)((Slices[0].Width + Slices[2].Width) * scale.X);
|
||||
float scale = GetSliceBorderScale(rect.Size);
|
||||
int centerHeight = rect.Height - (int)((Slices[0].Height + Slices[6].Height) * scale);
|
||||
int centerWidth = rect.Width - (int)((Slices[0].Width + Slices[2].Width) * scale);
|
||||
|
||||
for (int x = 0; x < 3; x++)
|
||||
{
|
||||
int width = (int)(x == 1 ? centerWidth : Slices[x].Width * scale.X);
|
||||
int width = (int)(x == 1 ? centerWidth : Slices[x].Width * scale);
|
||||
if (width <= 0) { continue; }
|
||||
for (int y = 0; y < 3; y++)
|
||||
{
|
||||
int height = (int)(y == 1 ? centerHeight : Slices[x + y * 3].Height * scale.Y);
|
||||
int height = (int)(y == 1 ? centerHeight : Slices[x + y * 3].Height * scale);
|
||||
if (height <= 0) { continue; }
|
||||
|
||||
spriteBatch.Draw(Sprite.Texture,
|
||||
|
||||
@@ -176,10 +176,10 @@ namespace Barotrauma
|
||||
|
||||
background.RectTransform.NonScaledSize = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
|
||||
|
||||
videoFrame.RectTransform.NonScaledSize += scaledVideoResolution + new Point(scaledBorderSize, scaledBorderSize);
|
||||
videoView.RectTransform.NonScaledSize += scaledVideoResolution;
|
||||
videoFrame.RectTransform.NonScaledSize = scaledVideoResolution + new Point(scaledBorderSize, scaledBorderSize);
|
||||
videoView.RectTransform.NonScaledSize = scaledVideoResolution;
|
||||
|
||||
title.RectTransform.NonScaledSize += new Point(scaledTextWidth, scaledTitleHeight);
|
||||
title.RectTransform.NonScaledSize = new Point(scaledTextWidth, scaledTitleHeight);
|
||||
title.RectTransform.AbsoluteOffset = new Point((int)(5 * GUI.Scale), (int)(10 * GUI.Scale));
|
||||
|
||||
if (textSettings != null && !string.IsNullOrEmpty(textSettings.Text))
|
||||
@@ -187,7 +187,7 @@ namespace Barotrauma
|
||||
textSettings.Text = ToolBox.WrapText(textSettings.Text, scaledTextWidth, GUI.Font);
|
||||
int wrappedHeight = textSettings.Text.Split('\n').Length * scaledTextHeight;
|
||||
|
||||
textFrame.RectTransform.NonScaledSize += new Point(scaledTextWidth + scaledBorderSize, wrappedHeight + scaledBorderSize + scaledButtonSize.Y + scaledTitleHeight);
|
||||
textFrame.RectTransform.NonScaledSize = new Point(scaledTextWidth + scaledBorderSize, wrappedHeight + scaledBorderSize + scaledButtonSize.Y + scaledTitleHeight);
|
||||
|
||||
if (useTextOnRightSide)
|
||||
{
|
||||
@@ -198,7 +198,7 @@ namespace Barotrauma
|
||||
textFrame.RectTransform.AbsoluteOffset = new Point(0, scaledVideoResolution.Y + scaledBorderSize * 2);
|
||||
}
|
||||
|
||||
textContent.RectTransform.NonScaledSize += new Point(scaledTextWidth, wrappedHeight);
|
||||
textContent.RectTransform.NonScaledSize = new Point(scaledTextWidth, wrappedHeight);
|
||||
textContent.RectTransform.AbsoluteOffset = new Point(0, scaledBorderSize + scaledTitleHeight);
|
||||
}
|
||||
|
||||
@@ -210,7 +210,7 @@ namespace Barotrauma
|
||||
objectiveText.RectTransform.AbsoluteOffset = new Point(scaledXOffset, textContent.RectTransform.Rect.Height + objectiveTitle.Rect.Height + (int)(scaledTextHeight * 2.25f));
|
||||
|
||||
textFrame.RectTransform.NonScaledSize += new Point(0, scaledObjectiveFrameHeight);
|
||||
objectiveText.RectTransform.NonScaledSize += new Point(textFrame.Rect.Width, scaledTextHeight);
|
||||
objectiveText.RectTransform.NonScaledSize = new Point(textFrame.Rect.Width, scaledTextHeight);
|
||||
objectiveTitle.Visible = objectiveText.Visible = true;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -765,6 +765,60 @@ namespace Barotrauma
|
||||
|
||||
SoundPlayer.Update((float)Timing.Step);
|
||||
|
||||
if (PlayerInput.KeyHit(Keys.Escape) && WindowActive)
|
||||
{
|
||||
// Check if a text input is selected.
|
||||
if (GUI.KeyboardDispatcher.Subscriber != null)
|
||||
{
|
||||
if (GUI.KeyboardDispatcher.Subscriber is GUITextBox textBox)
|
||||
{
|
||||
textBox.Deselect();
|
||||
}
|
||||
GUI.KeyboardDispatcher.Subscriber = null;
|
||||
}
|
||||
//if a verification prompt (are you sure you want to x) is open, close it
|
||||
else if (GUIMessageBox.VisibleBox as GUIMessageBox != null &&
|
||||
GUIMessageBox.VisibleBox.UserData as string == "verificationprompt")
|
||||
{
|
||||
((GUIMessageBox)GUIMessageBox.VisibleBox).Close();
|
||||
}
|
||||
else if (Tutorial.Initialized && Tutorial.ContentRunning)
|
||||
{
|
||||
(GameSession.GameMode as TutorialMode).Tutorial.CloseActiveContentGUI();
|
||||
}
|
||||
else if (GUI.PauseMenuOpen)
|
||||
{
|
||||
GUI.TogglePauseMenu();
|
||||
}
|
||||
//open the pause menu if not controlling a character OR if the character has no UIs active that can be closed with ESC
|
||||
else if ((Character.Controlled == null || !itemHudActive())
|
||||
//TODO: do we need to check Inventory.SelectedSlot?
|
||||
&& Inventory.SelectedSlot == null && CharacterHealth.OpenHealthWindow == null
|
||||
&& !CrewManager.IsCommandInterfaceOpen)
|
||||
{
|
||||
// Otherwise toggle pausing, unless another window/interface is open.
|
||||
GUI.TogglePauseMenu();
|
||||
}
|
||||
|
||||
bool itemHudActive()
|
||||
{
|
||||
if (Character.Controlled?.SelectedConstruction == null) { return false; }
|
||||
return
|
||||
Character.Controlled.SelectedConstruction.ActiveHUDs.Any(ic => ic.GuiFrame != null) ||
|
||||
((Character.Controlled.ViewTarget as Item)?.Prefab?.FocusOnSelected ?? false);
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
if (GameMain.NetworkMember == null)
|
||||
{
|
||||
if (PlayerInput.KeyHit(Keys.P) && !(GUI.KeyboardDispatcher.Subscriber is GUITextBox))
|
||||
{
|
||||
DebugConsole.Paused = !DebugConsole.Paused;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
GUI.ClearUpdateList();
|
||||
Paused = (DebugConsole.IsOpen || GUI.PauseMenuOpen || GUI.SettingsMenuOpen || Tutorial.ContentRunning || DebugConsole.Paused) &&
|
||||
(NetworkMember == null || !NetworkMember.GameStarted);
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Barotrauma
|
||||
private GUIFrame guiFrame;
|
||||
private GUIFrame crewArea;
|
||||
private GUIListBox crewList;
|
||||
private GUIButton toggleCrewButton;
|
||||
private GUIButton commandButton, toggleCrewButton;
|
||||
private float crewListOpenState;
|
||||
private bool toggleCrewListOpen = true;
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace Barotrauma
|
||||
|
||||
public List<GUIButton> OrderOptionButtons = new List<GUIButton>();
|
||||
|
||||
private Sprite jobIndicatorBackground, previousOrderArrow, cancelIcon, crewMemberBackground;
|
||||
private Sprite jobIndicatorBackground, previousOrderArrow, cancelIcon;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -112,11 +112,12 @@ namespace Barotrauma
|
||||
};
|
||||
|
||||
var buttonSize = new Point((int)(182.0f / 99.0f * buttonHeight), buttonHeight);
|
||||
var commandButton = new GUIButton(
|
||||
commandButton = new GUIButton(
|
||||
new RectTransform(buttonSize, parent: crewAreaWithButtons.RectTransform),
|
||||
style: "CommandButton")
|
||||
{
|
||||
ToolTip = TextManager.Get("inputtype.command"),
|
||||
// TODO: Update keybind if it's changed
|
||||
ToolTip = TextManager.Get("inputtype.command") + " (" + GameMain.Config.KeyBindText(InputType.Command) + ")",
|
||||
OnClicked = (button, userData) =>
|
||||
{
|
||||
ToggleCommandUI();
|
||||
@@ -124,23 +125,6 @@ namespace Barotrauma
|
||||
}
|
||||
};
|
||||
|
||||
var keybindText = new GUITextBlock(new RectTransform(new Vector2(0.9f), commandButton.RectTransform, Anchor.Center),
|
||||
"",
|
||||
font: GUI.SmallFont,
|
||||
textAlignment: Alignment.TopLeft,
|
||||
textColor: GUI.Style.TextColorBright,
|
||||
style: null)
|
||||
{
|
||||
TextGetter = () =>
|
||||
{
|
||||
//hide the text if using a long non-default keybind
|
||||
string txt = GameMain.Config.KeyBindText(InputType.Command);
|
||||
return txt.Length > 2 ? "" : txt;
|
||||
},
|
||||
Padding = Vector4.One * 3,
|
||||
CanBeFocused = false
|
||||
};
|
||||
|
||||
// AbsoluteOffset is set in UpdateProjectSpecific based on crewListOpenState
|
||||
crewList = new GUIListBox(
|
||||
new RectTransform(
|
||||
@@ -150,6 +134,8 @@ namespace Barotrauma
|
||||
isScrollBarOnDefaultSide: false)
|
||||
{
|
||||
AutoHideScrollBar = false,
|
||||
OnSelected = (component, userData) => false,
|
||||
SelectMultiple = false,
|
||||
Spacing = (int)(GUI.Scale * 10)
|
||||
};
|
||||
|
||||
@@ -172,7 +158,6 @@ namespace Barotrauma
|
||||
jobIndicatorBackground = new Sprite("Content/UI/CommandUIAtlas.png", new Rectangle(0, 512, 128, 128));
|
||||
previousOrderArrow = new Sprite("Content/UI/CommandUIAtlas.png", new Rectangle(128, 512, 128, 128));
|
||||
cancelIcon = new Sprite("Content/UI/CommandUIAtlas.png", new Rectangle(512, 384, 128, 128));
|
||||
crewMemberBackground = new Sprite("Content/UI/CommandUIAtlas.png", new Rectangle(0, 728, 320, 40));
|
||||
|
||||
#region Chatbox
|
||||
|
||||
@@ -224,6 +209,14 @@ namespace Barotrauma
|
||||
#endregion
|
||||
|
||||
#region Reports
|
||||
var chatBox = ChatBox ?? GameMain.Client?.ChatBox;
|
||||
chatBox.ToggleButton = new GUIButton(new RectTransform(new Point((int)(182f * GUI.Scale * 0.4f), (int)(99f * GUI.Scale * 0.4f)), guiFrame.RectTransform), style: "ChatToggleButton");
|
||||
chatBox.ToggleButton.RectTransform.AbsoluteOffset = new Point(0, HUDLayoutSettings.ChatBoxArea.Height - chatBox.ToggleButton.Rect.Height);
|
||||
chatBox.ToggleButton.OnClicked += (GUIButton btn, object userdata) =>
|
||||
{
|
||||
chatBox.ToggleOpen = !chatBox.ToggleOpen;
|
||||
return true;
|
||||
};
|
||||
|
||||
var reports = Order.PrefabList.FindAll(o => o.TargetAllCharacters && o.SymbolSprite != null);
|
||||
if (reports.None())
|
||||
@@ -231,14 +224,17 @@ namespace Barotrauma
|
||||
DebugConsole.ThrowError("No valid orders for report buttons found! Cannot create report buttons. The orders for the report buttons must have 'targetallcharacters' attribute enabled and a valid 'symbolsprite' defined.");
|
||||
return;
|
||||
}
|
||||
|
||||
ReportButtonFrame = new GUILayoutGroup(new RectTransform(
|
||||
new Point((HUDLayoutSettings.ChatBoxArea.Height - (int)((reports.Count - 1) * 5 * GUI.Scale)) / reports.Count, HUDLayoutSettings.ChatBoxArea.Height), guiFrame.RectTransform))
|
||||
new Point((HUDLayoutSettings.ChatBoxArea.Height - (int)((reports.Count - 1) * 5 * GUI.Scale)) / reports.Count, HUDLayoutSettings.ChatBoxArea.Height - chatBox.ToggleButton.Rect.Height), guiFrame.RectTransform))
|
||||
{
|
||||
AbsoluteSpacing = (int)(5 * GUI.Scale),
|
||||
UserData = "reportbuttons",
|
||||
CanBeFocused = false
|
||||
};
|
||||
|
||||
ReportButtonFrame.RectTransform.AbsoluteOffset = new Point(0, -chatBox.ToggleButton.Rect.Height);
|
||||
|
||||
//report buttons
|
||||
foreach (Order order in reports)
|
||||
{
|
||||
@@ -247,7 +243,7 @@ namespace Barotrauma
|
||||
{
|
||||
OnClicked = (GUIButton button, object userData) =>
|
||||
{
|
||||
if (Character.Controlled == null || Character.Controlled.SpeechImpediment >= 100.0f) { return false; }
|
||||
if (!CanIssueOrders) { return false; }
|
||||
SetCharacterOrder(null, order, null, Character.Controlled);
|
||||
var visibleHulls = new List<Hull>(Character.Controlled.GetVisibleHulls());
|
||||
foreach (var hull in visibleHulls)
|
||||
@@ -261,7 +257,7 @@ namespace Barotrauma
|
||||
ToolTip = order.Name
|
||||
};
|
||||
|
||||
new GUIFrame(new RectTransform(new Vector2(1.5f), btn.RectTransform, Anchor.Center), "OuterGlow")
|
||||
new GUIFrame(new RectTransform(new Vector2(1.5f), btn.RectTransform, Anchor.Center), "InnerGlowCircular")
|
||||
{
|
||||
Color = GUI.Style.Red * 0.8f,
|
||||
HoverColor = GUI.Style.Red * 1.0f,
|
||||
@@ -381,17 +377,18 @@ namespace Barotrauma
|
||||
|
||||
private void AddCharacterToCrewList(Character character)
|
||||
{
|
||||
if (character == null) { return; }
|
||||
|
||||
int width = crewList.Content.Rect.Width - HUDLayoutSettings.Padding;
|
||||
int height = Math.Max(32, (int)((1.0f / 8.0f) * width));
|
||||
var background = new GUIImage(
|
||||
var background = new GUIFrame(
|
||||
new RectTransform(new Point(width, height), parent: crewList.Content.RectTransform, anchor: Anchor.TopRight),
|
||||
crewMemberBackground,
|
||||
scaleToFit: true)
|
||||
style: "CrewListBackground")
|
||||
{
|
||||
UserData = character
|
||||
};
|
||||
|
||||
var iconRelativeSize = (float)height / background.Rect.Width;
|
||||
var iconRelativeWidth = (float)height / background.Rect.Width;
|
||||
|
||||
var layoutGroup = new GUILayoutGroup(
|
||||
new RectTransform(Vector2.One, parent: background.RectTransform),
|
||||
@@ -399,12 +396,17 @@ namespace Barotrauma
|
||||
childAnchor: Anchor.CenterLeft)
|
||||
{
|
||||
CanBeFocused = false,
|
||||
RelativeSpacing = 0.1f * iconRelativeSize,
|
||||
RelativeSpacing = 0.1f * iconRelativeWidth,
|
||||
UserData = character
|
||||
};
|
||||
|
||||
// "Padding" to prevent member-specific command button from overlapping job indicator
|
||||
var commandButtonAbsoluteHeight = Math.Min(40.0f, 0.67f * background.Rect.Height);
|
||||
var paddingRelativeWidth = 0.35f * commandButtonAbsoluteHeight / background.Rect.Width;
|
||||
new GUIFrame(new RectTransform(new Vector2(paddingRelativeWidth, 1.0f), layoutGroup.RectTransform), style: null);
|
||||
|
||||
var jobIconBackground = new GUIImage(
|
||||
new RectTransform(new Vector2(iconRelativeSize, 0.9f), layoutGroup.RectTransform),
|
||||
new RectTransform(new Vector2(0.8f * iconRelativeWidth, 0.8f), layoutGroup.RectTransform),
|
||||
jobIndicatorBackground,
|
||||
scaleToFit: true)
|
||||
{
|
||||
@@ -427,27 +429,46 @@ namespace Barotrauma
|
||||
};
|
||||
}
|
||||
|
||||
var relativeWidth = 1.0f - 4.5f * iconRelativeSize - 5 * layoutGroup.RelativeSpacing;
|
||||
var nameRelativeWidth = 1.0f - paddingRelativeWidth - 3.7f * iconRelativeWidth;
|
||||
var font = layoutGroup.Rect.Width < 150 ? GUI.SmallFont : GUI.Font;
|
||||
new GUITextBlock(
|
||||
var nameBlock = new GUITextBlock(
|
||||
new RectTransform(
|
||||
new Vector2(relativeWidth, 1.0f),
|
||||
layoutGroup.RectTransform),
|
||||
ToolBox.LimitString(character.Name, font, (int)(relativeWidth * layoutGroup.Rect.Width)),
|
||||
new Vector2(nameRelativeWidth, 1.0f),
|
||||
layoutGroup.RectTransform)
|
||||
{
|
||||
MaxSize = new Point(150, background.Rect.Height)
|
||||
},
|
||||
ToolBox.LimitString(character.Name, font, (int)(nameRelativeWidth * layoutGroup.Rect.Width)),
|
||||
font: font,
|
||||
textColor: character.Info?.Job?.Prefab?.UIColor)
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
|
||||
var nameActualRealtiveWidth = Math.Min(nameRelativeWidth * background.Rect.Width, 150) / background.Rect.Width;
|
||||
var characterButton = new GUIButton(
|
||||
new RectTransform(
|
||||
new Vector2(iconRelativeSize + layoutGroup.RelativeSpacing + relativeWidth, 1.0f),
|
||||
new Vector2(paddingRelativeWidth + 0.8f * iconRelativeWidth + nameActualRealtiveWidth + 2 * layoutGroup.RelativeSpacing, 1.0f),
|
||||
background.RectTransform),
|
||||
style: null)
|
||||
{
|
||||
UserData = character
|
||||
};
|
||||
// Only create a tooltip if the name doesn't fit the name block
|
||||
if (nameBlock.Text.EndsWith("..."))
|
||||
{
|
||||
var characterTooltip = character.Name;
|
||||
if (character.Info?.Job?.Name != null) { characterTooltip += " (" + character.Info.Job.Name + ")"; };
|
||||
characterButton.ToolTip = characterTooltip;
|
||||
if (character.Info?.Job?.Prefab != null)
|
||||
{
|
||||
characterButton.TooltipColorData = new List<ColorData>() { new ColorData()
|
||||
{
|
||||
Color = character.Info.Job.Prefab.UIColor,
|
||||
EndIndex = characterTooltip.Length - 1
|
||||
}};
|
||||
}
|
||||
}
|
||||
if (IsSinglePlayer)
|
||||
{
|
||||
characterButton.OnClicked = CharacterClicked;
|
||||
@@ -459,13 +480,13 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
new GUIImage(
|
||||
new RectTransform(new Vector2(0.5f * iconRelativeSize, 0.5f), layoutGroup.RectTransform),
|
||||
new RectTransform(new Vector2(0.5f * iconRelativeWidth, 0.5f), layoutGroup.RectTransform),
|
||||
style: "VerticalLine")
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
|
||||
var soundIcons = new GUIFrame(new RectTransform(new Vector2(iconRelativeSize, 0.8f), layoutGroup.RectTransform), style: null)
|
||||
var soundIcons = new GUIFrame(new RectTransform(new Vector2(0.8f * iconRelativeWidth, 0.8f), layoutGroup.RectTransform), style: null)
|
||||
{
|
||||
CanBeFocused = false,
|
||||
UserData = "soundicons"
|
||||
@@ -488,6 +509,17 @@ namespace Barotrauma
|
||||
UserData = "soundicondisabled",
|
||||
Visible = false
|
||||
};
|
||||
|
||||
new GUIButton(new RectTransform(new Point((int)commandButtonAbsoluteHeight), background.RectTransform), style: "CrewListCommandButton")
|
||||
{
|
||||
ToolTip = TextManager.Get("inputtype.command"),
|
||||
OnClicked = (component, userData) =>
|
||||
{
|
||||
if (!CanIssueOrders) { return false; }
|
||||
CreateCommandUI(character);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -716,15 +748,14 @@ namespace Barotrauma
|
||||
|
||||
var orderFrame = new GUIButton(
|
||||
new RectTransform(
|
||||
new Vector2(layoutGroup.GetChildByUserData("job").RectTransform.RelativeSize.X, 0.8f),
|
||||
layoutGroup.GetChildByUserData("job").RectTransform.RelativeSize,
|
||||
layoutGroup.RectTransform),
|
||||
style: null)
|
||||
{
|
||||
UserData = new OrderInfo(order, option),
|
||||
OnClicked = (button, userData) =>
|
||||
{
|
||||
if (Character.Controlled == null || Character.Controlled.SpeechImpediment >= 100.0f) { return false; }
|
||||
|
||||
if (!CanIssueOrders) { return false; }
|
||||
SetCharacterOrder(character, dismissedOrderPrefab, null, Character.Controlled);
|
||||
return true;
|
||||
}
|
||||
@@ -739,7 +770,7 @@ namespace Barotrauma
|
||||
UserData = "cancel",
|
||||
Visible = false
|
||||
};
|
||||
orderFrame.RectTransform.RepositionChildInHierarchy(3);
|
||||
orderFrame.RectTransform.RepositionChildInHierarchy(4);
|
||||
characterFrame.SetAsFirstChild();
|
||||
}
|
||||
|
||||
@@ -750,14 +781,14 @@ namespace Barotrauma
|
||||
var previousOrderInfo = new OrderInfo(currentOrderInfo);
|
||||
var prevOrderFrame = new GUIButton(
|
||||
new RectTransform(
|
||||
new Vector2(characterComponent.GetChildByUserData("job").RectTransform.RelativeSize.X, 0.8f),
|
||||
characterComponent.GetChildByUserData("job").RectTransform.RelativeSize,
|
||||
characterComponent.RectTransform),
|
||||
style: null)
|
||||
{
|
||||
UserData = previousOrderInfo,
|
||||
OnClicked = (button, userData) =>
|
||||
{
|
||||
if (Character.Controlled == null || Character.Controlled.SpeechImpediment >= 100.0f) { return false; }
|
||||
if (!CanIssueOrders) { return false; }
|
||||
var orderInfo = (OrderInfo)userData;
|
||||
SetCharacterOrder(character, orderInfo.Order, orderInfo.OrderOption, Character.Controlled);
|
||||
return true;
|
||||
@@ -785,7 +816,7 @@ namespace Barotrauma
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
prevOrderFrame.RectTransform.RepositionChildInHierarchy(GetCurrentOrderComponent(characterComponent) != null ? 4 : 3);
|
||||
prevOrderFrame.RectTransform.RepositionChildInHierarchy(GetCurrentOrderComponent(characterComponent) != null ? 5 : 4);
|
||||
}
|
||||
|
||||
private GUIComponent GetCurrentOrderComponent(GUILayoutGroup characterComponent)
|
||||
@@ -874,18 +905,20 @@ namespace Barotrauma
|
||||
|
||||
public void SelectNextCharacter()
|
||||
{
|
||||
if (!AllowCharacterSwitch) { return; }
|
||||
if (GameMain.IsMultiplayer) { return; }
|
||||
if (characters.None()) { return; }
|
||||
SelectCharacter(characters[TryAdjustIndex(1)]);
|
||||
if (!AllowCharacterSwitch || GameMain.IsMultiplayer || characters.None()) { return; }
|
||||
if (crewList.Content.GetChild(TryAdjustIndex(1))?.UserData is Character character)
|
||||
{
|
||||
SelectCharacter(character);
|
||||
}
|
||||
}
|
||||
|
||||
public void SelectPreviousCharacter()
|
||||
{
|
||||
if (!AllowCharacterSwitch) { return; }
|
||||
if (GameMain.IsMultiplayer) { return; }
|
||||
if (characters.None()) { return; }
|
||||
SelectCharacter(characters[TryAdjustIndex(-1)]);
|
||||
if (!AllowCharacterSwitch || GameMain.IsMultiplayer || characters.None()) { return; }
|
||||
if (crewList.Content.GetChild(TryAdjustIndex(-1))?.UserData is Character character)
|
||||
{
|
||||
SelectCharacter(character);
|
||||
}
|
||||
}
|
||||
|
||||
private void SelectCharacter(Character character)
|
||||
@@ -902,8 +935,9 @@ namespace Barotrauma
|
||||
|
||||
private int TryAdjustIndex(int amount)
|
||||
{
|
||||
int index = Character.Controlled == null ? 0 : characters.IndexOf(Character.Controlled) + amount;
|
||||
int lastIndex = characters.Count - 1;
|
||||
int index = Character.Controlled == null ? 0 :
|
||||
crewList.Content.GetChildIndex(crewList.Content.GetChildByUserData(Character.Controlled)) + amount;
|
||||
int lastIndex = crewList.Content.CountChildren - 1;
|
||||
if (index > lastIndex)
|
||||
{
|
||||
index = 0;
|
||||
@@ -934,39 +968,31 @@ namespace Barotrauma
|
||||
|
||||
#region Command UI
|
||||
|
||||
if (PlayerInput.KeyDown(InputType.Command) && (GUI.KeyboardDispatcher.Subscriber == null || GUI.KeyboardDispatcher.Subscriber == crewList) &&
|
||||
(!GameMain.IsMultiplayer || (GameMain.IsMultiplayer && (Character.Controlled != null || DebugConsole.CheatsEnabled))) &&
|
||||
commandFrame == null && !clicklessSelectionActive)
|
||||
{
|
||||
bool canIssueOrders = false;
|
||||
if (Character.Controlled != null && Character.Controlled.SpeechImpediment < 100.0f)
|
||||
{
|
||||
WifiComponent radio = GetHeadset(Character.Controlled, true);
|
||||
canIssueOrders = radio != null && radio.CanTransmit();
|
||||
}
|
||||
WasCommandInterfaceDisabledThisUpdate = false;
|
||||
|
||||
if (canIssueOrders)
|
||||
{
|
||||
CreateCommandUI(GUI.MouseOn?.UserData as Character);
|
||||
clicklessSelectionActive = isOpeningClick = true;
|
||||
}
|
||||
if (PlayerInput.KeyDown(InputType.Command) && (GUI.KeyboardDispatcher.Subscriber == null || GUI.KeyboardDispatcher.Subscriber == crewList) &&
|
||||
commandFrame == null && !clicklessSelectionActive && CanIssueOrders)
|
||||
{
|
||||
CreateCommandUI(GUI.MouseOn?.UserData as Character);
|
||||
clicklessSelectionActive = isOpeningClick = true;
|
||||
}
|
||||
|
||||
if (commandFrame != null)
|
||||
{
|
||||
void ResetNodeSelection(GUIButton newSelectedNode = null)
|
||||
{
|
||||
if (commandFrame == null) { return; }
|
||||
selectedNode?.Children.ForEach(c => c.Color = c.HoverColor * nodeColorMultiplier);
|
||||
selectedNode = newSelectedNode;
|
||||
timeSelected = 0;
|
||||
isSelectionHighlighted = false;
|
||||
}
|
||||
|
||||
if (Character.Controlled == null || Character.Controlled.SpeechImpediment >= 100.0f)
|
||||
if (!CanIssueOrders)
|
||||
{
|
||||
DisableCommandUI();
|
||||
}
|
||||
else if (PlayerInput.RightButtonClicked() && characterContext == null &&
|
||||
else if (PlayerInput.SecondaryMouseButtonClicked() && characterContext == null &&
|
||||
(optionNodes.Any(n => GUI.IsMouseOn(n.Item1)) || shortcutNodes.Any(n => GUI.IsMouseOn(n))))
|
||||
{
|
||||
var node = optionNodes.Find(n => GUI.IsMouseOn(n.Item1))?.Item1;
|
||||
@@ -988,7 +1014,7 @@ namespace Barotrauma
|
||||
}
|
||||
// TODO: Consider using HUD.CloseHUD() instead of KeyHit(Escape), the former method is also used for health UI
|
||||
else if ((PlayerInput.KeyHit(InputType.Command) && selectedNode == null && !clicklessSelectionActive) ||
|
||||
PlayerInput.KeyHit(InputType.Deselect) || PlayerInput.KeyHit(Microsoft.Xna.Framework.Input.Keys.Escape))
|
||||
PlayerInput.KeyHit(InputType.Deselect) || PlayerInput.KeyHit(Keys.Escape))
|
||||
{
|
||||
DisableCommandUI();
|
||||
}
|
||||
@@ -1093,11 +1119,24 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (PlayerInput.KeyUp(InputType.Command))
|
||||
else if (!PlayerInput.KeyDown(InputType.Command))
|
||||
{
|
||||
clicklessSelectionActive = false;
|
||||
}
|
||||
|
||||
// TODO: Expand crew list to use command button's space when it's not visible
|
||||
if (!IsSinglePlayer && commandButton != null)
|
||||
{
|
||||
if (!CanIssueOrders && commandButton.Visible)
|
||||
{
|
||||
commandButton.Visible = false;
|
||||
}
|
||||
else if (CanIssueOrders && !commandButton.Visible)
|
||||
{
|
||||
commandButton.Visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
if (GUI.DisableUpperHUD) { return; }
|
||||
@@ -1141,40 +1180,40 @@ namespace Barotrauma
|
||||
if (child.UserData is Character character)
|
||||
{
|
||||
child.Visible = Character.Controlled == null || Character.Controlled.TeamID == character.TeamID;
|
||||
if (child.Visible && child.FindChild(c => c is GUILayoutGroup) is GUILayoutGroup layoutGroup)
|
||||
if (child.Visible)
|
||||
{
|
||||
if (GetCurrentOrderComponent(layoutGroup) is GUIComponent orderButton &&
|
||||
if (character == Character.Controlled && child.State != GUIComponent.ComponentState.Selected)
|
||||
{
|
||||
crewList.Select(character, force: true);
|
||||
}
|
||||
if (child.FindChild(c => c is GUILayoutGroup) is GUILayoutGroup layoutGroup)
|
||||
{
|
||||
if (GetCurrentOrderComponent(layoutGroup) is GUIComponent orderButton &&
|
||||
orderButton.GetChildByUserData("colorsource") is GUIComponent orderIcon &&
|
||||
orderButton.GetChildByUserData("cancel") is GUIComponent cancelIcon)
|
||||
{
|
||||
cancelIcon.Visible = GUI.IsMouseOn(orderIcon);
|
||||
}
|
||||
if (layoutGroup.GetChildByUserData("soundicons")?
|
||||
.FindChild(c => c.UserData is Pair<string, float> pair && pair.First == "soundicon") is GUIImage soundIcon)
|
||||
{
|
||||
VoipClient.UpdateVoiceIndicator(soundIcon, 0.0f, deltaTime);
|
||||
{
|
||||
cancelIcon.Visible = GUI.IsMouseOn(orderIcon);
|
||||
}
|
||||
if (layoutGroup.GetChildByUserData("soundicons")?
|
||||
.FindChild(c => c.UserData is Pair<string, float> pair && pair.First == "soundicon") is GUIImage soundIcon)
|
||||
{
|
||||
VoipClient.UpdateVoiceIndicator(soundIcon, 0.0f, deltaTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
crewArea.RectTransform.AbsoluteOffset = Vector2.SmoothStep(
|
||||
new Vector2(-crewArea.Rect.Width - HUDLayoutSettings.Padding, 0.0f),
|
||||
Vector2.Zero,
|
||||
crewListOpenState).ToPoint();
|
||||
new Vector2(-crewArea.Rect.Width - HUDLayoutSettings.Padding, 0.0f),
|
||||
Vector2.Zero,
|
||||
crewListOpenState).ToPoint();
|
||||
crewListOpenState = ToggleCrewListOpen ?
|
||||
Math.Min(crewListOpenState + deltaTime * 2.0f, 1.0f) :
|
||||
Math.Max(crewListOpenState - deltaTime * 2.0f, 0.0f);
|
||||
|
||||
if (GUI.KeyboardDispatcher.Subscriber == null &&
|
||||
PlayerInput.KeyHit(InputType.CrewOrders) &&
|
||||
characters.Contains(Character.Controlled))
|
||||
if (GUI.KeyboardDispatcher.Subscriber == null && PlayerInput.KeyHit(InputType.CrewOrders))
|
||||
{
|
||||
//deselect construction unless it's the ladders the character is climbing
|
||||
if (Character.Controlled != null && !Character.Controlled.IsClimbing)
|
||||
{
|
||||
Character.Controlled.SelectedConstruction = null;
|
||||
}
|
||||
ToggleCrewListOpen = !ToggleCrewListOpen;
|
||||
}
|
||||
|
||||
@@ -1189,7 +1228,14 @@ namespace Barotrauma
|
||||
{
|
||||
get
|
||||
{
|
||||
return GameMain.GameSession?.CrewManager?.commandFrame != null;
|
||||
if (GameMain.GameSession?.CrewManager == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return GameMain.GameSession.CrewManager.commandFrame != null || GameMain.GameSession.CrewManager.WasCommandInterfaceDisabledThisUpdate;
|
||||
}
|
||||
}
|
||||
}
|
||||
private GUIFrame commandFrame, targetFrame;
|
||||
@@ -1222,9 +1268,23 @@ namespace Barotrauma
|
||||
private Order dismissedOrderPrefab;
|
||||
private Character characterContext;
|
||||
private Point shorcutCenterNodeOffset;
|
||||
private bool WasCommandInterfaceDisabledThisUpdate { get; set; }
|
||||
private bool CanIssueOrders
|
||||
{
|
||||
get
|
||||
{
|
||||
return Character.Controlled != null && Character.Controlled.SpeechImpediment < 100.0f;
|
||||
}
|
||||
}
|
||||
|
||||
private bool CanSomeoneHearCharacter()
|
||||
{
|
||||
return Character.Controlled != null && characters.Any(c => c != Character.Controlled && c.CanHearCharacter(Character.Controlled));
|
||||
}
|
||||
|
||||
private void CreateCommandUI(Character characterContext = null)
|
||||
{
|
||||
if (commandFrame != null) { DisableCommandUI(); }
|
||||
CharacterHealth.OpenHealthWindow = null;
|
||||
ScaleCommandUI();
|
||||
commandFrame = new GUIFrame(
|
||||
@@ -1233,7 +1293,7 @@ namespace Barotrauma
|
||||
color: Color.Transparent);
|
||||
background = new GUIImage(
|
||||
new RectTransform(Vector2.One, commandFrame.RectTransform, anchor: Anchor.Center),
|
||||
Order.CommandBackground);
|
||||
"CommandBackground");
|
||||
background.Color = background.Color * 0.8f;
|
||||
|
||||
this.characterContext = characterContext;
|
||||
@@ -1243,7 +1303,7 @@ namespace Barotrauma
|
||||
startNode = new GUIButton(
|
||||
new RectTransform(centerNodeSize, parent: commandFrame.RectTransform, anchor: Anchor.Center),
|
||||
style: null);
|
||||
CreateNodeIcon(startNode.RectTransform, Order.StartNode, Color.White);
|
||||
CreateNodeIcon(startNode.RectTransform, "CommandStartNode");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1254,7 +1314,7 @@ namespace Barotrauma
|
||||
// Container
|
||||
new GUIImage(
|
||||
new RectTransform(Vector2.One, startNode.RectTransform, anchor: Anchor.Center),
|
||||
Order.NodeContainer,
|
||||
"CommandNodeContainer",
|
||||
scaleToFit: true)
|
||||
{
|
||||
Color = characterContext.Info.Job.Prefab.UIColor * nodeColorMultiplier,
|
||||
@@ -1290,18 +1350,9 @@ namespace Barotrauma
|
||||
{
|
||||
if (commandFrame == null)
|
||||
{
|
||||
if ((!GameMain.IsMultiplayer || (GameMain.IsMultiplayer && (Character.Controlled != null || DebugConsole.CheatsEnabled))))
|
||||
if (CanIssueOrders)
|
||||
{
|
||||
bool canIssueOrders = false;
|
||||
if (Character.Controlled != null && Character.Controlled.SpeechImpediment < 100.0f)
|
||||
{
|
||||
WifiComponent radio = GetHeadset(Character.Controlled, true);
|
||||
canIssueOrders = radio != null && radio.CanTransmit();
|
||||
}
|
||||
if (canIssueOrders)
|
||||
{
|
||||
CreateCommandUI();
|
||||
}
|
||||
CreateCommandUI();
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1387,6 +1438,7 @@ namespace Barotrauma
|
||||
public void DisableCommandUI()
|
||||
{
|
||||
if (commandFrame == null) { return; }
|
||||
WasCommandInterfaceDisabledThisUpdate = true;
|
||||
RemoveOptionNodes();
|
||||
historyNodes.Clear();
|
||||
nodeConnectors = null;
|
||||
@@ -1400,7 +1452,7 @@ namespace Barotrauma
|
||||
background = null;
|
||||
commandFrame = null;
|
||||
extraOptionCharacters.Clear();
|
||||
clicklessSelectionActive = isOpeningClick = isSelectionHighlighted = false;
|
||||
isOpeningClick = isSelectionHighlighted = false;
|
||||
characterContext = null;
|
||||
returnNodeHotkey = expandNodeHotkey = Keys.None;
|
||||
if (Character.Controlled != null)
|
||||
@@ -1573,12 +1625,12 @@ namespace Barotrauma
|
||||
};
|
||||
|
||||
node.RectTransform.MoveOverTime(offset, CommandNodeAnimDuration);
|
||||
if (Order.OrderCategoryIcons.TryGetValue(category, out Sprite sprite))
|
||||
if (Order.OrderCategoryIcons.TryGetValue(category, out Tuple<Sprite, Color> sprite))
|
||||
{
|
||||
var tooltip = TextManager.Get("ordercategorytitle." + category.ToString().ToLower());
|
||||
var categoryDescription = TextManager.Get("ordercategorydescription." + category.ToString(), true);
|
||||
if (!string.IsNullOrWhiteSpace(categoryDescription)) { tooltip += "\n" + categoryDescription; }
|
||||
CreateNodeIcon(node.RectTransform, sprite, Color.White, tooltip: tooltip);
|
||||
CreateNodeIcon(node.RectTransform, sprite.Item1, sprite.Item2, tooltip: tooltip);
|
||||
}
|
||||
CreateHotkeyIcon(node.RectTransform, hotkey % 10);
|
||||
optionNodes.Add(new Tuple<GUIComponent, Keys>(node, Keys.D0 + hotkey % 10));
|
||||
@@ -1659,7 +1711,7 @@ namespace Barotrauma
|
||||
shortcutCenterNode = new GUIButton(
|
||||
new RectTransform(shortcutCenterNodeSize, parent: commandFrame.RectTransform, anchor: Anchor.Center),
|
||||
style: null);
|
||||
CreateNodeIcon(shortcutCenterNode.RectTransform, Order.ShortcutNode, Color.Red);
|
||||
CreateNodeIcon(shortcutCenterNode.RectTransform, "CommandShortcutNode");
|
||||
foreach (GUIComponent c in shortcutCenterNode.Children)
|
||||
{
|
||||
c.HoverColor = c.Color;
|
||||
@@ -1682,11 +1734,11 @@ namespace Barotrauma
|
||||
var orders = Order.PrefabList.FindAll(o => o.Category == orderCategory && !o.TargetAllCharacters);
|
||||
var offsets = MathUtils.GetPointsOnCircumference(Vector2.Zero, nodeDistance,
|
||||
GetCircumferencePointCount(orders.Count), GetFirstNodeAngle(orders.Count));
|
||||
for(int i = 0; i < orders.Count; i++)
|
||||
for (int i = 0; i < orders.Count; i++)
|
||||
{
|
||||
optionNodes.Add(new Tuple<GUIComponent, Keys>(
|
||||
CreateOrderNode(nodeSize, commandFrame.RectTransform, offsets[i].ToPoint(), orders[i], (i + 1) % 10),
|
||||
Keys.D0 + (i + 1) % 10));
|
||||
CanSomeoneHearCharacter() ? Keys.D0 + (i + 1) % 10 : Keys.None));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1700,10 +1752,11 @@ namespace Barotrauma
|
||||
|
||||
node.RectTransform.MoveOverTime(offset, CommandNodeAnimDuration);
|
||||
|
||||
var canSomeoneHearCharacter = CanSomeoneHearCharacter();
|
||||
var hasOptions = order.ItemComponentType != null || order.ItemIdentifiers.Length > 0 || order.Options.Length > 1;
|
||||
node.OnClicked = (button, userData) =>
|
||||
{
|
||||
if (Character.Controlled == null || Character.Controlled.SpeechImpediment >= 100.0f) { return false; }
|
||||
if (!canSomeoneHearCharacter || !CanIssueOrders) { return false; }
|
||||
var o = userData as Order;
|
||||
// TODO: Consider defining orders' or order categories' quick-assignment possibility in the XML
|
||||
if (o.Category == OrderCategory.Movement && characterContext == null)
|
||||
@@ -1721,10 +1774,20 @@ namespace Barotrauma
|
||||
}
|
||||
return true;
|
||||
};
|
||||
CreateNodeIcon(node.RectTransform, order.SymbolSprite, order.Color,
|
||||
tooltip: hasOptions || characterContext != null ? order.Name :
|
||||
order.Name + "\nLMB: " + TextManager.Get("commandui.quickassigntooltip") + "\nRMB: " + TextManager.Get("commandui.manualassigntooltip"));
|
||||
if (hotkey >= 0) { CreateHotkeyIcon(node.RectTransform, hotkey); }
|
||||
var icon = CreateNodeIcon(node.RectTransform, order.SymbolSprite, order.Color,
|
||||
tooltip: hasOptions || characterContext != null ? order.Name : order.Name +
|
||||
"\n" + (!PlayerInput.MouseButtonsSwapped() ? TextManager.Get("input.leftmouse") : TextManager.Get("input.rightmouse")) + ": " + TextManager.Get("commandui.quickassigntooltip") +
|
||||
"\n" + (!PlayerInput.MouseButtonsSwapped() ? TextManager.Get("input.rightmouse") : TextManager.Get("input.leftmouse")) + ": " + TextManager.Get("commandui.manualassigntooltip"));
|
||||
|
||||
if (!canSomeoneHearCharacter)
|
||||
{
|
||||
node.CanBeFocused = icon.CanBeFocused = false;
|
||||
CreateBlockIcon(node.RectTransform);
|
||||
}
|
||||
else if (hotkey >= 0)
|
||||
{
|
||||
CreateHotkeyIcon(node.RectTransform, hotkey);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -1839,7 +1902,7 @@ namespace Barotrauma
|
||||
Font = GUI.SmallFont,
|
||||
OnClicked = (_, userData) =>
|
||||
{
|
||||
if (Character.Controlled == null || Character.Controlled.SpeechImpediment >= 100.0f) { return false; }
|
||||
if (!CanIssueOrders) { return false; }
|
||||
var o = userData as Tuple<Order, string>;
|
||||
SetCharacterOrder(characterContext ?? GetBestCharacterForOrder(o.Item1), o.Item1, o.Item2, Character.Controlled);
|
||||
DisableCommandUI();
|
||||
@@ -1888,20 +1951,31 @@ namespace Barotrauma
|
||||
UserData = new Tuple<Order, string>(order, option),
|
||||
OnClicked = (_, userData) =>
|
||||
{
|
||||
if (Character.Controlled == null || Character.Controlled.SpeechImpediment >= 100.0f) { return false; }
|
||||
if (!CanIssueOrders) { return false; }
|
||||
var o = userData as Tuple<Order, string>;
|
||||
SetCharacterOrder(characterContext ?? GetBestCharacterForOrder(o.Item1), o.Item1, o.Item2, Character.Controlled);
|
||||
DisableCommandUI();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
GUIImage icon = null;
|
||||
if (order.Prefab.OptionSprites.TryGetValue(option, out Sprite sprite))
|
||||
{
|
||||
CreateNodeIcon(node.RectTransform, sprite, order.Color,
|
||||
tooltip: characterContext != null ? optionName :
|
||||
optionName + "\nLMB: " + TextManager.Get("commandui.quickassigntooltip") + "\nRMB: " + TextManager.Get("commandui.manualassigntooltip"));
|
||||
icon = CreateNodeIcon(node.RectTransform, sprite, order.Color,
|
||||
tooltip: characterContext != null ? optionName : optionName +
|
||||
"\n" + (!PlayerInput.MouseButtonsSwapped() ? TextManager.Get("input.leftmouse") : TextManager.Get("input.rightmouse")) + ": " + TextManager.Get("commandui.quickassigntooltip") +
|
||||
"\n" + (!PlayerInput.MouseButtonsSwapped() ? TextManager.Get("input.rightmouse") : TextManager.Get("input.leftmouse")) + ": " + TextManager.Get("commandui.manualassigntooltip"));
|
||||
}
|
||||
if (!CanSomeoneHearCharacter())
|
||||
{
|
||||
node.CanBeFocused = false;
|
||||
if (icon != null) { icon.CanBeFocused = false; }
|
||||
CreateBlockIcon(node.RectTransform);
|
||||
}
|
||||
else if (hotkey >= 0)
|
||||
{
|
||||
CreateHotkeyIcon(node.RectTransform, hotkey);
|
||||
}
|
||||
if (hotkey >= 0) { CreateHotkeyIcon(node.RectTransform, hotkey); }
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -1990,7 +2064,7 @@ namespace Barotrauma
|
||||
UserData = order,
|
||||
OnClicked = ExpandAssignmentNodes
|
||||
};
|
||||
CreateNodeIcon(expandNode.RectTransform, Order.ExpandNode, order.Item1.Color, tooltip: TextManager.Get("commandui.expand"));
|
||||
CreateNodeIcon(expandNode.RectTransform, "CommandExpandNode", order.Item1.Color, tooltip: TextManager.Get("commandui.expand"));
|
||||
|
||||
hotkey = optionNodes.Count + 1;
|
||||
CreateHotkeyIcon(expandNode.RectTransform, hotkey % 10);
|
||||
@@ -2029,7 +2103,7 @@ namespace Barotrauma
|
||||
{
|
||||
OnClicked = (button, userData) =>
|
||||
{
|
||||
if (Character.Controlled == null || Character.Controlled.SpeechImpediment >= 100.0f) { return false; }
|
||||
if (!CanIssueOrders) { return false; }
|
||||
SetCharacterOrder(character, order.Item1, order.Item2, Character.Controlled);
|
||||
DisableCommandUI();
|
||||
return true;
|
||||
@@ -2039,7 +2113,7 @@ namespace Barotrauma
|
||||
// Container
|
||||
var icon = new GUIImage(
|
||||
new RectTransform(new Vector2(1.2f), node.RectTransform, anchor: Anchor.Center),
|
||||
Order.NodeContainer,
|
||||
"CommandNodeContainer",
|
||||
scaleToFit: true)
|
||||
{
|
||||
Color = character.Info.Job.Prefab.UIColor * nodeColorMultiplier,
|
||||
@@ -2060,19 +2134,15 @@ namespace Barotrauma
|
||||
};
|
||||
|
||||
bool canHear = character.CanHearCharacter(Character.Controlled);
|
||||
|
||||
if (!canHear)
|
||||
{
|
||||
node.CanBeFocused = icon.CanBeFocused = false;
|
||||
new GUIImage(new RectTransform(Vector2.One, node.RectTransform, Anchor.Center), cancelIcon, scaleToFit: true)
|
||||
{
|
||||
Color = GUI.Style.Red * nodeColorMultiplier
|
||||
};
|
||||
CreateBlockIcon(node.RectTransform);
|
||||
}
|
||||
if (canHear && hotkey >= 0)
|
||||
if (hotkey >= 0)
|
||||
{
|
||||
CreateHotkeyIcon(node.RectTransform, hotkey);
|
||||
optionNodes.Add(new Tuple<GUIComponent, Keys>(node, Keys.D0 + hotkey));
|
||||
if (canHear) { CreateHotkeyIcon(node.RectTransform, hotkey); }
|
||||
optionNodes.Add(new Tuple<GUIComponent, Keys>(node, canHear ? Keys.D0 + hotkey : Keys.None));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2080,10 +2150,10 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateNodeIcon(RectTransform parent, Sprite sprite, Color color, string tooltip = null)
|
||||
private GUIImage CreateNodeIcon(RectTransform parent, Sprite sprite, Color color, string tooltip = null)
|
||||
{
|
||||
// Icon
|
||||
new GUIImage(
|
||||
return new GUIImage(
|
||||
new RectTransform(Vector2.One, parent),
|
||||
sprite,
|
||||
scaleToFit: true)
|
||||
@@ -2097,11 +2167,33 @@ namespace Barotrauma
|
||||
};
|
||||
}
|
||||
|
||||
private void CreateNodeIcon(RectTransform parent, string style, Color? color = null, string tooltip = null)
|
||||
{
|
||||
// Icon
|
||||
var icon = new GUIImage(
|
||||
new RectTransform(Vector2.One, parent),
|
||||
style,
|
||||
scaleToFit: true)
|
||||
{
|
||||
ToolTip = tooltip,
|
||||
UserData = "colorsource"
|
||||
};
|
||||
if (color.HasValue)
|
||||
{
|
||||
icon.Color = color.Value * nodeColorMultiplier;
|
||||
icon.HoverColor = color.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
icon.Color = icon.HoverColor * nodeColorMultiplier;
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateHotkeyIcon(RectTransform parent, int hotkey, bool enlargeIcon = false)
|
||||
{
|
||||
var bg = new GUIImage(
|
||||
new RectTransform(new Vector2(enlargeIcon ? 0.4f : 0.25f), parent, anchor: Anchor.BottomCenter, pivot: Pivot.Center),
|
||||
Order.HotkeyContainer,
|
||||
"CommandHotkeyContainer",
|
||||
scaleToFit: true)
|
||||
{
|
||||
CanBeFocused = false,
|
||||
@@ -2117,6 +2209,15 @@ namespace Barotrauma
|
||||
};
|
||||
}
|
||||
|
||||
private void CreateBlockIcon(RectTransform parent)
|
||||
{
|
||||
new GUIImage(new RectTransform(Vector2.One, parent, anchor: Anchor.Center), cancelIcon, scaleToFit: true)
|
||||
{
|
||||
Color = GUI.Style.Red * nodeColorMultiplier,
|
||||
HoverColor = GUI.Style.Red
|
||||
};
|
||||
}
|
||||
|
||||
private int GetCircumferencePointCount(int nodes)
|
||||
{
|
||||
return nodes % 2 > 0 ? nodes : nodes + 1;
|
||||
@@ -2134,7 +2235,7 @@ namespace Barotrauma
|
||||
else if (shortcutCenterNode != null)
|
||||
{
|
||||
bearing = GetBearing(
|
||||
centerNode.RectTransform.AbsoluteOffset.ToVector2(),
|
||||
centerNode.RectTransform.AnimTargetPos.ToVector2(),
|
||||
shorcutCenterNodeOffset.ToVector2());
|
||||
}
|
||||
return nodeCount % 2 > 0 ?
|
||||
@@ -2155,7 +2256,8 @@ namespace Barotrauma
|
||||
|
||||
private Character GetBestCharacterForOrder(Order order)
|
||||
{
|
||||
return characters.FindAll(c => c != Character.Controlled)
|
||||
if (Character.Controlled == null) { return null; }
|
||||
return characters.FindAll(c => c != Character.Controlled && c.TeamID == Character.Controlled.TeamID)
|
||||
.OrderByDescending(c => c.CurrentOrder == null || c.CurrentOrder.Identifier == dismissedOrderPrefab.Identifier)
|
||||
.ThenByDescending(c => order.HasAppropriateJob(c))
|
||||
.ThenBy(c => c.CurrentOrder?.Weight)
|
||||
@@ -2164,15 +2266,17 @@ namespace Barotrauma
|
||||
|
||||
private List<Character> GetCharactersSortedForOrder(Order order)
|
||||
{
|
||||
if (Character.Controlled == null) { return new List<Character>(); }
|
||||
if (order.Identifier == "follow")
|
||||
{
|
||||
return characters.FindAll(c => c != Character.Controlled)
|
||||
return characters.FindAll(c => c != Character.Controlled && c.TeamID == Character.Controlled.TeamID)
|
||||
.OrderByDescending(c => c.CurrentOrder == null || c.CurrentOrder.Identifier == dismissedOrderPrefab.Identifier)
|
||||
.ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
return characters.OrderByDescending(c => c.CurrentOrder == null || c.CurrentOrder.Identifier == dismissedOrderPrefab.Identifier)
|
||||
return characters.FindAll(c => c.TeamID == Character.Controlled.TeamID)
|
||||
.OrderByDescending(c => c.CurrentOrder == null || c.CurrentOrder.Identifier == dismissedOrderPrefab.Identifier)
|
||||
.ThenByDescending(c => order.HasAppropriateJob(c))
|
||||
.ThenBy(c => c.CurrentOrder?.Weight)
|
||||
.ToList();
|
||||
@@ -2285,18 +2389,14 @@ namespace Barotrauma
|
||||
if (canIssueOrders)
|
||||
{
|
||||
//report buttons are hidden when accessing another character's inventory
|
||||
ReportButtonFrame.Visible =
|
||||
Character.Controlled?.SelectedCharacter?.Inventory == null ||
|
||||
!Character.Controlled.SelectedCharacter.CanInventoryBeAccessed;
|
||||
ReportButtonFrame.Visible = !Character.Controlled.ShouldLockHud() &&
|
||||
(Character.Controlled?.SelectedCharacter?.Inventory == null ||
|
||||
!Character.Controlled.SelectedCharacter.CanInventoryBeAccessed);
|
||||
|
||||
var reportButtonParent = ChatBox ?? GameMain.Client?.ChatBox;
|
||||
if (reportButtonParent == null) { return; }
|
||||
|
||||
/*reportButtonFrame.RectTransform.AbsoluteOffset = new Point(
|
||||
Math.Min(reportButtonParent.GUIFrame.Rect.X, reportButtonParent.ToggleButton.Rect.X) - reportButtonFrame.Rect.Width - (int)(10 * GUI.Scale),
|
||||
reportButtonParent.GUIFrame.Rect.Y);*/
|
||||
|
||||
ReportButtonFrame.RectTransform.AbsoluteOffset = new Point(reportButtonParent.GUIFrame.Rect.Right + (int)(10 * GUI.Scale), reportButtonParent.GUIFrame.Rect.Y);
|
||||
ReportButtonFrame.RectTransform.AbsoluteOffset = new Point(reportButtonParent.GUIFrame.Rect.Right + (int)(10 * GUI.Scale), reportButtonParent.GUIFrame.Rect.Y - reportButtonParent.ToggleButton.Rect.Height);
|
||||
|
||||
bool hasFires = Character.Controlled.CurrentHull.FireSources.Count > 0;
|
||||
ToggleReportButton("reportfire", hasFires);
|
||||
|
||||
@@ -348,6 +348,9 @@ namespace Barotrauma.Tutorials
|
||||
TriggerTutorialSegment(4); // Deconstruct
|
||||
|
||||
SetHighlight(mechanic_craftingCabinet.Item, true);
|
||||
|
||||
bool gotOxygenTank = false;
|
||||
bool gotSodium = false;
|
||||
do
|
||||
{
|
||||
if (mechanic.SelectedConstruction == mechanic_craftingCabinet.Item)
|
||||
@@ -381,8 +384,18 @@ namespace Barotrauma.Tutorials
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!gotOxygenTank && mechanic.Inventory.FindItemByIdentifier("oxygentank") != null)
|
||||
{
|
||||
gotOxygenTank = true;
|
||||
}
|
||||
if (!gotSodium && mechanic.Inventory.FindItemByIdentifier("sodium") != null)
|
||||
{
|
||||
gotSodium = true;
|
||||
}
|
||||
yield return null;
|
||||
} while ((mechanic.Inventory.FindItemByIdentifier("oxygentank") == null && mechanic.Inventory.FindItemByIdentifier("aluminium") == null) || mechanic.Inventory.FindItemByIdentifier("sodium") == null); // Wait until looted
|
||||
} while (!gotOxygenTank || !gotSodium); // Wait until looted
|
||||
|
||||
yield return new WaitForSeconds(1.0f, false);
|
||||
SetHighlight(mechanic_craftingCabinet.Item, false);
|
||||
SetHighlight(mechanic_deconstructor.Item, true);
|
||||
@@ -424,7 +437,9 @@ namespace Barotrauma.Tutorials
|
||||
}
|
||||
}
|
||||
yield return null;
|
||||
} while (mechanic.Inventory.FindItemByIdentifier("aluminium") == null); // Wait until deconstructed
|
||||
} while (
|
||||
mechanic.Inventory.FindItemByIdentifier("aluminium") == null &&
|
||||
mechanic_fabricator.InputContainer.Inventory.FindItemByIdentifier("aluminium") == null); // Wait until aluminium obtained
|
||||
|
||||
SetHighlight(mechanic_deconstructor.Item, false);
|
||||
RemoveCompletedObjective(segments[4]);
|
||||
|
||||
@@ -403,20 +403,20 @@ namespace Barotrauma
|
||||
UnsavedSettings = true;
|
||||
|
||||
var msgBox = new GUIMessageBox(
|
||||
TextManager.Get("RestartRequiredLabel"),
|
||||
TextManager.Get("RestartRequiredLanguage"),
|
||||
buttons: new string[] { TextManager.Get("Cancel"), TextManager.Get("OK") });
|
||||
TextManager.Get("RestartRequiredLabel"),
|
||||
TextManager.Get("RestartRequiredLanguage"),
|
||||
buttons: new string[] { TextManager.Get("OK"), TextManager.Get("Cancel") });
|
||||
msgBox.Buttons[0].OnClicked += (btn, userdata) =>
|
||||
{
|
||||
ApplySettings();
|
||||
GameMain.Instance.Exit();
|
||||
return true;
|
||||
}; msgBox.Buttons[1].OnClicked += (btn, userdata) =>
|
||||
{
|
||||
Language = prevLanguage;
|
||||
languageDD.SelectItem(Language);
|
||||
msgBox.Close();
|
||||
return true;
|
||||
}; msgBox.Buttons[1].OnClicked += (btn, userdata) =>
|
||||
{
|
||||
ApplySettings();
|
||||
GameMain.Instance.Exit();
|
||||
return true;
|
||||
};
|
||||
|
||||
return true;
|
||||
@@ -1057,7 +1057,7 @@ namespace Barotrauma
|
||||
{
|
||||
UserData = i
|
||||
};
|
||||
keyBox.Text = ToolBox.LimitString(keyBox.Text, keyBox.Font, keyBox.Rect.Width);
|
||||
keyBox.Text = ToolBox.LimitString(keyBox.Text, keyBox.Font, (int)(keyBox.Rect.Width - keyBox.Padding.X - keyBox.Padding.Z));
|
||||
keyBox.OnSelected += KeyBoxSelected;
|
||||
keyBox.SelectedColor = Color.Gold * 0.3f;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ using System.Xml.Linq;
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class CharacterInventory : Inventory
|
||||
{
|
||||
{
|
||||
public enum Layout
|
||||
{
|
||||
Default,
|
||||
@@ -35,20 +35,13 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
private static Dictionary<InvSlotType, Sprite> limbSlotIcons;
|
||||
private static Sprite inventoryBackgroundSprite, inventoryExtendButton, inventoryExtendUpArrow, inventoryExtendDownArrow;
|
||||
|
||||
public Rectangle InventoryToggleArea;
|
||||
public bool InventoryToggleContains = false;
|
||||
private Vector2 inventoryExtendButtonOffset, inventoryArrowOffset;
|
||||
private int inventoryOpeningOffset;
|
||||
|
||||
private Point prevResolution;
|
||||
|
||||
public const InvSlotType PersonalSlots = InvSlotType.Card | InvSlotType.Headset | InvSlotType.InnerClothes | InvSlotType.OuterClothes | InvSlotType.Head;
|
||||
|
||||
public Vector2[] SlotPositions;
|
||||
private Vector2 bgScale;
|
||||
private Point screenResolution;
|
||||
|
||||
public Vector2[] SlotPositions;
|
||||
|
||||
private Layout layout;
|
||||
public Layout CurrentLayout
|
||||
{
|
||||
@@ -57,7 +50,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (layout == value) return;
|
||||
layout = value;
|
||||
SetSlotPositions();
|
||||
SetSlotPositions(layout);
|
||||
}
|
||||
}
|
||||
public bool Hidden { get; set; }
|
||||
@@ -66,8 +59,6 @@ namespace Barotrauma
|
||||
private float hidePersonalSlotsState;
|
||||
private GUIButton hideButton;
|
||||
private Rectangle personalSlotArea;
|
||||
private bool inventoryOpen = false;
|
||||
private bool wasInventoryToggledAutomatically = false;
|
||||
|
||||
public bool HidePersonalSlots
|
||||
{
|
||||
@@ -112,16 +103,10 @@ namespace Barotrauma
|
||||
limbSlotIcons.Add(InvSlotType.LeftHand, new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(634, 0, 128, 128)));
|
||||
limbSlotIcons.Add(InvSlotType.RightHand, new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(762, 0, 128, 128)));
|
||||
limbSlotIcons.Add(InvSlotType.OuterClothes, new Sprite("Content/UI/MainIconsAtlas.png", new Rectangle(256 + margin, 128 + margin, 128 - margin * 2, 128 - margin * 2)));
|
||||
|
||||
inventoryBackgroundSprite = new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(252, 317, 263, 197));
|
||||
inventoryExtendButton = new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(533, 300, 96, 19));
|
||||
inventoryExtendUpArrow = new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(640, 310, 10, 10));
|
||||
inventoryExtendDownArrow = new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(668, 310, 10, 10));
|
||||
}
|
||||
|
||||
SlotPositions = new Vector2[SlotTypes.Length];
|
||||
CurrentLayout = Layout.Default;
|
||||
SetSlotPositions();
|
||||
SetSlotPositions(layout);
|
||||
}
|
||||
|
||||
protected override ItemInventory GetActiveEquippedSubInventory(int slotIndex)
|
||||
@@ -157,6 +142,8 @@ namespace Barotrauma
|
||||
public override void CreateSlots()
|
||||
{
|
||||
if (slots == null) { slots = new InventorySlot[capacity]; }
|
||||
|
||||
float multiplier = !GUI.IsFourByThree() ? UIScale : UIScale * 0.925f;
|
||||
|
||||
for (int i = 0; i < capacity; i++)
|
||||
{
|
||||
@@ -166,7 +153,7 @@ namespace Barotrauma
|
||||
Rectangle slotRect = new Rectangle(
|
||||
(int)(SlotPositions[i].X),
|
||||
(int)(SlotPositions[i].Y),
|
||||
(int)(slotSprite.size.X * UIScale), (int)(slotSprite.size.Y * UIScale));
|
||||
(int)(slotSprite.size.X * multiplier), (int)(slotSprite.size.Y * multiplier));
|
||||
|
||||
if (Items[i] != null)
|
||||
{
|
||||
@@ -208,54 +195,31 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
screenResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
|
||||
CalculateBackgroundFrame();
|
||||
}
|
||||
|
||||
protected override void CalculateBackgroundFrame()
|
||||
{
|
||||
Rectangle frame = Rectangle.Empty;
|
||||
int firstSlotLocationY = 0;
|
||||
int lastSlotLocationY = 0;
|
||||
|
||||
for (int i = 0; i < capacity; i++)
|
||||
{
|
||||
if (HideSlot(i)) continue;
|
||||
if (PersonalSlots.HasFlag(SlotTypes[i])) continue;
|
||||
if (IsHandSlot(SlotTypes[i])) continue;
|
||||
if (frame == Rectangle.Empty)
|
||||
{
|
||||
firstSlotLocationY = slots[i].Rect.Location.Y;
|
||||
frame = slots[i].Rect;
|
||||
continue;
|
||||
}
|
||||
frame = Rectangle.Union(frame, slots[i].Rect);
|
||||
lastSlotLocationY = slots[i].Rect.Location.Y;
|
||||
}
|
||||
|
||||
frame.Inflate(25f * UIScale, 25f * UIScale);
|
||||
|
||||
if (layout == Layout.Default)
|
||||
{
|
||||
inventoryOpeningOffset = firstSlotLocationY - lastSlotLocationY;
|
||||
|
||||
bgScale = new Vector2((float)frame.Width / (float)inventoryBackgroundSprite.SourceRect.Width, (float)frame.Height / (float)inventoryBackgroundSprite.SourceRect.Height);
|
||||
|
||||
inventoryExtendButtonOffset = new Vector2(inventoryExtendButton.size.X * UIScale * 1.5f / 2f, inventoryExtendButton.size.Y * UIScale * 1.5f / 2f + UIScale * 6);
|
||||
inventoryArrowOffset = new Vector2(inventoryExtendUpArrow.size.X * UIScale * 1.25f / 2f, inventoryExtendUpArrow.size.Y * UIScale * 1.25f / 2f);
|
||||
InventoryToggleArea = new Rectangle(new Point(frame.Center.X, frame.Top) - inventoryExtendButtonOffset.ToPoint(), inventoryExtendButton.size.ToPoint() + new Point(0, (int)(UIScale * 6f)));
|
||||
if (!inventoryOpen)
|
||||
{
|
||||
frame.Offset(0, inventoryOpeningOffset);
|
||||
InventoryToggleArea.Offset(0, inventoryOpeningOffset);
|
||||
}
|
||||
}
|
||||
|
||||
frame.Inflate(10, 30);
|
||||
frame.Location -= new Point(0, 25);
|
||||
BackgroundFrame = frame;
|
||||
}
|
||||
|
||||
protected override bool HideSlot(int i)
|
||||
{
|
||||
if (slots[i].Disabled) return true;
|
||||
if (slots[i].Disabled || (hideEmptySlot[i] && Items[i] == null)) return true;
|
||||
|
||||
if (layout == Layout.Default)
|
||||
{
|
||||
@@ -268,23 +232,34 @@ namespace Barotrauma
|
||||
return true;
|
||||
}
|
||||
|
||||
//don't show the equip slot if the item is also in the default inventory
|
||||
if (SlotTypes[i] != InvSlotType.Any && Items[i] != null)
|
||||
{
|
||||
for (int j = 0; j < capacity; j++)
|
||||
{
|
||||
if (SlotTypes[j] == InvSlotType.Any && Items[j] == Items[i]) return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override bool IsSlotHiddenDueToToggleState(int i)
|
||||
private void SetSlotPositions(Layout layout)
|
||||
{
|
||||
return layout == Layout.Default && !inventoryOpen && slots[i].QuickUseKey == Keys.None && SlotTypes[i] == InvSlotType.Any;
|
||||
}
|
||||
int spacing;
|
||||
|
||||
private void SetSlotPositions()
|
||||
{
|
||||
Layout layout = CurrentLayout;
|
||||
int spacing = (int)(10 * UIScale);
|
||||
Point slotSize = (SlotSpriteSmall.size * UIScale).ToPoint();
|
||||
bool isFourByThree = GUI.IsFourByThree();
|
||||
if (isFourByThree)
|
||||
{
|
||||
spacing = (int)(5 * UIScale);
|
||||
}
|
||||
else
|
||||
{
|
||||
spacing = (int)(10 * UIScale);
|
||||
}
|
||||
|
||||
Point slotSize = !isFourByThree ? (SlotSpriteSmall.size * UIScale).ToPoint() : (SlotSpriteSmall.size * UIScale * .925f).ToPoint();
|
||||
int bottomOffset = slotSize.Y + spacing * 2 + ContainedIndicatorHeight;
|
||||
|
||||
prevResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
|
||||
|
||||
if (slots == null) { CreateSlots(); }
|
||||
|
||||
hideButton.Visible = false;
|
||||
@@ -296,47 +271,27 @@ namespace Barotrauma
|
||||
int personalSlotCount = SlotTypes.Count(s => PersonalSlots.HasFlag(s));
|
||||
int normalSlotCount = SlotTypes.Count(s => !PersonalSlots.HasFlag(s));
|
||||
|
||||
int firstRowSlotCount = hotkeyCount > normalSlotCount ? normalSlotCount : hotkeyCount;
|
||||
|
||||
int startX = GameMain.GraphicsWidth / 2 - firstRowSlotCount * (slotSize.X + spacing) / 2;
|
||||
int x = startX;
|
||||
int equipmentX = GameMain.GraphicsWidth - slotSize.X * 2;
|
||||
int buttonIndex = 0;
|
||||
int startY = GameMain.GraphicsHeight - bottomOffset;
|
||||
int y = startY;
|
||||
int handIndex = 1;
|
||||
int x = GameMain.GraphicsWidth / 2 - normalSlotCount * (slotSize.X + spacing) / 2;
|
||||
int upperX = GameMain.GraphicsWidth - slotSize.X * 2;
|
||||
|
||||
//make sure the rightmost normal slot doesn't overlap with the personal slots
|
||||
x -= Math.Max(x + firstRowSlotCount * (slotSize.X + spacing) - (equipmentX - personalSlotCount * (slotSize.X + spacing)), 0);
|
||||
x -= Math.Max((x + normalSlotCount * (slotSize.X + spacing)) - (upperX - personalSlotCount * (slotSize.X + spacing)), 0);
|
||||
|
||||
int hideButtonSlotIndex = -1;
|
||||
for (int i = 0; i < SlotPositions.Length; i++)
|
||||
{
|
||||
if (PersonalSlots.HasFlag(SlotTypes[i]))
|
||||
{
|
||||
SlotPositions[i] = new Vector2(equipmentX, startY);
|
||||
equipmentX -= slotSize.X + spacing;
|
||||
SlotPositions[i] = new Vector2(upperX, GameMain.GraphicsHeight - bottomOffset);
|
||||
upperX -= slotSize.X + spacing;
|
||||
personalSlotArea = (hideButtonSlotIndex == -1) ?
|
||||
new Rectangle(SlotPositions[i].ToPoint(), slotSize) :
|
||||
Rectangle.Union(personalSlotArea, new Rectangle(SlotPositions[i].ToPoint(), slotSize));
|
||||
hideButtonSlotIndex = i;
|
||||
}
|
||||
else if (IsHandSlot(SlotTypes[i]))
|
||||
{
|
||||
SlotPositions[i] = new Vector2(startX - (slotSize.X + spacing * 4) - (slotSize.X + spacing) * handIndex, startY);
|
||||
handIndex--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (buttonIndex >= hotkeyCount)
|
||||
{
|
||||
y -= bottomOffset;
|
||||
buttonIndex = 0;
|
||||
x = startX;
|
||||
}
|
||||
|
||||
buttonIndex++;
|
||||
SlotPositions[i] = new Vector2(x, y);
|
||||
SlotPositions[i] = new Vector2(x, GameMain.GraphicsHeight - bottomOffset);
|
||||
x += slotSize.X + spacing;
|
||||
}
|
||||
}
|
||||
@@ -354,6 +309,7 @@ namespace Barotrauma
|
||||
break;
|
||||
case Layout.Right:
|
||||
{
|
||||
int extraOffset = 0;
|
||||
int x = HUDLayoutSettings.InventoryAreaLower.Right;
|
||||
int personalSlotX = HUDLayoutSettings.InventoryAreaLower.Right - slotSize.X - spacing;
|
||||
for (int i = 0; i < slots.Length; i++)
|
||||
@@ -364,35 +320,24 @@ namespace Barotrauma
|
||||
//upperX -= slotSize.X + spacing;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i < slots.Length - 5)
|
||||
{
|
||||
x -= slotSize.X + spacing;
|
||||
}
|
||||
{
|
||||
x -= slotSize.X + spacing;
|
||||
}
|
||||
}
|
||||
|
||||
int lowerX = x;
|
||||
int y = GameMain.GraphicsHeight - bottomOffset;
|
||||
|
||||
for (int i = 0; i < SlotPositions.Length; i++)
|
||||
{
|
||||
if (HideSlot(i)) continue;
|
||||
if (PersonalSlots.HasFlag(SlotTypes[i]))
|
||||
{
|
||||
SlotPositions[i] = new Vector2(personalSlotX, y - bottomOffset);
|
||||
SlotPositions[i] = new Vector2(personalSlotX, GameMain.GraphicsHeight - bottomOffset * 2 - extraOffset - spacing * 2);
|
||||
personalSlotX -= slots[i].Rect.Width + spacing;
|
||||
}
|
||||
else
|
||||
{
|
||||
SlotPositions[i] = new Vector2(x, y);
|
||||
SlotPositions[i] = new Vector2(x, GameMain.GraphicsHeight - bottomOffset - extraOffset);
|
||||
x += slots[i].Rect.Width + spacing;
|
||||
|
||||
if (i == SlotPositions.Length - 6)
|
||||
{
|
||||
x = lowerX + (slots[i].Rect.Width + spacing) * 2;
|
||||
y -= bottomOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -401,37 +346,28 @@ namespace Barotrauma
|
||||
{
|
||||
if (!HideSlot(i)) continue;
|
||||
x -= slots[i].Rect.Width + spacing;
|
||||
SlotPositions[i] = new Vector2(x, y);
|
||||
SlotPositions[i] = new Vector2(x, GameMain.GraphicsHeight - bottomOffset - extraOffset);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Layout.Left:
|
||||
{
|
||||
int x = HUDLayoutSettings.InventoryAreaLower.Left;
|
||||
int y = GameMain.GraphicsHeight - bottomOffset;
|
||||
int x = HUDLayoutSettings.InventoryAreaLower.X;
|
||||
int personalSlotX = x;
|
||||
|
||||
for (int i = 0; i < SlotPositions.Length; i++)
|
||||
{
|
||||
if (HideSlot(i)) continue;
|
||||
if (PersonalSlots.HasFlag(SlotTypes[i]))
|
||||
{
|
||||
SlotPositions[i] = new Vector2(personalSlotX, y - bottomOffset);
|
||||
SlotPositions[i] = new Vector2(personalSlotX, GameMain.GraphicsHeight - bottomOffset * 2 - spacing * 2);
|
||||
personalSlotX += slots[i].Rect.Width + spacing;
|
||||
}
|
||||
else
|
||||
{
|
||||
SlotPositions[i] = new Vector2(x, y);
|
||||
SlotPositions[i] = new Vector2(x, GameMain.GraphicsHeight - bottomOffset);
|
||||
x += slots[i].Rect.Width + spacing;
|
||||
|
||||
if (i == SlotPositions.Length - 7)
|
||||
{
|
||||
x -= (slots[i].Rect.Width + spacing) * 6;
|
||||
y -= bottomOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < SlotPositions.Length; i++)
|
||||
{
|
||||
if (!HideSlot(i)) continue;
|
||||
@@ -483,11 +419,7 @@ namespace Barotrauma
|
||||
{
|
||||
HUDLayoutSettings.InventoryTopY = slots[0].EquipButtonRect.Y - (int)(15 * GUI.Scale);
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsHandSlot(InvSlotType slotType)
|
||||
{
|
||||
return slotType == InvSlotType.LeftHand || slotType == InvSlotType.RightHand;
|
||||
|
||||
}
|
||||
|
||||
protected override void ControlInput(Camera cam)
|
||||
@@ -500,32 +432,6 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public void ToggleInventory(bool automaticToggle = false)
|
||||
{
|
||||
if (Character.Controlled == null || !Character.Controlled.IsHuman || wasInventoryToggledAutomatically || inventoryOpen && automaticToggle) return;
|
||||
inventoryOpen = !inventoryOpen;
|
||||
if (inventoryOpen)
|
||||
{
|
||||
wasInventoryToggledAutomatically = automaticToggle;
|
||||
BackgroundFrame.Offset(0, -inventoryOpeningOffset);
|
||||
InventoryToggleArea.Offset(0, -inventoryOpeningOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
BackgroundFrame.Offset(0, inventoryOpeningOffset);
|
||||
InventoryToggleArea.Offset(0, inventoryOpeningOffset);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleAutomaticInventoryState()
|
||||
{
|
||||
if (wasInventoryToggledAutomatically && inventoryOpen && Character.Controlled.SelectedConstruction == null && Character.Controlled.SelectedCharacter == null)
|
||||
{
|
||||
wasInventoryToggledAutomatically = false;
|
||||
ToggleInventory();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime, Camera cam, bool isSubInventory = false)
|
||||
{
|
||||
if (!AccessibleWhenAlive && !character.IsDead)
|
||||
@@ -534,8 +440,6 @@ namespace Barotrauma
|
||||
return;
|
||||
}
|
||||
|
||||
HandleAutomaticInventoryState();
|
||||
|
||||
base.Update(deltaTime, cam);
|
||||
|
||||
bool hoverOnInventory = GUI.MouseOn == null &&
|
||||
@@ -564,12 +468,6 @@ namespace Barotrauma
|
||||
slots[i].DrawOffset = Vector2.Lerp(Vector2.Zero, new Vector2(personalSlotArea.Width, 0.0f), hidePersonalSlotsState);
|
||||
}
|
||||
}
|
||||
|
||||
InventoryToggleContains = InventoryToggleArea.Contains(PlayerInput.MousePosition);
|
||||
if (InventoryToggleContains && PlayerInput.PrimaryMouseButtonClicked())
|
||||
{
|
||||
ToggleInventory();
|
||||
}
|
||||
}
|
||||
|
||||
if (hoverOnInventory) { HideTimer = 0.5f; }
|
||||
@@ -726,10 +624,7 @@ namespace Barotrauma
|
||||
|
||||
private void HandleButtonEquipStates(Item item, InventorySlot slot, float deltaTime)
|
||||
{
|
||||
Rectangle modifiedRect = slot.EquipButtonRect;
|
||||
modifiedRect.Width = slot.InteractRect.Width;
|
||||
|
||||
slot.EquipButtonState = modifiedRect.Contains(PlayerInput.MousePosition) ?
|
||||
slot.EquipButtonState = slot.EquipButtonRect.Contains(PlayerInput.MousePosition) ?
|
||||
GUIComponent.ComponentState.Hover : GUIComponent.ComponentState.None;
|
||||
if (PlayerInput.LeftButtonHeld() && PlayerInput.RightButtonHeld())
|
||||
{
|
||||
@@ -803,8 +698,6 @@ namespace Barotrauma
|
||||
continue;
|
||||
}
|
||||
|
||||
if (num > hotkeyCount) break;
|
||||
|
||||
if (SlotTypes[i] == InvSlotType.Any)
|
||||
{
|
||||
slots[i].QuickUseKey = Keys.D0 + num % 10;
|
||||
@@ -950,7 +843,7 @@ namespace Barotrauma
|
||||
if (character.SelectedCharacter != null && character.SelectedCharacter.Inventory != null)
|
||||
{
|
||||
//player has selected the inventory of another character -> attempt to move the item there
|
||||
success = character.SelectedCharacter.Inventory.TryPutItem(item, Character.Controlled, item.AllowedSlots, true, true);
|
||||
success = character.SelectedCharacter.Inventory.TryPutItem(item, Character.Controlled, item.AllowedSlots, true);
|
||||
}
|
||||
break;
|
||||
case QuickUseAction.PutToContainer:
|
||||
@@ -966,7 +859,7 @@ namespace Barotrauma
|
||||
character.SelectedBy.Inventory != null)
|
||||
{
|
||||
//item is in the inventory of another character -> attempt to get the item from there
|
||||
success = character.SelectedBy.Inventory.TryPutItemWithAutoEquipCheck(item, Character.Controlled, item.AllowedSlots, true, true);
|
||||
success = character.SelectedBy.Inventory.TryPutItemWithAutoEquipCheck(item, Character.Controlled, item.AllowedSlots, true);
|
||||
}
|
||||
break;
|
||||
case QuickUseAction.TakeFromContainer:
|
||||
@@ -985,7 +878,7 @@ namespace Barotrauma
|
||||
// No subinventory found or placing unsuccessful -> attempt to put in the character's inventory
|
||||
if (!success)
|
||||
{
|
||||
success = TryPutItemWithAutoEquipCheck(item, Character.Controlled, item.AllowedSlots, true, true);
|
||||
success = TryPutItemWithAutoEquipCheck(item, Character.Controlled, item.AllowedSlots, true);
|
||||
}
|
||||
break;
|
||||
case QuickUseAction.PutToEquippedItem:
|
||||
@@ -1017,86 +910,128 @@ namespace Barotrauma
|
||||
GUI.PlayUISound(success ? GUISoundType.PickItem : GUISoundType.PickItemFail);
|
||||
}
|
||||
|
||||
public void DrawThis(SpriteBatch spriteBatch)
|
||||
public void DrawOwn(SpriteBatch spriteBatch)
|
||||
{
|
||||
if (!AccessibleWhenAlive && !character.IsDead) { return; }
|
||||
if (slots == null) { CreateSlots(); }
|
||||
|
||||
if (prevResolution.X != GameMain.GraphicsWidth || prevResolution.Y != GameMain.GraphicsHeight)
|
||||
if (!AccessibleWhenAlive && !character.IsDead) return;
|
||||
if (slots == null) CreateSlots();
|
||||
if (GameMain.GraphicsWidth != screenResolution.X ||
|
||||
GameMain.GraphicsHeight != screenResolution.Y ||
|
||||
prevUIScale != UIScale ||
|
||||
prevHUDScale != GUI.Scale)
|
||||
{
|
||||
SetSlotPositions();
|
||||
SetSlotPositions(layout);
|
||||
prevUIScale = UIScale;
|
||||
prevHUDScale = GUI.Scale;
|
||||
}
|
||||
|
||||
if (layout == Layout.Center)
|
||||
{
|
||||
CalculateBackgroundFrame();
|
||||
GUI.DrawRectangle(spriteBatch, BackgroundFrame, Color.Black * 0.8f, true);
|
||||
GUI.DrawString(spriteBatch,
|
||||
new Vector2((int)(BackgroundFrame.Center.X - GUI.Font.MeasureString(character.Name).X / 2), (int)BackgroundFrame.Y + 5),
|
||||
character.Name, Color.White * 0.9f);
|
||||
}
|
||||
|
||||
for (int i = 0; i < capacity; i++)
|
||||
{
|
||||
if (HideSlot(i)) continue;
|
||||
|
||||
Rectangle interactRect = slots[i].InteractRect;
|
||||
interactRect.Location += slots[i].DrawOffset.ToPoint();
|
||||
|
||||
//don't draw the item if it's being dragged out of the slot
|
||||
bool drawItem = draggingItem == null || draggingItem != Items[i] || interactRect.Contains(PlayerInput.MousePosition);
|
||||
DrawSlot(spriteBatch, this, slots[i], Items[i], i, drawItem, SlotTypes[i]);
|
||||
}
|
||||
|
||||
if (hideButton != null && hideButton.Visible && !Locked)
|
||||
{
|
||||
hideButton.DrawManually(spriteBatch, alsoChildren: true);
|
||||
}
|
||||
|
||||
if (layout == Layout.Default)
|
||||
{
|
||||
inventoryBackgroundSprite.Draw(spriteBatch, BackgroundFrame.Location.ToVector2(), Color.White, Vector2.Zero, rotate: 0, scale: bgScale);
|
||||
|
||||
Vector2 backgroundFrameCenter = new Vector2(BackgroundFrame.Center.X, BackgroundFrame.Top);
|
||||
inventoryExtendButton.Draw(spriteBatch, backgroundFrameCenter - inventoryExtendButtonOffset, Color.White, scale: UIScale * 1.5f);
|
||||
|
||||
Vector2 arrowPosition = backgroundFrameCenter - inventoryArrowOffset;
|
||||
if (inventoryOpen)
|
||||
{
|
||||
inventoryExtendDownArrow.Draw(spriteBatch, arrowPosition, Color.White, scale: UIScale * 1.25f);
|
||||
}
|
||||
else
|
||||
{
|
||||
inventoryExtendUpArrow.Draw(spriteBatch, arrowPosition, Color.White, scale: UIScale * 1.25f);
|
||||
}
|
||||
|
||||
GUI.DrawString(spriteBatch, arrowPosition + new Vector2(UIScale * 25, -3 * UIScale), GameMain.Config.KeyBindText(InputType.ToggleInventory), Color.White, font: GUI.HotkeyFont);
|
||||
}
|
||||
|
||||
InventorySlot highlightedQuickUseSlot = null;
|
||||
for (int i = 0; i < capacity; i++)
|
||||
{
|
||||
if (HideSlot(i)) continue;
|
||||
if (IsSlotHiddenDueToToggleState(i)) continue;
|
||||
|
||||
InventorySlot slot = slots[i];
|
||||
|
||||
Item item = Items[i];
|
||||
InvSlotType slotType = SlotTypes[i];
|
||||
|
||||
Rectangle interactRect = slot.InteractRect;
|
||||
interactRect.Location += slot.DrawOffset.ToPoint();
|
||||
|
||||
//don't draw the item if it's being dragged out of the slot
|
||||
bool drawItem = draggingItem == null || draggingItem != item || interactRect.Contains(PlayerInput.MousePosition);
|
||||
DrawSlot(spriteBatch, this, slot, item, i, drawItem, slotType);
|
||||
|
||||
if (item == null || (draggingItem == item && !slot.InteractRect.Contains(PlayerInput.MousePosition)) || !item.AllowedSlots.Any(a => a != InvSlotType.Any))
|
||||
if (Items[i] == null ||
|
||||
(draggingItem == Items[i] && !slots[i].InteractRect.Contains(PlayerInput.MousePosition)) ||
|
||||
!Items[i].AllowedSlots.Any(a => a != InvSlotType.Any))
|
||||
{
|
||||
//draw limb icons on empty slots
|
||||
if (limbSlotIcons.ContainsKey(slotType))
|
||||
if (limbSlotIcons.ContainsKey(SlotTypes[i]))
|
||||
{
|
||||
var icon = limbSlotIcons[slotType];
|
||||
icon.Draw(spriteBatch, slot.Rect.Center.ToVector2() + slot.DrawOffset, GUIColorSettings.EquipmentSlotIconColor, origin: icon.size / 2, scale: slot.Rect.Width / icon.size.X);
|
||||
var icon = limbSlotIcons[SlotTypes[i]];
|
||||
icon.Draw(spriteBatch, slots[i].Rect.Center.ToVector2() + slots[i].DrawOffset, GUIColorSettings.EquipmentSlotIconColor, origin: icon.size / 2, scale: slots[i].Rect.Width / icon.size.X);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (draggingItem == Items[i] && !slots[i].IsHighlighted) continue;
|
||||
|
||||
//draw hand icons if the item is equipped in a hand slot
|
||||
if (IsInLimbSlot(Items[i], InvSlotType.LeftHand))
|
||||
{
|
||||
var icon = limbSlotIcons[InvSlotType.LeftHand];
|
||||
icon.Draw(spriteBatch, new Vector2(slots[i].Rect.X, slots[i].Rect.Bottom) + slots[i].DrawOffset, Color.White * 0.6f, origin: new Vector2(icon.size.X * 0.35f, icon.size.Y * 0.75f), scale: slots[i].Rect.Width / icon.size.X * 0.7f);
|
||||
}
|
||||
if (IsInLimbSlot(Items[i], InvSlotType.RightHand))
|
||||
{
|
||||
var icon = limbSlotIcons[InvSlotType.RightHand];
|
||||
icon.Draw(spriteBatch, new Vector2(slots[i].Rect.Right, slots[i].Rect.Bottom) + slots[i].DrawOffset, Color.White * 0.6f, origin: new Vector2(icon.size.X * 0.65f, icon.size.Y * 0.75f), scale: slots[i].Rect.Width / icon.size.X * 0.7f);
|
||||
}
|
||||
|
||||
// Draw always on hotkeys
|
||||
if (slot.QuickUseKey != Keys.None)
|
||||
{
|
||||
DrawIndicatorAndHotkey(spriteBatch, slot, slot.EquipButtonState == GUIComponent.ComponentState.Hover);
|
||||
}
|
||||
GUIComponent.ComponentState state = slots[i].EquipButtonState;
|
||||
if (state == GUIComponent.ComponentState.Hover)
|
||||
{
|
||||
highlightedQuickUseSlot = slots[i];
|
||||
}
|
||||
|
||||
if (!Items[i].AllowedSlots.Any(a => a == InvSlotType.Any))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (draggingItem == item && !slot.IsHighlighted) continue;
|
||||
|
||||
bool hover = slot.EquipButtonState == GUIComponent.ComponentState.Hover;
|
||||
if (hover) highlightedQuickUseSlot = slot;
|
||||
|
||||
if (!item.AllowedSlots.Any(a => a == InvSlotType.Any)) continue;
|
||||
|
||||
DrawIndicatorAndHotkey(spriteBatch, slot, hover);
|
||||
Color color = Color.White;
|
||||
if (Locked)
|
||||
{
|
||||
color *= 0.5f;
|
||||
}
|
||||
|
||||
if (character.HasEquippedItem(Items[i]))
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case GUIComponent.ComponentState.None:
|
||||
EquippedIndicator.Draw(spriteBatch, slots[i].EquipButtonRect.Center.ToVector2(), color, EquippedIndicator.Origin, 0, UIScale * IndicatorScaleAdjustment);
|
||||
break;
|
||||
case GUIComponent.ComponentState.Hover:
|
||||
EquippedHoverIndicator.Draw(spriteBatch, slots[i].EquipButtonRect.Center.ToVector2(), color, EquippedIndicator.Origin, 0, UIScale * IndicatorScaleAdjustment);
|
||||
break;
|
||||
case GUIComponent.ComponentState.Pressed:
|
||||
case GUIComponent.ComponentState.Selected:
|
||||
case GUIComponent.ComponentState.HoverSelected:
|
||||
EquippedClickedIndicator.Draw(spriteBatch, slots[i].EquipButtonRect.Center.ToVector2(), color, EquippedIndicator.Origin, 0, UIScale * IndicatorScaleAdjustment);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case GUIComponent.ComponentState.None:
|
||||
UnequippedIndicator.Draw(spriteBatch, slots[i].EquipButtonRect.Center.ToVector2(), color, EquippedIndicator.Origin, 0, UIScale * IndicatorScaleAdjustment);
|
||||
break;
|
||||
case GUIComponent.ComponentState.Hover:
|
||||
UnequippedHoverIndicator.Draw(spriteBatch, slots[i].EquipButtonRect.Center.ToVector2(), color, EquippedIndicator.Origin, 0, UIScale * IndicatorScaleAdjustment);
|
||||
break;
|
||||
case GUIComponent.ComponentState.Pressed:
|
||||
case GUIComponent.ComponentState.Selected:
|
||||
case GUIComponent.ComponentState.HoverSelected:
|
||||
UnequippedClickedIndicator.Draw(spriteBatch, slots[i].EquipButtonRect.Center.ToVector2(), color, EquippedIndicator.Origin, 0, UIScale * IndicatorScaleAdjustment);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (highlightedQuickUseSlot != null && !string.IsNullOrEmpty(highlightedQuickUseSlot.QuickUseButtonToolTip))
|
||||
@@ -1104,30 +1039,5 @@ namespace Barotrauma
|
||||
GUIComponent.DrawToolTip(spriteBatch, highlightedQuickUseSlot.QuickUseButtonToolTip, highlightedQuickUseSlot.EquipButtonRect);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawIndicatorAndHotkey(SpriteBatch spriteBatch, InventorySlot slot, bool hover)
|
||||
{
|
||||
|
||||
Color indicatorColor = (hover) ? Color.White : Color.White * 0.8f;
|
||||
|
||||
/*if (character.HasEquippedItem(item))
|
||||
{
|
||||
indicatorColor = hover ? GUIColorSettings.InventorySlotEquippedColor : GUIColorSettings.InventorySlotEquippedColor * 0.8f;
|
||||
}
|
||||
else
|
||||
{
|
||||
indicatorColor = hover ? GUIColorSettings.InventorySlotColor : GUIColorSettings.InventorySlotColor * 0.8f;
|
||||
}*/
|
||||
|
||||
if (Locked) indicatorColor *= 0.3f;
|
||||
|
||||
Rectangle equipRect = slot.EquipButtonRect;
|
||||
EquipIndicator.Draw(spriteBatch, new Vector2(equipRect.Center.X, equipRect.Bottom), indicatorColor, EquipIndicator.Origin, 0, UIScale * 0.6f);
|
||||
|
||||
if (slot.QuickUseKey != Keys.None)
|
||||
{
|
||||
GUI.DrawString(spriteBatch, new Vector2(slot.Rect.Center.X - 2, slot.Rect.Top), slot.QuickUseKey.ToString().Substring(1, 1), Color.Black, font: GUI.HotkeyFont);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,9 +334,9 @@ namespace Barotrauma.Items.Components
|
||||
//docking interface ----------------------------------------------------
|
||||
float dockingButtonSize = 1.1f;
|
||||
float elementScale = 0.6f;
|
||||
dockingContainer = new GUIFrame(new RectTransform(new Point(160).Multiply(GUI.Scale * dockingButtonSize), GuiFrame.RectTransform, Anchor.BottomLeft)
|
||||
dockingContainer = new GUIFrame(new RectTransform(Sonar.controlBoxSize, GuiFrame.RectTransform, Anchor.BottomLeft, scaleBasis: ScaleBasis.Smallest)
|
||||
{
|
||||
RelativeOffset = new Vector2(Sonar.controlBoxOffset.X + 0.15f, -0.1f)
|
||||
RelativeOffset = Sonar.controlBoxOffset
|
||||
}, style: null);
|
||||
|
||||
dockText = TextManager.Get("label.navterminaldock", fallBackTag: "captain.dock");
|
||||
|
||||
@@ -156,6 +156,10 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
panel.DisconnectedWires.Add(DraggingConnected);
|
||||
}
|
||||
else if (DraggingConnected.Connections[0] == null && DraggingConnected.Connections[1] == null)
|
||||
{
|
||||
DraggingConnected.ClearConnections(user: Character.Controlled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,7 +191,7 @@ namespace Barotrauma.Items.Components
|
||||
x = (int)(x + width / 2 - step * (panel.DisconnectedWires.Count() - 1) / 2);
|
||||
foreach (Wire wire in panel.DisconnectedWires)
|
||||
{
|
||||
if (wire == DraggingConnected) { continue; }
|
||||
if (wire == DraggingConnected && mouseInRect) { continue; }
|
||||
|
||||
Connection recipient = wire.OtherConnection(null);
|
||||
string label = recipient == null ? "" : recipient.item.Name + $" ({recipient.DisplayName})";
|
||||
|
||||
@@ -109,17 +109,20 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
base.CreateEditingHUD(editor);
|
||||
|
||||
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(customInterfaceElementList[0]);
|
||||
PropertyDescriptor labelProperty = properties.Find("Label", false);
|
||||
PropertyDescriptor signalProperty = properties.Find("Signal", false);
|
||||
for (int i = 0; i < customInterfaceElementList.Count; i++)
|
||||
{
|
||||
editor.CreateStringField(customInterfaceElementList[i],
|
||||
new SerializableProperty(labelProperty),
|
||||
customInterfaceElementList[i].Label, "Label #" + (i + 1), "");
|
||||
editor.CreateStringField(customInterfaceElementList[i],
|
||||
new SerializableProperty(signalProperty),
|
||||
customInterfaceElementList[i].Signal, "Signal #" + (i + 1), "");
|
||||
if (customInterfaceElementList.Count > 0)
|
||||
{
|
||||
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(customInterfaceElementList[0]);
|
||||
PropertyDescriptor labelProperty = properties.Find("Label", false);
|
||||
PropertyDescriptor signalProperty = properties.Find("Signal", false);
|
||||
for (int i = 0; i < customInterfaceElementList.Count; i++)
|
||||
{
|
||||
editor.CreateStringField(customInterfaceElementList[i],
|
||||
new SerializableProperty(labelProperty),
|
||||
customInterfaceElementList[i].Label, "Label #" + (i + 1), "");
|
||||
editor.CreateStringField(customInterfaceElementList[i],
|
||||
new SerializableProperty(signalProperty),
|
||||
customInterfaceElementList[i].Signal, "Signal #" + (i + 1), "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -444,9 +444,10 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
powerIndicator.DrawManually(spriteBatch, true);
|
||||
|
||||
int requiredChargeIndicatorPos = (int)((powerConsumption / (batteryCapacity * 3600.0f)) * powerIndicator.Rect.Width);
|
||||
Rectangle sliderRect = powerIndicator.GetSliderRect(1.0f);
|
||||
int requiredChargeIndicatorPos = (int)(powerConsumption / (batteryCapacity * 3600.0f) * sliderRect.Width);
|
||||
GUI.DrawRectangle(spriteBatch,
|
||||
new Rectangle(powerIndicator.Rect.X + requiredChargeIndicatorPos, powerIndicator.Rect.Y, 3, powerIndicator.Rect.Height),
|
||||
new Rectangle(sliderRect.X + requiredChargeIndicatorPos, sliderRect.Y, 2, sliderRect.Height),
|
||||
Color.White * 0.5f, true);
|
||||
}
|
||||
|
||||
@@ -459,7 +460,7 @@ namespace Barotrauma.Items.Components
|
||||
Point invSlotPos = new Point(GameMain.GraphicsWidth / 2 - totalWidth / 2, (int)(60 * GUI.Scale));
|
||||
for (int i = 0; i < availableAmmo.Count; i++)
|
||||
{
|
||||
// TODO: Optimize? Creates multiple new classes per frame?
|
||||
// TODO: Optimize? Creates multiple new objects per frame?
|
||||
Inventory.DrawSlot(spriteBatch, null,
|
||||
new InventorySlot(new Rectangle(invSlotPos + new Point((i % slotsPerRow) * (slotSize.X + spacing), (int)Math.Floor(i / (float)slotsPerRow) * (slotSize.Y + spacing)), slotSize)),
|
||||
availableAmmo[i], -1, true);
|
||||
|
||||
@@ -53,10 +53,12 @@ namespace Barotrauma
|
||||
{
|
||||
int buttonDir = Math.Sign(SubInventoryDir);
|
||||
|
||||
Vector2 equipIndicatorPos = new Vector2(Rect.Left, Rect.Top);
|
||||
float sizeY = Inventory.UnequippedIndicator.size.Y * Inventory.UIScale * Inventory.IndicatorScaleAdjustment;
|
||||
|
||||
Vector2 equipIndicatorPos = new Vector2(Rect.Left, Rect.Center.Y + (Rect.Height / 2 + 25 * Inventory.UIScale) * buttonDir - sizeY / 2f);
|
||||
equipIndicatorPos += DrawOffset;
|
||||
|
||||
return new Rectangle((int)equipIndicatorPos.X, (int)equipIndicatorPos.Y, Rect.Width, (int)(Inventory.EquipIndicator.size.Y * Inventory.UIScale));
|
||||
return new Rectangle((int)equipIndicatorPos.X, (int)equipIndicatorPos.Y, (int)Rect.Width, (int)sizeY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,19 +138,27 @@ namespace Barotrauma
|
||||
{
|
||||
if (slotSpriteSmall == null)
|
||||
{
|
||||
//TODO: define these in xml
|
||||
slotSpriteSmall = new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(12, 9, 115, 115), null, 0);
|
||||
slotSpriteSmall.size = new Vector2(SlotSpriteSmall.SourceRect.Width * 0.682f, SlotSpriteSmall.SourceRect.Height * 0.682f);
|
||||
//TODO: define this in xml
|
||||
slotSpriteSmall = new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(10, 6, 119, 120), null, 0);
|
||||
// Adjustment to match the old size of 75,71
|
||||
SlotSpriteSmall.size = new Vector2(SlotSpriteSmall.SourceRect.Width * 0.625f, SlotSpriteSmall.SourceRect.Height * 0.625f);
|
||||
}
|
||||
return slotSpriteSmall;
|
||||
}
|
||||
}
|
||||
public static Sprite DraggableIndicator;
|
||||
public static Sprite EquipIndicator;
|
||||
|
||||
public static Sprite UnequippedIndicator, UnequippedHoverIndicator, UnequippedClickedIndicator, EquippedIndicator, EquippedHoverIndicator, EquippedClickedIndicator;
|
||||
public static float IndicatorScaleAdjustment
|
||||
{
|
||||
get
|
||||
{
|
||||
return !GUI.IsFourByThree() ? 0.85f : 0.75f;
|
||||
}
|
||||
}
|
||||
|
||||
public static Inventory DraggingInventory;
|
||||
|
||||
public Rectangle BackgroundFrame;
|
||||
public Rectangle BackgroundFrame { get; protected set; }
|
||||
|
||||
private ushort[] receivedItemIDs;
|
||||
private CoroutineHandle syncItemsCoroutine;
|
||||
@@ -305,7 +315,7 @@ namespace Barotrauma
|
||||
int columns = Math.Min(slotsPerRow, capacity);
|
||||
|
||||
Vector2 spacing = new Vector2(5.0f * UIScale);
|
||||
spacing.Y += (this is CharacterInventory) ? EquipIndicator.size.Y : ContainedIndicatorHeight;
|
||||
spacing.Y += (this is CharacterInventory) ? UnequippedIndicator.size.Y * UIScale : ContainedIndicatorHeight;
|
||||
Vector2 rectSize = new Vector2(60.0f * UIScale);
|
||||
|
||||
padding = new Vector4(spacing.X, spacing.Y, spacing.X, spacing.X);
|
||||
@@ -384,12 +394,7 @@ namespace Barotrauma
|
||||
|
||||
protected virtual bool HideSlot(int i)
|
||||
{
|
||||
return slots[i].Disabled;
|
||||
}
|
||||
|
||||
protected virtual bool IsSlotHiddenDueToToggleState(int i)
|
||||
{
|
||||
return false;
|
||||
return slots[i].Disabled || (hideEmptySlot[i] && Items[i] == null);
|
||||
}
|
||||
|
||||
public virtual void Update(float deltaTime, Camera cam, bool subInventory = false)
|
||||
@@ -405,7 +410,7 @@ namespace Barotrauma
|
||||
{
|
||||
for (int i = 0; i < capacity; i++)
|
||||
{
|
||||
if (HideSlot(i) || IsSlotHiddenDueToToggleState(i)) { continue; }
|
||||
if (HideSlot(i)) { continue; }
|
||||
UpdateSlot(slots[i], i, Items[i], subInventory);
|
||||
}
|
||||
if (!isSubInventory)
|
||||
@@ -557,7 +562,16 @@ namespace Barotrauma
|
||||
var slot = slots[slotIndex];
|
||||
int dir = slot.SubInventoryDir;
|
||||
Rectangle subRect = slot.Rect;
|
||||
Vector2 spacing = new Vector2(10 * UIScale, (10 * UIScale + EquipIndicator.size.Y));
|
||||
Vector2 spacing;
|
||||
|
||||
if (GUI.IsFourByThree())
|
||||
{
|
||||
spacing = new Vector2(5 * UIScale, (5 + UnequippedIndicator.size.Y) * UIScale);
|
||||
}
|
||||
else
|
||||
{
|
||||
spacing = new Vector2(10 * UIScale, (10 + UnequippedIndicator.size.Y) * UIScale);
|
||||
}
|
||||
|
||||
int columns = (int)Math.Max(Math.Floor(Math.Sqrt(itemCapacity)), 1);
|
||||
while (itemCapacity / columns * (subRect.Height + spacing.Y) > GameMain.GraphicsHeight * 0.5f)
|
||||
@@ -653,24 +667,18 @@ namespace Barotrauma
|
||||
/// Is the mouse on any inventory element (slot, equip button, subinventory...)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static bool IsMouseOnInventory(bool ignoreDrag = false)
|
||||
public static bool IsMouseOnInventory()
|
||||
{
|
||||
if (Character.Controlled == null) return false;
|
||||
|
||||
if (!ignoreDrag && draggingItem != null || DraggingInventory != null) return true;
|
||||
if (draggingItem != null || DraggingInventory != null) return true;
|
||||
|
||||
if (Character.Controlled.Inventory != null)
|
||||
{
|
||||
var inv = Character.Controlled.Inventory;
|
||||
|
||||
if (inv.BackgroundFrame.Contains(PlayerInput.MousePosition) || inv.InventoryToggleContains) return true;
|
||||
|
||||
for (var i = 0; i < inv.slots.Length; i++)
|
||||
{
|
||||
var slot = inv.slots[i];
|
||||
|
||||
if (inv.HideSlot(i) || inv.IsSlotHiddenDueToToggleState(i)) continue;
|
||||
|
||||
if (slot.InteractRect.Contains(PlayerInput.MousePosition))
|
||||
{
|
||||
return true;
|
||||
@@ -743,11 +751,6 @@ namespace Barotrauma
|
||||
|
||||
if (inv == null) { return CursorState.Default; }
|
||||
|
||||
if (inv.InventoryToggleContains)
|
||||
{
|
||||
return CursorState.Hand;
|
||||
}
|
||||
|
||||
foreach (var item in inv.Items)
|
||||
{
|
||||
var container = item?.GetComponent<ItemContainer>();
|
||||
@@ -798,12 +801,8 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < inv.slots.Length; i++)
|
||||
foreach (var slot in inv.slots)
|
||||
{
|
||||
InventorySlot slot = inv.slots[i];
|
||||
|
||||
if (inv.IsSlotHiddenDueToToggleState(i)) continue;
|
||||
|
||||
if (slot.EquipButtonRect.Contains(PlayerInput.MousePosition))
|
||||
{
|
||||
return CursorState.Hand;
|
||||
@@ -820,7 +819,6 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CursorState.Default;
|
||||
}
|
||||
|
||||
@@ -931,20 +929,17 @@ namespace Barotrauma
|
||||
|
||||
if (selectedSlot == null)
|
||||
{
|
||||
if (!IsMouseOnInventory(true))
|
||||
if (DraggingItemToWorld &&
|
||||
Character.Controlled.FocusedItem?.OwnInventory != null &&
|
||||
Character.Controlled.FocusedItem.OwnInventory.CanBePut(draggingItem) &&
|
||||
Character.Controlled.FocusedItem.OwnInventory.TryPutItem(draggingItem, Character.Controlled))
|
||||
{
|
||||
if (DraggingItemToWorld &&
|
||||
Character.Controlled.FocusedItem?.OwnInventory != null &&
|
||||
Character.Controlled.FocusedItem.OwnInventory.CanBePut(draggingItem) &&
|
||||
Character.Controlled.FocusedItem.OwnInventory.TryPutItem(draggingItem, Character.Controlled))
|
||||
{
|
||||
GUI.PlayUISound(GUISoundType.PickItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.PlayUISound(GUISoundType.DropItem);
|
||||
draggingItem.Drop(Character.Controlled);
|
||||
}
|
||||
GUI.PlayUISound(GUISoundType.PickItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.PlayUISound(GUISoundType.DropItem);
|
||||
draggingItem.Drop(Character.Controlled);
|
||||
}
|
||||
}
|
||||
else if (selectedSlot.ParentInventory.Items[selectedSlot.SlotIndex] != draggingItem)
|
||||
@@ -1076,7 +1071,7 @@ namespace Barotrauma
|
||||
|
||||
bool mouseOnHealthInterface = CharacterHealth.OpenHealthWindow != null && CharacterHealth.OpenHealthWindow.MouseOnElement;
|
||||
|
||||
if ((GUI.MouseOn == null || mouseOnHealthInterface) && selectedSlot == null && !IsMouseOnInventory(true))
|
||||
if ((GUI.MouseOn == null || mouseOnHealthInterface) && selectedSlot == null)
|
||||
{
|
||||
var shadowSprite = GUI.Style.GetComponentStyle("OuterGlow").Sprites[GUIComponent.ComponentState.None][0];
|
||||
string toolTip = mouseOnHealthInterface ? TextManager.Get("QuickUseAction.UseTreatment") :
|
||||
@@ -1101,7 +1096,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedSlot != null && selectedSlot.Item != null && selectedSlot.Slot.EquipButtonState != GUIComponent.ComponentState.Hover)
|
||||
if (selectedSlot != null && selectedSlot.Item != null)
|
||||
{
|
||||
Rectangle slotRect = selectedSlot.Slot.Rect;
|
||||
slotRect.Location += selectedSlot.Slot.DrawOffset.ToPoint();
|
||||
@@ -1136,30 +1131,15 @@ namespace Barotrauma
|
||||
{
|
||||
Sprite slotSprite = slot.SlotSprite ?? SlotSpriteSmall;
|
||||
|
||||
if (inventory != null && (CharacterInventory.PersonalSlots.HasFlag(type) || (inventory.isSubInventory && (inventory.Owner as Item) != null
|
||||
/*if (inventory != null && (CharacterInventory.PersonalSlots.HasFlag(type) || (inventory.isSubInventory && (inventory.Owner as Item) != null
|
||||
&& (inventory.Owner as Item).AllowedSlots.Any(a => CharacterInventory.PersonalSlots.HasFlag(a)))))
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
slotColor = slot.IsHighlighted ? GUIColorSettings.EquipmentSlotEmptyColor : GUIColorSettings.EquipmentSlotEmptyColor * 0.8f;
|
||||
}
|
||||
else
|
||||
{
|
||||
slotColor = slot.IsHighlighted ? GUIColorSettings.EquipmentSlotColor : GUIColorSettings.EquipmentSlotColor * 0.8f;
|
||||
}
|
||||
|
||||
slotColor = slot.IsHighlighted ? GUIColorSettings.EquipmentSlotColor : GUIColorSettings.EquipmentSlotColor * 0.8f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (item != null && Character.Controlled != null && Character.Controlled.HasEquippedItem(item))
|
||||
{
|
||||
slotColor = slot.IsHighlighted ? GUIColorSettings.InventorySlotEquippedColor : GUIColorSettings.InventorySlotEquippedColor * 0.8f;
|
||||
}
|
||||
else
|
||||
{
|
||||
slotColor = slot.IsHighlighted ? GUIColorSettings.InventorySlotColor : GUIColorSettings.InventorySlotColor * 0.8f;
|
||||
}
|
||||
}
|
||||
slotColor = slot.IsHighlighted ? GUIColorSettings.InventorySlotColor : GUIColorSettings.InventorySlotColor * 0.8f;
|
||||
}*/
|
||||
|
||||
if (inventory != null && inventory.Locked) { slotColor = Color.Gray * 0.5f; }
|
||||
spriteBatch.Draw(slotSprite.Texture, rect, slotSprite.SourceRect, slotColor);
|
||||
@@ -1183,7 +1163,7 @@ namespace Barotrauma
|
||||
canBePut = true;
|
||||
}
|
||||
}
|
||||
if (slot.MouseOn() && canBePut)
|
||||
if (slot.MouseOn() && canBePut && selectedSlot?.Slot == slot)
|
||||
{
|
||||
GUI.UIGlow.Draw(spriteBatch, rect, GUI.Style.Green);
|
||||
}
|
||||
@@ -1273,7 +1253,7 @@ namespace Barotrauma
|
||||
if (GameMain.DebugDraw)
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch, rect, Color.White, false, 0, 1);
|
||||
GUI.DrawRectangle(spriteBatch, slot.EquipButtonRect, Color.Red, false, 0, 1);
|
||||
GUI.DrawRectangle(spriteBatch, slot.EquipButtonRect, Color.White, false, 0, 1);
|
||||
}
|
||||
|
||||
if (slot.HighlightColor != Color.Transparent)
|
||||
@@ -1284,11 +1264,8 @@ namespace Barotrauma
|
||||
if (item != null && drawItem)
|
||||
{
|
||||
Sprite sprite = item.Prefab.InventoryIcon ?? item.Sprite;
|
||||
|
||||
float equipButtonHeightAdjustment = inventory == Character.Controlled?.Inventory ? slot.EquipButtonRect.Height : 0;
|
||||
|
||||
float scale = Math.Min(Math.Min((rect.Width - 10) / sprite.size.X, (rect.Height - 5 - equipButtonHeightAdjustment) / sprite.size.Y), 2.0f);
|
||||
Vector2 itemPos = rect.Center.ToVector2() + new Vector2(0, equipButtonHeightAdjustment / 2f);
|
||||
float scale = Math.Min(Math.Min((rect.Width - 10) / sprite.size.X, (rect.Height - 10) / sprite.size.Y), 2.0f);
|
||||
Vector2 itemPos = rect.Center.ToVector2();
|
||||
if (itemPos.Y > GameMain.GraphicsHeight)
|
||||
{
|
||||
itemPos.Y -= Math.Min(
|
||||
@@ -1314,6 +1291,15 @@ namespace Barotrauma
|
||||
}
|
||||
sprite.Draw(spriteBatch, itemPos, spriteColor, rotation, scale);
|
||||
}
|
||||
|
||||
if (inventory != null &&
|
||||
!inventory.Locked &&
|
||||
Character.Controlled?.Inventory == inventory &&
|
||||
slot.QuickUseKey != Keys.None)
|
||||
{
|
||||
spriteBatch.Draw(slotHotkeySprite.Texture, rect.ScaleSize(1.15f), slotHotkeySprite.SourceRect, slotColor);
|
||||
GUI.DrawString(spriteBatch, rect.Location.ToVector2() + new Vector2((int)(4 * UIScale), (int)(-1.25f * UIScale)), slot.QuickUseKey.ToString().Substring(1, 1), Color.Black, font: GUI.SmallFont);
|
||||
}
|
||||
}
|
||||
|
||||
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
||||
|
||||
@@ -708,6 +708,8 @@ namespace Barotrauma
|
||||
foreach (ItemComponent ic in activeHUDs)
|
||||
{
|
||||
if (ic.GuiFrame == null || ic.AllowUIOverlap || ic.GetLinkUIToComponent() != null) { continue; }
|
||||
//if the frame covers nearly all of the screen, don't trying to prevent overlaps because it'd fail anyway
|
||||
if (ic.GuiFrame.Rect.Width >= GameMain.GraphicsWidth * 0.9f && ic.GuiFrame.Rect.Height >= GameMain.GraphicsHeight * 0.9f) { continue; }
|
||||
ic.GuiFrame.RectTransform.ScreenSpaceOffset = Point.Zero;
|
||||
elementsToMove.Add(ic.GuiFrame);
|
||||
debugInitialHudPositions.Add(ic.GuiFrame.Rect);
|
||||
@@ -779,10 +781,10 @@ namespace Barotrauma
|
||||
foreach (ItemComponent ic in activeComponents)
|
||||
{
|
||||
if (ic.HudPriority > 0 && ic.ShouldDrawHUD(character) &&
|
||||
(ic.CanBeSelected || character.HasEquippedItem(this)) &&
|
||||
(ic.CanBeSelected || (character.HasEquippedItem(this) && ic.DrawHudWhenEquipped)) &&
|
||||
(maxPriorityHUDs.Count == 0 || ic.HudPriority >= maxPriorityHUDs[0].HudPriority))
|
||||
{
|
||||
if (maxPriorityHUDs.Count > 0 && ic.HudPriority > maxPriorityHUDs[0].HudPriority) maxPriorityHUDs.Clear();
|
||||
if (maxPriorityHUDs.Count > 0 && ic.HudPriority > maxPriorityHUDs[0].HudPriority) { maxPriorityHUDs.Clear(); }
|
||||
maxPriorityHUDs.Add(ic);
|
||||
}
|
||||
}
|
||||
@@ -795,7 +797,8 @@ namespace Barotrauma
|
||||
{
|
||||
foreach (ItemComponent ic in activeComponents)
|
||||
{
|
||||
if ((ic.CanBeSelected || character.HasEquippedItem(this)) && ic.ShouldDrawHUD(character))
|
||||
if (ic.ShouldDrawHUD(character) &&
|
||||
(ic.CanBeSelected || (character.HasEquippedItem(this) && ic.DrawHudWhenEquipped)))
|
||||
{
|
||||
activeHUDs.Add(ic);
|
||||
}
|
||||
|
||||
@@ -11,12 +11,6 @@ namespace Barotrauma
|
||||
{
|
||||
base.ControlInput(cam);
|
||||
cam.OffsetAmount = 0;
|
||||
|
||||
if (Character.Controlled?.Inventory != null)
|
||||
{
|
||||
Character.Controlled.Inventory.ToggleInventory(true);
|
||||
}
|
||||
|
||||
//if this is used, we need to implement syncing this inventory with the server
|
||||
/*Character.DisableControls = true;
|
||||
if (Character.Controlled != null)
|
||||
@@ -25,7 +19,7 @@ namespace Barotrauma
|
||||
{
|
||||
Character.Controlled.SelectedConstruction = null;
|
||||
}
|
||||
}*/
|
||||
}*/
|
||||
}
|
||||
|
||||
protected override void CalculateBackgroundFrame()
|
||||
|
||||
@@ -60,6 +60,8 @@ namespace Barotrauma.Networking
|
||||
|
||||
private bool connected;
|
||||
|
||||
private bool roundInitialized;
|
||||
|
||||
private byte myID;
|
||||
|
||||
private List<Client> otherClients;
|
||||
@@ -148,6 +150,8 @@ namespace Barotrauma.Networking
|
||||
this.ownerKey = ownerKey;
|
||||
this.steamP2POwner = steamP2POwner;
|
||||
|
||||
roundInitialized = false;
|
||||
|
||||
allowReconnect = true;
|
||||
|
||||
netStats = new NetStats();
|
||||
@@ -708,6 +712,9 @@ namespace Barotrauma.Networking
|
||||
case ServerPacketHeader.STARTGAME:
|
||||
startGameCoroutine = GameMain.Instance.ShowLoading(StartGame(inc), false);
|
||||
break;
|
||||
case ServerPacketHeader.STARTGAMEFINALIZE:
|
||||
ReadStartGameFinalize(inc);
|
||||
break;
|
||||
case ServerPacketHeader.ENDGAME:
|
||||
string endMessage = inc.ReadString();
|
||||
bool missionSuccessful = inc.ReadBoolean();
|
||||
@@ -767,7 +774,26 @@ namespace Barotrauma.Networking
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void ReadStartGameFinalize(IReadMessage inc)
|
||||
{
|
||||
int levelEqualityCheckVal = inc.ReadInt32();
|
||||
|
||||
if (Level.Loaded.EqualityCheckVal != levelEqualityCheckVal)
|
||||
{
|
||||
string errorMsg = "Level equality check failed. The level generated at your end doesn't match the level generated by the server (seed: " + Level.Loaded.Seed +
|
||||
", sub: " + Submarine.MainSub.Name + " (" + Submarine.MainSub.MD5Hash.ShortHash + ")" +
|
||||
", mirrored: " + Level.Loaded.Mirrored + ").";
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameClient.StartGame:LevelsDontMatch" + Level.Loaded.Seed, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||
throw new Exception(errorMsg);
|
||||
}
|
||||
|
||||
GameMain.GameSession.Mission?.ClientReadInitial(inc);
|
||||
|
||||
roundInitialized = true;
|
||||
}
|
||||
|
||||
|
||||
private void OnDisconnect()
|
||||
{
|
||||
if (SteamManager.IsInitialized)
|
||||
@@ -782,7 +808,11 @@ namespace Barotrauma.Networking
|
||||
|
||||
string[] splitMsg = disconnectMsg.Split('/');
|
||||
DisconnectReason disconnectReason = DisconnectReason.Unknown;
|
||||
if (splitMsg.Length > 0) { Enum.TryParse(splitMsg[0], out disconnectReason); }
|
||||
bool disconnectReasonIncluded = false;
|
||||
if (splitMsg.Length > 0)
|
||||
{
|
||||
if (Enum.TryParse(splitMsg[0], out disconnectReason)) { disconnectReasonIncluded = true; }
|
||||
}
|
||||
|
||||
if (disconnectMsg == Lidgren.Network.NetConnection.NoResponseMessage)
|
||||
{
|
||||
@@ -857,7 +887,8 @@ namespace Barotrauma.Networking
|
||||
|
||||
DebugConsole.NewMessage("Attempting to reconnect...");
|
||||
|
||||
string msg = TextManager.GetServerMessage(disconnectMsg);
|
||||
//if the first part of the message is the disconnect reason Enum, don't include it in the popup message
|
||||
string msg = TextManager.GetServerMessage(disconnectReasonIncluded ? string.Join('/', splitMsg.Skip(1)) : disconnectMsg);
|
||||
msg = string.IsNullOrWhiteSpace(msg) ?
|
||||
TextManager.Get("ConnectionLostReconnecting") :
|
||||
msg + '\n' + TextManager.Get("ConnectionLostReconnecting");
|
||||
@@ -871,6 +902,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
else
|
||||
{
|
||||
connected = false;
|
||||
connectCancelled = true;
|
||||
|
||||
string msg = "";
|
||||
@@ -1113,9 +1145,11 @@ namespace Barotrauma.Networking
|
||||
|
||||
EndVoteTickBox.Selected = false;
|
||||
|
||||
roundInitialized = false;
|
||||
|
||||
int seed = inc.ReadInt32();
|
||||
string levelSeed = inc.ReadString();
|
||||
int levelEqualityCheckVal = inc.ReadInt32();
|
||||
//int levelEqualityCheckVal = inc.ReadInt32();
|
||||
float levelDifficulty = inc.ReadSingle();
|
||||
|
||||
byte losMode = inc.ReadByte();
|
||||
@@ -1151,6 +1185,8 @@ namespace Barotrauma.Networking
|
||||
|
||||
serverSettings.ReadMonsterEnabled(inc);
|
||||
|
||||
bool includesFinalize = inc.ReadBoolean(); inc.ReadPadBits();
|
||||
|
||||
GameModePreset gameMode = GameModePreset.List.Find(gm => gm.Identifier == modeIdentifier);
|
||||
MultiPlayerCampaign campaign =
|
||||
GameMain.NetLobbyScreen.SelectedMode == GameMain.GameSession?.GameMode.Preset && gameMode == GameMain.NetLobbyScreen.SelectedMode ?
|
||||
@@ -1238,7 +1274,44 @@ namespace Barotrauma.Networking
|
||||
mirrorLevel: campaign.Map.CurrentLocation != campaign.Map.SelectedConnection.Locations[0]);
|
||||
}
|
||||
|
||||
GameMain.GameSession.Mission?.ClientReadInitial(inc);
|
||||
if (includesFinalize)
|
||||
{
|
||||
ReadStartGameFinalize(inc);
|
||||
}
|
||||
|
||||
//wait for up to 30 seconds for the server to send the STARTGAMEFINALIZE message
|
||||
DateTime timeOut = DateTime.Now + new TimeSpan(0, 0, seconds: 30);
|
||||
while (DateTime.Now < timeOut)
|
||||
{
|
||||
if (!connected)
|
||||
{
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
if (roundInitialized)
|
||||
{
|
||||
break;
|
||||
}
|
||||
try
|
||||
{
|
||||
clientPeer?.Update((float)Timing.Step);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("There was an error initializing the round.", e, true);
|
||||
roundInitialized = false;
|
||||
break;
|
||||
}
|
||||
|
||||
//waiting for a STARTGAMEFINALIZE message
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
if (!roundInitialized)
|
||||
{
|
||||
DebugConsole.ThrowError("Error while starting the round (did not receive STARTROUNDFINALIZE message from the server). Stopping the round...");
|
||||
CoroutineManager.StartCoroutine(EndGame(""));
|
||||
yield return CoroutineStatus.Failure;
|
||||
}
|
||||
|
||||
if (GameMain.GameSession.Submarine.IsFileCorrupted)
|
||||
{
|
||||
@@ -1258,23 +1331,12 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
if (Level.Loaded.EqualityCheckVal != levelEqualityCheckVal)
|
||||
{
|
||||
string errorMsg = "Level equality check failed. The level generated at your end doesn't match the level generated by the server (seed: " + Level.Loaded.Seed +
|
||||
", sub: " + Submarine.MainSub.Name + " (" + Submarine.MainSub.MD5Hash.ShortHash + ")" +
|
||||
", mirrored: " + Level.Loaded.Mirrored + ").";
|
||||
DebugConsole.ThrowError(errorMsg, createMessageBox: true);
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameClient.StartGame:LevelsDontMatch" + levelSeed, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||
CoroutineManager.StartCoroutine(EndGame(""));
|
||||
yield return CoroutineStatus.Failure;
|
||||
}
|
||||
|
||||
if (respawnAllowed) { respawnManager = new RespawnManager(this, GameMain.NetLobbyScreen.UsingShuttle ? GameMain.NetLobbyScreen.SelectedShuttle : null); }
|
||||
|
||||
GameMain.GameSession.EventManager.PreloadContent(contentToPreload);
|
||||
|
||||
ServerSettings.ServerDetailsChanged = true;
|
||||
gameStarted = true;
|
||||
ServerSettings.ServerDetailsChanged = true;
|
||||
|
||||
GameMain.GameScreen.Select();
|
||||
|
||||
@@ -1422,7 +1484,7 @@ namespace Barotrauma.Networking
|
||||
existingClient.Muted = tc.Muted;
|
||||
existingClient.AllowKicking = tc.AllowKicking;
|
||||
GameMain.NetLobbyScreen.SetPlayerNameAndJobPreference(existingClient);
|
||||
if (tc.CharacterID > 0)
|
||||
if (Screen.Selected != GameMain.NetLobbyScreen && tc.CharacterID > 0)
|
||||
{
|
||||
existingClient.Character = Entity.FindEntityByID(tc.CharacterID) as Character;
|
||||
if (existingClient.Character == null)
|
||||
|
||||
@@ -91,6 +91,7 @@ namespace Barotrauma.Networking
|
||||
return;
|
||||
}
|
||||
|
||||
incomingLidgrenMessages.Clear();
|
||||
netClient.ReadMessages(incomingLidgrenMessages);
|
||||
|
||||
foreach (NetIncomingMessage inc in incomingLidgrenMessages)
|
||||
@@ -107,8 +108,6 @@ namespace Barotrauma.Networking
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
incomingLidgrenMessages.Clear();
|
||||
}
|
||||
|
||||
private void HandleDataMessage(NetIncomingMessage inc)
|
||||
|
||||
@@ -49,11 +49,11 @@ namespace Barotrauma
|
||||
{
|
||||
if (!forceColor)
|
||||
{
|
||||
if (!body.Enabled)
|
||||
if (!FarseerBody.Enabled)
|
||||
{
|
||||
color = Color.Black;
|
||||
}
|
||||
else if (!body.Awake)
|
||||
else if (!FarseerBody.Awake)
|
||||
{
|
||||
color = Color.Blue;
|
||||
}
|
||||
@@ -71,7 +71,7 @@ namespace Barotrauma
|
||||
|
||||
if (drawOffset != Vector2.Zero)
|
||||
{
|
||||
Vector2 pos = ConvertUnits.ToDisplayUnits(body.Position);
|
||||
Vector2 pos = ConvertUnits.ToDisplayUnits(FarseerBody.Position);
|
||||
if (Submarine != null) pos += Submarine.DrawPosition;
|
||||
|
||||
GUI.DrawLine(spriteBatch,
|
||||
@@ -160,7 +160,7 @@ namespace Barotrauma
|
||||
|
||||
Vector2 newPosition = SimPosition;
|
||||
float? newRotation = null;
|
||||
bool awake = body.Awake;
|
||||
bool awake = FarseerBody.Awake;
|
||||
Vector2 newVelocity = LinearVelocity;
|
||||
float? newAngularVelocity = null;
|
||||
|
||||
|
||||
@@ -228,7 +228,7 @@ namespace Barotrauma
|
||||
{
|
||||
var sub = child.UserData as Submarine;
|
||||
if (sub == null) { return; }
|
||||
child.Visible = string.IsNullOrEmpty(filter) ? true : sub.Name.ToLower().Contains(filter.ToLower());
|
||||
child.Visible = string.IsNullOrEmpty(filter) ? true : sub.DisplayName.ToLower().Contains(filter.ToLower());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,7 +292,7 @@ namespace Barotrauma
|
||||
{
|
||||
var textBlock = new GUITextBlock(
|
||||
new RectTransform(new Vector2(1, 0.1f), subList.Content.RectTransform) { MinSize = new Point(0, 30) },
|
||||
ToolBox.LimitString(sub.Name, GUI.Font, subList.Rect.Width - 65), style: "ListBoxElement")
|
||||
ToolBox.LimitString(sub.DisplayName, GUI.Font, subList.Rect.Width - 65), style: "ListBoxElement")
|
||||
{
|
||||
ToolTip = sub.Description,
|
||||
UserData = sub
|
||||
|
||||
@@ -319,6 +319,14 @@ namespace Barotrauma
|
||||
|
||||
GameMain.Instance.OnResolutionChanged += () =>
|
||||
{
|
||||
foreach (GUIComponent c in Frame.GetAllChildren())
|
||||
{
|
||||
if (c.Style != null)
|
||||
{
|
||||
c.ApplySizeRestrictions(c.Style);
|
||||
}
|
||||
}
|
||||
|
||||
if (innerFrame != null)
|
||||
{
|
||||
innerFrame.RectTransform.MaxSize = new Point(int.MaxValue, GameMain.GraphicsHeight - 50);
|
||||
@@ -565,7 +573,8 @@ namespace Barotrauma
|
||||
|
||||
// Chat input
|
||||
|
||||
var chatRow = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.07f), socialHolder.RectTransform), true)
|
||||
var chatRow = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.07f), socialHolder.RectTransform),
|
||||
isHorizontal: true, childAnchor: Anchor.CenterLeft)
|
||||
{
|
||||
Stretch = true
|
||||
};
|
||||
@@ -652,9 +661,13 @@ namespace Barotrauma
|
||||
}
|
||||
};
|
||||
clientHiddenElements.Add(StartButton);
|
||||
|
||||
bottomBar.RectTransform.MinSize =
|
||||
new Point(0, (int)Math.Max(ReadyToStartBox.RectTransform.MinSize.Y / 0.75f, StartButton.RectTransform.MinSize.Y));
|
||||
GameMain.Instance.OnResolutionChanged += () =>
|
||||
{
|
||||
bottomBar.RectTransform.MinSize =
|
||||
new Point(0, (int)Math.Max(ReadyToStartBox.RectTransform.MinSize.Y / 0.75f, StartButton.RectTransform.MinSize.Y));
|
||||
};
|
||||
|
||||
//autorestart ------------------------------------------------------------------
|
||||
|
||||
@@ -700,6 +713,10 @@ namespace Barotrauma
|
||||
clientHiddenElements.Add(SettingsButton);
|
||||
|
||||
lobbyHeader.RectTransform.MinSize = new Point(0, Math.Max(ServerName.Rect.Height, SettingsButton.Rect.Height));
|
||||
GameMain.Instance.OnResolutionChanged += () =>
|
||||
{
|
||||
lobbyHeader.RectTransform.MinSize = new Point(0, Math.Max(ServerName.Rect.Height, SettingsButton.Rect.Height));
|
||||
};
|
||||
|
||||
GUILayoutGroup lobbyContent = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.9f), infoFrameContent.RectTransform), isHorizontal: true)
|
||||
{
|
||||
@@ -806,6 +823,10 @@ namespace Barotrauma
|
||||
};
|
||||
shuttleList.ListBox.RectTransform.MinSize = new Point(250, 0);
|
||||
shuttleHolder.RectTransform.MinSize = new Point(0, shuttleList.RectTransform.Children.Max(c => c.MinSize.Y));
|
||||
GameMain.Instance.OnResolutionChanged += () =>
|
||||
{
|
||||
shuttleHolder.RectTransform.MinSize = new Point(0, shuttleList.RectTransform.Children.Max(c => c.MinSize.Y));
|
||||
};
|
||||
|
||||
subPreviewContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.9f), rightColumn.RectTransform), style: null);
|
||||
subPreviewContainer.RectTransform.SizeChanged += () =>
|
||||
@@ -866,7 +887,7 @@ namespace Barotrauma
|
||||
};
|
||||
levelDifficultyScrollBar = new GUIScrollBar(new RectTransform(new Vector2(0.25f, 1.0f), miscSettingsHolder.RectTransform), style: "GUISlider", barSize: 0.2f)
|
||||
{
|
||||
Step = 0.05f,
|
||||
Step = 0.01f,
|
||||
Range = new Vector2(0.0f, 100.0f),
|
||||
ToolTip = TextManager.Get("leveldifficultyexplanation"),
|
||||
OnReleased = (scrollbar, value) =>
|
||||
@@ -883,7 +904,9 @@ namespace Barotrauma
|
||||
levelDifficultyScrollBar.OnMoved = (scrollbar, value) =>
|
||||
{
|
||||
if (EventManagerSettings.List.Count == 0) { return true; }
|
||||
difficultyName.Text = EventManagerSettings.List[Math.Min((int)Math.Floor(value * EventManagerSettings.List.Count), EventManagerSettings.List.Count - 1)].Name;
|
||||
difficultyName.Text =
|
||||
EventManagerSettings.List[Math.Min((int)Math.Floor(value * EventManagerSettings.List.Count), EventManagerSettings.List.Count - 1)].Name
|
||||
+ " (" + ((int)Math.Round(scrollbar.BarScrollValue)) + " %)";
|
||||
difficultyName.TextColor = ToolBox.GradientLerp(scrollbar.BarScroll, GUI.Style.Green, GUI.Style.Orange, GUI.Style.Red);
|
||||
return true;
|
||||
};
|
||||
@@ -944,6 +967,10 @@ namespace Barotrauma
|
||||
style: "GameModeIcon." + mode.Identifier, scaleToFit: true);
|
||||
|
||||
modeFrame.RectTransform.MinSize = new Point(0, (int)(modeContent.Children.Sum(c => c.Rect.Height + modeContent.AbsoluteSpacing) / modeContent.RectTransform.RelativeSize.Y));
|
||||
GameMain.Instance.OnResolutionChanged += () =>
|
||||
{
|
||||
modeFrame.RectTransform.MinSize = new Point(0, (int)(modeContent.Children.Sum(c => c.Rect.Height + modeContent.AbsoluteSpacing) / modeContent.RectTransform.RelativeSize.Y));
|
||||
};
|
||||
}
|
||||
|
||||
var gameModeSpecificFrame = new GUIFrame(new RectTransform(new Vector2(0.333f, 1.0f), gameModeBackground.RectTransform), style: null);
|
||||
@@ -1286,6 +1313,8 @@ namespace Barotrauma
|
||||
if (GameMain.Client == null) return;
|
||||
spectateButton.Visible = true;
|
||||
spectateButton.Enabled = true;
|
||||
|
||||
StartButton.Visible = false;
|
||||
}
|
||||
|
||||
public void SetCampaignCharacterInfo(CharacterInfo newCampaignCharacterInfo)
|
||||
@@ -1482,17 +1511,17 @@ namespace Barotrauma
|
||||
|
||||
private void CreateJobVariantTooltip(JobPrefab jobPrefab, int variant, GUIComponent parentSlot)
|
||||
{
|
||||
jobVariantTooltip = new GUIFrame(new RectTransform(new Point((int)(500 * GUI.Scale), (int)(200 * GUI.Scale)), GUI.Canvas, pivot: Pivot.TopRight),
|
||||
jobVariantTooltip = new GUIFrame(new RectTransform(new Point((int)(500 * GUI.Scale), (int)(200 * GUI.Scale)), GUI.Canvas, pivot: Pivot.BottomRight),
|
||||
style: "GUIToolTip")
|
||||
{
|
||||
UserData = new Pair<JobPrefab, int>(jobPrefab, variant)
|
||||
};
|
||||
jobVariantTooltip.RectTransform.AbsoluteOffset = new Point(parentSlot.Rect.Right, parentSlot.Rect.Bottom);
|
||||
jobVariantTooltip.RectTransform.AbsoluteOffset = new Point(parentSlot.Rect.Right, parentSlot.Rect.Y);
|
||||
|
||||
var content = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.95f), jobVariantTooltip.RectTransform, Anchor.Center))
|
||||
{
|
||||
Stretch = true,
|
||||
RelativeSpacing = 0.02f
|
||||
AbsoluteSpacing = (int)(15 * GUI.Scale)
|
||||
};
|
||||
|
||||
string name =
|
||||
@@ -1506,10 +1535,18 @@ namespace Barotrauma
|
||||
"";
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), content.RectTransform), description, wrap: true, font: GUI.SmallFont);
|
||||
new GUICustomComponent(new RectTransform(new Vector2(1.0f, 0.3f), content.RectTransform, Anchor.BottomLeft),
|
||||
onDraw: (sb, component) => { DrawJobVariantItems(sb, component, new Pair<JobPrefab, int>(jobPrefab, variant)); });
|
||||
|
||||
jobVariantTooltip.RectTransform.MinSize = new Point(0, content.RectTransform.Children.Sum(c => c.Rect.Height));
|
||||
var itemIdentifiers = jobPrefab.ItemIdentifiers[variant]
|
||||
.Distinct()
|
||||
.Where(id => jobPrefab.ShowItemPreview[variant][id]);
|
||||
|
||||
int itemsPerRow = 5;
|
||||
int rows = (int)Math.Max(Math.Ceiling(itemIdentifiers.Count() / (float)itemsPerRow), 1);
|
||||
|
||||
new GUICustomComponent(new RectTransform(new Vector2(1.0f, 0.4f * rows), content.RectTransform, Anchor.BottomLeft),
|
||||
onDraw: (sb, component) => { DrawJobVariantItems(sb, component, new Pair<JobPrefab, int>(jobPrefab, variant), itemsPerRow); });
|
||||
|
||||
jobVariantTooltip.RectTransform.MinSize = new Point(0, content.RectTransform.Children.Sum(c => c.Rect.Height + content.AbsoluteSpacing));
|
||||
}
|
||||
|
||||
public bool ToggleSpectate(GUITickBox tickBox)
|
||||
@@ -2302,7 +2339,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawJobVariantItems(SpriteBatch spriteBatch, GUICustomComponent component, Pair<JobPrefab, int> jobPrefab)
|
||||
private void DrawJobVariantItems(SpriteBatch spriteBatch, GUICustomComponent component, Pair<JobPrefab, int> jobPrefab, int itemsPerRow)
|
||||
{
|
||||
var itemIdentifiers = jobPrefab.First.ItemIdentifiers[jobPrefab.Second]
|
||||
.Distinct()
|
||||
@@ -2311,18 +2348,29 @@ namespace Barotrauma
|
||||
Point slotSize = new Point(component.Rect.Height);
|
||||
int spacing = (int)(5 * GUI.Scale);
|
||||
int slotCount = itemIdentifiers.Count();
|
||||
int slotCountPerRow = Math.Min(slotCount, itemsPerRow);
|
||||
int rows = (int)Math.Max(Math.Ceiling(itemIdentifiers.Count() / (float)itemsPerRow), 1);
|
||||
|
||||
float totalWidth = slotSize.X * slotCount + spacing * (slotCount - 1);
|
||||
float totalWidth = slotSize.X * slotCountPerRow + spacing * (slotCountPerRow - 1);
|
||||
float totalHeight = slotSize.Y * rows + spacing * (rows - 1);
|
||||
if (totalWidth > component.Rect.Width)
|
||||
{
|
||||
slotSize = slotSize.Multiply(component.Rect.Width / totalWidth);
|
||||
slotSize = new Point(
|
||||
Math.Min((int)Math.Floor((slotSize.X - spacing) * (component.Rect.Width / totalWidth)),
|
||||
(int)Math.Floor((slotSize.Y - spacing) * (component.Rect.Height / totalHeight))));
|
||||
}
|
||||
int i = 0;
|
||||
Rectangle tooltipRect = Rectangle.Empty;
|
||||
string tooltip = null;
|
||||
foreach (string itemIdentifier in itemIdentifiers)
|
||||
{
|
||||
if (!(MapEntityPrefab.Find(null, identifier: itemIdentifier, showErrorMessages: false) is ItemPrefab itemPrefab)) { continue; }
|
||||
|
||||
Vector2 slotPos = new Vector2(component.Rect.X + (slotSize.X + spacing) * i, component.Rect.Center.Y - slotSize.Y / 2);
|
||||
int row = (int)Math.Floor(i / (float)slotCountPerRow);
|
||||
int slotsPerThisRow = Math.Min((slotCount - row * slotCountPerRow), slotCountPerRow);
|
||||
Vector2 slotPos = new Vector2(
|
||||
component.Rect.Center.X + (slotSize.X + spacing) * (i % slotCountPerRow - slotsPerThisRow * 0.5f),
|
||||
component.Rect.Bottom - (rows * (slotSize.Y + spacing)) + (slotSize.Y + spacing) * row);
|
||||
|
||||
Rectangle slotRect = new Rectangle(slotPos.ToPoint(), slotSize);
|
||||
Inventory.SlotSpriteSmall.Draw(spriteBatch, slotPos,
|
||||
@@ -2342,10 +2390,15 @@ namespace Barotrauma
|
||||
|
||||
if (slotRect.Contains(PlayerInput.MousePosition))
|
||||
{
|
||||
GUIComponent.DrawToolTip(spriteBatch, itemPrefab.Name + '\n' + itemPrefab.Description, slotRect);
|
||||
tooltipRect = slotRect;
|
||||
tooltip = itemPrefab.Name + '\n' + itemPrefab.Description;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(tooltip))
|
||||
{
|
||||
GUIComponent.DrawToolTip(spriteBatch, tooltip, tooltipRect);
|
||||
}
|
||||
}
|
||||
|
||||
public void NewChatMessage(ChatMessage message)
|
||||
@@ -2754,7 +2807,7 @@ namespace Barotrauma
|
||||
GUIFrame innerFrame = null;
|
||||
List<JobPrefab.OutfitPreview> outfitPreviews = jobPrefab.GetJobOutfitSprites(Gender.Male, useInventoryIcon: true, out var maxDimensions);
|
||||
|
||||
innerFrame = new GUIFrame(new RectTransform(Vector2.One * 0.8f, parent.RectTransform, Anchor.Center), style: null)
|
||||
innerFrame = new GUIFrame(new RectTransform(Vector2.One * 0.85f, parent.RectTransform, Anchor.Center), style: null)
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
@@ -2781,11 +2834,18 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.35f), parent.RectTransform, Anchor.BottomCenter), style: "OuterGlow")
|
||||
{
|
||||
Color = Color.Black,
|
||||
HoverColor = Color.Black,
|
||||
SelectedColor = Color.Black
|
||||
};
|
||||
|
||||
var textBlock = new GUITextBlock(
|
||||
innerFrame.CountChildren == 0 ?
|
||||
new RectTransform(Vector2.One, parent.RectTransform, Anchor.Center) :
|
||||
new RectTransform(new Vector2(selectedByPlayer ? 0.65f : 0.95f, 0.3f), parent.RectTransform, Anchor.TopCenter),
|
||||
jobPrefab.Name, wrap: true, textAlignment: Alignment.TopCenter)
|
||||
new RectTransform(new Vector2(selectedByPlayer ? 0.65f : 0.95f, 0.3f), parent.RectTransform, Anchor.BottomCenter),
|
||||
jobPrefab.Name, wrap: true, textAlignment: Alignment.BottomCenter)
|
||||
{
|
||||
Padding = Vector4.Zero,
|
||||
HoverColor = Color.Transparent,
|
||||
@@ -2794,6 +2854,7 @@ namespace Barotrauma
|
||||
CanBeFocused = false,
|
||||
AutoScaleHorizontal = true
|
||||
};
|
||||
textBlock.TextAlignment = textBlock.WrappedText.Contains('\n') ? Alignment.BottomCenter : Alignment.Center;
|
||||
textBlock.RectTransform.SizeChanged += () => { textBlock.TextScale = 1.0f; };
|
||||
|
||||
return retVal;
|
||||
@@ -3043,7 +3104,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
// Info button
|
||||
new GUIButton(new RectTransform(new Vector2(0.15f), slot.RectTransform, Anchor.TopLeft, scaleBasis: ScaleBasis.BothWidth) { RelativeOffset = new Vector2(0.05f) },
|
||||
new GUIButton(new RectTransform(new Vector2(0.15f), slot.RectTransform, Anchor.BottomLeft, scaleBasis: ScaleBasis.BothWidth) { RelativeOffset = new Vector2(0.075f) },
|
||||
style: "GUIButtonInfo")
|
||||
{
|
||||
UserData = jobPrefab,
|
||||
@@ -3051,7 +3112,7 @@ namespace Barotrauma
|
||||
};
|
||||
|
||||
// Remove button
|
||||
new GUIButton(new RectTransform(new Vector2(0.15f), slot.RectTransform, Anchor.TopRight, scaleBasis: ScaleBasis.BothWidth) { RelativeOffset = new Vector2(0.05f) },
|
||||
new GUIButton(new RectTransform(new Vector2(0.15f), slot.RectTransform, Anchor.BottomRight, scaleBasis: ScaleBasis.BothWidth) { RelativeOffset = new Vector2(0.075f) },
|
||||
style: "GUICancelButton")
|
||||
{
|
||||
UserData = i,
|
||||
@@ -3105,7 +3166,7 @@ namespace Barotrauma
|
||||
{
|
||||
float relativeSize = 0.2f;
|
||||
|
||||
var btn = new GUIButton(new RectTransform(new Vector2(relativeSize), slot.RectTransform, Anchor.BottomCenter, scaleBasis: ScaleBasis.BothHeight)
|
||||
var btn = new GUIButton(new RectTransform(new Vector2(relativeSize), slot.RectTransform, Anchor.TopCenter, scaleBasis: ScaleBasis.BothHeight)
|
||||
{ RelativeOffset = new Vector2(relativeSize * 1.05f * (variantIndex - (variantCount - 1) / 2.0f), 0.02f) },
|
||||
(variantIndex + 1).ToString(), style: "JobVariantButton")
|
||||
{
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma</Product>
|
||||
<Version>0.9.705.0</Version>
|
||||
<Version>0.9.707.0</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>Barotrauma</AssemblyName>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma</Product>
|
||||
<Version>0.9.705.0</Version>
|
||||
<Version>0.9.707.0</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>Barotrauma</AssemblyName>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma</Product>
|
||||
<Version>0.9.705.0</Version>
|
||||
<Version>0.9.707.0</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>Barotrauma</AssemblyName>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma Dedicated Server</Product>
|
||||
<Version>0.9.705.0</Version>
|
||||
<Version>0.9.707.0</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>DedicatedServer</AssemblyName>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma Dedicated Server</Product>
|
||||
<Version>0.9.705.0</Version>
|
||||
<Version>0.9.707.0</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>DedicatedServer</AssemblyName>
|
||||
|
||||
@@ -283,6 +283,15 @@ namespace Barotrauma
|
||||
GameMain.NetLobbyScreen.SetBotCount(botCount);
|
||||
NewMessage("Set the number of bots to " + botCount, Color.White);
|
||||
});
|
||||
AssignOnClientRequestExecute("botcount", (Client client, Vector2 cursorPos, string[] args) =>
|
||||
{
|
||||
if (args.Length < 1 || GameMain.Server == null) return;
|
||||
int botCount = GameMain.Server.ServerSettings.BotCount;
|
||||
int.TryParse(args[0], out botCount);
|
||||
GameMain.NetLobbyScreen.SetBotCount(botCount);
|
||||
NewMessage(client.Name + " set the number of bots to " + botCount, Color.White);
|
||||
GameMain.Server.SendConsoleMessage("Set the number of bots to " + botCount, client);
|
||||
});
|
||||
|
||||
AssignOnExecute("botspawnmode", (string[] args) =>
|
||||
{
|
||||
@@ -297,6 +306,20 @@ namespace Barotrauma
|
||||
NewMessage("\"" + args[0] + "\" is not a valid bot spawn mode. (Valid modes are Fill and Normal)", Color.White);
|
||||
}
|
||||
});
|
||||
AssignOnClientRequestExecute("botspawnmode", (Client client, Vector2 cursorPos, string[] args) =>
|
||||
{
|
||||
if (args.Length < 1 || GameMain.Server == null) return;
|
||||
if (Enum.TryParse(args[0], true, out BotSpawnMode spawnMode))
|
||||
{
|
||||
GameMain.NetLobbyScreen.SetBotSpawnMode(spawnMode);
|
||||
NewMessage(client.Name + " set bot spawn mode to " + spawnMode, Color.White);
|
||||
GameMain.Server.SendConsoleMessage("Set bot spawn mode to " + spawnMode, client);
|
||||
}
|
||||
else
|
||||
{
|
||||
GameMain.Server.SendConsoleMessage("\"" + args[0] + "\" is not a valid bot spawn mode. (Valid modes are Fill and Normal)", client);
|
||||
}
|
||||
});
|
||||
|
||||
AssignOnExecute("killdisconnectedtimer", (string[] args) =>
|
||||
{
|
||||
@@ -304,13 +327,29 @@ namespace Barotrauma
|
||||
float seconds = GameMain.Server.ServerSettings.KillDisconnectedTime;
|
||||
if (float.TryParse(args[0], out seconds))
|
||||
{
|
||||
NewMessage("Set kill disconnected timer to " + seconds + " seconds", Color.White);
|
||||
seconds = Math.Max(0, seconds);
|
||||
NewMessage("Set kill disconnected timer to " + ToolBox.SecondsToReadableTime(seconds), Color.White);
|
||||
}
|
||||
else
|
||||
{
|
||||
NewMessage("\"" + args[0] + "\" is not a valid duration.", Color.White);
|
||||
}
|
||||
});
|
||||
AssignOnClientRequestExecute("killdisconnectedtimer", (Client client, Vector2 cursorPos, string[] args) =>
|
||||
{
|
||||
if (args.Length < 1 || GameMain.Server == null) return;
|
||||
float seconds = GameMain.Server.ServerSettings.KillDisconnectedTime;
|
||||
if (float.TryParse(args[0], out seconds))
|
||||
{
|
||||
seconds = Math.Max(0, seconds);
|
||||
GameMain.Server.SendConsoleMessage("Set kill disconnected timer to " + ToolBox.SecondsToReadableTime(seconds), client);
|
||||
NewMessage(client.Name + " set kill disconnected timer to " + ToolBox.SecondsToReadableTime(seconds), Color.White);
|
||||
}
|
||||
else
|
||||
{
|
||||
GameMain.Server.SendConsoleMessage("\"" + args[0] + "\" is not a valid duration.", client);
|
||||
}
|
||||
});
|
||||
|
||||
AssignOnExecute("autorestart", (string[] args) =>
|
||||
{
|
||||
@@ -329,10 +368,6 @@ namespace Barotrauma
|
||||
if (GameMain.Server.ServerSettings.AutoRestartInterval <= 0) GameMain.Server.ServerSettings.AutoRestartInterval = 10;
|
||||
GameMain.Server.ServerSettings.AutoRestartTimer = GameMain.Server.ServerSettings.AutoRestartInterval;
|
||||
GameMain.Server.ServerSettings.AutoRestart = enabled;
|
||||
#if CLIENT
|
||||
//TODO: reimplement
|
||||
GameMain.NetLobbyScreen.SetAutoRestart(enabled, GameMain.Server.AutoRestartTimer);
|
||||
#endif
|
||||
GameMain.NetLobbyScreen.LastUpdateID++;
|
||||
}
|
||||
NewMessage(GameMain.Server.ServerSettings.AutoRestart ? "Automatic restart enabled." : "Automatic restart disabled.", Color.White);
|
||||
@@ -357,10 +392,6 @@ namespace Barotrauma
|
||||
GameMain.Server.ServerSettings.AutoRestart = false;
|
||||
NewMessage("Autorestart disabled.", Color.White);
|
||||
}
|
||||
#if CLIENT
|
||||
//TODO: redo again
|
||||
GameMain.NetLobbyScreen.SetAutoRestart(GameMain.Server.AutoRestart, GameMain.Server.AutoRestartTimer);
|
||||
#endif
|
||||
GameMain.NetLobbyScreen.LastUpdateID++;
|
||||
}
|
||||
}
|
||||
@@ -677,6 +708,13 @@ namespace Barotrauma
|
||||
GameMain.Server.ServerSettings.KarmaEnabled = !GameMain.Server.ServerSettings.KarmaEnabled;
|
||||
NewMessage(GameMain.Server.ServerSettings.KarmaEnabled ? "Karma system enabled." : "Karma system disabled.", Color.LightGreen);
|
||||
});
|
||||
AssignOnClientRequestExecute("togglekarma", (Client client, Vector2 cursorWorldPos, string[] args) =>
|
||||
{
|
||||
if (GameMain.Server == null) return;
|
||||
GameMain.Server.ServerSettings.KarmaEnabled = !GameMain.Server.ServerSettings.KarmaEnabled;
|
||||
NewMessage((GameMain.Server.ServerSettings.KarmaEnabled ? "Karma system enabled by " : "Karma system disabled by ") + client.Name, Color.LightGreen);
|
||||
GameMain.Server.SendConsoleMessage(GameMain.Server.ServerSettings.KarmaEnabled ? "Karma system enabled." : "Karma system disabled.", client);
|
||||
});
|
||||
|
||||
AssignOnExecute("resetkarma", (string[] args) =>
|
||||
{
|
||||
|
||||
@@ -91,7 +91,10 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
existingWire.RemoveConnection(item);
|
||||
item.GetComponent<ConnectionPanel>()?.DisconnectedWires.Add(existingWire);
|
||||
if (existingWire.Item.ParentInventory == null)
|
||||
{
|
||||
item.GetComponent<ConnectionPanel>()?.DisconnectedWires.Add(existingWire);
|
||||
}
|
||||
|
||||
if (!wires.Any(w => w.Contains(existingWire)))
|
||||
{
|
||||
@@ -103,8 +106,14 @@ namespace Barotrauma.Items.Components
|
||||
GameServer.Log(c.Character.LogName + " disconnected a wire from " +
|
||||
Connections[i].Item.Name + " (" + Connections[i].Name + ")", ServerLog.MessageType.Wiring);
|
||||
|
||||
if (!clientSideDisconnectedWires.Contains(existingWire))
|
||||
if (existingWire.Item.ParentInventory != null)
|
||||
{
|
||||
//in an inventory and not connected to anything -> the wire cannot have any nodes
|
||||
existingWire.ClearConnections();
|
||||
}
|
||||
else if (!clientSideDisconnectedWires.Contains(existingWire))
|
||||
{
|
||||
//not in an inventory, not connected to anything, not hanging loose from any panel -> must be dropped
|
||||
existingWire.Item.Drop(c.Character);
|
||||
}
|
||||
}
|
||||
@@ -145,7 +154,8 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (disconnectedWire.Connections[0] == null &&
|
||||
disconnectedWire.Connections[1] == null &&
|
||||
!clientSideDisconnectedWires.Contains(disconnectedWire))
|
||||
!clientSideDisconnectedWires.Contains(disconnectedWire) &&
|
||||
disconnectedWire.Item.ParentInventory == null)
|
||||
{
|
||||
disconnectedWire.Item.Drop(c.Character);
|
||||
GameServer.Log(c.Character.LogName + " dropped " + disconnectedWire.Name, ServerLog.MessageType.Inventory);
|
||||
|
||||
@@ -627,7 +627,7 @@ namespace Barotrauma.Networking
|
||||
//game already started -> send start message immediately
|
||||
if (gameStarted)
|
||||
{
|
||||
SendStartMessage(roundStartSeed, Submarine.MainSub, GameMain.GameSession.GameMode.Preset, connectedClient);
|
||||
SendStartMessage(roundStartSeed, GameMain.GameSession.Level.Seed, Submarine.MainSub, GameMain.GameSession.GameMode.Preset, connectedClient, true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1796,6 +1796,8 @@ namespace Barotrauma.Networking
|
||||
campaign.Map.SelectRandomLocation(preferUndiscovered: true);
|
||||
}
|
||||
|
||||
SendStartMessage(roundStartSeed, campaign.Map.SelectedConnection.Level.Seed, Submarine.MainSub, GameMain.GameSession.GameMode.Preset, connectedClients, false);
|
||||
|
||||
GameMain.GameSession.StartRound(campaign.Map.SelectedConnection.Level,
|
||||
reloadSub: true,
|
||||
loadSecondSub: teamCount > 1,
|
||||
@@ -1808,6 +1810,8 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
else
|
||||
{
|
||||
SendStartMessage(roundStartSeed, GameMain.NetLobbyScreen.LevelSeed, Submarine.MainSub, GameMain.GameSession.GameMode.Preset, connectedClients, false);
|
||||
|
||||
GameMain.GameSession.StartRound(GameMain.NetLobbyScreen.LevelSeed, serverSettings.SelectedLevelDifficulty, teamCount > 1);
|
||||
Log("Game mode: " + selectedMode.Name, ServerLog.MessageType.ServerMessage);
|
||||
Log("Submarine: " + selectedSub.Name, ServerLog.MessageType.ServerMessage);
|
||||
@@ -1946,7 +1950,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
GameAnalyticsManager.AddDesignEvent("Traitors:" + (TraitorManager == null ? "Disabled" : "Enabled"));
|
||||
|
||||
SendStartMessage(roundStartSeed, Submarine.MainSub, GameMain.GameSession.GameMode.Preset, connectedClients);
|
||||
SendRoundStartFinalize(connectedClients);
|
||||
|
||||
yield return CoroutineStatus.Running;
|
||||
|
||||
@@ -1965,22 +1969,21 @@ namespace Barotrauma.Networking
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
|
||||
private void SendStartMessage(int seed, Submarine selectedSub, GameModePreset selectedMode, List<Client> clients)
|
||||
private void SendStartMessage(int seed, string levelSeed, Submarine selectedSub, GameModePreset selectedMode, List<Client> clients, bool includesFinalize)
|
||||
{
|
||||
foreach (Client client in clients)
|
||||
{
|
||||
SendStartMessage(seed, selectedSub, selectedMode, client);
|
||||
SendStartMessage(seed, levelSeed, selectedSub, selectedMode, client, includesFinalize);
|
||||
}
|
||||
}
|
||||
|
||||
private void SendStartMessage(int seed, Submarine selectedSub, GameModePreset selectedMode, Client client)
|
||||
private void SendStartMessage(int seed, string levelSeed, Submarine selectedSub, GameModePreset selectedMode, Client client, bool includesFinalize)
|
||||
{
|
||||
IWriteMessage msg = new WriteOnlyMessage();
|
||||
msg.Write((byte)ServerPacketHeader.STARTGAME);
|
||||
|
||||
msg.Write(seed);
|
||||
msg.Write(GameMain.GameSession.Level.Seed);
|
||||
msg.Write(GameMain.GameSession.Level.EqualityCheckVal);
|
||||
msg.Write(levelSeed);
|
||||
msg.Write(serverSettings.SelectedLevelDifficulty);
|
||||
|
||||
msg.Write((byte)GameMain.Config.LosMode);
|
||||
@@ -2020,6 +2023,32 @@ namespace Barotrauma.Networking
|
||||
|
||||
serverSettings.WriteMonsterEnabled(msg);
|
||||
|
||||
msg.Write(includesFinalize); msg.WritePadBits();
|
||||
if (includesFinalize)
|
||||
{
|
||||
msg.Write(GameMain.GameSession.Level.EqualityCheckVal);
|
||||
GameMain.GameSession.Mission?.ServerWriteInitial(msg, client);
|
||||
}
|
||||
|
||||
//GameMain.GameSession.Mission?.ServerWriteInitial(msg, client);
|
||||
|
||||
serverPeer.Send(msg, client.Connection, DeliveryMethod.Reliable);
|
||||
}
|
||||
|
||||
private void SendRoundStartFinalize(List<Client> clients)
|
||||
{
|
||||
foreach (Client client in clients)
|
||||
{
|
||||
SendRoundStartFinalize(client);
|
||||
}
|
||||
}
|
||||
|
||||
private void SendRoundStartFinalize(Client client)
|
||||
{
|
||||
IWriteMessage msg = new WriteOnlyMessage();
|
||||
msg.Write((byte)ServerPacketHeader.STARTGAMEFINALIZE);
|
||||
|
||||
msg.Write(GameMain.GameSession.Level.EqualityCheckVal);
|
||||
GameMain.GameSession.Mission?.ServerWriteInitial(msg, client);
|
||||
|
||||
serverPeer.Send(msg, client.Connection, DeliveryMethod.Reliable);
|
||||
|
||||
@@ -184,29 +184,25 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
XDocument doc = new XDocument(new XElement("serversettings"));
|
||||
|
||||
SerializableProperty.SerializeProperties(this, doc.Root, true);
|
||||
|
||||
doc.Root.SetAttributeValue("name", ServerName);
|
||||
doc.Root.SetAttributeValue("public", IsPublic);
|
||||
doc.Root.SetAttributeValue("port", Port);
|
||||
#if USE_STEAM
|
||||
doc.Root.SetAttributeValue("queryport", QueryPort);
|
||||
#endif
|
||||
doc.Root.SetAttributeValue("password", password ?? "");
|
||||
|
||||
doc.Root.SetAttributeValue("enableupnp", EnableUPnP);
|
||||
|
||||
doc.Root.SetAttributeValue("autorestart", autoRestart);
|
||||
|
||||
if (!string.IsNullOrEmpty(password))
|
||||
{
|
||||
doc.Root.SetAttributeValue("password", password);
|
||||
}
|
||||
|
||||
doc.Root.SetAttributeValue("LevelDifficulty", ((int)selectedLevelDifficulty).ToString());
|
||||
|
||||
|
||||
doc.Root.SetAttributeValue("ServerMessage", ServerMessageText);
|
||||
|
||||
doc.Root.SetAttributeValue("AllowedRandomMissionTypes", string.Join(",", AllowedRandomMissionTypes));
|
||||
doc.Root.SetAttributeValue("AllowedClientNameChars", string.Join(",", AllowedClientNameChars.Select(c => c.First + "-" + c.Second)));
|
||||
|
||||
doc.Root.SetAttributeValue("ServerMessage", ServerMessageText);
|
||||
|
||||
SerializableProperty.SerializeProperties(this, doc.Root, true);
|
||||
|
||||
XmlWriterSettings settings = new XmlWriterSettings
|
||||
{
|
||||
|
||||
@@ -15,10 +15,10 @@ namespace Barotrauma
|
||||
msg.Write(SimPosition.Y);
|
||||
|
||||
#if DEBUG
|
||||
if (Math.Abs(body.LinearVelocity.X) > MaxVel ||
|
||||
Math.Abs(body.LinearVelocity.Y) > MaxVel)
|
||||
if (Math.Abs(FarseerBody.LinearVelocity.X) > MaxVel ||
|
||||
Math.Abs(FarseerBody.LinearVelocity.Y) > MaxVel)
|
||||
{
|
||||
DebugConsole.ThrowError("Item velocity out of range (" + body.LinearVelocity + ")");
|
||||
DebugConsole.ThrowError("Item velocity out of range (" + FarseerBody.LinearVelocity + ")");
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -27,20 +27,20 @@ namespace Barotrauma
|
||||
|
||||
if (!FarseerBody.FixedRotation)
|
||||
{
|
||||
msg.WriteRangedSingle(MathUtils.WrapAngleTwoPi(body.Rotation), 0.0f, MathHelper.TwoPi, 8);
|
||||
msg.WriteRangedSingle(MathUtils.WrapAngleTwoPi(FarseerBody.Rotation), 0.0f, MathHelper.TwoPi, 8);
|
||||
}
|
||||
if (FarseerBody.Awake)
|
||||
{
|
||||
body.Enabled = true;
|
||||
body.LinearVelocity = new Vector2(
|
||||
MathHelper.Clamp(body.LinearVelocity.X, -MaxVel, MaxVel),
|
||||
MathHelper.Clamp(body.LinearVelocity.Y, -MaxVel, MaxVel));
|
||||
msg.WriteRangedSingle(body.LinearVelocity.X, -MaxVel, MaxVel, 12);
|
||||
msg.WriteRangedSingle(body.LinearVelocity.Y, -MaxVel, MaxVel, 12);
|
||||
FarseerBody.Enabled = true;
|
||||
FarseerBody.LinearVelocity = new Vector2(
|
||||
MathHelper.Clamp(FarseerBody.LinearVelocity.X, -MaxVel, MaxVel),
|
||||
MathHelper.Clamp(FarseerBody.LinearVelocity.Y, -MaxVel, MaxVel));
|
||||
msg.WriteRangedSingle(FarseerBody.LinearVelocity.X, -MaxVel, MaxVel, 12);
|
||||
msg.WriteRangedSingle(FarseerBody.LinearVelocity.Y, -MaxVel, MaxVel, 12);
|
||||
if (!FarseerBody.FixedRotation)
|
||||
{
|
||||
body.AngularVelocity = MathHelper.Clamp(body.AngularVelocity, -MaxAngularVel, MaxAngularVel);
|
||||
msg.WriteRangedSingle(body.AngularVelocity, -MaxAngularVel, MaxAngularVel, 8);
|
||||
FarseerBody.AngularVelocity = MathHelper.Clamp(FarseerBody.AngularVelocity, -MaxAngularVel, MaxAngularVel);
|
||||
msg.WriteRangedSingle(FarseerBody.AngularVelocity, -MaxAngularVel, MaxAngularVel, 8);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma Dedicated Server</Product>
|
||||
<Version>0.9.705.0</Version>
|
||||
<Version>0.9.707.0</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>DedicatedServer</AssemblyName>
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
<Item file="Content/Items/Materials/medmaterials.xml" />
|
||||
<Item file="Content/Items/Materials/minerals.xml" />
|
||||
<Item file="Content/Items/Medical/medical.xml" />
|
||||
<Item file="Content/Items/Medical/poisons.xml" />
|
||||
<Item file="Content/Items/Medical/buffs.xml" />
|
||||
<Item file="Content/Items/Misc/misc.xml" />
|
||||
<Item file="Content/Items/OxygenGenerator/oxygengenerator.xml" />
|
||||
<Item file="Content/Items/Pump/pump.xml" />
|
||||
|
||||
@@ -20,13 +20,7 @@ namespace Barotrauma
|
||||
class Order
|
||||
{
|
||||
public static Dictionary<string, Order> Prefabs { get; private set; }
|
||||
public static Dictionary<OrderCategory, Sprite> OrderCategoryIcons { get; private set; }
|
||||
public static Sprite StartNode { get; private set; }
|
||||
public static Sprite ShortcutNode { get; private set; }
|
||||
public static Sprite ExpandNode { get; private set; }
|
||||
public static Sprite NodeContainer { get; private set; }
|
||||
public static Sprite HotkeyContainer { get; private set; }
|
||||
public static Sprite CommandBackground { get; private set; }
|
||||
public static Dictionary<OrderCategory, Tuple<Sprite, Color>> OrderCategoryIcons { get; private set; }
|
||||
public static List<Order> PrefabList { get; private set; }
|
||||
public static Order GetPrefab(string identifier)
|
||||
{
|
||||
@@ -52,7 +46,30 @@ namespace Barotrauma
|
||||
|
||||
public readonly string Identifier;
|
||||
|
||||
public readonly Color Color;
|
||||
private Color? color;
|
||||
public Color Color
|
||||
{
|
||||
get
|
||||
{
|
||||
if (color.HasValue)
|
||||
{
|
||||
return color.Value;
|
||||
}
|
||||
else if (OrderCategoryIcons.TryGetValue(Category, out Tuple<Sprite, Color> sprite))
|
||||
{
|
||||
return sprite.Item2;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Color.White;
|
||||
}
|
||||
}
|
||||
private set
|
||||
{
|
||||
color = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//if true, the order is issued to all available characters
|
||||
public bool TargetAllCharacters;
|
||||
@@ -80,7 +97,7 @@ namespace Barotrauma
|
||||
static Order()
|
||||
{
|
||||
Prefabs = new Dictionary<string, Order>();
|
||||
OrderCategoryIcons = new Dictionary<OrderCategory, Sprite>();
|
||||
OrderCategoryIcons = new Dictionary<OrderCategory, Tuple<Sprite, Color>>();
|
||||
|
||||
foreach (ContentFile file in GameMain.Instance.GetFilesOfType(ContentType.Orders))
|
||||
{
|
||||
@@ -125,7 +142,7 @@ namespace Barotrauma
|
||||
else if (name.Equals("ordercategory", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var category = (OrderCategory)Enum.Parse(typeof(OrderCategory), element.GetAttributeString("category", "undefined"), true);
|
||||
if (OrderCategoryIcons.TryGetValue(category, out Sprite duplicate))
|
||||
if (OrderCategoryIcons.ContainsKey(category))
|
||||
{
|
||||
if (allowOverriding || sourceElement.IsOverride())
|
||||
{
|
||||
@@ -142,35 +159,8 @@ namespace Barotrauma
|
||||
if (spriteElement != null)
|
||||
{
|
||||
var sprite = new Sprite(spriteElement, lazyLoad: true);
|
||||
OrderCategoryIcons.Add(category, sprite);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var spriteElement = element.GetChildElement("sprite");
|
||||
if (spriteElement != null)
|
||||
{
|
||||
switch (name.ToLowerInvariant())
|
||||
{
|
||||
case "startnode":
|
||||
StartNode = new Sprite(spriteElement, lazyLoad: true);
|
||||
break;
|
||||
case "shortcutnode":
|
||||
ShortcutNode = new Sprite(spriteElement, lazyLoad: true);
|
||||
break;
|
||||
case "expandnode":
|
||||
ExpandNode = new Sprite(spriteElement, lazyLoad: true);
|
||||
break;
|
||||
case "nodecontainer":
|
||||
NodeContainer = new Sprite(spriteElement, lazyLoad: true);
|
||||
break;
|
||||
case "hotkeycontainer":
|
||||
HotkeyContainer = new Sprite(spriteElement, lazyLoad: true);
|
||||
break;
|
||||
case "commandbackground":
|
||||
CommandBackground = new Sprite(spriteElement, lazyLoad: true);
|
||||
break;
|
||||
}
|
||||
var color = element.GetAttributeColor("color", Color.White);
|
||||
OrderCategoryIcons.Add(category, new Tuple<Sprite, Color>(sprite, color));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -201,7 +191,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
ItemIdentifiers = orderElement.GetAttributeStringArray("targetitemidentifiers", new string[0], trim: true, convertToLowerInvariant: true);
|
||||
Color = orderElement.GetAttributeColor("color", Color.White);
|
||||
color = orderElement.GetAttributeColor("color");
|
||||
FadeOutTime = orderElement.GetAttributeFloat("fadeouttime", 0.0f);
|
||||
UseController = orderElement.GetAttributeBool("usecontroller", false);
|
||||
TargetAllCharacters = orderElement.GetAttributeBool("targetallcharacters", false);
|
||||
@@ -271,6 +261,7 @@ namespace Barotrauma
|
||||
AppropriateJobs = prefab.AppropriateJobs;
|
||||
FadeOutTime = prefab.FadeOutTime;
|
||||
Weight = prefab.Weight;
|
||||
Category = prefab.Category;
|
||||
OrderGiver = orderGiver;
|
||||
|
||||
TargetEntity = targetEntity;
|
||||
@@ -300,22 +291,22 @@ namespace Barotrauma
|
||||
}
|
||||
for (int i = 0; i < AppropriateJobs.Length; i++)
|
||||
{
|
||||
if (character.Info.Job.Prefab.Identifier.ToLowerInvariant() == AppropriateJobs[i].ToLowerInvariant()) return true;
|
||||
if (character.Info.Job.Prefab.Identifier.ToLowerInvariant() == AppropriateJobs[i].ToLowerInvariant()) { return true; }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public string GetChatMessage(string targetCharacterName, string targetRoomName, bool givingOrderToSelf, string orderOption = "")
|
||||
{
|
||||
orderOption = orderOption ?? "";
|
||||
orderOption ??= "";
|
||||
|
||||
string messageTag = (givingOrderToSelf && !TargetAllCharacters ? "OrderDialogSelf." : "OrderDialog.") + Identifier;
|
||||
if (!string.IsNullOrEmpty(orderOption)) messageTag += "." + orderOption;
|
||||
if (!string.IsNullOrEmpty(orderOption)) { messageTag += "." + orderOption; }
|
||||
|
||||
if (targetCharacterName == null) targetCharacterName = "";
|
||||
if (targetRoomName == null) targetRoomName = "";
|
||||
if (targetCharacterName == null) { targetCharacterName = ""; }
|
||||
if (targetRoomName == null) { targetRoomName = ""; }
|
||||
string msg = TextManager.GetWithVariables(messageTag, new string[2] { "[name]", "[roomname]" }, new string[2] { targetCharacterName, targetRoomName }, new bool[2] { false, true }, true);
|
||||
if (msg == null) return "";
|
||||
if (msg == null) { return ""; }
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
@@ -78,8 +78,12 @@ namespace Barotrauma
|
||||
if (frozen == value) return;
|
||||
|
||||
frozen = value;
|
||||
|
||||
Collider.PhysEnabled = !frozen;
|
||||
|
||||
Collider.FarseerBody.LinearDamping = frozen ? (1.5f / (float)Timing.Step) : 0.0f;
|
||||
Collider.FarseerBody.AngularDamping = frozen ? (1.5f / (float)Timing.Step) : 0.0f;
|
||||
Collider.FarseerBody.IgnoreGravity = frozen;
|
||||
|
||||
//Collider.PhysEnabled = !frozen;
|
||||
if (frozen && MainLimb != null) MainLimb.PullJointWorldAnchorB = MainLimb.SimPosition;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,15 +312,7 @@ namespace Barotrauma
|
||||
selectedCharacter.selectedBy = null;
|
||||
selectedCharacter = value;
|
||||
if (selectedCharacter != null)
|
||||
{
|
||||
selectedCharacter.selectedBy = this;
|
||||
#if CLIENT
|
||||
if (Inventory != null)
|
||||
{
|
||||
Inventory.ToggleInventory(true);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1269,7 +1269,7 @@ namespace Barotrauma
|
||||
{
|
||||
//if the command is not defined client-side, we'll relay it anyway because it may be a custom command at the server's side
|
||||
GameMain.Client.SendConsoleCommand(command);
|
||||
NewMessage("Server command: " + command, Color.White);
|
||||
NewMessage("Server command: " + command, Color.Cyan);
|
||||
return;
|
||||
}
|
||||
else if (GameMain.Client.HasConsoleCommandPermission(splitCommand[0].ToLowerInvariant()))
|
||||
@@ -1277,7 +1277,7 @@ namespace Barotrauma
|
||||
if (matchingCommand.RelayToServer)
|
||||
{
|
||||
GameMain.Client.SendConsoleCommand(command);
|
||||
NewMessage("Server command: " + command, Color.White);
|
||||
NewMessage("Server command: " + command, Color.Cyan);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1424,8 +1424,6 @@ namespace Barotrauma
|
||||
var variant = job != null ? Rand.Range(0, job.Variants, Rand.RandSync.Server) : 0;
|
||||
CharacterInfo characterInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: job, variant: variant);
|
||||
spawnedCharacter = Character.Create(characterInfo, spawnPosition, ToolBox.RandomSeed(8));
|
||||
spawnedCharacter.GiveJobItems(spawnPoint);
|
||||
|
||||
if (GameMain.GameSession != null)
|
||||
{
|
||||
if (GameMain.GameSession.GameMode != null && !GameMain.GameSession.GameMode.IsSinglePlayer)
|
||||
@@ -1437,6 +1435,7 @@ namespace Barotrauma
|
||||
GameMain.GameSession.CrewManager.AddCharacter(spawnedCharacter);
|
||||
#endif
|
||||
}
|
||||
spawnedCharacter.GiveJobItems(spawnPoint);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace Barotrauma
|
||||
get { return activeEvents; }
|
||||
}
|
||||
|
||||
public EventManager(GameSession session)
|
||||
public EventManager()
|
||||
{
|
||||
isClient = GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient;
|
||||
}
|
||||
@@ -70,21 +70,9 @@ namespace Barotrauma
|
||||
pendingEventSets.Clear();
|
||||
selectedEvents.Clear();
|
||||
|
||||
var suitableSettings = EventManagerSettings.List.FindAll(s =>
|
||||
level.Difficulty >= s.MinLevelDifficulty &&
|
||||
level.Difficulty <= s.MaxLevelDifficulty);
|
||||
|
||||
if (suitableSettings.Count == 0)
|
||||
{
|
||||
DebugConsole.ThrowError("No suitable event manager settings found for the selected level (difficulty " + level.Difficulty + ")");
|
||||
settings = EventManagerSettings.List[Rand.Int(EventManagerSettings.List.Count, Rand.RandSync.Server)];
|
||||
}
|
||||
else
|
||||
{
|
||||
settings = suitableSettings[Rand.Int(suitableSettings.Count, Rand.RandSync.Server)];
|
||||
}
|
||||
|
||||
this.level = level;
|
||||
SelectSettings();
|
||||
|
||||
var initialEventSet = SelectRandomEvents(ScriptedEventSet.List);
|
||||
if (initialEventSet != null)
|
||||
{
|
||||
@@ -102,6 +90,32 @@ namespace Barotrauma
|
||||
eventCoolDown = 0.0f;
|
||||
}
|
||||
|
||||
private void SelectSettings()
|
||||
{
|
||||
if (EventManagerSettings.List.Count == 0)
|
||||
{
|
||||
throw new InvalidOperationException("Could not select EventManager settings (no settings loaded).");
|
||||
}
|
||||
if (level == null)
|
||||
{
|
||||
throw new InvalidOperationException("Could not select EventManager settings (level not set).");
|
||||
}
|
||||
|
||||
var suitableSettings = EventManagerSettings.List.FindAll(s =>
|
||||
level.Difficulty >= s.MinLevelDifficulty &&
|
||||
level.Difficulty <= s.MaxLevelDifficulty);
|
||||
|
||||
if (suitableSettings.Count == 0)
|
||||
{
|
||||
DebugConsole.ThrowError("No suitable event manager settings found for the selected level (difficulty " + level.Difficulty + ")");
|
||||
settings = EventManagerSettings.List[Rand.Int(EventManagerSettings.List.Count, Rand.RandSync.Server)];
|
||||
}
|
||||
else
|
||||
{
|
||||
settings = suitableSettings[Rand.Int(suitableSettings.Count, Rand.RandSync.Server)];
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<ContentFile> GetFilesToPreload()
|
||||
{
|
||||
foreach (List<ScriptedEvent> eventList in selectedEvents.Values)
|
||||
@@ -310,6 +324,18 @@ namespace Barotrauma
|
||||
|
||||
roundDuration += deltaTime;
|
||||
|
||||
if (settings == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Event settings not set before updating EventManager. Attempting to select...");
|
||||
SelectSettings();
|
||||
if (settings == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Could not select EventManager settings. Disabling EventManager for the round...");
|
||||
Enabled = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
eventThreshold += settings.EventThresholdIncrease * deltaTime;
|
||||
if (eventCoolDown > 0.0f)
|
||||
{
|
||||
|
||||
@@ -17,9 +17,18 @@ namespace Barotrauma.Extensions
|
||||
/// <summary>
|
||||
/// Randomizes the list in place.
|
||||
/// </summary>
|
||||
public static void RandomizeList<T>(this List<T> source)
|
||||
public static void RandomizeList<T>(this List<T> list)
|
||||
{
|
||||
source.Sort((x, y) => Rand.Value().CompareTo(Rand.Value()));
|
||||
//Fisher-Yates shuffle
|
||||
int n = list.Count;
|
||||
while (n > 1)
|
||||
{
|
||||
n--;
|
||||
int k = Rand.Int(n + 1);
|
||||
T value = list[k];
|
||||
list[k] = list[n];
|
||||
list[n] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static T GetRandom<T>(this IEnumerable<T> source, Func<T, bool> predicate, Rand.RandSync randSync = Rand.RandSync.Unsynced)
|
||||
|
||||
@@ -82,7 +82,8 @@ namespace Barotrauma
|
||||
// Another pass for items with containers because also they can spawn inside other items (like smg magazine)
|
||||
prefabsWithContainer.ForEach(i => SpawnItems(i));
|
||||
// Spawn items that don't have containers last
|
||||
prefabsWithoutContainer.Randomize().ForEach(i => SpawnItems(i));
|
||||
prefabsWithoutContainer.RandomizeList();
|
||||
prefabsWithoutContainer.ForEach(i => SpawnItems(i));
|
||||
|
||||
if (OutputDebugInfo)
|
||||
{
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace Barotrauma
|
||||
Submarine.MainSub = submarine;
|
||||
this.Submarine = submarine;
|
||||
GameMain.GameSession = this;
|
||||
EventManager = new EventManager(this);
|
||||
EventManager = new EventManager();
|
||||
this.SavePath = savePath;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ namespace Barotrauma
|
||||
|
||||
partial class CharacterInventory : Inventory
|
||||
{
|
||||
private const int hotkeyCount = 5;
|
||||
private Character character;
|
||||
|
||||
public InvSlotType[] SlotTypes
|
||||
@@ -53,7 +52,16 @@ namespace Barotrauma
|
||||
{
|
||||
DebugConsole.ThrowError("Error in the inventory config of \"" + character.SpeciesName + "\" - " + slotTypeNames[i] + " is not a valid inventory slot type.");
|
||||
}
|
||||
SlotTypes[i] = parsedSlotType;
|
||||
SlotTypes[i] = parsedSlotType;
|
||||
switch (SlotTypes[i])
|
||||
{
|
||||
//case InvSlotType.Head:
|
||||
//case InvSlotType.OuterClothes:
|
||||
case InvSlotType.LeftHand:
|
||||
case InvSlotType.RightHand:
|
||||
hideEmptySlot[i] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
InitProjSpecific(element);
|
||||
@@ -122,25 +130,25 @@ namespace Barotrauma
|
||||
/// <summary>
|
||||
/// If there is no room in the generic inventory (InvSlotType.Any), check if the item can be auto-equipped into its respective limbslot
|
||||
/// </summary>
|
||||
public bool TryPutItemWithAutoEquipCheck(Item item, Character user, List<InvSlotType> allowedSlots = null, bool createNetworkEvent = true, bool preferNonHotkeys = false)
|
||||
public bool TryPutItemWithAutoEquipCheck(Item item, Character user, List<InvSlotType> allowedSlots = null, bool createNetworkEvent = true)
|
||||
{
|
||||
// Does not auto-equip the item if specified and no suitable any slot found (for example handcuffs are not auto-equipped)
|
||||
if (item.AllowedSlots.Contains(InvSlotType.Any))
|
||||
{
|
||||
var wearable = item.GetComponent<Wearable>();
|
||||
if (wearable != null && !wearable.AutoEquipWhenFull && CheckIfAnySlotAvailable(item, false, preferNonHotkeys) == -1)
|
||||
if (wearable != null && !wearable.AutoEquipWhenFull && CheckIfAnySlotAvailable(item, false) == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return TryPutItem(item, user, allowedSlots, createNetworkEvent, preferNonHotkeys);
|
||||
return TryPutItem(item, user, allowedSlots, createNetworkEvent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If there is room, puts the item in the inventory and returns true, otherwise returns false
|
||||
/// </summary>
|
||||
public override bool TryPutItem(Item item, Character user, List<InvSlotType> allowedSlots = null, bool createNetworkEvent = true, bool preferNonHotkeys = false)
|
||||
public override bool TryPutItem(Item item, Character user, List<InvSlotType> allowedSlots = null, bool createNetworkEvent = true)
|
||||
{
|
||||
if (allowedSlots == null || !allowedSlots.Any()) return false;
|
||||
|
||||
@@ -164,7 +172,7 @@ namespace Barotrauma
|
||||
//try to place the item in a LimbSlot.Any slot if that's allowed
|
||||
if (allowedSlots.Contains(InvSlotType.Any) && item.AllowedSlots.Contains(InvSlotType.Any))
|
||||
{
|
||||
int freeIndex = CheckIfAnySlotAvailable(item, inWrongSlot, preferNonHotkeys);
|
||||
int freeIndex = CheckIfAnySlotAvailable(item, inWrongSlot);
|
||||
if (freeIndex > -1)
|
||||
{
|
||||
PutItem(item, freeIndex, user, true, createNetworkEvent);
|
||||
@@ -207,7 +215,12 @@ namespace Barotrauma
|
||||
#if CLIENT
|
||||
if (PersonalSlots.HasFlag(SlotTypes[i])) { hidePersonalSlots = false; }
|
||||
#endif
|
||||
bool removeFromOtherSlots = item.ParentInventory != this || (placedInSlot == -1 && inWrongSlot);
|
||||
bool removeFromOtherSlots = item.ParentInventory != this;
|
||||
if (placedInSlot == -1 && inWrongSlot)
|
||||
{
|
||||
if (!hideEmptySlot[i] || SlotTypes[currentSlot] != InvSlotType.Any) removeFromOtherSlots = true;
|
||||
}
|
||||
|
||||
PutItem(item, i, user, removeFromOtherSlots, createNetworkEvent);
|
||||
item.Equip(character);
|
||||
placedInSlot = i;
|
||||
@@ -219,19 +232,16 @@ namespace Barotrauma
|
||||
return placedInSlot > -1;
|
||||
}
|
||||
|
||||
public int CheckIfAnySlotAvailable(Item item, bool inWrongSlot, bool preferNonHotkeys)
|
||||
public int CheckIfAnySlotAvailable(Item item, bool inWrongSlot)
|
||||
{
|
||||
for (int i = 0; i < capacity; i++)
|
||||
{
|
||||
if (SlotTypes[i] != InvSlotType.Any) continue;
|
||||
if (Items[i] == item)
|
||||
for (int i = 0; i < capacity; i++)
|
||||
{
|
||||
return i;
|
||||
if (SlotTypes[i] != InvSlotType.Any) continue;
|
||||
if (Items[i] == item)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!preferNonHotkeys)
|
||||
{
|
||||
for (int i = 0; i < capacity; i++)
|
||||
{
|
||||
if (SlotTypes[i] != InvSlotType.Any) continue;
|
||||
@@ -246,45 +256,11 @@ namespace Barotrauma
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int hotkeysCounted = 0;
|
||||
// First go through non-hotkeyed slots
|
||||
for (int i = 0; i < capacity; i++)
|
||||
{
|
||||
if (SlotTypes[i] != InvSlotType.Any) continue;
|
||||
hotkeysCounted++;
|
||||
|
||||
if (hotkeysCounted <= hotkeyCount) continue;
|
||||
|
||||
if (inWrongSlot)
|
||||
{
|
||||
if (Items[i] != item && Items[i] != null) continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Items[i] != null) continue;
|
||||
}
|
||||
|
||||
#if CLIENT
|
||||
if (!inventoryOpen)
|
||||
{
|
||||
ToggleInventory();
|
||||
}
|
||||
#endif
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
// Then redo with no preference
|
||||
return CheckIfAnySlotAvailable(item, inWrongSlot, false);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public override bool TryPutItem(Item item, int index, bool allowSwapping, bool allowCombine, Character user, bool createNetworkEvent = true, bool avoidHotkeys = false)
|
||||
public override bool TryPutItem(Item item, int index, bool allowSwapping, bool allowCombine, Character user, bool createNetworkEvent = true)
|
||||
{
|
||||
if (index < 0 || index >= Items.Length)
|
||||
{
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public virtual bool OnPicked(Character picker)
|
||||
{
|
||||
if (picker.Inventory.TryPutItemWithAutoEquipCheck(item, picker, allowedSlots, true, true))
|
||||
if (picker.Inventory.TryPutItemWithAutoEquipCheck(item, picker, allowedSlots))
|
||||
{
|
||||
if (!picker.HasSelectedItem(item) && item.body != null) item.body.Enabled = false;
|
||||
this.picker = picker;
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private string prevSignal;
|
||||
|
||||
[Serialize(Character.TeamType.None, false, description: "WiFi components can only communicate with components that have the same Team ID.")]
|
||||
[Serialize(Character.TeamType.None, true, description: "WiFi components can only communicate with components that have the same Team ID.")]
|
||||
public Character.TeamType TeamID { get; set; }
|
||||
|
||||
[Editable, Serialize(20000.0f, false, description: "How close the recipient has to be to receive a signal from this WiFi component.")]
|
||||
|
||||
@@ -190,7 +190,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
if (newNodeIndex == 0)
|
||||
if (newNodeIndex == 0 && nodes.Count > 1)
|
||||
{
|
||||
nodes.Insert(0, nodePos);
|
||||
}
|
||||
@@ -499,7 +499,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearConnections(Character user = null)
|
||||
public void ClearConnections(Character user = null)
|
||||
{
|
||||
nodes.Clear();
|
||||
sections.Clear();
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace Barotrauma
|
||||
protected readonly int capacity;
|
||||
|
||||
public Item[] Items;
|
||||
protected bool[] hideEmptySlot;
|
||||
|
||||
public bool Locked;
|
||||
|
||||
@@ -31,6 +32,7 @@ namespace Barotrauma
|
||||
this.Owner = owner;
|
||||
|
||||
Items = new Item[capacity];
|
||||
hideEmptySlot = new bool[capacity];
|
||||
|
||||
#if CLIENT
|
||||
this.slotsPerRow = slotsPerRow;
|
||||
@@ -39,8 +41,15 @@ namespace Barotrauma
|
||||
{
|
||||
DraggableIndicator = GUI.Style.GetComponentStyle("GUIDragIndicator").Sprites[GUIComponent.ComponentState.None][0].Sprite;
|
||||
|
||||
EquipIndicator = new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(137, 10, 112, 25), new Vector2(0.5f, 1f), 0);
|
||||
EquipIndicator.size = new Vector2(EquipIndicator.SourceRect.Width * 0.682f, EquipIndicator.SourceRect.Height * 0.682f);
|
||||
slotHotkeySprite = new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(258, 7, 120, 120), null, 0);
|
||||
|
||||
EquippedIndicator = new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(550, 137, 87, 16), new Vector2(0.5f, 0.5f), 0);
|
||||
EquippedHoverIndicator = new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(550, 157, 87, 16), new Vector2(0.5f, 0.5f), 0);
|
||||
EquippedClickedIndicator = new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(550, 177, 87, 16), new Vector2(0.5f, 0.5f), 0);
|
||||
|
||||
UnequippedIndicator = new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(550, 197, 87, 16), new Vector2(0.5f, 0.5f), 0);
|
||||
UnequippedHoverIndicator = new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(550, 217, 87, 16), new Vector2(0.5f, 0.5f), 0);
|
||||
UnequippedClickedIndicator = new Sprite("Content/UI/InventoryUIAtlas.png", new Rectangle(550, 237, 87, 16), new Vector2(0.5f, 0.5f), 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -102,7 +111,7 @@ namespace Barotrauma
|
||||
/// <summary>
|
||||
/// If there is room, puts the item in the inventory and returns true, otherwise returns false
|
||||
/// </summary>
|
||||
public virtual bool TryPutItem(Item item, Character user, List<InvSlotType> allowedSlots = null, bool createNetworkEvent = true, bool avoidHotkeys = false)
|
||||
public virtual bool TryPutItem(Item item, Character user, List<InvSlotType> allowedSlots = null, bool createNetworkEvent = true)
|
||||
{
|
||||
int slot = FindAllowedSlot(item);
|
||||
if (slot < 0) return false;
|
||||
@@ -111,7 +120,7 @@ namespace Barotrauma
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual bool TryPutItem(Item item, int i, bool allowSwapping, bool allowCombine, Character user, bool createNetworkEvent = true, bool avoidHotkeys = false)
|
||||
public virtual bool TryPutItem(Item item, int i, bool allowSwapping, bool allowCombine, Character user, bool createNetworkEvent = true)
|
||||
{
|
||||
if (i < 0 || i >= Items.Length)
|
||||
{
|
||||
|
||||
@@ -1986,7 +1986,14 @@ namespace Barotrauma
|
||||
body.ResetDynamics();
|
||||
if (dropper != null)
|
||||
{
|
||||
body.SetTransform(dropper.SimPosition, 0.0f);
|
||||
if (body.Removed)
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to drop the item \"" + Name + "\" (body has been removed).");
|
||||
}
|
||||
else
|
||||
{
|
||||
body.SetTransform(dropper.SimPosition, 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,9 +47,9 @@ namespace Barotrauma
|
||||
return (item != null && Items[i] == null && container.CanBeContained(item));
|
||||
}
|
||||
|
||||
public override bool TryPutItem(Item item, Character user, List<InvSlotType> allowedSlots = null, bool createNetworkEvent = true, bool preferNonHotkeys = false)
|
||||
public override bool TryPutItem(Item item, Character user, List<InvSlotType> allowedSlots = null, bool createNetworkEvent = true)
|
||||
{
|
||||
bool wasPut = base.TryPutItem(item, user, allowedSlots, createNetworkEvent, preferNonHotkeys);
|
||||
bool wasPut = base.TryPutItem(item, user, allowedSlots, createNetworkEvent);
|
||||
|
||||
if (wasPut)
|
||||
{
|
||||
@@ -68,9 +68,9 @@ namespace Barotrauma
|
||||
return wasPut;
|
||||
}
|
||||
|
||||
public override bool TryPutItem(Item item, int i, bool allowSwapping, bool allowCombine, Character user, bool createNetworkEvent = true, bool preferNonHotkeys = false)
|
||||
public override bool TryPutItem(Item item, int i, bool allowSwapping, bool allowCombine, Character user, bool createNetworkEvent = true)
|
||||
{
|
||||
bool wasPut = base.TryPutItem(item, i, allowSwapping, allowCombine, user, createNetworkEvent, preferNonHotkeys);
|
||||
bool wasPut = base.TryPutItem(item, i, allowSwapping, allowCombine, user, createNetworkEvent);
|
||||
|
||||
if (wasPut)
|
||||
{
|
||||
|
||||
@@ -60,6 +60,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
QUERY_STARTGAME, //ask the clients whether they're ready to start
|
||||
STARTGAME, //start a new round
|
||||
STARTGAMEFINALIZE, //finalize round initialization
|
||||
ENDGAME,
|
||||
|
||||
TRAITOR_MESSAGE,
|
||||
|
||||
@@ -88,14 +88,13 @@ namespace Barotrauma
|
||||
Circle, Rectangle, Capsule, HorizontalCapsule
|
||||
};
|
||||
|
||||
private static List<PhysicsBody> list = new List<PhysicsBody>();
|
||||
private static readonly List<PhysicsBody> list = new List<PhysicsBody>();
|
||||
public static List<PhysicsBody> List
|
||||
{
|
||||
get { return list; }
|
||||
}
|
||||
|
||||
//the farseer physics body of the item
|
||||
private Body body;
|
||||
|
||||
protected Vector2 prevPosition;
|
||||
protected float prevRotation;
|
||||
|
||||
@@ -105,6 +104,12 @@ namespace Barotrauma
|
||||
private Vector2 drawPosition;
|
||||
private float drawRotation;
|
||||
|
||||
public bool Removed
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public Vector2 LastSentPosition
|
||||
{
|
||||
get;
|
||||
@@ -114,7 +119,7 @@ namespace Barotrauma
|
||||
private Shape bodyShape;
|
||||
public float height, width, radius;
|
||||
|
||||
private float density;
|
||||
private readonly float density;
|
||||
|
||||
//the direction the item is facing (for example, a gun has to be
|
||||
//flipped horizontally if the Character holding it turns around)
|
||||
@@ -198,7 +203,7 @@ namespace Barotrauma
|
||||
isEnabled = value;
|
||||
try
|
||||
{
|
||||
if (isEnabled) body.Enabled = isPhysEnabled; else body.Enabled = false;
|
||||
if (isEnabled) FarseerBody.Enabled = isPhysEnabled; else FarseerBody.Enabled = false;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -206,7 +211,7 @@ namespace Barotrauma
|
||||
if (UserData != null) DebugConsole.NewMessage("PhysicsBody UserData: " + UserData.GetType().ToString(), Color.Red);
|
||||
if (GameMain.World.ContactManager == null) DebugConsole.NewMessage("ContactManager is null!", Color.Red);
|
||||
else if (GameMain.World.ContactManager.BroadPhase == null) DebugConsole.NewMessage("Broadphase is null!", Color.Red);
|
||||
if (body.FixtureList == null) DebugConsole.NewMessage("FixtureList is null!", Color.Red);
|
||||
if (FarseerBody.FixtureList == null) DebugConsole.NewMessage("FixtureList is null!", Color.Red);
|
||||
|
||||
if (UserData is Entity entity)
|
||||
{
|
||||
@@ -218,18 +223,18 @@ namespace Barotrauma
|
||||
|
||||
public bool PhysEnabled
|
||||
{
|
||||
get { return body.Enabled; }
|
||||
set { isPhysEnabled = value; if (Enabled) body.Enabled = value; }
|
||||
get { return FarseerBody.Enabled; }
|
||||
set { isPhysEnabled = value; if (Enabled) FarseerBody.Enabled = value; }
|
||||
}
|
||||
|
||||
public Vector2 SimPosition
|
||||
{
|
||||
get { return body.Position; }
|
||||
get { return FarseerBody.Position; }
|
||||
}
|
||||
|
||||
public Vector2 Position
|
||||
{
|
||||
get { return ConvertUnits.ToDisplayUnits(body.Position); }
|
||||
get { return ConvertUnits.ToDisplayUnits(FarseerBody.Position); }
|
||||
}
|
||||
|
||||
public Vector2 PrevPosition
|
||||
@@ -239,7 +244,7 @@ namespace Barotrauma
|
||||
|
||||
public float Rotation
|
||||
{
|
||||
get { return body.Rotation; }
|
||||
get { return FarseerBody.Rotation; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -249,27 +254,27 @@ namespace Barotrauma
|
||||
|
||||
public Vector2 LinearVelocity
|
||||
{
|
||||
get { return body.LinearVelocity; }
|
||||
get { return FarseerBody.LinearVelocity; }
|
||||
set
|
||||
{
|
||||
if (!IsValidValue(value, "velocity", -1000.0f, 1000.0f)) return;
|
||||
body.LinearVelocity = value;
|
||||
FarseerBody.LinearVelocity = value;
|
||||
}
|
||||
}
|
||||
|
||||
public float AngularVelocity
|
||||
{
|
||||
get { return body.AngularVelocity; }
|
||||
get { return FarseerBody.AngularVelocity; }
|
||||
set
|
||||
{
|
||||
if (!IsValidValue(value, "angular velocity", -1000f, 1000f)) return;
|
||||
body.AngularVelocity = value;
|
||||
FarseerBody.AngularVelocity = value;
|
||||
}
|
||||
}
|
||||
|
||||
public float Mass
|
||||
{
|
||||
get { return body.Mass; }
|
||||
get { return FarseerBody.Mass; }
|
||||
}
|
||||
|
||||
public float Density
|
||||
@@ -277,36 +282,33 @@ namespace Barotrauma
|
||||
get { return density; }
|
||||
}
|
||||
|
||||
public Body FarseerBody
|
||||
{
|
||||
get { return body; }
|
||||
}
|
||||
public Body FarseerBody { get; private set; }
|
||||
|
||||
public object UserData
|
||||
{
|
||||
get { return body.UserData; }
|
||||
set { body.UserData = value; }
|
||||
get { return FarseerBody.UserData; }
|
||||
set { FarseerBody.UserData = value; }
|
||||
}
|
||||
|
||||
public float Friction
|
||||
{
|
||||
set { body.Friction = value; }
|
||||
set { FarseerBody.Friction = value; }
|
||||
}
|
||||
|
||||
public BodyType BodyType
|
||||
{
|
||||
get { return body.BodyType; }
|
||||
set { body.BodyType = value; }
|
||||
get { return FarseerBody.BodyType; }
|
||||
set { FarseerBody.BodyType = value; }
|
||||
}
|
||||
|
||||
public Category CollisionCategories
|
||||
{
|
||||
set { body.CollisionCategories = value; }
|
||||
set { FarseerBody.CollisionCategories = value; }
|
||||
}
|
||||
|
||||
public Category CollidesWith
|
||||
{
|
||||
set { body.CollidesWith = value; }
|
||||
set { FarseerBody.CollidesWith = value; }
|
||||
}
|
||||
|
||||
public PhysicsBody(XElement element, float scale = 1.0f) : this(element, Vector2.Zero, scale) { }
|
||||
@@ -316,15 +318,15 @@ namespace Barotrauma
|
||||
public PhysicsBody(float width, float height, float radius, float density)
|
||||
{
|
||||
CreateBody(width, height, radius, density);
|
||||
LastSentPosition = body.Position;
|
||||
LastSentPosition = FarseerBody.Position;
|
||||
list.Add(this);
|
||||
}
|
||||
|
||||
public PhysicsBody(Body farseerBody)
|
||||
{
|
||||
body = farseerBody;
|
||||
if (body.UserData == null) body.UserData = this;
|
||||
LastSentPosition = body.Position;
|
||||
FarseerBody = farseerBody;
|
||||
if (FarseerBody.UserData == null) FarseerBody.UserData = this;
|
||||
LastSentPosition = FarseerBody.Position;
|
||||
list.Add(this);
|
||||
}
|
||||
|
||||
@@ -335,13 +337,13 @@ namespace Barotrauma
|
||||
float width = ConvertUnits.ToSimUnits(colliderParams.Width) * colliderParams.Ragdoll.LimbScale;
|
||||
density = 10;
|
||||
CreateBody(width, height, radius, density);
|
||||
body.BodyType = BodyType.Dynamic;
|
||||
body.CollidesWith = Physics.CollisionWall | Physics.CollisionLevel;
|
||||
body.CollisionCategories = Physics.CollisionCharacter;
|
||||
body.AngularDamping = 5.0f;
|
||||
body.FixedRotation = true;
|
||||
body.Friction = 0.05f;
|
||||
body.Restitution = 0.05f;
|
||||
FarseerBody.BodyType = BodyType.Dynamic;
|
||||
FarseerBody.CollidesWith = Physics.CollisionWall | Physics.CollisionLevel;
|
||||
FarseerBody.CollisionCategories = Physics.CollisionCharacter;
|
||||
FarseerBody.AngularDamping = 5.0f;
|
||||
FarseerBody.FixedRotation = true;
|
||||
FarseerBody.Friction = 0.05f;
|
||||
FarseerBody.Restitution = 0.05f;
|
||||
SetTransformIgnoreContacts(position, 0.0f);
|
||||
LastSentPosition = position;
|
||||
list.Add(this);
|
||||
@@ -354,13 +356,13 @@ namespace Barotrauma
|
||||
float width = ConvertUnits.ToSimUnits(limbParams.Width) * limbParams.Ragdoll.LimbScale;
|
||||
density = limbParams.Density;
|
||||
CreateBody(width, height, radius, density);
|
||||
body.BodyType = BodyType.Dynamic;
|
||||
body.CollidesWith = Physics.CollisionWall | Physics.CollisionLevel;
|
||||
body.CollisionCategories = Physics.CollisionItem;
|
||||
body.Friction = limbParams.Friction;
|
||||
body.Restitution = limbParams.Restitution;
|
||||
body.AngularDamping = limbParams.AngularDamping;
|
||||
body.UserData = this;
|
||||
FarseerBody.BodyType = BodyType.Dynamic;
|
||||
FarseerBody.CollidesWith = Physics.CollisionWall | Physics.CollisionLevel;
|
||||
FarseerBody.CollisionCategories = Physics.CollisionItem;
|
||||
FarseerBody.Friction = limbParams.Friction;
|
||||
FarseerBody.Restitution = limbParams.Restitution;
|
||||
FarseerBody.AngularDamping = limbParams.AngularDamping;
|
||||
FarseerBody.UserData = this;
|
||||
SetTransformIgnoreContacts(position, 0.0f);
|
||||
LastSentPosition = position;
|
||||
list.Add(this);
|
||||
@@ -374,12 +376,12 @@ namespace Barotrauma
|
||||
density = element.GetAttributeFloat("density", 10.0f);
|
||||
CreateBody(width, height, radius, density);
|
||||
//Enum.TryParse(element.GetAttributeString("bodytype", "Dynamic"), out BodyType bodyType);
|
||||
body.BodyType = BodyType.Dynamic;
|
||||
body.CollisionCategories = Physics.CollisionItem;
|
||||
body.CollidesWith = Physics.CollisionWall | Physics.CollisionLevel | Physics.CollisionPlatform;
|
||||
body.Friction = element.GetAttributeFloat("friction", 0.3f);
|
||||
body.Restitution = element.GetAttributeFloat("restitution", 0.05f);
|
||||
body.UserData = this;
|
||||
FarseerBody.BodyType = BodyType.Dynamic;
|
||||
FarseerBody.CollisionCategories = Physics.CollisionItem;
|
||||
FarseerBody.CollidesWith = Physics.CollisionWall | Physics.CollisionLevel | Physics.CollisionPlatform;
|
||||
FarseerBody.Friction = element.GetAttributeFloat("friction", 0.3f);
|
||||
FarseerBody.Restitution = element.GetAttributeFloat("restitution", 0.05f);
|
||||
FarseerBody.UserData = this;
|
||||
SetTransformIgnoreContacts(position, 0.0f);
|
||||
LastSentPosition = position;
|
||||
list.Add(this);
|
||||
@@ -393,16 +395,16 @@ namespace Barotrauma
|
||||
switch (bodyShape)
|
||||
{
|
||||
case Shape.Capsule:
|
||||
body = GameMain.World.CreateCapsule(height, radius, density);
|
||||
FarseerBody = GameMain.World.CreateCapsule(height, radius, density);
|
||||
break;
|
||||
case Shape.HorizontalCapsule:
|
||||
body = GameMain.World.CreateCapsuleHorizontal(width, radius, density);
|
||||
FarseerBody = GameMain.World.CreateCapsuleHorizontal(width, radius, density);
|
||||
break;
|
||||
case Shape.Circle:
|
||||
body = GameMain.World.CreateCircle(radius, density);
|
||||
FarseerBody = GameMain.World.CreateCircle(radius, density);
|
||||
break;
|
||||
case Shape.Rectangle:
|
||||
body = GameMain.World.CreateRectangle(width, height, density);
|
||||
FarseerBody = GameMain.World.CreateRectangle(width, height, density);
|
||||
break;
|
||||
default:
|
||||
throw new NotImplementedException(bodyShape.ToString());
|
||||
@@ -567,15 +569,15 @@ namespace Barotrauma
|
||||
|
||||
public void ResetDynamics()
|
||||
{
|
||||
body.ResetDynamics();
|
||||
FarseerBody.ResetDynamics();
|
||||
}
|
||||
|
||||
public void ApplyLinearImpulse(Vector2 impulse)
|
||||
{
|
||||
if (!IsValidValue(impulse / body.Mass, "new velocity", -1000f, 1000f)) return;
|
||||
if (!IsValidValue(impulse / FarseerBody.Mass, "new velocity", -1000f, 1000f)) return;
|
||||
if (!IsValidValue(impulse, "impulse", -1e10f, 1e10f)) return;
|
||||
|
||||
body.ApplyLinearImpulse(impulse);
|
||||
FarseerBody.ApplyLinearImpulse(impulse);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -587,24 +589,24 @@ namespace Barotrauma
|
||||
if (!IsValidValue(maxVelocity, "max velocity")) return;
|
||||
|
||||
Vector2 velocityAddition = impulse / Mass;
|
||||
Vector2 newVelocity = body.LinearVelocity + velocityAddition;
|
||||
Vector2 newVelocity = FarseerBody.LinearVelocity + velocityAddition;
|
||||
float newSpeedSqr = newVelocity.LengthSquared();
|
||||
if (newSpeedSqr > maxVelocity * maxVelocity)
|
||||
{
|
||||
newVelocity = newVelocity.ClampLength(maxVelocity);
|
||||
}
|
||||
|
||||
if (!IsValidValue((newVelocity - body.LinearVelocity), "new velocity", -1000.0f, 1000.0f)) return;
|
||||
if (!IsValidValue((newVelocity - FarseerBody.LinearVelocity), "new velocity", -1000.0f, 1000.0f)) return;
|
||||
|
||||
body.ApplyLinearImpulse((newVelocity - body.LinearVelocity) * Mass);
|
||||
FarseerBody.ApplyLinearImpulse((newVelocity - FarseerBody.LinearVelocity) * Mass);
|
||||
}
|
||||
|
||||
public void ApplyLinearImpulse(Vector2 impulse, Vector2 point)
|
||||
{
|
||||
if (!IsValidValue(impulse, "impulse", -1e10f, 1e10f)) return;
|
||||
if (!IsValidValue(point, "point")) return;
|
||||
if (!IsValidValue(impulse / body.Mass, "new velocity", -1000.0f, 1000.0f)) return;
|
||||
body.ApplyLinearImpulse(impulse, point);
|
||||
if (!IsValidValue(impulse / FarseerBody.Mass, "new velocity", -1000.0f, 1000.0f)) return;
|
||||
FarseerBody.ApplyLinearImpulse(impulse, point);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -617,18 +619,18 @@ namespace Barotrauma
|
||||
if (!IsValidValue(maxVelocity, "max velocity")) return;
|
||||
|
||||
Vector2 velocityAddition = impulse / Mass;
|
||||
Vector2 newVelocity = body.LinearVelocity + velocityAddition;
|
||||
Vector2 newVelocity = FarseerBody.LinearVelocity + velocityAddition;
|
||||
float newSpeedSqr = newVelocity.LengthSquared();
|
||||
if (newSpeedSqr > maxVelocity * maxVelocity)
|
||||
{
|
||||
newVelocity = newVelocity.ClampLength(maxVelocity);
|
||||
}
|
||||
|
||||
if (!IsValidValue((newVelocity - body.LinearVelocity), "new velocity", -1000.0f, 1000.0f)) return;
|
||||
if (!IsValidValue((newVelocity - FarseerBody.LinearVelocity), "new velocity", -1000.0f, 1000.0f)) return;
|
||||
|
||||
body.ApplyLinearImpulse((newVelocity - body.LinearVelocity) * Mass, point);
|
||||
body.AngularVelocity = MathHelper.Clamp(
|
||||
body.AngularVelocity,
|
||||
FarseerBody.ApplyLinearImpulse((newVelocity - FarseerBody.LinearVelocity) * Mass, point);
|
||||
FarseerBody.AngularVelocity = MathHelper.Clamp(
|
||||
FarseerBody.AngularVelocity,
|
||||
-NetConfig.MaxPhysicsBodyAngularVelocity,
|
||||
NetConfig.MaxPhysicsBodyAngularVelocity);
|
||||
}
|
||||
@@ -636,7 +638,7 @@ namespace Barotrauma
|
||||
public void ApplyForce(Vector2 force)
|
||||
{
|
||||
if (!IsValidValue(force, "force", -1e10f, 1e10f)) return;
|
||||
body.ApplyForce(force);
|
||||
FarseerBody.ApplyForce(force);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -647,10 +649,10 @@ namespace Barotrauma
|
||||
if (!IsValidValue(maxVelocity, "max velocity")) return;
|
||||
|
||||
Vector2 velocityAddition = force / Mass * (float)Timing.Step;
|
||||
Vector2 newVelocity = body.LinearVelocity + velocityAddition;
|
||||
Vector2 newVelocity = FarseerBody.LinearVelocity + velocityAddition;
|
||||
|
||||
float newSpeedSqr = newVelocity.LengthSquared();
|
||||
if (newSpeedSqr > maxVelocity * maxVelocity && Vector2.Dot(body.LinearVelocity, force) > 0.0f)
|
||||
if (newSpeedSqr > maxVelocity * maxVelocity && Vector2.Dot(FarseerBody.LinearVelocity, force) > 0.0f)
|
||||
{
|
||||
float newSpeed = (float)Math.Sqrt(newSpeedSqr);
|
||||
float maxVelAddition = maxVelocity - newSpeed;
|
||||
@@ -659,20 +661,20 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
if (!IsValidValue(force, "clamped force", -1e10f, 1e10f)) return;
|
||||
body.ApplyForce(force);
|
||||
FarseerBody.ApplyForce(force);
|
||||
}
|
||||
|
||||
public void ApplyForce(Vector2 force, Vector2 point)
|
||||
{
|
||||
if (!IsValidValue(force, "force", -1e10f, 1e10f)) return;
|
||||
if (!IsValidValue(point, "point")) return;
|
||||
body.ApplyForce(force, point);
|
||||
FarseerBody.ApplyForce(force, point);
|
||||
}
|
||||
|
||||
public void ApplyTorque(float torque)
|
||||
{
|
||||
if (!IsValidValue(torque, "torque")) return;
|
||||
body.ApplyTorque(torque);
|
||||
FarseerBody.ApplyTorque(torque);
|
||||
}
|
||||
|
||||
public bool SetTransform(Vector2 simPosition, float rotation, bool setPrevTransform = true)
|
||||
@@ -684,7 +686,7 @@ namespace Barotrauma
|
||||
if (!IsValidValue(simPosition, "position", -1e10f, 1e10f)) return false;
|
||||
if (!IsValidValue(rotation, "rotation")) return false;
|
||||
|
||||
body.SetTransform(simPosition, rotation);
|
||||
FarseerBody.SetTransform(simPosition, rotation);
|
||||
if (setPrevTransform) { SetPrevTransform(simPosition, rotation); }
|
||||
return true;
|
||||
}
|
||||
@@ -698,7 +700,7 @@ namespace Barotrauma
|
||||
if (!IsValidValue(simPosition, "position", -1e10f, 1e10f)) return false;
|
||||
if (!IsValidValue(rotation, "rotation")) return false;
|
||||
|
||||
body.SetTransformIgnoreContacts(ref simPosition, rotation);
|
||||
FarseerBody.SetTransformIgnoreContacts(ref simPosition, rotation);
|
||||
if (setPrevTransform) { SetPrevTransform(simPosition, rotation); }
|
||||
return true;
|
||||
}
|
||||
@@ -718,9 +720,9 @@ namespace Barotrauma
|
||||
|
||||
if (lerp)
|
||||
{
|
||||
if (Vector2.DistanceSquared((Vector2)targetPosition, body.Position) < 10.0f * 10.0f)
|
||||
if (Vector2.DistanceSquared((Vector2)targetPosition, FarseerBody.Position) < 10.0f * 10.0f)
|
||||
{
|
||||
drawOffset = -((Vector2)targetPosition - (body.Position + drawOffset));
|
||||
drawOffset = -((Vector2)targetPosition - (FarseerBody.Position + drawOffset));
|
||||
prevPosition = (Vector2)targetPosition;
|
||||
}
|
||||
else
|
||||
@@ -729,26 +731,26 @@ namespace Barotrauma
|
||||
}
|
||||
if (targetRotation.HasValue)
|
||||
{
|
||||
rotationOffset = -MathUtils.GetShortestAngle(body.Rotation + rotationOffset, targetRotation.Value);
|
||||
rotationOffset = -MathUtils.GetShortestAngle(FarseerBody.Rotation + rotationOffset, targetRotation.Value);
|
||||
}
|
||||
}
|
||||
|
||||
SetTransformIgnoreContacts((Vector2)targetPosition, targetRotation == null ? body.Rotation : (float)targetRotation);
|
||||
SetTransformIgnoreContacts((Vector2)targetPosition, targetRotation == null ? FarseerBody.Rotation : (float)targetRotation);
|
||||
targetPosition = null;
|
||||
targetRotation = null;
|
||||
}
|
||||
|
||||
public void MoveToPos(Vector2 simPosition, float force, Vector2? pullPos = null)
|
||||
{
|
||||
if (pullPos == null) pullPos = body.Position;
|
||||
if (pullPos == null) pullPos = FarseerBody.Position;
|
||||
|
||||
if (!IsValidValue(simPosition, "position", -1e10f, 1e10f)) return;
|
||||
if (!IsValidValue(force, "force")) return;
|
||||
|
||||
Vector2 vel = body.LinearVelocity;
|
||||
Vector2 vel = FarseerBody.LinearVelocity;
|
||||
Vector2 deltaPos = simPosition - (Vector2)pullPos;
|
||||
deltaPos *= force;
|
||||
body.ApplyLinearImpulse((deltaPos - vel * 0.5f) * body.Mass, (Vector2)pullPos);
|
||||
FarseerBody.ApplyLinearImpulse((deltaPos - vel * 0.5f) * FarseerBody.Mass, (Vector2)pullPos);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -774,7 +776,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
ApplyForce(dragForce + buoyancy, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
|
||||
ApplyTorque(body.AngularVelocity * body.Mass * -0.08f);
|
||||
ApplyTorque(FarseerBody.AngularVelocity * FarseerBody.Mass * -0.08f);
|
||||
}
|
||||
|
||||
public void Update()
|
||||
@@ -789,9 +791,9 @@ namespace Barotrauma
|
||||
|
||||
public void UpdateDrawPosition()
|
||||
{
|
||||
drawPosition = Timing.Interpolate(prevPosition, body.Position);
|
||||
drawPosition = Timing.Interpolate(prevPosition, FarseerBody.Position);
|
||||
drawPosition = ConvertUnits.ToDisplayUnits(drawPosition + drawOffset);
|
||||
drawRotation = Timing.InterpolateRotation(prevRotation, body.Rotation) + rotationOffset;
|
||||
drawRotation = Timing.InterpolateRotation(prevRotation, FarseerBody.Rotation) + rotationOffset;
|
||||
}
|
||||
|
||||
public void CorrectPosition<T>(List<T> positionBuffer,
|
||||
@@ -827,27 +829,29 @@ namespace Barotrauma
|
||||
/// <param name="wrapAngle">Should the angles be wrapped. Set to false if it makes a difference whether the angle of the body is 0.0f or 360.0f.</param>
|
||||
public void SmoothRotate(float targetRotation, float force = 10.0f, bool wrapAngle = true)
|
||||
{
|
||||
float nextAngle = body.Rotation + body.AngularVelocity * (float)Timing.Step;
|
||||
float nextAngle = FarseerBody.Rotation + FarseerBody.AngularVelocity * (float)Timing.Step;
|
||||
float angle = wrapAngle ?
|
||||
MathUtils.GetShortestAngle(nextAngle, targetRotation) :
|
||||
MathHelper.Clamp(targetRotation - nextAngle, -MathHelper.Pi, MathHelper.Pi);
|
||||
float torque = angle * 60.0f * (force / 100.0f);
|
||||
|
||||
if (body.BodyType == BodyType.Kinematic)
|
||||
if (FarseerBody.BodyType == BodyType.Kinematic)
|
||||
{
|
||||
if (!IsValidValue(torque, "torque")) return;
|
||||
body.AngularVelocity = torque;
|
||||
FarseerBody.AngularVelocity = torque;
|
||||
}
|
||||
else
|
||||
{
|
||||
ApplyTorque(body.Mass * torque);
|
||||
ApplyTorque(FarseerBody.Mass * torque);
|
||||
}
|
||||
}
|
||||
|
||||
public void Remove()
|
||||
{
|
||||
list.Remove(this);
|
||||
GameMain.World.Remove(body);
|
||||
GameMain.World.Remove(FarseerBody);
|
||||
|
||||
Removed = true;
|
||||
|
||||
DisposeProjSpecific();
|
||||
}
|
||||
|
||||
@@ -399,6 +399,12 @@ namespace Barotrauma
|
||||
return ParseColor(element.Attribute(name).Value);
|
||||
}
|
||||
|
||||
public static Color? GetAttributeColor(this XElement element, string name)
|
||||
{
|
||||
if (element == null || element.Attribute(name) == null) { return null; }
|
||||
return ParseColor(element.Attribute(name).Value);
|
||||
}
|
||||
|
||||
public static Color[] GetAttributeColorArray(this XElement element, string name, Color[] defaultValue)
|
||||
{
|
||||
if (element?.Attribute(name) == null) return defaultValue;
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,169 +1,45 @@
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
v0.9.705.0 (Unstable)
|
||||
v0.9.707.0
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
|
||||
- Fixed server owner occasionally timing out if loading the round takes too long.
|
||||
- Fixed server owner's character occasionally being killed due to round start timeouts.
|
||||
- Reduced the severity of the burns caused by deusizine.
|
||||
- Fixed report buttons doing nothing.
|
||||
- Fixed report buttons being visible when not controlling a character.
|
||||
- Fixed sonar markers being visible when not receiving a signal from a remotely controlled shuttle.
|
||||
- Fixed wire being drawn twice in the connection panel interface if it's first connected from both ends and then dragged away from the connection.
|
||||
- Fixed client-side giveperm/giverank.
|
||||
- Added "killdisconnectedtime" command that can be used to set the time after a disconnected player's character gets automatically killed.
|
||||
- Increased default killdisconnectedtime to 2 minutes.
|
||||
- Fixed items that can be put in either hand slot, but not in the "Any" slots (e.g. duffel bag), being put into both hand slots.
|
||||
- Fixed crashing when attempting to draw an inventory when not controlling a character (happened in the sub editor when selecting an item container in the character mode and switching to default mode).
|
||||
- Fixed crashing if there's no audio device available.
|
||||
- Fixed wire being drawn twice in the connection panel interface if it's first connected from both ends and then dragged away from the connection.
|
||||
- Fixed inventory toggle button working unreliably.
|
||||
- Fixed alarm buzzer not returning to the original rotation when the alarm stops.
|
||||
- Fixed grenades sometimes not exploding client-side in multiplayer.
|
||||
- Fixed characters letting go of ladders when opening the health interface.
|
||||
- An attempt to fix occasional crashing when autoupdating workshop items.
|
||||
- Improved crewlist scaling on small resolutions.
|
||||
- Fixes to text overflows on small resolutions.
|
||||
- Whoops, fixed crashing in multiplayer due to CrewManager attempting to access the single player chatbox.
|
||||
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
v0.9.704.0 (Unstable)
|
||||
v0.9.706.0
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
|
||||
- Numerous UI fixes again.
|
||||
- Inventory remake.
|
||||
- Fixed yet another bug that caused inventory items to get mixed up in the campaign.
|
||||
- Fixed a bug that caused clients to get disconnected with an "invalid object header" error when a character has a large amount of different afflictions.
|
||||
- Fixed monster missions occasionally causing "entity not found" errors in the multiplayer campaign.
|
||||
- Rebalanced medical items: stat-boosting effects last much longer.
|
||||
- Modified vigor buffs from steroids and hyperzine to be intantaneous instead of delayed.
|
||||
- Nerfed opiate spawning.
|
||||
- Updated localizations (new texts are now translated to all languages).
|
||||
- Reduced the number of monsters inside ruins in high-difficulty levels, improving performance in those levels.
|
||||
- New loading screen.
|
||||
- Health interface improvements.
|
||||
- Improvements to the command interface.
|
||||
- Fixed clients failing to select a submarine file downloaded from the server if it replaced an older version of the sub.
|
||||
- Fixed performance issues when two items with editable properties are in the inventory (for example a headset and a diving suit).
|
||||
- Fixed header texts not being visible in Russian.
|
||||
- Skill gain values are now moddable (see Content/SkillSettings.xml).
|
||||
- Balanced skill levels and skill gains.
|
||||
- Job variant descriptions and items are now shown when hovering the cursor over the job variant button.
|
||||
- Fix bots occasionally getting stuck on water waypoints.
|
||||
- Fixed bots occasionally letting go of ladders too soon when going to operate an item, causing them to fall down.
|
||||
- The filter in the sub editor only searches from the currently selected category.
|
||||
- Made Unstable watermark less intrusive in sub editor.
|
||||
- Fixed chatbox disappearing when any character is accessing another character's inventory.
|
||||
- Chatbox is hidden after the message has been sent if it was hidden when starting to enter the message.
|
||||
- Fixed wifi components in the respawn shuttle being able to communicate with the main sub in non-combat missions.
|
||||
- Fixed engine sound range being up to 20 times larger than it should be.
|
||||
- Prevent dragging items while dragging inventories.
|
||||
- Fixed monsters occasionally being able to attack characters inside the sub.
|
||||
- Screwdrivers can be used as shivs!
|
||||
- Fixed last wire node appearing to be outside the submarine if a character gets electrocuted while connecting the first end of the wire.
|
||||
- Fixes to bugs that occasionally caused the client hosting a server to get silently disconnected from the server, getting stuck in a "limbo" where they can't interact with anything.
|
||||
- Fix crash with command UI when there is no reactor on the sub.
|
||||
- Fixed all items being highlighted in the multiplayer campaign store menu when another player buys something.
|
||||
- Fixed setting the number of items to buy by typing a number in the text box being practically impossible in the multiplayer campaign store.
|
||||
- Fixed grenades exploding multiple times if you throw one, pick it up before it explodes and rethrow it.
|
||||
- Fixed equipped wire being shown twice in the wiring interface if you connect and disconnect it when the other end of the wire is not connected to anything.
|
||||
- Fixed antibiotic glue being marked as a suitable treatment for gunshot wounds and internal damage, even though it only treats burns and bleeding.
|
||||
- Fixed a waypoint issue in Orca's engineering compartment that prevented the bots from reaching the oxygen generator.
|
||||
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
v0.9.703.0 (Unstable)
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
|
||||
- Numerous UI fixes (layout improvements, improved scaling on different resolutions, fixed item interface overlaps, text overflow fixes).
|
||||
- Added Korean translation.
|
||||
- Numerous fixes to random events to better pace new level dimensions.
|
||||
- Fixed non-host clients crashing when disconnecting from the server.
|
||||
- Made giveperm/giverank commands suck less by allowing names, endpoints and SteamIDs instead of clientlist id, and allowing users to skip question prompt by adding rank or perm as a second parameter.
|
||||
- Fixes to render order oddities (structures with a depth > 0.5 always rendering behind all items, inconsistent render order between sub editor and in-game). Now structures with a depth of >= 0.9 are always behind everything (and visible through the LOS effect), and item's sprite depth is capped to 0.9.
|
||||
- Fixed engines causing crashes if MinVoltage is set to 0.
|
||||
- Fixed multiplayer campaign saves appearing in the single player "load game" menu if they're placed in the singleplayer save folder (leading to a crash if a player starts to load the save).
|
||||
- Fixed fabricator cancellation failing to be communicated under certain circumstances.
|
||||
- Fixed fabricator and deconstructor operating faster when run on overvoltage, making it possible to fabricate/deconstruct things almost instantaneously by using relays.
|
||||
- Fixed campaign store filter doing nothing.
|
||||
- Potentially a fixed race condition when autoupdating Workshop items during loading screen.
|
||||
- Fixed subinventories not opening when trying to heal an unconscious character.
|
||||
- Fixed crashing when moving the nodes of a wire that's not connected to anything in the sub editor.
|
||||
- Fixed inability to drag wires out of the wiring interface (even if they're disconnected from both ends).
|
||||
- Another fix to inventory items occasionally getting messed up in multiplayer.
|
||||
- Removed oxygenite shards as a product of deconstructing liquid oxygenite to prevent production loops.
|
||||
- Fixed sonar showing everything around the sub when sending out a directional ping and switching to passive.
|
||||
- Fixed inability to drag characters from room to another in alien ruins.
|
||||
- Fixed excessively large tonic liquid collider.
|
||||
- Fixed reactor's on/off state not being saved.
|
||||
- Fixed crashing if a modded UI style contains multiple child styles with the same name.
|
||||
- Wifi components in the respawn shuttle can't communicate with components in other submarines/shuttles.
|
||||
- Fixed wire nodes getting misplaced when flipping wires in the sub editor.
|
||||
- Fixed groups of items that include wires sometimes not getting placed at the position of the cursor when pasting them in the sub editor.
|
||||
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
v0.9.702.0 (Unstable)
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
|
||||
- UI overhaul
|
||||
- Increased level sizes.
|
||||
- Rebalanced monster spawns.
|
||||
- Added a few new artifact missions.
|
||||
- Fixed server not sending condition updates for inactive items, potentially causing the condition to get desynced when all of the components of the item go inactive.
|
||||
- Fixed clients being unable to rejoin a SteamP2P server after they've left.
|
||||
- Fix to inventory items occasionally getting mixed up in the campaign.
|
||||
- Power consumption of damaged devices doesn't increase as much anymore.
|
||||
- Player cap can be adjusted in the server settings.
|
||||
- Fixed "cannot remove joints when the world is locked" error message when a character latched onto the sub is attacked.
|
||||
- Fixed currents heavily slowing down the submarine regardless of the force or direction of the current.
|
||||
- Improved name tag hiding.
|
||||
- Fixed explosives that disappear after exploding (e.g. nuclear explosives) not playing the explosion sound.
|
||||
- Fixed server list not listing passworded SteamP2P servers correctly.
|
||||
- Reduced Daedalic splash screen volume further!
|
||||
- Made tonic liquid purchasable.
|
||||
- Subscribed Workshop items aren't shown in the Popular tab.
|
||||
- Fixed some held items vibrating/twitching when moving.
|
||||
- Fixed turrets emitting muzzle flash particles in an incorrect direction (the rotation of the particle was correct but the direction it flied towards not, which isn't noticeable with the non-moving vanilla particles).
|
||||
- Fixed clients not relaying console commands that don't exist client-side to the server (i.e. custom commands implemented by a server mod can now be used by clients).
|
||||
- Added combat priorities to alien weapons to allow bots to use them.
|
||||
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
v0.9.701.0 (Unstable)
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
|
||||
- Fixed SteamP2P server hosting.
|
||||
- Fixed a bug that caused "missing entity" errors when joining mid-round. Occurred if entities were created or removed while the client was in the process of getting in sync with the server, for example if the other players were firing turrets while the client was joining. However, there may still be other bugs left that can cause the same "missing entity" error message.
|
||||
- Cap the framerate to 200 FPS when VSync is off to prevent overloading the GPU. The cap can be adjusted by changing the "framelimit" attribute in config_player.xml.
|
||||
- Rebalanced random events.
|
||||
- Numerous fixes and improvements to Berilia.
|
||||
- Give job items to humans spawned with the "spawn" command.
|
||||
- Fixed content package hash mismatches between Windows and Linux.
|
||||
- Fixed client crashing when disconnecting from the server as a host.
|
||||
- Fixed clients crashing when an order message is received while in the server lobby.
|
||||
- New sprites (that actually match the worn sprite) for dropped outfits.
|
||||
- Slightly increased the view range of the coilguns and railguns.
|
||||
- Cursor changes according to what it's hovered on (hand icon when on a button, caret icon when on a textbox, etc).
|
||||
- The automatically placed items are not listed in the debug console by default anymore. Listing them can be re-enabled with the command "outfitdebug".
|
||||
- Fixed crashing when saving structures into item assemblies.
|
||||
- Fixed sub editor allowing vanilla subs to be deleted.
|
||||
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
v0.9.700.0 (Unstable)
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
|
||||
- Additional logging to diagnose event/entity ID errors: server and clients write a log file with a bunch of debug information the error happens. The files can be found in the ServerLogs folder after the error has occurred. If you get log files, please send them to us to help us diagnose these bugs!
|
||||
|
||||
- Fixed "skip tutorials" returning to the main menu instead of opening the correct tab when starting a new game.
|
||||
- Fixed crashing when an enemy takes damage from something else than a character.
|
||||
- Fixed clients disconnecting if a sub with no version number (or a sub the client hasn't received yet) is selected.
|
||||
- Fixed crash when spawning a human without specified job through the console.
|
||||
- Fixed several bugs that were causing crashes due to race conditions in the server list.
|
||||
- Made "showseed" console command usable by clients.
|
||||
- Fixed accordion collider.
|
||||
- Fixed doors not blocking hitscan weapons.
|
||||
- Continue playing the main menu and editor musics from previous position instead of restarting when switching between screens.
|
||||
- Added missing sonar display background to sonar monitor.
|
||||
- Fuel rods now always return their steel on deconstruction.
|
||||
- Constructing fuel rods now requires lead.
|
||||
- Added an improved version of Typhon.
|
||||
- Reworked Berilia.
|
||||
- Reverted back to the old inventory UI (with updated graphics) for now.
|
||||
- Miscellaneous UI layout fixes and improvements.
|
||||
- Visual improvements to the health interface.
|
||||
- Fixed bots spawned using console commands not getting assigned the correct team id on their headsets, causing them to be disabled in the command interface.
|
||||
- Fixed team ids of character's headsets resetting after the first campaign round, preventing them from communicating via radio with the players/bots who are playing their first round.
|
||||
- Fixed collider tunneling when client is slow to send inputs. Caused characters to occasionally noclip through walls when the connection or framerate is poor.
|
||||
- Improved the way clients initialize rounds to prevent timeouts if loading the round takes too long.
|
||||
- Fixed enemy team being visible in the command UI in combat missions.
|
||||
- Adjusted repair times to better suit current skill balance.
|
||||
- Medical item balancing.
|
||||
- Command button is hidden when it cannot be used.
|
||||
- Added a button to give orders to crew members directly.
|
||||
- Don't close item UI when opening crew list with keybind.
|
||||
- Allow toggling crew list with keybind in spectator and freecam modes.
|
||||
- Fixed command UI hotkey navigation triggering inventory hotkey in the last step.
|
||||
- Fixed command UI being immediately re-enabled after giving an order in clickless mode.
|
||||
- Fixed sonar beacon UI overlapping with the chatbox.
|
||||
- Fixed nav terminal's docking button overlapping with the chatbox.
|
||||
- Marked "editsubs" a cheat command.
|
||||
- Fixed cursor getting stuck to the dragging or hand state if dragging/highlighting a wire is interrupted by any other reason than letting go of the left mouse button (electrocution, getting killed, ending the round...)
|
||||
- Improved server lobby scaling when switching resolutions.
|
||||
- Fixed some server-side console commands not sending anything back to the client executing them, making it seem as if the command did nothing (botcount, botspawnmode, killdisconnectedtimer, togglekarma).
|
||||
- Fixed progress bars having a bunch of dead space at the beginning and end (causing battery/repair sliders to appear empty when below ~5%, and full when above ~95%).
|
||||
- Fixed CustomInterface crashing the game when selected if it contains no buttons/tickboxes.
|
||||
- Fixed a couple of unfair ruin traps (rooms with coil/sensor placement that makes it impossible to pass through without getting zapped).
|
||||
- Fixed tutorial video scaling when opened more than once.
|
||||
- Lock portrait area, health bar, affliction icons and report buttons when using a turret.
|
||||
- Fixed lower docking port ladder on Typhon 2.
|
||||
- Safeguards to prevent EventManager from crashing the game due to missing EventManagerSettings (#2066).
|
||||
- Some safeguards and extra error logging for case where the world field of a physics body seems to be null when dropping an item (#2252).
|
||||
- Fixed a rare crash with the message "Compare() method returns inconsistent results" when autoplacing items in the sub.
|
||||
- Fixed mechanic tutorial getting softlocked if the player never has an oxygen tank (or aluminium) and sodium in their inventory at the same time. I.e. if they deconstruct the oxygen tanks first and put the aluminium in the fabricator, and then get the sodium and put it in the fabricator.
|
||||
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
v0.9.7.0
|
||||
@@ -171,6 +47,8 @@ v0.9.7.0
|
||||
|
||||
UI/UX improvements:
|
||||
- Graphical and functional overhaul of all user interfaces.
|
||||
- Cursor changes according to what it's hovered on (hand icon when on a button, caret icon when on a textbox, etc).
|
||||
- New loading screen.
|
||||
- Better feedback on shooting.
|
||||
- Double clicking on an item moves it to the equipped inventory (e.g. ammo to the equipped weapon).
|
||||
- Periscopes can be deselected by pressing esc.
|
||||
@@ -190,6 +68,7 @@ UI/UX improvements:
|
||||
- Made docking indicators more visible on the sonar.
|
||||
- Show mic input level also when Push-to-Talk mode is selected to make it easier to adjust the level without having to switch the mode to Voice Activity.
|
||||
- Pressing the up arrow brings up previously sent chat messages, making it easier to resend them.
|
||||
- The filter in the sub editor only searches from the currently selected category.
|
||||
|
||||
Optimizations:
|
||||
- Major physics optimization. Most importantly, the physics are now multithreaded, making the game perform much better when there are large numbers of characters active.
|
||||
@@ -201,8 +80,16 @@ Optimizations:
|
||||
- Improved the performance of human AI (bots).
|
||||
|
||||
Additions and changes:
|
||||
- Added Korean translation.
|
||||
- Added an improved version of Typhon.
|
||||
- Reworked Berilia.
|
||||
- New shuttle, "Hemulen".
|
||||
- Merged Selkie and Bunyip into a new, improved shuttle (just called Selkie now).
|
||||
- Increased level sizes.
|
||||
- Rebalanced monster spawns.
|
||||
- Balanced skill levels and skill gains.
|
||||
- Skill gain values are now moddable (see Content/SkillSettings.xml).
|
||||
- Added a few new artifact missions.
|
||||
- The job gear variants are not just visually different versions of the same item, but completely separate items. The job variants now allow the players to choose what kind of gear they want to spawn with, not just the look of the uniform.
|
||||
- Attachable items and wire nodes can now be freely placed around the character instead of always being placed at the position of the character. When attaching items/wires, there's a placement grid that makes it much easier to neatly attach/wire things mid-round.
|
||||
- The submarines now get automatically outfitted with a semi-random selection of supplies when starting a campaign. The items that have been manually placed in the submarine editor are kept as-is.
|
||||
@@ -219,8 +106,14 @@ Additions and changes:
|
||||
- Added subtle chromatic aberration & blur when suffering from heavy bloodloss.
|
||||
- Nerfed hull damage from plasma cutter and welding tool explosions.
|
||||
- Removed repair thresholds from items; any device that's not in perfect condition can now be repaired.
|
||||
- Rebalanced medical items: stat-boosting effects last much longer.
|
||||
- Modified vigor buffs from steroids and hyperzine to be intantaneous instead of delayed.
|
||||
- Tweaked opiates. They now do less overdose damage, produce a lower addiction for skilled users, but produce a serious addiction for unskilled users.
|
||||
- Bandages now have 3 uses.
|
||||
- Removed oxygenite shards as a product of deconstructing liquid oxygenite to prevent production loops.
|
||||
- Screwdrivers can be used as shivs!
|
||||
- Fuel rods now always return their steel on deconstruction.
|
||||
- Constructing fuel rods now requires lead.
|
||||
- Mouse button names are now translated.
|
||||
- Improved tiger thresher texture and lights.
|
||||
- Replaced the legacy ladder, stair and docking port sprites.
|
||||
@@ -250,6 +143,16 @@ Additions and changes:
|
||||
- Lowers number of dependencies, simplifying the installation process.
|
||||
- Introduces features that will translate into further stability and performance improvements in the future.
|
||||
- Switched from MP4 to WebM to minimize bloat and dependencies on patented tech.
|
||||
- Cap the framerate to 200 FPS when VSync is off to prevent overloading the GPU. The cap can be adjusted by changing the "framelimit" attribute in config_player.xml.
|
||||
- Wifi components in the respawn shuttle can't communicate with components in other submarines/shuttles.
|
||||
- Power consumption of damaged devices doesn't increase as much anymore.
|
||||
- Made tonic liquid purchasable.
|
||||
- Added combat priorities to alien weapons to allow bots to use them.
|
||||
- Improved name tag hiding.
|
||||
- Give job items to humans spawned with the "spawn" command.
|
||||
- Slightly increased the view range of the coilguns and railguns.
|
||||
- Continue playing the main menu and editor music from the previous position instead of restarting when switching between screens.
|
||||
- Marked "editsubs" a cheat command (so you can't just switch to the sub editor, spawn whatever you need and go back to the game without enabling cheats).
|
||||
|
||||
AI:
|
||||
- Bots can now undock the sub.
|
||||
@@ -277,7 +180,7 @@ Monsters:
|
||||
- Revised Matriarch's behavior: Matriarchs now spawn in swarms, protected by other Hammerheads, and they try to keep the distance to the submarine. Boosted the explosion and increased the Spawn count.
|
||||
- Added new missions about Hammerhead Matriarch.
|
||||
- Revised all the creatures using the new behaviors.
|
||||
- Changed how "attack when provoked" works. The previous state is now reset when the target changes. Also fixed several relate issues. Rename the property (requires action if custom characters use it).
|
||||
- Changed how "attack when provoked" works. The previous state is now reset when the target changes. Also fixed several relate issues. Rename the property (requires action if custom characters use it). When a creature is attacked and "attack when provoked" is false and the attacker is not found in the predefined ai targets, the creature flees by default instead of just ignoring the attacker.
|
||||
- Refactored the eating behavior: fixes small creatures not being able to eat significantly larger creatures.
|
||||
- Adjusted the commonness and the reward of the Thresher swarm mission.
|
||||
- Improved the indoors escaping behavior.
|
||||
@@ -297,20 +200,34 @@ Monsters:
|
||||
- Fixed Mudraptors sometimes squeezing themselves towards doors without being able to attack them.
|
||||
- Fixed monsters not reacting to being fired with turrets unless they can target the attacker.
|
||||
- Fixed minor slipping in Mudraptor's walking animation.
|
||||
- Weapons and tools now have ai targets that are only activated when the items are used -> shooting monsters should make you much more attractive target than just swimming peacefully around.
|
||||
|
||||
Multiplayer:
|
||||
- Fixed a bunch of bugs that caused "missing entity" errors. However, there are many different reasons the error can occur, so even though we have not run into the issue anymore during out testing rounds, there is still a chance it may occur in some situations.
|
||||
- Fixed inventory items occasionally getting mixed up in the multiplayer campaign.
|
||||
- Fixed a bug that caused clients to get disconnected with an "invalid object header" error when a character has a large amount of different afflictions.
|
||||
- Fixed server owner occasionally timing out if loading the round takes too long.
|
||||
- Fixed server owner's character occasionally being killed due to round start timeouts.
|
||||
- Fixed players not getting notified in any way when their connection to the server has timed out, allowing them to keep playing without being able to interact with anything.
|
||||
- Made giveperm/giverank commands suck less by allowing names, endpoints and SteamIDs instead of clientlist id, and allowing users to skip question prompt by adding rank or perm as a second parameter.
|
||||
- Fixed multiplayer campaign saves appearing in the single player "load game" menu if they're placed in the singleplayer save folder (leading to a crash if a player starts to load the save).
|
||||
- Fixed server not sending condition updates for inactive items, potentially causing the condition to get desynced when all of the components of the item go inactive.
|
||||
- Fixed clients only being informed of the reason for their ban the moment they're banned, but not if they try to rejoin.
|
||||
- Fixed clients not attempting to reconnect to the server automatically when the connection is lost, forcing the client to rejoin the server manually.
|
||||
- Fixed clients sometimes being able to noclip through walls when the framerate or connection is poor.
|
||||
- Karma system can be enabled/disabled in the "host server" menu.
|
||||
- Option to set the number of password retries before a ban.
|
||||
- Fixed voice chat indicators not working in the in-game crew list.
|
||||
- Moved "End Round" button to the pause menu.
|
||||
- Added a separate server log category for wiring.
|
||||
- Fixed clients not relaying console commands that don't exist client-side to the server (i.e. custom commands implemented by a server mod can now be used by clients).
|
||||
- Added "killdisconnectedtime" command that can be used to set the time after a disconnected player's character gets automatically killed.
|
||||
- Increased default killdisconnectedtime to 2 minutes.
|
||||
- Player cap can be adjusted in the server settings.
|
||||
- Made "showseed" console command usable by clients.
|
||||
|
||||
Bugfixes:
|
||||
- Fixed camera position "twitching" when moving the cursor around while unconscious.
|
||||
- Fixed texts in mission/traitor notifications occasionally overflowing outside the border of the message box.
|
||||
- Fixes to render order oddities (structures with a depth > 0.5 always rendering behind all items, inconsistent render order between sub editor and in-game). Now structures with a depth of >= 0.9 are always behind everything (and visible through the LOS effect), and item's sprite depth is capped to 0.9.
|
||||
- Fixed background structures that are resizeable on both axes always being drawn behind other background structures regardless of the sprite depth.
|
||||
- Fixed Kastrull flooding when the drone undocks.
|
||||
- Fixed ballast pumps deteriorating in Kastrull's drone despite being unreachable by the players.
|
||||
@@ -319,6 +236,13 @@ Bugfixes:
|
||||
- Fixed charactes being unable to get through multi-layer walls from inside the sub (for example the walls above Humpback's command room).
|
||||
- Fixed plasma cutter not cutting through holes in walls.
|
||||
- Fixed melee weapons not working inside ruins due to the colliders that block subs from entering the ruins.
|
||||
- Fixed fabricator cancellation failing to be communicated under certain circumstances.
|
||||
- Fixed fabricator and deconstructor operating faster when run on overvoltage, making it possible to fabricate/deconstruct things almost instantaneously by using relays.
|
||||
- Fixed camera position "twitching" when moving the cursor around while unconscious.
|
||||
- Fixed crashing if there's no audio device available.
|
||||
- Fixed texts in mission/traitor notifications occasionally overflowing outside the border of the message box.
|
||||
- Fixed subinventories not opening when trying to heal an unconscious character.
|
||||
- Fixed engines causing crashes if MinVoltage is set to 0.
|
||||
- Fixed small "twitch" when a character enters or exits a submarine.
|
||||
- Fixed starting a combat mission with just 1 player counting as winning the mission.
|
||||
- Fixed linked shuttles occasionally spawning at the wrong side of a sub's docking port.
|
||||
@@ -334,6 +258,28 @@ Bugfixes:
|
||||
- Fixed crashes in the character editor when creating a humanoid with incomplete limb definitions.
|
||||
- Fixed the character editor crashing if no textures were found.
|
||||
- Don't allow to save invalid texture paths in the character editor.
|
||||
- Decreased the range of some of the motion sensors inside alien ruins to prevent certain rooms from being nearly impossible to get past without getting zapped by an alien coil.
|
||||
- Fixed excessively large tonic liquid collider.
|
||||
- Fixed accordion collider.
|
||||
- Fixed doors not blocking hitscan weapons.
|
||||
- Fixed sonar showing everything around the sub when sending out a directional ping and immediately switching to passive.
|
||||
- Fixed inability to drag characters from room to another in alien ruins.
|
||||
- Fixed crashing if a modded UI style contains multiple child styles with the same name.
|
||||
- Fixed wire nodes getting misplaced when flipping wires in the sub editor.
|
||||
- Fixed groups of items that include wires sometimes not getting placed at the position of the cursor when pasting them in the sub editor.
|
||||
- Fixed currents heavily slowing down the submarine regardless of the force or direction of the current.
|
||||
- Fixed some held items vibrating/twitching when moving.
|
||||
- Fixed turrets emitting muzzle flash particles in an incorrect direction (the rotation of the particle was correct but the direction it flew towards not, which isn't noticeable with the non-moving vanilla particles).
|
||||
- Fixed "skip tutorials" returning to the main menu instead of opening the correct tab when starting a new game.
|
||||
- Fixed all items being highlighted in the multiplayer campaign store menu when another player buys something.
|
||||
- Fixed setting the number of items to buy by typing a number in the text box being practically impossible in the multiplayer campaign store.
|
||||
- Fixed grenades exploding multiple times if you throw one, pick it up before it explodes and rethrow it.
|
||||
- Fixed bots occasionally letting go of ladders too soon when going to operate an item, causing them to fall down.
|
||||
- Fixed some waypoint issues in Orca.
|
||||
- Fixed wifi components in the respawn shuttle being able to communicate with the main sub in non-combat missions.
|
||||
- Fixed engine sound range being up to 20 times larger than it should be.
|
||||
- Fixed monsters occasionally being able to attack through walls.
|
||||
- Fixed alarm buzzer not returning to the original rotation when the alarm stops.
|
||||
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
v0.9.6.0
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<serversettings
|
||||
name="Server"
|
||||
public="false"
|
||||
password=""
|
||||
port="27015"
|
||||
queryport="27016"
|
||||
playstyle="Casual"
|
||||
maxplayers="10"
|
||||
enableupnp="false"
|
||||
autorestart="false"
|
||||
LevelDifficulty="20"
|
||||
AllowedRandomMissionTypes="Random,Salvage,Monster,Cargo,Combat"
|
||||
AllowedClientNameChars="32-33,38-46,48-57,65-90,91-91,93-93,95-122,192-255,384-591,1024-1279,19968-40959,13312-19903,131072-15043983,15043985-173791,173824-178207,178208-183983,63744-64255,194560-195103"
|
||||
ServerMessage=""
|
||||
tickrate="20"
|
||||
randomizeseed="True"
|
||||
userespawnshuttle="True"
|
||||
@@ -39,15 +52,4 @@
|
||||
missiontype="Random"
|
||||
autobantime="3600"
|
||||
maxautobantime="86400"
|
||||
name="Server"
|
||||
public="false"
|
||||
port="27015"
|
||||
queryport="27016"
|
||||
playstyle="Casual"
|
||||
maxplayers="10"
|
||||
enableupnp="false"
|
||||
autorestart="false"
|
||||
LevelDifficulty="20"
|
||||
AllowedRandomMissionTypes="Random,Salvage,Monster,Cargo,Combat"
|
||||
AllowedClientNameChars="32-33,38-46,48-57,65-90,91-91,93-93,95-122,192-255,384-591,1024-1279,19968-40959,13312-19903,131072-15043983,15043985-173791,173824-178207,178208-183983,63744-64255,194560-195103"
|
||||
ServerMessage="" />
|
||||
/>
|
||||
@@ -723,6 +723,8 @@ namespace FarseerPhysics.Dynamics
|
||||
public void SetTransformIgnoreContacts(ref Vector2 position, float angle)
|
||||
{
|
||||
Debug.Assert(World != null);
|
||||
if (World == null)
|
||||
throw new InvalidOperationException("Could not set the transform of a body (World was null - has the body been removed?)");
|
||||
if (World.IsLocked)
|
||||
throw new WorldLockedException("Cannot modify the transform of a body when the World is locked.");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user