v0.12.0.2
This commit is contained in:
@@ -47,6 +47,8 @@ namespace Barotrauma
|
||||
set { maxZoom = MathHelper.Clamp(value, 1.0f, 10.0f); }
|
||||
}
|
||||
|
||||
public float FreeCamMoveSpeed = 1.0f;
|
||||
|
||||
private float zoom;
|
||||
|
||||
private float offsetAmount;
|
||||
@@ -197,10 +199,15 @@ namespace Barotrauma
|
||||
|
||||
private void CreateMatrices()
|
||||
{
|
||||
resolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
|
||||
worldView = new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight);
|
||||
viewMatrix = Matrix.CreateTranslation(new Vector3(GameMain.GraphicsWidth / 2.0f, GameMain.GraphicsHeight / 2.0f, 0));
|
||||
SetResolution(new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight));
|
||||
}
|
||||
|
||||
public void SetResolution(Point res)
|
||||
{
|
||||
resolution = res;
|
||||
|
||||
worldView = new Rectangle(0, 0, res.X, res.Y);
|
||||
viewMatrix = Matrix.CreateTranslation(new Vector3(res.X / 2.0f, res.Y / 2.0f, 0));
|
||||
globalZoomScale = (float)Math.Pow(new Vector2(GUI.UIWidth, resolution.Y).Length() / GUI.ReferenceResolution.Length(), 2);
|
||||
}
|
||||
|
||||
@@ -265,17 +272,17 @@ namespace Barotrauma
|
||||
{
|
||||
if (GUI.KeyboardDispatcher.Subscriber == null)
|
||||
{
|
||||
if (PlayerInput.KeyDown(Keys.LeftShift)) moveSpeed *= 2.0f;
|
||||
if (PlayerInput.KeyDown(Keys.LeftControl)) moveSpeed *= 0.5f;
|
||||
if (PlayerInput.KeyDown(Keys.LeftShift)) { moveSpeed *= 2.0f; }
|
||||
if (PlayerInput.KeyDown(Keys.LeftControl)) { moveSpeed *= 0.5f; }
|
||||
|
||||
if (GameMain.Config.KeyBind(InputType.Left).IsDown()) moveInput.X -= 1.0f;
|
||||
if (GameMain.Config.KeyBind(InputType.Right).IsDown()) moveInput.X += 1.0f;
|
||||
if (GameMain.Config.KeyBind(InputType.Down).IsDown()) moveInput.Y -= 1.0f;
|
||||
if (GameMain.Config.KeyBind(InputType.Up).IsDown()) moveInput.Y += 1.0f;
|
||||
if (GameMain.Config.KeyBind(InputType.Left).IsDown()) { moveInput.X -= 1.0f; }
|
||||
if (GameMain.Config.KeyBind(InputType.Right).IsDown()) { moveInput.X += 1.0f; }
|
||||
if (GameMain.Config.KeyBind(InputType.Down).IsDown()) { moveInput.Y -= 1.0f; }
|
||||
if (GameMain.Config.KeyBind(InputType.Up).IsDown()) { moveInput.Y += 1.0f; }
|
||||
}
|
||||
|
||||
velocity = Vector2.Lerp(velocity, moveInput, deltaTime * 10.0f);
|
||||
moveCam = velocity * moveSpeed * deltaTime * 60.0f;
|
||||
moveCam = velocity * moveSpeed * deltaTime * FreeCamMoveSpeed * 60.0f;
|
||||
|
||||
if (Screen.Selected == GameMain.GameScreen && FollowSub)
|
||||
{
|
||||
@@ -291,14 +298,21 @@ namespace Barotrauma
|
||||
{
|
||||
Vector2 mouseInWorld = ScreenToWorld(PlayerInput.MousePosition);
|
||||
Vector2 diffViewCenter;
|
||||
diffViewCenter = ((mouseInWorld - Position) * Zoom);
|
||||
diffViewCenter = (mouseInWorld - Position) * Zoom;
|
||||
targetZoom = MathHelper.Clamp(
|
||||
targetZoom + (PlayerInput.ScrollWheelSpeed / 1000.0f) * zoom,
|
||||
targetZoom + PlayerInput.ScrollWheelSpeed / 1000.0f * zoom,
|
||||
GameMain.DebugDraw ? MinZoom * 0.1f : MinZoom,
|
||||
MaxZoom);
|
||||
|
||||
if (PlayerInput.KeyDown(Keys.LeftControl))
|
||||
{
|
||||
Zoom += (targetZoom - zoom) / (ZoomSmoothness * 10.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
Zoom = MathHelper.Lerp(Zoom, targetZoom, deltaTime * 10.0f);
|
||||
if (!PlayerInput.KeyDown(Keys.F)) Position = mouseInWorld - (diffViewCenter / Zoom);
|
||||
}
|
||||
if (!PlayerInput.KeyDown(Keys.F)) { Position = mouseInWorld - (diffViewCenter / Zoom); }
|
||||
}
|
||||
}
|
||||
else if (allowMove)
|
||||
|
||||
@@ -31,8 +31,6 @@ namespace Barotrauma
|
||||
|
||||
GUI.DrawString(spriteBatch, pos + textOffset, Character.Name, Color.White, Color.Black);
|
||||
|
||||
if (ObjectiveManager != null)
|
||||
{
|
||||
var currentOrder = ObjectiveManager.CurrentOrder;
|
||||
if (currentOrder != null)
|
||||
{
|
||||
@@ -82,7 +80,6 @@ namespace Barotrauma
|
||||
}
|
||||
GUI.DrawString(spriteBatch, pos + textOffset + new Vector2(120, offsetMultiplier * 18 + 100), $"{objective.DebugTag} ({objective.Priority.FormatZeroDecimal()})", Color.White, Color.Black * 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
if (steeringManager is IndoorsSteeringManager pathSteering)
|
||||
{
|
||||
@@ -116,6 +113,14 @@ namespace Barotrauma
|
||||
GUI.DrawLine(spriteBatch, pos, pos + ConvertUnits.ToDisplayUnits(new Vector2(Character.AnimController.TargetMovement.X, -Character.AnimController.TargetMovement.Y)), Color.SteelBlue, width: 2);
|
||||
GUI.DrawLine(spriteBatch, pos, pos + ConvertUnits.ToDisplayUnits(new Vector2(Steering.X, -Steering.Y)), Color.Blue, width: 3);
|
||||
|
||||
if (Character.AnimController.InWater && objectiveManager.GetActiveObjective() is AIObjectiveGoTo gotoObjective && gotoObjective.TargetGap != null)
|
||||
{
|
||||
Vector2 gapPosition = gotoObjective.TargetGap.WorldPosition;
|
||||
gapPosition.Y = -gapPosition.Y;
|
||||
GUI.DrawRectangle(spriteBatch, gapPosition - new Vector2(10.0f, 10.0f), new Vector2(20.0f, 20.0f), Color.Orange, false);
|
||||
GUI.DrawLine(spriteBatch, pos, gapPosition, Color.Orange * 0.5f, 0, 5);
|
||||
}
|
||||
|
||||
//if (Character.IsKeyDown(InputType.Aim))
|
||||
//{
|
||||
// GUI.DrawLine(spriteBatch, pos, new Vector2(Character.CursorWorldPosition.X, -Character.CursorWorldPosition.Y), Color.Yellow, width: 4);
|
||||
|
||||
@@ -481,13 +481,13 @@ namespace Barotrauma
|
||||
var controller = character.SelectedConstruction?.GetComponent<Controller>();
|
||||
if (controller != null && controller.ControlCharacterPose && controller.User == character)
|
||||
{
|
||||
if (controller.Item.SpriteDepth > maxDepth)
|
||||
if (controller.Item.SpriteDepth <= maxDepth || controller.DrawUserBehind)
|
||||
{
|
||||
depthOffset = Math.Max(controller.Item.SpriteDepth - 0.0001f - maxDepth, 0.0f);
|
||||
depthOffset = Math.Max(controller.Item.GetDrawDepth() + 0.0001f - minDepth, -minDepth);
|
||||
}
|
||||
else
|
||||
{
|
||||
depthOffset = Math.Max(controller.Item.SpriteDepth + 0.0001f - minDepth, -minDepth);
|
||||
depthOffset = Math.Max(controller.Item.GetDrawDepth() - 0.0001f - maxDepth, 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace Barotrauma
|
||||
|
||||
if (sound != null)
|
||||
{
|
||||
SoundPlayer.PlaySound(sound.Sound, worldPosition, sound.Volume, sound.Range);
|
||||
SoundPlayer.PlaySound(sound.Sound, worldPosition, sound.Volume, sound.Range, ignoreMuffling: sound.IgnoreMuffling);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -457,7 +457,7 @@ namespace Barotrauma
|
||||
if (draggingItemToWorld)
|
||||
{
|
||||
if (item.OwnInventory == null ||
|
||||
!item.OwnInventory.CanBePut(CharacterInventory.draggingItem) ||
|
||||
!item.OwnInventory.CanBePut(CharacterInventory.DraggingItems.First()) ||
|
||||
!CanAccessInventory(item.OwnInventory))
|
||||
{
|
||||
continue;
|
||||
@@ -561,7 +561,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (InvisibleTimer > 0.0f)
|
||||
{
|
||||
if (Controlled == null || (Controlled.CharacterHealth.GetAffliction("psychosis")?.Strength ?? 0.0f) <= 0.0f)
|
||||
if (Controlled == null || Controlled == this || (Controlled.CharacterHealth.GetAffliction("psychosis")?.Strength ?? 0.0f) <= 0.0f)
|
||||
{
|
||||
InvisibleTimer = 0.0f;
|
||||
}
|
||||
@@ -579,15 +579,15 @@ namespace Barotrauma
|
||||
{
|
||||
soundTimer -= deltaTime;
|
||||
}
|
||||
else if (AIController != null)
|
||||
else if (AIController is EnemyAIController enemyAI)
|
||||
{
|
||||
switch (AIController.State)
|
||||
switch (enemyAI.State)
|
||||
{
|
||||
case AIState.Attack:
|
||||
PlaySound(CharacterSound.SoundType.Attack);
|
||||
break;
|
||||
default:
|
||||
var petBehavior = (AIController as EnemyAIController)?.PetBehavior;
|
||||
var petBehavior = enemyAI.PetBehavior;
|
||||
if (petBehavior != null && petBehavior.Happiness < petBehavior.MaxHappiness * 0.25f)
|
||||
{
|
||||
PlaySound(CharacterSound.SoundType.Unhappy);
|
||||
@@ -741,7 +741,7 @@ namespace Barotrauma
|
||||
|
||||
if (speechBubbleTimer > 0.0f)
|
||||
{
|
||||
GUI.SpeechBubbleIcon.Draw(spriteBatch, pos - Vector2.UnitY * 30,
|
||||
GUI.SpeechBubbleIcon.Draw(spriteBatch, pos - Vector2.UnitY * 5,
|
||||
speechBubbleColor * Math.Min(speechBubbleTimer, 1.0f), 0.0f,
|
||||
Math.Min(speechBubbleTimer, 1.0f));
|
||||
}
|
||||
@@ -803,7 +803,7 @@ namespace Barotrauma
|
||||
Color nameColor = Color.White;
|
||||
if (Controlled != null && TeamID != Controlled.TeamID)
|
||||
{
|
||||
nameColor = TeamID == TeamType.FriendlyNPC ? Color.SkyBlue : GUI.Style.Red;
|
||||
nameColor = TeamID == CharacterTeamType.FriendlyNPC ? Color.SkyBlue : GUI.Style.Red;
|
||||
}
|
||||
if (CampaignInteractionType != CampaignMode.InteractionType.None && AllowCustomInteract)
|
||||
{
|
||||
@@ -902,7 +902,7 @@ namespace Barotrauma
|
||||
}
|
||||
var selectedSound = matchingSounds.GetRandom();
|
||||
if (selectedSound?.Sound == null) { return; }
|
||||
soundChannel = SoundPlayer.PlaySound(selectedSound.Sound, AnimController.WorldPosition, selectedSound.Volume, selectedSound.Range, hullGuess: CurrentHull);
|
||||
soundChannel = SoundPlayer.PlaySound(selectedSound.Sound, AnimController.WorldPosition, selectedSound.Volume, selectedSound.Range, hullGuess: CurrentHull, ignoreMuffling: selectedSound.IgnoreMuffling);
|
||||
soundTimer = soundInterval;
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace Barotrauma
|
||||
!ConversationAction.FadeScreenToBlack;
|
||||
}
|
||||
|
||||
private static string GetCachedHudText(string textTag, string keyBind)
|
||||
public static string GetCachedHudText(string textTag, string keyBind)
|
||||
{
|
||||
if (cachedHudTexts.TryGetValue(textTag + keyBind, out string text))
|
||||
{
|
||||
@@ -76,10 +76,10 @@ namespace Barotrauma
|
||||
{
|
||||
if (character.Inventory != null)
|
||||
{
|
||||
for (int i = 0; i < character.Inventory.Items.Length - 1; i++)
|
||||
for (int i = 0; i < character.Inventory.Capacity; i++)
|
||||
{
|
||||
var item = character.Inventory.Items[i];
|
||||
if (item == null || character.Inventory.SlotTypes[i] == InvSlotType.Any) continue;
|
||||
var item = character.Inventory.GetItemAt(i);
|
||||
if (item == null || character.Inventory.SlotTypes[i] == InvSlotType.Any) { continue; }
|
||||
|
||||
foreach (ItemComponent ic in item.Components)
|
||||
{
|
||||
@@ -131,10 +131,10 @@ namespace Barotrauma
|
||||
character.Inventory.ClearSubInventories();
|
||||
}
|
||||
|
||||
for (int i = 0; i < character.Inventory.Items.Length - 1; i++)
|
||||
for (int i = 0; i < character.Inventory.Capacity; i++)
|
||||
{
|
||||
var item = character.Inventory.Items[i];
|
||||
if (item == null || character.Inventory.SlotTypes[i] == InvSlotType.Any) continue;
|
||||
var item = character.Inventory.GetItemAt(i);
|
||||
if (item == null || character.Inventory.SlotTypes[i] == InvSlotType.Any) { continue; }
|
||||
|
||||
foreach (ItemComponent ic in item.Components)
|
||||
{
|
||||
@@ -206,22 +206,31 @@ namespace Barotrauma
|
||||
orderIndicatorCount.Clear();
|
||||
foreach (Pair<Order, float?> activeOrder in GameMain.GameSession.CrewManager.ActiveOrders)
|
||||
{
|
||||
if (!DrawIcon(activeOrder.First)) { continue; }
|
||||
|
||||
if (activeOrder.Second.HasValue)
|
||||
{
|
||||
DrawOrderIndicator(spriteBatch, cam, character, activeOrder.First, iconAlpha: MathHelper.Clamp(activeOrder.Second.Value / 10.0f, 0.2f, 1.0f));
|
||||
}
|
||||
else
|
||||
{
|
||||
float iconAlpha = GetDistanceBasedIconAlpha(activeOrder.First.TargetSpatialEntity, maxDistance: 350.0f);
|
||||
float iconAlpha = GetDistanceBasedIconAlpha(activeOrder.First.TargetSpatialEntity, maxDistance: 450.0f);
|
||||
if (iconAlpha <= 0.0f) { continue; }
|
||||
DrawOrderIndicator(spriteBatch, cam, character, activeOrder.First, iconAlpha: iconAlpha, createOffset: false, scaleMultiplier: 0.5f);
|
||||
DrawOrderIndicator(spriteBatch, cam, character, activeOrder.First,
|
||||
iconAlpha: iconAlpha, createOffset: false, scaleMultiplier: 0.5f, overrideAlpha: true);
|
||||
}
|
||||
}
|
||||
|
||||
if (character.CurrentOrder != null)
|
||||
if (DrawIcon(character.CurrentOrder))
|
||||
{
|
||||
DrawOrderIndicator(spriteBatch, cam, character, character.CurrentOrder, 1.0f);
|
||||
}
|
||||
|
||||
static bool DrawIcon(Order o) =>
|
||||
o != null &&
|
||||
(!(o.TargetEntity is Item i) ||
|
||||
o.DrawIconWhenContained ||
|
||||
i.GetRootInventoryOwner() == i);
|
||||
}
|
||||
|
||||
foreach (Character.ObjectiveEntity objectiveEntity in character.ActiveObjectiveEntities)
|
||||
@@ -231,7 +240,7 @@ namespace Barotrauma
|
||||
|
||||
foreach (Item brokenItem in brokenItems)
|
||||
{
|
||||
if (brokenItem.NonInteractable) { continue; }
|
||||
if (!brokenItem.IsInteractable(character)) { continue; }
|
||||
float alpha = GetDistanceBasedIconAlpha(brokenItem);
|
||||
if (alpha <= 0.0f) continue;
|
||||
GUI.DrawIndicator(spriteBatch, brokenItem.DrawPosition, cam, 100.0f, GUI.BrokenIcon,
|
||||
@@ -244,7 +253,7 @@ namespace Barotrauma
|
||||
return Math.Min((maxDistance - dist) / maxDistance * 2.0f, 1.0f);
|
||||
}
|
||||
|
||||
if (!character.IsIncapacitated && character.Stun <= 0.0f && !IsCampaignInterfaceOpen && (!character.IsKeyDown(InputType.Aim) || character.SelectedItems.Any(it => it?.GetComponent<Sprayer>() == null)))
|
||||
if (!character.IsIncapacitated && character.Stun <= 0.0f && !IsCampaignInterfaceOpen && (!character.IsKeyDown(InputType.Aim) || character.HeldItems.Any(it => it?.GetComponent<Sprayer>() == null)))
|
||||
{
|
||||
if (character.FocusedCharacter != null && character.FocusedCharacter.CanBeSelected)
|
||||
{
|
||||
@@ -291,8 +300,8 @@ namespace Barotrauma
|
||||
|
||||
int dir = Math.Sign(focusedItem.WorldPosition.X - character.WorldPosition.X);
|
||||
|
||||
Vector2 textSize = GUI.Font.MeasureString(focusedItem.Name);
|
||||
Vector2 largeTextSize = GUI.SubHeadingFont.MeasureString(focusedItem.Name);
|
||||
Vector2 textSize = GUI.Font.MeasureString(hudTexts.First().Text);
|
||||
Vector2 largeTextSize = GUI.SubHeadingFont.MeasureString(hudTexts.First().Text);
|
||||
|
||||
Vector2 startPos = cam.WorldToScreen(focusedItem.DrawPosition);
|
||||
startPos.Y -= (hudTexts.Count + 1) * textSize.Y;
|
||||
@@ -307,11 +316,11 @@ namespace Barotrauma
|
||||
|
||||
float alpha = MathHelper.Clamp((focusedItemOverlayTimer - ItemOverlayDelay) * 2.0f, 0.0f, 1.0f);
|
||||
|
||||
GUI.DrawString(spriteBatch, textPos, focusedItem.Name, GUI.Style.TextColor * alpha, Color.Black * alpha * 0.7f, 2, font: GUI.SubHeadingFont);
|
||||
GUI.DrawString(spriteBatch, textPos, hudTexts.First().Text, hudTexts.First().Color * alpha, Color.Black * alpha * 0.7f, 2, font: GUI.SubHeadingFont);
|
||||
startPos.X += dir * 10.0f * GUI.Scale;
|
||||
textPos.X += dir * 10.0f * GUI.Scale;
|
||||
textPos.Y += largeTextSize.Y;
|
||||
foreach (ColoredText coloredText in hudTexts)
|
||||
foreach (ColoredText coloredText in hudTexts.Skip(1))
|
||||
{
|
||||
if (dir == -1) textPos.X = (int)(startPos.X - GUI.SmallFont.MeasureString(coloredText.Text).X);
|
||||
GUI.DrawString(spriteBatch, textPos, coloredText.Text, coloredText.Color * alpha, Color.Black * alpha * 0.7f, 2, GUI.SmallFont);
|
||||
@@ -341,9 +350,8 @@ namespace Barotrauma
|
||||
}
|
||||
if (Character.Controlled.Inventory != null)
|
||||
{
|
||||
foreach (Item item in Character.Controlled.Inventory.Items)
|
||||
foreach (Item item in Character.Controlled.Inventory.AllItems)
|
||||
{
|
||||
if (item == null) { continue; }
|
||||
if (Character.Controlled.HasEquippedItem(item))
|
||||
{
|
||||
item.DrawHUD(spriteBatch, cam, Character.Controlled);
|
||||
@@ -355,10 +363,10 @@ namespace Barotrauma
|
||||
|
||||
if (character.Inventory != null)
|
||||
{
|
||||
for (int i = 0; i < character.Inventory.Items.Length - 1; i++)
|
||||
for (int i = 0; i < character.Inventory.Capacity; i++)
|
||||
{
|
||||
var item = character.Inventory.Items[i];
|
||||
if (item == null || character.Inventory.SlotTypes[i] == InvSlotType.Any) continue;
|
||||
var item = character.Inventory.GetItemAt(i);
|
||||
if (item == null || character.Inventory.SlotTypes[i] == InvSlotType.Any) { continue; }
|
||||
|
||||
foreach (ItemComponent ic in item.Components)
|
||||
{
|
||||
@@ -432,7 +440,10 @@ namespace Barotrauma
|
||||
|
||||
private static void DrawCharacterHoverTexts(SpriteBatch spriteBatch, Camera cam, Character character)
|
||||
{
|
||||
foreach (Item item in character.Inventory.Items)
|
||||
var allItems = character.Inventory?.AllItems;
|
||||
if (allItems != null)
|
||||
{
|
||||
foreach (Item item in allItems)
|
||||
{
|
||||
var statusHUD = item?.GetComponent<StatusHUD>();
|
||||
if (statusHUD != null && statusHUD.IsActive && statusHUD.VisibleCharacters.Contains(character.FocusedCharacter))
|
||||
@@ -440,6 +451,7 @@ namespace Barotrauma
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vector2 startPos = character.DrawPosition + (character.FocusedCharacter.DrawPosition - character.DrawPosition) * 0.7f;
|
||||
startPos = cam.WorldToScreen(startPos);
|
||||
@@ -454,7 +466,7 @@ namespace Barotrauma
|
||||
Color nameColor = GUI.Style.TextColor;
|
||||
if (character.TeamID != character.FocusedCharacter.TeamID)
|
||||
{
|
||||
nameColor = character.FocusedCharacter.TeamID == Character.TeamType.FriendlyNPC ? Color.SkyBlue : GUI.Style.Red;
|
||||
nameColor = character.FocusedCharacter.TeamID == CharacterTeamType.FriendlyNPC ? Color.SkyBlue : GUI.Style.Red;
|
||||
}
|
||||
|
||||
GUI.DrawString(spriteBatch, textPos, focusName, nameColor, Color.Black * 0.7f, 2, GUI.SubHeadingFont);
|
||||
@@ -493,7 +505,9 @@ namespace Barotrauma
|
||||
return character.ShouldLockHud();
|
||||
}
|
||||
|
||||
private static void DrawOrderIndicator(SpriteBatch spriteBatch, Camera cam, Character character, Order order, float iconAlpha = 1.0f, bool createOffset = true, float scaleMultiplier = 1.0f)
|
||||
/// <param name="overrideAlpha">Override the distance-based alpha value with the iconAlpha parameter value</param>
|
||||
private static void DrawOrderIndicator(SpriteBatch spriteBatch, Camera cam, Character character, Order order,
|
||||
float iconAlpha = 1.0f, bool createOffset = true, float scaleMultiplier = 1.0f, bool overrideAlpha = false)
|
||||
{
|
||||
if (order?.SymbolSprite == null) { return; }
|
||||
if (order.IsReport && order.OrderGiver != character && !order.HasAppropriateJob(character)) { return; }
|
||||
@@ -514,7 +528,8 @@ namespace Barotrauma
|
||||
Vector2 drawPos = target is Entity ? (target as Entity).DrawPosition :
|
||||
target.Submarine == null ? target.Position : target.Position + target.Submarine.DrawPosition;
|
||||
drawPos += Vector2.UnitX * order.SymbolSprite.size.X * 1.5f * orderIndicatorCount[target];
|
||||
GUI.DrawIndicator(spriteBatch, drawPos, cam, 100.0f, order.SymbolSprite, order.Color * iconAlpha, createOffset: createOffset, scaleMultiplier: scaleMultiplier);
|
||||
GUI.DrawIndicator(spriteBatch, drawPos, cam, 100.0f, order.SymbolSprite, order.Color * iconAlpha,
|
||||
createOffset: createOffset, scaleMultiplier: scaleMultiplier, overrideAlpha: overrideAlpha ? (float?)iconAlpha : null);
|
||||
|
||||
orderIndicatorCount[target] = orderIndicatorCount[target] + 1;
|
||||
}
|
||||
|
||||
@@ -152,34 +152,19 @@ namespace Barotrauma
|
||||
|
||||
partial void OnSkillChanged(string skillIdentifier, float prevLevel, float newLevel, Vector2 textPopupPos)
|
||||
{
|
||||
if (TeamID == Character.TeamType.FriendlyNPC) { return; }
|
||||
if (TeamID == CharacterTeamType.FriendlyNPC) { return; }
|
||||
if (Character.Controlled != null && Character.Controlled.TeamID != TeamID) { return; }
|
||||
|
||||
if (newLevel - prevLevel > 0.1f)
|
||||
{
|
||||
GUI.AddMessage(
|
||||
"+" + ((int)((newLevel - prevLevel) * 100.0f)).ToString() + " XP",
|
||||
GUI.Style.Green,
|
||||
textPopupPos,
|
||||
Vector2.UnitY * 10.0f,
|
||||
playSound: false);
|
||||
}
|
||||
else if (prevLevel % 0.1f > 0.05f && newLevel % 0.1f < 0.05f)
|
||||
{
|
||||
GUI.AddMessage(
|
||||
"+10 XP",
|
||||
GUI.Style.Green,
|
||||
textPopupPos,
|
||||
Vector2.UnitY * 10.0f,
|
||||
playSound: false);
|
||||
}
|
||||
|
||||
if ((int)newLevel > (int)prevLevel)
|
||||
{
|
||||
int increase = Math.Max((int)newLevel - (int)prevLevel, 1);
|
||||
GUI.AddMessage(
|
||||
TextManager.GetWithVariables("SkillIncreased", new string[3] { "[name]", "[skillname]", "[newlevel]" },
|
||||
new string[3] { Name, TextManager.Get("SkillName." + skillIdentifier), ((int)newLevel).ToString() },
|
||||
new bool[3] { false, true, false }), GUI.Style.Green);
|
||||
string.Format("+{0} {1}", increase, TextManager.Get("SkillName." + skillIdentifier)),
|
||||
GUI.Style.Green,
|
||||
textPopupPos,
|
||||
Vector2.UnitY * 10.0f,
|
||||
playSound: false,
|
||||
subId: Character?.Submarine?.ID ?? -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -349,7 +349,7 @@ namespace Barotrauma
|
||||
{
|
||||
string skillIdentifier = msg.ReadString();
|
||||
float skillLevel = msg.ReadSingle();
|
||||
info?.SetSkillLevel(skillIdentifier, skillLevel, WorldPosition + Vector2.UnitY * 150.0f);
|
||||
info?.SetSkillLevel(skillIdentifier, skillLevel, Position + Vector2.UnitY * 150.0f);
|
||||
}
|
||||
break;
|
||||
case 4: //NetEntityEvent.Type.ExecuteAttack
|
||||
@@ -434,7 +434,7 @@ namespace Barotrauma
|
||||
CharacterInfo info = CharacterInfo.ClientRead(infoSpeciesName, inc);
|
||||
|
||||
character = Create(speciesName, position, seed, characterInfo: info, id: id, isRemotePlayer: ownerId > 0 && GameMain.Client.ID != ownerId, hasAi: hasAi);
|
||||
character.TeamID = (TeamType)teamID;
|
||||
character.TeamID = (CharacterTeamType)teamID;
|
||||
character.CampaignInteractionType = (CampaignMode.InteractionType)inc.ReadByte();
|
||||
if (character.CampaignInteractionType != CampaignMode.InteractionType.None)
|
||||
{
|
||||
@@ -487,7 +487,7 @@ namespace Barotrauma
|
||||
character.ReadStatus(inc);
|
||||
}
|
||||
|
||||
if (character.IsHuman && character.TeamID != TeamType.FriendlyNPC && !character.IsDead)
|
||||
if (character.IsHuman && character.TeamID != CharacterTeamType.FriendlyNPC && !character.IsDead)
|
||||
{
|
||||
CharacterInfo duplicateCharacterInfo = GameMain.GameSession.CrewManager.GetCharacterInfos().FirstOrDefault(c => c.ID == info.ID);
|
||||
GameMain.GameSession.CrewManager.RemoveCharacterInfo(duplicateCharacterInfo);
|
||||
|
||||
@@ -18,6 +18,11 @@ namespace Barotrauma
|
||||
public float Range => roundSound == null ? 0.0f : roundSound.Range;
|
||||
public Sound Sound => roundSound?.Sound;
|
||||
|
||||
public bool IgnoreMuffling
|
||||
{
|
||||
get { return roundSound?.IgnoreMuffling ?? false; }
|
||||
}
|
||||
|
||||
public CharacterSound(CharacterParams.SoundParams soundParams)
|
||||
{
|
||||
Params = soundParams;
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace Barotrauma
|
||||
FadeTimer = 1.0f;
|
||||
if (!string.IsNullOrEmpty(textTag))
|
||||
{
|
||||
textTag = textTag;
|
||||
this.textTag = textTag;
|
||||
Text = TextManager.Get(textTag);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace Barotrauma
|
||||
{
|
||||
partial void UpdateMessages()
|
||||
{
|
||||
if (Prefab is AfflictionPrefabHusk { SendMessages: false }) { return; }
|
||||
switch (State)
|
||||
{
|
||||
case InfectionState.Dormant:
|
||||
|
||||
@@ -912,7 +912,7 @@ namespace Barotrauma
|
||||
|
||||
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)
|
||||
if (Inventory.DraggingItems.Any())
|
||||
{
|
||||
if (highlightedLimbIndex > -1)
|
||||
{
|
||||
@@ -1632,8 +1632,8 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
//can't apply treatment to dead characters
|
||||
if (Character.IsDead) return true;
|
||||
if (item == null || !item.UseInHealthInterface) return true;
|
||||
if (Character.IsDead) { return true; }
|
||||
if (item == null || !item.UseInHealthInterface) { return true; }
|
||||
if (!ignoreMousePos)
|
||||
{
|
||||
if (highlightedLimbIndex > -1)
|
||||
@@ -1652,33 +1652,25 @@ namespace Barotrauma
|
||||
private List<Item> GetAvailableMedicalItems()
|
||||
{
|
||||
List<Item> allInventoryItems = new List<Item>();
|
||||
allInventoryItems.AddRange(Character.Inventory.Items);
|
||||
allInventoryItems.AddRange(Character.Inventory.AllItems);
|
||||
if (Character.SelectedCharacter?.Inventory != null && Character.CanAccessInventory(Character.SelectedCharacter.Inventory))
|
||||
{
|
||||
allInventoryItems.AddRange(Character.SelectedCharacter.Inventory.Items);
|
||||
allInventoryItems.AddRange(Character.SelectedCharacter.Inventory.AllItems);
|
||||
}
|
||||
if (Character.SelectedBy?.Inventory != null)
|
||||
{
|
||||
allInventoryItems.AddRange(Character.SelectedBy.Inventory.Items);
|
||||
allInventoryItems.AddRange(Character.SelectedBy.Inventory.AllItems);
|
||||
}
|
||||
|
||||
List<Item> medicalItems = new List<Item>();
|
||||
foreach (Item item in allInventoryItems)
|
||||
{
|
||||
if (item == null) continue;
|
||||
|
||||
var containedItems = item.ContainedItems;
|
||||
if (containedItems != null)
|
||||
foreach (Item containedItem in item.ContainedItems)
|
||||
{
|
||||
foreach (Item containedItem in containedItems)
|
||||
{
|
||||
if (containedItem == null) continue;
|
||||
if (!containedItem.HasTag("medical") && !containedItem.HasTag("chem")) continue;
|
||||
if (!containedItem.HasTag("medical") && !containedItem.HasTag("chem")) { continue; }
|
||||
medicalItems.Add(containedItem);
|
||||
}
|
||||
}
|
||||
|
||||
if (!item.HasTag("medical") && !item.HasTag("chem")) continue;
|
||||
if (!item.HasTag("medical") && !item.HasTag("chem")) { continue; }
|
||||
medicalItems.Add(item);
|
||||
}
|
||||
|
||||
@@ -1804,6 +1796,8 @@ namespace Barotrauma
|
||||
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, Lights.CustomBlendStates.Multiplicative);
|
||||
|
||||
if (limbIndicatorOverlay != null)
|
||||
{
|
||||
float overlayScale = Math.Min(
|
||||
drawArea.Width / (float)limbIndicatorOverlay.FrameSize.X,
|
||||
drawArea.Height / (float)limbIndicatorOverlay.FrameSize.Y);
|
||||
@@ -1822,6 +1816,7 @@ namespace Barotrauma
|
||||
|
||||
limbIndicatorOverlay.Draw(spriteBatch, frame, drawArea.Center.ToVector2(), Color.Gray, origin: limbIndicatorOverlay.FrameSize.ToVector2() / 2, rotate: 0.0f,
|
||||
scale: Vector2.One * overlayScale);
|
||||
}
|
||||
|
||||
if (allowHighlight)
|
||||
{
|
||||
|
||||
@@ -22,8 +22,8 @@ namespace Barotrauma
|
||||
float strength = MathHelper.Lerp(0, 1, MathUtils.InverseLerp(0, MathHelper.Pi, diff));
|
||||
float jointAngle = JointAngle * strength;
|
||||
|
||||
JointBendDeformation limbADeformation = LimbA.Deformations.Find(d => d is JointBendDeformation) as JointBendDeformation;
|
||||
JointBendDeformation limbBDeformation = LimbB.Deformations.Find(d => d is JointBendDeformation) as JointBendDeformation;
|
||||
JointBendDeformation limbADeformation = LimbA.ActiveDeformations.Find(d => d is JointBendDeformation) as JointBendDeformation;
|
||||
JointBendDeformation limbBDeformation = LimbB.ActiveDeformations.Find(d => d is JointBendDeformation) as JointBendDeformation;
|
||||
|
||||
if (limbADeformation != null && limbBDeformation != null)
|
||||
{
|
||||
@@ -114,7 +114,10 @@ namespace Barotrauma
|
||||
/// Note that different limbs can share the same deformations.
|
||||
/// Use ragdoll.SpriteDeformations for a collection that cannot have duplicates.
|
||||
/// </summary>
|
||||
public List<SpriteDeformation> Deformations { get; private set; } = new List<SpriteDeformation>();
|
||||
private List<SpriteDeformation> Deformations { get; set; } = new List<SpriteDeformation>();
|
||||
private List<SpriteDeformation> NonConditionalDeformations { get; set; } = new List<SpriteDeformation>();
|
||||
private List<(ConditionalSprite, IEnumerable<SpriteDeformation>)> ConditionalDeformations { get; set; } = new List<(ConditionalSprite, IEnumerable<SpriteDeformation>)>();
|
||||
public List<SpriteDeformation> ActiveDeformations { get; set; } = new List<SpriteDeformation>();
|
||||
|
||||
public Sprite Sprite { get; protected set; }
|
||||
|
||||
@@ -178,6 +181,9 @@ namespace Barotrauma
|
||||
{
|
||||
public float RotationState;
|
||||
public float OffsetState;
|
||||
public Vector2 RandomOffsetMultiplier = new Vector2(Rand.Range(-1.0f, 1.0f), Rand.Range(-1.0f, 1.0f));
|
||||
public float RandomRotationFactor = Rand.Range(0.0f, 1.0f);
|
||||
public float RandomScaleFactor = Rand.Range(0.0f, 1.0f);
|
||||
public bool IsActive = true;
|
||||
}
|
||||
|
||||
@@ -282,12 +288,16 @@ namespace Barotrauma
|
||||
ConditionalSprites.Add(conditionalSprite);
|
||||
if (conditionalSprite.DeformableSprite != null)
|
||||
{
|
||||
CreateDeformations(subElement.GetChildElement("deformablesprite"));
|
||||
var conditionalDeformations = CreateDeformations(subElement.GetChildElement("deformablesprite"));
|
||||
Deformations.AddRange(conditionalDeformations);
|
||||
ConditionalDeformations.Add((conditionalSprite, conditionalDeformations));
|
||||
}
|
||||
break;
|
||||
case "deformablesprite":
|
||||
_deformSprite = new DeformableSprite(subElement, filePath: GetSpritePath(subElement, Params.deformSpriteParams));
|
||||
CreateDeformations(subElement);
|
||||
var deformations = CreateDeformations(subElement);
|
||||
Deformations.AddRange(deformations);
|
||||
NonConditionalDeformations.AddRange(deformations);
|
||||
break;
|
||||
case "lightsource":
|
||||
LightSource = new LightSource(subElement, GetConditionalTarget())
|
||||
@@ -315,8 +325,9 @@ namespace Barotrauma
|
||||
return targetEntity;
|
||||
}
|
||||
|
||||
void CreateDeformations(XElement e)
|
||||
IEnumerable<SpriteDeformation> CreateDeformations(XElement e)
|
||||
{
|
||||
List<SpriteDeformation> deformations = new List<SpriteDeformation>();
|
||||
foreach (XElement animationElement in e.GetChildElements("spritedeformation"))
|
||||
{
|
||||
int sync = animationElement.GetAttributeInt("sync", -1);
|
||||
@@ -340,14 +351,39 @@ namespace Barotrauma
|
||||
}
|
||||
if (deformation != null)
|
||||
{
|
||||
Deformations.Add(deformation);
|
||||
deformations.Add(deformation);
|
||||
}
|
||||
}
|
||||
return deformations;
|
||||
}
|
||||
}
|
||||
LightSource?.CheckConditionals();
|
||||
}
|
||||
|
||||
private void RefreshDeformations()
|
||||
{
|
||||
if (_deformSprite == null) { return; }
|
||||
if (ConditionalSprites.None())
|
||||
{
|
||||
ActiveDeformations = Deformations;
|
||||
}
|
||||
else
|
||||
{
|
||||
ActiveDeformations.Clear();
|
||||
if (_deformSprite == DeformSprite)
|
||||
{
|
||||
ActiveDeformations.AddRange(NonConditionalDeformations);
|
||||
}
|
||||
foreach (var conditionalDeformation in ConditionalDeformations)
|
||||
{
|
||||
if (conditionalDeformation.Item1.IsActive)
|
||||
{
|
||||
ActiveDeformations.AddRange(conditionalDeformation.Item2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RecreateSprites()
|
||||
{
|
||||
if (Sprite != null)
|
||||
@@ -390,19 +426,25 @@ namespace Barotrauma
|
||||
character.Info?.CalculateHeadPosition(sprite);
|
||||
}
|
||||
|
||||
private string _texturePath;
|
||||
private string GetSpritePath(XElement element, SpriteParams spriteParams)
|
||||
{
|
||||
if (_texturePath == null)
|
||||
{
|
||||
if (spriteParams != null)
|
||||
{
|
||||
return GetSpritePath(spriteParams.GetTexturePath());
|
||||
string texturePath = character.Params.VariantFile?.Root?.GetAttributeString("texture", null) ?? spriteParams.GetTexturePath();
|
||||
_texturePath = GetSpritePath(texturePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
string texturePath = element.GetAttributeString("texture", null);
|
||||
texturePath = string.IsNullOrWhiteSpace(texturePath) ? ragdoll.RagdollParams.Texture : texturePath;
|
||||
return GetSpritePath(texturePath);
|
||||
_texturePath = GetSpritePath(texturePath);
|
||||
}
|
||||
}
|
||||
return _texturePath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the full path of a limb sprite, taking into account tags, gender and head id
|
||||
@@ -537,7 +579,7 @@ namespace Barotrauma
|
||||
else
|
||||
{
|
||||
var spriteParams = Params.GetSprite();
|
||||
if (spriteParams.DeadColorTime > 0 && deadTimer < spriteParams.DeadColorTime)
|
||||
if (spriteParams != null && spriteParams.DeadColorTime > 0 && deadTimer < spriteParams.DeadColorTime)
|
||||
{
|
||||
deadTimer += deltaTime;
|
||||
}
|
||||
@@ -587,6 +629,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
UpdateSpriteStates(deltaTime);
|
||||
RefreshDeformations();
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, Camera cam, Color? overrideColor = null)
|
||||
@@ -637,13 +680,13 @@ namespace Barotrauma
|
||||
var deformSprite = DeformSprite;
|
||||
if (deformSprite != null)
|
||||
{
|
||||
if (Deformations != null && Deformations.Any())
|
||||
if (ActiveDeformations.Any())
|
||||
{
|
||||
var deformation = SpriteDeformation.GetDeformation(Deformations, deformSprite.Size);
|
||||
var deformation = SpriteDeformation.GetDeformation(ActiveDeformations, deformSprite.Size);
|
||||
deformSprite.Deform(deformation);
|
||||
if (LightSource != null && LightSource.DeformableLightSprite != null)
|
||||
{
|
||||
deformation = SpriteDeformation.GetDeformation(Deformations, deformSprite.Size, dir == Direction.Left);
|
||||
deformation = SpriteDeformation.GetDeformation(ActiveDeformations, deformSprite.Size, dir == Direction.Left);
|
||||
LightSource.DeformableLightSprite.Deform(deformation);
|
||||
}
|
||||
}
|
||||
@@ -666,9 +709,9 @@ namespace Barotrauma
|
||||
if (conditionalSprite.DeformableSprite != null)
|
||||
{
|
||||
var defSprite = conditionalSprite.DeformableSprite;
|
||||
if (Deformations != null && Deformations.Any())
|
||||
if (ActiveDeformations.Any())
|
||||
{
|
||||
var deformation = SpriteDeformation.GetDeformation(Deformations, defSprite.Size);
|
||||
var deformation = SpriteDeformation.GetDeformation(ActiveDeformations, defSprite.Size);
|
||||
defSprite.Deform(deformation);
|
||||
}
|
||||
else
|
||||
@@ -705,13 +748,13 @@ namespace Barotrauma
|
||||
c = Color.Lerp(c, spriteParams.DeadColor, MathUtils.InverseLerp(0, Params.GetSprite().DeadColorTime, deadTimer));
|
||||
}
|
||||
c = overrideColor ?? c;
|
||||
float rotation = decorativeSprite.GetRotation(ref spriteAnimState[decorativeSprite].RotationState);
|
||||
Vector2 offset = decorativeSprite.GetOffset(ref spriteAnimState[decorativeSprite].OffsetState) * Scale;
|
||||
float rotation = decorativeSprite.GetRotation(ref spriteAnimState[decorativeSprite].RotationState, spriteAnimState[decorativeSprite].RandomRotationFactor);
|
||||
Vector2 offset = decorativeSprite.GetOffset(ref spriteAnimState[decorativeSprite].OffsetState, spriteAnimState[decorativeSprite].RandomOffsetMultiplier) * Scale;
|
||||
var ca = (float)Math.Cos(-body.Rotation);
|
||||
var sa = (float)Math.Sin(-body.Rotation);
|
||||
Vector2 transformedOffset = new Vector2(ca * offset.X + sa * offset.Y, -sa * offset.X + ca * offset.Y);
|
||||
decorativeSprite.Sprite.Draw(spriteBatch, new Vector2(body.DrawPosition.X + transformedOffset.X, -(body.DrawPosition.Y + transformedOffset.Y)), c,
|
||||
-body.Rotation + rotation, decorativeSprite.Scale * Scale, spriteEffect,
|
||||
-body.Rotation + rotation, decorativeSprite.GetScale(spriteAnimState[decorativeSprite].RandomScaleFactor) * Scale, spriteEffect,
|
||||
depth: decorativeSprite.Sprite.Depth);
|
||||
}
|
||||
float depthStep = 0.000001f;
|
||||
|
||||
@@ -13,6 +13,8 @@ using System.Globalization;
|
||||
using FarseerPhysics;
|
||||
using Barotrauma.Extensions;
|
||||
using Barotrauma.Steam;
|
||||
using System.Threading.Tasks;
|
||||
using Barotrauma.MapCreatures.Behavior;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -69,6 +71,8 @@ namespace Barotrauma
|
||||
|
||||
private static readonly ChatManager chatManager = new ChatManager(true, 64);
|
||||
|
||||
public static Dictionary<Keys, string> Keybinds = new Dictionary<Keys, string>();
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
OpenAL.Alc.SetErrorReasonCallback((string msg) => NewMessage(msg, Color.Orange));
|
||||
@@ -145,6 +149,17 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
if (!IsOpen && GUI.KeyboardDispatcher.Subscriber == null)
|
||||
{
|
||||
foreach (var (key, command) in Keybinds)
|
||||
{
|
||||
if (PlayerInput.KeyHit(key))
|
||||
{
|
||||
ExecuteCommand(command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
activeQuestionText?.SetAsLastChild();
|
||||
|
||||
if (PlayerInput.KeyHit(Keys.F3))
|
||||
@@ -227,6 +242,13 @@ namespace Barotrauma
|
||||
case "fpscounter":
|
||||
case "dumptofile":
|
||||
case "findentityids":
|
||||
case "setfreecamspeed":
|
||||
case "togglevoicechatfilters":
|
||||
case "bindkey":
|
||||
case "savebinds":
|
||||
case "unbindkey":
|
||||
case "wikiimage_character":
|
||||
case "wikiimage_sub":
|
||||
return true;
|
||||
default:
|
||||
return client.HasConsoleCommandPermission(command);
|
||||
@@ -234,6 +256,8 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
public static void DequeueMessages()
|
||||
{
|
||||
lock (queuedMessages)
|
||||
{
|
||||
while (queuedMessages.Count > 0)
|
||||
{
|
||||
@@ -251,6 +275,7 @@ namespace Barotrauma
|
||||
if (GameSettings.SaveDebugConsoleLogs) unsavedMessages.Add(newMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddMessage(ColoredText msg)
|
||||
{
|
||||
@@ -487,6 +512,24 @@ namespace Barotrauma
|
||||
GameMain.CharacterEditorScreen.Select();
|
||||
}));
|
||||
|
||||
commands.Add(new Command("quickstart", "Starts a singleplayer sandbox", (string[] args) =>
|
||||
{
|
||||
if (Screen.Selected != GameMain.MainMenuScreen)
|
||||
{
|
||||
ThrowError("This command can only be executed from the main menu.");
|
||||
return;
|
||||
}
|
||||
|
||||
string subName = args.Length > 0 ? args[0] : "";
|
||||
if (string.IsNullOrWhiteSpace(subName))
|
||||
{
|
||||
ThrowError("No submarine specified.");
|
||||
return;
|
||||
}
|
||||
|
||||
GameMain.MainMenuScreen.QuickStart(fixedSeed: false, subName);
|
||||
}, getValidArgs: () => new[] { SubmarineInfo.SavedSubmarines.Select(s => s.Name).Distinct().ToArray() }));
|
||||
|
||||
commands.Add(new Command("steamnetdebug", "steamnetdebug: Toggles Steamworks networking debug logging.", (string[] args) =>
|
||||
{
|
||||
SteamManager.NetworkingDebugLog = !SteamManager.NetworkingDebugLog;
|
||||
@@ -498,6 +541,97 @@ namespace Barotrauma
|
||||
NewMessage("Ready checks can only be commenced in multiplayer.", Color.Red);
|
||||
}));
|
||||
|
||||
commands.Add(new Command("bindkey", "bindkey [key] [command]: Binds a key to a command.", (string[] args) =>
|
||||
{
|
||||
if (args.Length < 2)
|
||||
{
|
||||
ThrowError("No key or command specified.");
|
||||
return;
|
||||
}
|
||||
|
||||
string keyString = args[0];
|
||||
string command = args[1];
|
||||
|
||||
if (Enum.TryParse(typeof(Keys), keyString, ignoreCase: true, out object outKey) && outKey is Keys key)
|
||||
{
|
||||
if (Keybinds.ContainsKey(key))
|
||||
{
|
||||
Keybinds[key] = command;
|
||||
}
|
||||
else
|
||||
{
|
||||
Keybinds.Add(key, command);
|
||||
}
|
||||
NewMessage($"\"{command}\" bound to {key}.", GUI.Style.Green);
|
||||
|
||||
if (GameMain.Config.keyMapping.FirstOrDefault(bind => bind.Key != Keys.None && bind.Key == key) is { } existingBind)
|
||||
{
|
||||
AddWarning($"\"{key}\" has already been bound to {(InputType)GameMain.Config.keyMapping.IndexOf(existingBind)}. The keybind will perform both actions when pressed.");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ThrowError($"Invalid key {keyString}.");
|
||||
}, isCheat: false, getValidArgs: () => new[] { Enum.GetNames(typeof(Keys)), new[] { "\"\"" } }));
|
||||
|
||||
commands.Add(new Command("unbindkey", "unbindkey [key]: Unbinds a command.", (string[] args) =>
|
||||
{
|
||||
if (args.Length < 1)
|
||||
{
|
||||
ThrowError("No key specified.");
|
||||
return;
|
||||
}
|
||||
|
||||
string keyString = args[0];
|
||||
if (Enum.TryParse(typeof(Keys), keyString, ignoreCase: true, out object outKey) && outKey is Keys key)
|
||||
{
|
||||
if (Keybinds.ContainsKey(key))
|
||||
{
|
||||
Keybinds.Remove(key);
|
||||
}
|
||||
NewMessage("Keybind unbound.", GUI.Style.Green);
|
||||
return;
|
||||
}
|
||||
ThrowError($"Invalid key {keyString}.");
|
||||
}, isCheat: false, getValidArgs: () => new[] { Keybinds.Keys.Select(keys => keys.ToString()).Distinct().ToArray() }));
|
||||
|
||||
commands.Add(new Command("savebinds", "savebinds: Writes current keybinds into the config file.", (string[] args) =>
|
||||
{
|
||||
ShowQuestionPrompt($"Some keybinds may render the game unusable, are you sure you want to make these keybinds persistent? ({Keybinds.Count} keybind(s) assigned) Y/N",
|
||||
(option2) =>
|
||||
{
|
||||
if (option2.ToLower() != "y")
|
||||
{
|
||||
NewMessage("Aborted.", GUI.Style.Red);
|
||||
return;
|
||||
}
|
||||
|
||||
GameSettings.ConsoleKeybinds = new Dictionary<Keys, string>(Keybinds);
|
||||
GameMain.Config.SaveNewPlayerConfig();
|
||||
|
||||
NewMessage($"{Keybinds.Count} keybind(s) written to the config file.", GUI.Style.Green);
|
||||
});
|
||||
}, isCheat: false));
|
||||
|
||||
commands.Add(new Command("togglegrid", "Toggle visual snap grid in sub editor.", (string[] args) =>
|
||||
{
|
||||
SubEditorScreen.ShouldDrawGrid = !SubEditorScreen.ShouldDrawGrid;
|
||||
NewMessage(SubEditorScreen.ShouldDrawGrid ? "Enabled submarine grid." : "Disabled submarine grid.", GUI.Style.Green);
|
||||
}));
|
||||
|
||||
commands.Add(new Command("wikiimage_character", "Save an image of the currently controlled character with a transparent background.", (string[] args) =>
|
||||
{
|
||||
if (Character.Controlled == null) { return; }
|
||||
WikiImage.Create(Character.Controlled);
|
||||
}));
|
||||
|
||||
commands.Add(new Command("wikiimage_sub", "Save an image of the main submarine with a transparent background.", (string[] args) =>
|
||||
{
|
||||
if (Submarine.MainSub == null) { return; }
|
||||
WikiImage.Create(Submarine.MainSub);
|
||||
}));
|
||||
|
||||
AssignRelayToServer("kick", false);
|
||||
AssignRelayToServer("kickid", false);
|
||||
AssignRelayToServer("ban", false);
|
||||
@@ -510,11 +644,18 @@ namespace Barotrauma
|
||||
AssignRelayToServer("verboselogging", false);
|
||||
AssignRelayToServer("freecam", false);
|
||||
AssignRelayToServer("steamnetdebug", false);
|
||||
AssignRelayToServer("quickstart", false);
|
||||
AssignRelayToServer("togglegrid", false);
|
||||
AssignRelayToServer("bindkey", false);
|
||||
AssignRelayToServer("unbindkey", false);
|
||||
AssignRelayToServer("savebinds", false);
|
||||
#if DEBUG
|
||||
AssignRelayToServer("crash", false);
|
||||
AssignRelayToServer("showballastflorasprite", false);
|
||||
AssignRelayToServer("simulatedlatency", false);
|
||||
AssignRelayToServer("simulatedloss", false);
|
||||
AssignRelayToServer("simulatedduplicateschance", false);
|
||||
AssignRelayToServer("storeinfo", false);
|
||||
#endif
|
||||
|
||||
commands.Add(new Command("clientlist", "", (string[] args) => { }));
|
||||
@@ -998,6 +1139,17 @@ namespace Barotrauma
|
||||
});
|
||||
AssignRelayToServer("debugdraw", false);
|
||||
|
||||
AssignOnExecute("togglevoicechatfilters", (string[] args) =>
|
||||
{
|
||||
if (args.None() || !bool.TryParse(args[0], out bool state))
|
||||
{
|
||||
state = !GameMain.Config.DisableVoiceChatFilters;
|
||||
}
|
||||
GameMain.Config.DisableVoiceChatFilters = state;
|
||||
NewMessage("Voice chat filters " + (GameMain.Config.DisableVoiceChatFilters ? "disabled" : "enabled"), Color.White);
|
||||
});
|
||||
AssignRelayToServer("togglevoicechatfilters", false);
|
||||
|
||||
commands.Add(new Command("fpscounter", "fpscounter: Toggle the FPS counter.", (string[] args) =>
|
||||
{
|
||||
GameMain.ShowFPS = !GameMain.ShowFPS;
|
||||
@@ -1383,6 +1535,16 @@ namespace Barotrauma
|
||||
File.WriteAllLines(filePath, debugLines);
|
||||
ToolBox.OpenFileWithShell(Path.GetFullPath(filePath));
|
||||
}));
|
||||
|
||||
commands.Add(new Command("setfreecamspeed", "setfreecamspeed [speed]: Set the camera movement speed when not controlling a character. Defaults to 1.", (string[] args) =>
|
||||
{
|
||||
if (args.Length > 0)
|
||||
{
|
||||
float.TryParse(args[0], NumberStyles.Number, CultureInfo.InvariantCulture, out float speed);
|
||||
Screen.Selected.Cam.FreeCamMoveSpeed = speed;
|
||||
}
|
||||
}));
|
||||
|
||||
#if DEBUG
|
||||
commands.Add(new Command("setplanthealth", "setplanthealth [value]: Sets the health of the selected plant in sub editor.", (string[] args) =>
|
||||
{
|
||||
@@ -1417,6 +1579,12 @@ namespace Barotrauma
|
||||
}
|
||||
}));
|
||||
|
||||
commands.Add(new Command("showballastflorasprite", "", (string[] args) =>
|
||||
{
|
||||
BallastFloraBehavior.AlwaysShowBallastFloraSprite = !BallastFloraBehavior.AlwaysShowBallastFloraSprite;
|
||||
NewMessage("ok", GUI.Style.Green);
|
||||
}));
|
||||
|
||||
commands.Add(new Command("printreceivertransfers", "", (string[] args) =>
|
||||
{
|
||||
GameMain.Client.PrintReceiverTransters();
|
||||
@@ -1834,13 +2002,15 @@ namespace Barotrauma
|
||||
#if DEBUG
|
||||
commands.Add(new Command("querylobbies", "Queries all SteamP2P lobbies", (args) =>
|
||||
{
|
||||
Steamworks.Data.LobbyQuery lobbyQuery = Steamworks.SteamMatchmaking.CreateLobbyQuery().FilterDistanceWorldwide();
|
||||
|
||||
Steamworks.Data.Lobby[] lobbies = lobbyQuery.RequestAsync().Result;
|
||||
TaskPool.Add("DebugQueryLobbies",
|
||||
SteamManager.LobbyQueryRequest(), (t) => {
|
||||
var lobbies = ((Task<List<Steamworks.Data.Lobby>>)t).Result;
|
||||
foreach (var lobby in lobbies)
|
||||
{
|
||||
DebugConsole.NewMessage(lobby.GetData("name") + ", " + lobby.GetData("lobbyowner"));
|
||||
NewMessage(lobby.GetData("name") + ", " + lobby.GetData("lobbyowner"), Color.Yellow);
|
||||
}
|
||||
NewMessage($"Retrieved a total of {lobbies.Count} lobbies", Color.Lime);
|
||||
});
|
||||
}));
|
||||
|
||||
commands.Add(new Command("checkduplicates", "Checks the given language for duplicate translation keys and writes to file.", (string[] args) =>
|
||||
|
||||
@@ -210,9 +210,33 @@ namespace Barotrauma
|
||||
}
|
||||
};
|
||||
|
||||
double allowCloseTime = Timing.TotalTime + 0.5;
|
||||
closeButton.Children.ForEach(child => child.SpriteEffects = SpriteEffects.FlipVertically);
|
||||
closeButton.Frame.FadeIn(0.5f, 0.5f);
|
||||
closeButton.SlideIn(0.5f, 0.33f, 16, SlideDirection.Down);
|
||||
|
||||
InputType? closeInput = null;
|
||||
if (GameMain.Config.KeyBind(InputType.Use).MouseButton == MouseButton.None)
|
||||
{
|
||||
closeInput = InputType.Use;
|
||||
}
|
||||
else if (GameMain.Config.KeyBind(InputType.Select).MouseButton == MouseButton.None)
|
||||
{
|
||||
closeInput = InputType.Select;
|
||||
}
|
||||
if (closeInput.HasValue)
|
||||
{
|
||||
closeButton.ToolTip = TextManager.ParseInputTypes($"{TextManager.Get("Close")} ([InputType.{closeInput.Value}])");
|
||||
closeButton.OnAddedToGUIUpdateList += (GUIComponent component) =>
|
||||
{
|
||||
if (Timing.TotalTime > allowCloseTime && PlayerInput.KeyHit(closeInput.Value))
|
||||
{
|
||||
GUIButton btn = component as GUIButton;
|
||||
btn?.OnClicked(btn, btn.UserData);
|
||||
btn?.Flash(GUI.Style.Green);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < optionButtons.Count; i++)
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
GUI.DrawString(spriteBatch, new Vector2(10, y), "EventManager", Color.White, Color.Black * 0.6f, 0, GUI.SmallFont);
|
||||
GUI.DrawString(spriteBatch, new Vector2(15, y + 20), "Event cooldown: " + eventCoolDown, Color.White, Color.Black * 0.6f, 0, GUI.SmallFont);
|
||||
GUI.DrawString(spriteBatch, new Vector2(15, y + 20), "Event cooldown: " + (int)Math.Max(eventCoolDown, 0), Color.White, Color.Black * 0.6f, 0, GUI.SmallFont);
|
||||
GUI.DrawString(spriteBatch, new Vector2(15, y + 35), "Current intensity: " + (int)Math.Round(currentIntensity * 100), Color.Lerp(Color.White, GUI.Style.Red, currentIntensity), Color.Black * 0.6f, 0, GUI.SmallFont);
|
||||
GUI.DrawString(spriteBatch, new Vector2(15, y + 50), "Target intensity: " + (int)Math.Round(targetIntensity * 100), Color.Lerp(Color.White, GUI.Style.Red, targetIntensity), Color.Black * 0.6f, 0, GUI.SmallFont);
|
||||
|
||||
@@ -86,14 +86,25 @@ namespace Barotrauma
|
||||
new Vector2(graphRect.Right + 5, graphRect.Y + graphRect.Height * (1.0f - eventThreshold)), Color.Orange, 0, 1);
|
||||
|
||||
y = graphRect.Bottom + 20;
|
||||
if (eventCoolDown > 0.0f)
|
||||
int x = graphRect.X;
|
||||
if (isCrewAway && crewAwayDuration < settings.FreezeDurationWhenCrewAway)
|
||||
{
|
||||
GUI.DrawString(spriteBatch, new Vector2(graphRect.X, y), "Event cooldown active: " + (int) eventCoolDown, Color.LightGreen * 0.8f, null, 0, GUI.SmallFont);
|
||||
GUI.DrawString(spriteBatch, new Vector2(x, y), "Events frozen (crew away from sub): " + ToolBox.SecondsToReadableTime(settings.FreezeDurationWhenCrewAway - crewAwayDuration), Color.LightGreen * 0.8f, null, 0, GUI.SmallFont);
|
||||
y += 15;
|
||||
}
|
||||
else if (crewAwayResetTimer > 0.0f)
|
||||
{
|
||||
GUI.DrawString(spriteBatch, new Vector2(x, y), "Events frozen (crew just returned to the sub): " + ToolBox.SecondsToReadableTime(crewAwayResetTimer), Color.LightGreen * 0.8f, null, 0, GUI.SmallFont);
|
||||
y += 15;
|
||||
}
|
||||
else if (eventCoolDown > 0.0f)
|
||||
{
|
||||
GUI.DrawString(spriteBatch, new Vector2(x, y), "Event cooldown active: " + ToolBox.SecondsToReadableTime(eventCoolDown), Color.LightGreen * 0.8f, null, 0, GUI.SmallFont);
|
||||
y += 15;
|
||||
}
|
||||
else if (currentIntensity > eventThreshold)
|
||||
{
|
||||
GUI.DrawString(spriteBatch, new Vector2(graphRect.X, y),
|
||||
GUI.DrawString(spriteBatch, new Vector2(x, y),
|
||||
"Intensity too high for new events: " + (int)(currentIntensity * 100) + "%/" + (int)(eventThreshold * 100) + "%", Color.LightGreen * 0.8f, null, 0, GUI.SmallFont);
|
||||
y += 15;
|
||||
}
|
||||
@@ -102,22 +113,27 @@ namespace Barotrauma
|
||||
{
|
||||
if (Submarine.MainSub == null) { break; }
|
||||
|
||||
GUI.DrawString(spriteBatch, new Vector2(graphRect.X, y), "New event (ID " + eventSet.DebugIdentifier + ") after: ", Color.Orange * 0.8f, null, 0, GUI.SmallFont);
|
||||
GUI.DrawString(spriteBatch, new Vector2(x, y), "New event (ID " + eventSet.DebugIdentifier + ") after: ", Color.Orange * 0.8f, null, 0, GUI.SmallFont);
|
||||
y += 12;
|
||||
|
||||
if (eventSet.PerCave)
|
||||
{
|
||||
GUI.DrawString(spriteBatch, new Vector2(x, y), " submarine near cave", Color.Orange * 0.8f, null, 0, GUI.SmallFont);
|
||||
y += 12;
|
||||
}
|
||||
if (eventSet.PerWreck)
|
||||
{
|
||||
GUI.DrawString(spriteBatch, new Vector2(graphRect.X, y), " submarine near the wreck", Color.Orange * 0.8f, null, 0, GUI.SmallFont);
|
||||
GUI.DrawString(spriteBatch, new Vector2(x, y), " submarine near the wreck", Color.Orange * 0.8f, null, 0, GUI.SmallFont);
|
||||
y += 12;
|
||||
}
|
||||
if (eventSet.PerRuin)
|
||||
{
|
||||
GUI.DrawString(spriteBatch, new Vector2(graphRect.X, y), " submarine near the ruins", Color.Orange * 0.8f, null, 0, GUI.SmallFont);
|
||||
GUI.DrawString(spriteBatch, new Vector2(x, y), " submarine near the ruins", Color.Orange * 0.8f, null, 0, GUI.SmallFont);
|
||||
y += 12;
|
||||
}
|
||||
if (roundDuration < eventSet.MinMissionTime)
|
||||
{
|
||||
GUI.DrawString(spriteBatch, new Vector2(graphRect.X, y),
|
||||
GUI.DrawString(spriteBatch, new Vector2(x, y),
|
||||
" " + (int) (eventSet.MinDistanceTraveled * 100.0f) + "% travelled (current: " + (int) (distanceTraveled * 100.0f) + " %)",
|
||||
((Submarine.MainSub == null || distanceTraveled < eventSet.MinDistanceTraveled) ? Color.Lerp(GUI.Style.Yellow, GUI.Style.Red, eventSet.MinDistanceTraveled - distanceTraveled) : GUI.Style.Green) * 0.8f, null, 0, GUI.SmallFont);
|
||||
y += 12;
|
||||
@@ -125,7 +141,7 @@ namespace Barotrauma
|
||||
|
||||
if (CurrentIntensity < eventSet.MinIntensity || CurrentIntensity > eventSet.MaxIntensity)
|
||||
{
|
||||
GUI.DrawString(spriteBatch, new Vector2(graphRect.X, y),
|
||||
GUI.DrawString(spriteBatch, new Vector2(x, y),
|
||||
" intensity between " + ((int) eventSet.MinIntensity) + " and " + ((int) eventSet.MaxIntensity),
|
||||
Color.Orange * 0.8f, null, 0, GUI.SmallFont);
|
||||
y += 12;
|
||||
@@ -133,22 +149,28 @@ namespace Barotrauma
|
||||
|
||||
if (roundDuration < eventSet.MinMissionTime)
|
||||
{
|
||||
GUI.DrawString(spriteBatch, new Vector2(graphRect.X, y),
|
||||
GUI.DrawString(spriteBatch, new Vector2(x, y),
|
||||
" " + (int) (eventSet.MinMissionTime - roundDuration) + " s",
|
||||
Color.Lerp(GUI.Style.Yellow, GUI.Style.Red, (eventSet.MinMissionTime - roundDuration)), null, 0, GUI.SmallFont);
|
||||
}
|
||||
|
||||
y += 15;
|
||||
|
||||
if (y > GameMain.GraphicsHeight * 0.9f)
|
||||
{
|
||||
y = graphRect.Bottom + 35;
|
||||
x += 250;
|
||||
}
|
||||
}
|
||||
|
||||
GUI.DrawString(spriteBatch, new Vector2(graphRect.X, y), "Current events: ", Color.White * 0.9f, null, 0, GUI.SmallFont);
|
||||
GUI.DrawString(spriteBatch, new Vector2(x, y), "Current events: ", Color.White * 0.9f, null, 0, GUI.SmallFont);
|
||||
y += 15;
|
||||
|
||||
foreach (Event ev in activeEvents.Where(ev => !ev.IsFinished || PlayerInput.IsShiftDown()))
|
||||
{
|
||||
GUI.DrawString(spriteBatch, new Vector2(graphRect.X + 5, y), ev.ToString(), (!ev.IsFinished ? Color.White : Color.Red) * 0.8f, null, 0, GUI.SmallFont);
|
||||
GUI.DrawString(spriteBatch, new Vector2(x + 5, y), ev.ToString(), (!ev.IsFinished ? Color.White : Color.Red) * 0.8f, null, 0, GUI.SmallFont);
|
||||
|
||||
Rectangle rect = new Rectangle(new Point(graphRect.X + 5, y), GUI.SmallFont.MeasureString(ev.ToString()).ToPoint());
|
||||
Rectangle rect = new Rectangle(new Point(x + 5, y), GUI.SmallFont.MeasureString(ev.ToString()).ToPoint());
|
||||
|
||||
Rectangle outlineRect = new Rectangle(rect.Location, rect.Size);
|
||||
outlineRect.Inflate(4, 4);
|
||||
@@ -176,6 +198,11 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
y += 18;
|
||||
if (y > GameMain.GraphicsHeight * 0.9f)
|
||||
{
|
||||
y = graphRect.Bottom + 35;
|
||||
x += 250;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -333,7 +360,7 @@ namespace Barotrauma
|
||||
$"Spawn pending: {artifactEvent.SpawnPending.ColorizeObject()}\n" +
|
||||
$"Spawn position: {artifactEvent.SpawnPos.ColorizeObject()}\n";
|
||||
|
||||
if (artifactEvent.Item != null)
|
||||
if (artifactEvent.Item != null && !artifactEvent.Item.Removed)
|
||||
{
|
||||
Vector2 pos = artifactEvent.Item.WorldPosition;
|
||||
positions.Add(new DebugLine(pos, Color.White));
|
||||
@@ -364,7 +391,8 @@ namespace Barotrauma
|
||||
|
||||
foreach (Character monster in monsterEvent.Monsters)
|
||||
{
|
||||
text += $" {monster.ColorizeObject()} -> (Dead: {monster.IsDead.ColorizeObject()}, Health: {monster.HealthPercentage.ColorizeObject()}%, AIState: {(monster.AIController?.State).ColorizeObject()})\n";
|
||||
text += $" {monster.ColorizeObject()} -> (Dead: {monster.IsDead.ColorizeObject()}, Health: {monster.HealthPercentage.ColorizeObject()}%, AIState: {(monster.AIController is EnemyAIController enemyAI ? enemyAI.State : AIState.Idle ).ColorizeObject()})\n";
|
||||
if (monster.Removed) { continue; }
|
||||
positions.Add(new DebugLine(monster.WorldPosition, Color.Red));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
using Barotrauma.Networking;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
//team specific
|
||||
return descriptions[GameMain.Client.Character.TeamID == Character.TeamType.Team1 ? 1 : 2];
|
||||
return descriptions[GameMain.Client.Character.TeamID == CharacterTeamType.Team1 ? 1 : 2];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,23 @@ namespace Barotrauma
|
||||
{
|
||||
public override void ClientReadInitial(IReadMessage msg)
|
||||
{
|
||||
byte caveCount = msg.ReadByte();
|
||||
for (int i = 0; i < caveCount; i++)
|
||||
{
|
||||
byte selectedCave = msg.ReadByte();
|
||||
if (selectedCave < 255 && Level.Loaded != null)
|
||||
{
|
||||
if (selectedCave < Level.Loaded.Caves.Count)
|
||||
{
|
||||
Level.Loaded.Caves[selectedCave].DisplayOnSonar = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.ThrowError($"Cave index out of bounds when reading nest mission data. Index: {selectedCave}, number of caves: {Level.Loaded.Caves.Count}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < ResourceClusters.Count; i++)
|
||||
{
|
||||
var amount = msg.ReadByte();
|
||||
|
||||
@@ -8,9 +8,23 @@ namespace Barotrauma
|
||||
{
|
||||
public override void ClientReadInitial(IReadMessage msg)
|
||||
{
|
||||
byte selectedCaveIndex = msg.ReadByte();
|
||||
nestPosition = new Vector2(
|
||||
msg.ReadSingle(),
|
||||
msg.ReadSingle());
|
||||
if (selectedCaveIndex < 255 && Level.Loaded != null)
|
||||
{
|
||||
if (selectedCaveIndex < Level.Loaded.Caves.Count)
|
||||
{
|
||||
Level.Loaded.Caves[selectedCaveIndex].DisplayOnSonar = true;
|
||||
SpawnNestObjects(Level.Loaded, Level.Loaded.Caves[selectedCaveIndex]);
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.ThrowError($"Cave index out of bounds when reading nest mission data. Index: {selectedCaveIndex}, number of caves: {Level.Loaded.Caves.Count}");
|
||||
}
|
||||
}
|
||||
|
||||
ushort itemCount = msg.ReadUInt16();
|
||||
for (int i = 0; i < itemCount; i++)
|
||||
{
|
||||
|
||||
@@ -287,6 +287,7 @@ namespace Barotrauma
|
||||
{
|
||||
lock (mutex)
|
||||
{
|
||||
usedIndicatorAngles.Clear();
|
||||
|
||||
if (ScreenChanged)
|
||||
{
|
||||
@@ -1117,15 +1118,26 @@ namespace Barotrauma
|
||||
/// Set the cursor to an hourglass.
|
||||
/// Will automatically revert after 10 seconds or when <see cref="ClearCursorWait"/> is called.
|
||||
/// </summary>
|
||||
public static void SetCursorWaiting()
|
||||
public static void SetCursorWaiting(int waitSeconds = 10, Func<bool> endCondition = null)
|
||||
{
|
||||
CoroutineManager.StartCoroutine(WaitCursorCoroutine(), "WaitCursorTimeout");
|
||||
|
||||
static IEnumerable<object> WaitCursorCoroutine()
|
||||
IEnumerable<object> WaitCursorCoroutine()
|
||||
{
|
||||
MouseCursor = CursorState.Waiting;
|
||||
var timeOut = DateTime.Now + new TimeSpan(0, 0, 10);
|
||||
while (DateTime.Now < timeOut) { yield return CoroutineStatus.Running; }
|
||||
var timeOut = DateTime.Now + new TimeSpan(0, 0, waitSeconds);
|
||||
while (DateTime.Now < timeOut)
|
||||
{
|
||||
if (endCondition != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (endCondition.Invoke()) { break; }
|
||||
}
|
||||
catch { break; }
|
||||
}
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
if (MouseCursor == CursorState.Waiting) { MouseCursor = CursorState.Default; }
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
@@ -1219,7 +1231,7 @@ namespace Barotrauma
|
||||
{
|
||||
foreach (GUIMessage msg in messages)
|
||||
{
|
||||
if (msg.WorldSpace) continue;
|
||||
if (msg.WorldSpace) { continue; }
|
||||
msg.Timer -= deltaTime;
|
||||
|
||||
if (msg.Size.X > HUDLayoutSettings.MessageAreaTop.Width)
|
||||
@@ -1244,7 +1256,7 @@ namespace Barotrauma
|
||||
|
||||
foreach (GUIMessage msg in messages)
|
||||
{
|
||||
if (!msg.WorldSpace) continue;
|
||||
if (!msg.WorldSpace) { continue; }
|
||||
msg.Timer -= deltaTime;
|
||||
msg.Pos += msg.Velocity * deltaTime;
|
||||
}
|
||||
@@ -1256,18 +1268,21 @@ namespace Barotrauma
|
||||
|
||||
#region Element drawing
|
||||
|
||||
private static List<float> usedIndicatorAngles = new List<float>();
|
||||
|
||||
/// <param name="createOffset">Should the indicator move based on the camera position?</param>
|
||||
public static void DrawIndicator(SpriteBatch spriteBatch, Vector2 worldPosition, Camera cam, float hideDist, Sprite sprite, Color color, bool createOffset = true, float scaleMultiplier = 1.0f)
|
||||
/// <param name="overrideAlpha">Override the distance-based alpha value with the specified alpha value</param>
|
||||
public static void DrawIndicator(SpriteBatch spriteBatch, Vector2 worldPosition, Camera cam, float hideDist, Sprite sprite, Color color,
|
||||
bool createOffset = true, float scaleMultiplier = 1.0f, float? overrideAlpha = null)
|
||||
{
|
||||
Vector2 diff = worldPosition - cam.WorldViewCenter;
|
||||
float dist = diff.Length();
|
||||
|
||||
float symbolScale = Math.Min(64.0f / sprite.size.X, 1.0f) * scaleMultiplier;
|
||||
|
||||
if (dist > hideDist)
|
||||
if (overrideAlpha.HasValue || dist > hideDist)
|
||||
{
|
||||
float alpha = Math.Min((dist - hideDist) / 100.0f, 1.0f);
|
||||
float alpha = overrideAlpha ?? Math.Min((dist - hideDist) / 100.0f, 1.0f);
|
||||
Vector2 targetScreenPos = cam.WorldToScreen(worldPosition);
|
||||
|
||||
if (!createOffset)
|
||||
@@ -1279,6 +1294,28 @@ namespace Barotrauma
|
||||
float screenDist = Vector2.Distance(cam.WorldToScreen(cam.WorldViewCenter), targetScreenPos);
|
||||
float angle = MathUtils.VectorToAngle(diff);
|
||||
|
||||
float minAngleDiff = 0.05f;
|
||||
bool overlapFound = true;
|
||||
int iterations = 0;
|
||||
while (overlapFound && iterations < 10)
|
||||
{
|
||||
overlapFound = false;
|
||||
foreach (float usedIndicatorAngle in usedIndicatorAngles)
|
||||
{
|
||||
float shortestAngle = MathUtils.GetShortestAngle(angle, usedIndicatorAngle);
|
||||
if (MathUtils.NearlyEqual(shortestAngle, 0.0f)) { shortestAngle = 0.01f; }
|
||||
if (Math.Abs(shortestAngle) < minAngleDiff)
|
||||
{
|
||||
angle -= Math.Sign(shortestAngle) * (minAngleDiff - Math.Abs(shortestAngle));
|
||||
overlapFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
iterations++;
|
||||
}
|
||||
|
||||
usedIndicatorAngles.Add(angle);
|
||||
|
||||
Vector2 unclampedDiff = new Vector2(
|
||||
(float)Math.Cos(angle) * screenDist,
|
||||
(float)-Math.Sin(angle) * screenDist);
|
||||
@@ -1489,12 +1526,12 @@ namespace Barotrauma
|
||||
|
||||
foreach (GUIMessage msg in messages)
|
||||
{
|
||||
if (msg.WorldSpace) continue;
|
||||
if (msg.WorldSpace) { continue; }
|
||||
|
||||
Vector2 drawPos = new Vector2(HUDLayoutSettings.MessageAreaTop.Right, HUDLayoutSettings.MessageAreaTop.Center.Y);
|
||||
|
||||
msg.Font.DrawString(spriteBatch, msg.Text, drawPos + msg.Pos + Vector2.One, Color.Black, 0, msg.Origin, 1.0f, SpriteEffects.None, 0);
|
||||
msg.Font.DrawString(spriteBatch, msg.Text, drawPos + msg.Pos, msg.Color, 0, msg.Origin, 1.0f, SpriteEffects.None, 0);
|
||||
msg.Font.DrawString(spriteBatch, msg.Text, drawPos + msg.DrawPos + Vector2.One, Color.Black, 0, msg.Origin, 1.0f, SpriteEffects.None, 0);
|
||||
msg.Font.DrawString(spriteBatch, msg.Text, drawPos + msg.DrawPos, msg.Color, 0, msg.Origin, 1.0f, SpriteEffects.None, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1507,14 +1544,14 @@ namespace Barotrauma
|
||||
|
||||
foreach (GUIMessage msg in messages)
|
||||
{
|
||||
if (!msg.WorldSpace) continue;
|
||||
if (!msg.WorldSpace) { continue; }
|
||||
|
||||
if (cam != null)
|
||||
{
|
||||
float alpha = 1.0f;
|
||||
if (msg.Timer < 1.0f) alpha -= 1.0f - msg.Timer;
|
||||
if (msg.Timer < 1.0f) { alpha -= 1.0f - msg.Timer; }
|
||||
|
||||
Vector2 drawPos = cam.WorldToScreen(msg.Pos);
|
||||
Vector2 drawPos = cam.WorldToScreen(msg.DrawPos);
|
||||
msg.Font.DrawString(spriteBatch, msg.Text, drawPos + Vector2.One, Color.Black * alpha, 0, msg.Origin, 1.0f, SpriteEffects.None, 0);
|
||||
msg.Font.DrawString(spriteBatch, msg.Text, drawPos, msg.Color * alpha, 0, msg.Origin, 1.0f, SpriteEffects.None, 0);
|
||||
}
|
||||
@@ -1608,7 +1645,8 @@ namespace Barotrauma
|
||||
|
||||
public static Texture2D CreateCapsule(int radius, int height)
|
||||
{
|
||||
int textureWidth = radius * 2, textureHeight = height + radius * 2;
|
||||
int textureWidth = Math.Max(radius * 2, 1);
|
||||
int textureHeight = Math.Max(height + radius * 2, 1);
|
||||
|
||||
Color[] data = new Color[textureWidth * textureHeight];
|
||||
|
||||
@@ -2079,7 +2117,7 @@ namespace Barotrauma
|
||||
|
||||
if (pauseMenuOpen)
|
||||
{
|
||||
Inventory.draggingItem = null;
|
||||
Inventory.DraggingItems.Clear();
|
||||
Inventory.DraggingInventory = null;
|
||||
|
||||
PauseMenu = new GUIFrame(new RectTransform(Vector2.One, Canvas, Anchor.Center), style: null);
|
||||
@@ -2288,9 +2326,10 @@ namespace Barotrauma
|
||||
if (playSound) SoundPlayer.PlayUISound(GUISoundType.UIMessage);
|
||||
}
|
||||
|
||||
public static void AddMessage(string message, Color color, Vector2 worldPos, Vector2 velocity, float lifeTime = 3.0f, bool playSound = true, GUISoundType soundType = GUISoundType.UIMessage)
|
||||
public static void AddMessage(string message, Color color, Vector2 pos, Vector2 velocity, float lifeTime = 3.0f, bool playSound = true, GUISoundType soundType = GUISoundType.UIMessage, int subId = -1)
|
||||
{
|
||||
messages.Add(new GUIMessage(message, color, worldPos, velocity, lifeTime, Alignment.Center, LargeFont));
|
||||
Submarine sub = Submarine.Loaded.FirstOrDefault(s => s.ID == subId);
|
||||
messages.Add(new GUIMessage(message, color, pos, velocity, lifeTime, Alignment.Center, LargeFont, sub: sub));
|
||||
if (playSound) SoundPlayer.PlayUISound(soundType);
|
||||
}
|
||||
|
||||
|
||||
210
Barotrauma/BarotraumaClient/ClientSource/GUI/GUIColorPicker.cs
Normal file
210
Barotrauma/BarotraumaClient/ClientSource/GUI/GUIColorPicker.cs
Normal file
@@ -0,0 +1,210 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
public class GUIColorPicker : GUIComponent
|
||||
{
|
||||
public delegate bool OnColorSelectedHandler(GUIColorPicker component, Color color);
|
||||
public OnColorSelectedHandler? OnColorSelected;
|
||||
|
||||
public float SelectedHue;
|
||||
public float SelectedSaturation;
|
||||
public float SelectedValue;
|
||||
|
||||
public Color CurrentColor = Color.Black;
|
||||
|
||||
private Rectangle MainArea,
|
||||
HueArea;
|
||||
|
||||
private Texture2D? mainTexture,
|
||||
hueTexture;
|
||||
|
||||
private Color[]? colorData;
|
||||
|
||||
private Rectangle selectedRect;
|
||||
|
||||
private bool mouseHeld;
|
||||
private bool isInitialized;
|
||||
|
||||
private readonly Color transparentWhite = Color.White * 0.8f,
|
||||
transparentBlack = Color.Black * 0.8f;
|
||||
|
||||
public GUIColorPicker(RectTransform rectT, string? style = null) : base(style, rectT) { }
|
||||
|
||||
~GUIColorPicker()
|
||||
{
|
||||
DisposeTextures();
|
||||
}
|
||||
|
||||
private void Init()
|
||||
{
|
||||
int tWidth = Rect.Width;
|
||||
int sliceWidth = Rect.Width / 8;
|
||||
|
||||
int mainWidth = tWidth - sliceWidth;
|
||||
int hueWidth = sliceWidth;
|
||||
|
||||
MainArea = new Rectangle(0, 0, mainWidth, Rect.Height);
|
||||
HueArea = new Rectangle(mainWidth, 0, hueWidth, Rect.Height);
|
||||
|
||||
colorData = new Color[MainArea.Width * MainArea.Height];
|
||||
|
||||
if (mainTexture == null)
|
||||
{
|
||||
int width = MainArea.Width,
|
||||
height = MainArea.Height;
|
||||
|
||||
GenerateGradient(ref colorData!, width, height, DrawHVArea);
|
||||
mainTexture = CreateGradientTexture(colorData!, MainArea.Width, MainArea.Height);
|
||||
}
|
||||
|
||||
if (hueTexture == null)
|
||||
{
|
||||
int width = HueArea.Width,
|
||||
height = HueArea.Height;
|
||||
|
||||
Color[] hueData = new Color[width * height];
|
||||
|
||||
GenerateGradient(ref hueData, width, height, DrawHueArea);
|
||||
hueTexture = CreateGradientTexture(hueData, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
if (mainTexture == null || hueTexture == null || !isInitialized) { return; }
|
||||
|
||||
Rectangle mainArea = MainArea,
|
||||
hueArea = HueArea;
|
||||
|
||||
hueArea.Location += Rect.Location;
|
||||
mainArea.Location += Rect.Location;
|
||||
|
||||
Vector2 mainLocation = mainArea.Location.ToVector2(),
|
||||
hueLocation = hueArea.Location.ToVector2();
|
||||
|
||||
spriteBatch.Draw(mainTexture, mainLocation, Color.White);
|
||||
spriteBatch.Draw(hueTexture, hueLocation, Color.White);
|
||||
|
||||
float hueY = hueLocation.Y + ((SelectedHue / 360f) * hueArea.Height);
|
||||
spriteBatch.DrawLine(hueArea.Left, hueY, hueArea.Right, hueY, transparentWhite, thickness: 3);
|
||||
spriteBatch.DrawLine(hueArea.Left, hueY, hueArea.Right, hueY, transparentBlack, thickness: 1);
|
||||
|
||||
float saturationX = mainLocation.X + SelectedSaturation * MainArea.Width;
|
||||
float valueY = mainLocation.Y + (1.0f - SelectedValue) * MainArea.Height;
|
||||
|
||||
spriteBatch.DrawLine(saturationX, mainArea.Top,saturationX, mainArea.Bottom, transparentWhite, thickness: 3);
|
||||
spriteBatch.DrawLine(mainArea.Left,valueY, mainArea.Right, valueY, transparentWhite, thickness: 3);
|
||||
|
||||
spriteBatch.DrawLine(saturationX, mainArea.Top,saturationX, mainArea.Bottom, transparentBlack, thickness: 1);
|
||||
spriteBatch.DrawLine(mainArea.Left,valueY, mainArea.Right, valueY, transparentBlack, thickness: 1);
|
||||
}
|
||||
|
||||
protected override void Update(float deltaTime)
|
||||
{
|
||||
base.Update(deltaTime);
|
||||
|
||||
if (!isInitialized)
|
||||
{
|
||||
Init();
|
||||
isInitialized = true;
|
||||
}
|
||||
|
||||
if (!PlayerInput.PrimaryMouseButtonHeld())
|
||||
{
|
||||
mouseHeld = false;
|
||||
}
|
||||
|
||||
if (GUI.MouseOn != this) { return; }
|
||||
|
||||
Rectangle mainArea = MainArea,
|
||||
hueArea = HueArea;
|
||||
|
||||
hueArea.Location += Rect.Location;
|
||||
mainArea.Location += Rect.Location;
|
||||
|
||||
if (PlayerInput.PrimaryMouseButtonDown())
|
||||
{
|
||||
mouseHeld = true;
|
||||
if (hueArea.Contains(PlayerInput.MousePosition))
|
||||
{
|
||||
selectedRect = HueArea;
|
||||
}
|
||||
else if (mainArea.Contains(PlayerInput.MousePosition))
|
||||
{
|
||||
selectedRect = MainArea;
|
||||
}
|
||||
else
|
||||
{
|
||||
mouseHeld = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!PlayerInput.PrimaryMouseButtonHeld())
|
||||
{
|
||||
mouseHeld = false;
|
||||
}
|
||||
|
||||
if (mouseHeld && (PlayerInput.MouseSpeed != Vector2.Zero || PlayerInput.PrimaryMouseButtonDown()))
|
||||
{
|
||||
if (selectedRect == HueArea)
|
||||
{
|
||||
Vector2 pos = PlayerInput.MousePosition - hueArea.Location.ToVector2();
|
||||
SelectedHue = Math.Clamp(pos.Y / hueArea.Height * 360f, 0, 360);
|
||||
RefreshHue();
|
||||
|
||||
}
|
||||
else if (selectedRect == MainArea)
|
||||
{
|
||||
var (x, y) = PlayerInput.MousePosition - mainArea.Location.ToVector2();
|
||||
SelectedSaturation = Math.Clamp(x / mainArea.Width, 0, 1);
|
||||
SelectedValue = Math.Clamp(1f - (y / mainArea.Height), 0, 1);
|
||||
}
|
||||
|
||||
CurrentColor = ToolBox.HSVToRGB(SelectedHue, SelectedSaturation, SelectedValue);
|
||||
|
||||
OnColorSelected?.Invoke(this, CurrentColor);
|
||||
}
|
||||
}
|
||||
|
||||
public void DisposeTextures()
|
||||
{
|
||||
mainTexture?.Dispose();
|
||||
hueTexture?.Dispose();
|
||||
}
|
||||
|
||||
public void RefreshHue()
|
||||
{
|
||||
if (colorData == null || mainTexture == null) { return; }
|
||||
GenerateGradient(ref colorData, mainTexture.Width, mainTexture.Height, DrawHVArea);
|
||||
mainTexture.SetData(colorData);
|
||||
}
|
||||
|
||||
private Texture2D CreateGradientTexture(Color[] data, int width, int height)
|
||||
{
|
||||
Texture2D texture = new Texture2D(GameMain.GraphicsDeviceManager.GraphicsDevice, width, height);
|
||||
texture.SetData(data);
|
||||
return texture;
|
||||
}
|
||||
|
||||
private void GenerateGradient(ref Color[] data, int width, int height, Func<float, float, Color> algorithm)
|
||||
{
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
float relativeX = x / (float) width,
|
||||
relativeY = y / (float) height;
|
||||
|
||||
data[y * width + x] = algorithm(relativeX, relativeY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Color DrawHVArea(float x, float y) => ToolBox.HSVToRGB(SelectedHue, x, 1.0f - y);
|
||||
private Color DrawHueArea(float x, float y) => ToolBox.HSVToRGB(y * 360f, 1f, 1f);
|
||||
}
|
||||
}
|
||||
@@ -510,10 +510,10 @@ namespace Barotrauma
|
||||
for (int i = 0; i < Content.CountChildren; i++)
|
||||
{
|
||||
var child = Content.RectTransform.GetChild(i)?.GUIComponent;
|
||||
if (child == null) continue;
|
||||
if (child == null || !child.Visible) { continue; }
|
||||
|
||||
// selecting
|
||||
if (Enabled && CanBeFocused && child.CanBeFocused && (GUI.IsMouseOn(child)) && child.Rect.Contains(PlayerInput.MousePosition))
|
||||
if (Enabled && CanBeFocused && child.CanBeFocused && child.Rect.Contains(PlayerInput.MousePosition) && GUI.IsMouseOn(child))
|
||||
{
|
||||
child.State = ComponentState.Hover;
|
||||
|
||||
|
||||
@@ -55,6 +55,20 @@ namespace Barotrauma
|
||||
private set;
|
||||
}
|
||||
|
||||
public Submarine Submarine
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public Vector2 DrawPos
|
||||
{
|
||||
get
|
||||
{
|
||||
return Submarine == null ? Pos : Pos + Submarine.DrawPosition;
|
||||
}
|
||||
}
|
||||
|
||||
public GUIMessage(string text, Color color, float lifeTime, ScalableFont font = null)
|
||||
{
|
||||
coloredText = new ColoredText(text, color, false, false);
|
||||
@@ -67,11 +81,11 @@ namespace Barotrauma
|
||||
Font = font;
|
||||
}
|
||||
|
||||
public GUIMessage(string text, Color color, Vector2 worldPosition, Vector2 velocity, float lifeTime, Alignment textAlignment = Alignment.Center, ScalableFont font = null)
|
||||
public GUIMessage(string text, Color color, Vector2 position, Vector2 velocity, float lifeTime, Alignment textAlignment = Alignment.Center, ScalableFont font = null, Submarine sub = null)
|
||||
{
|
||||
coloredText = new ColoredText(text, color, false, false);
|
||||
WorldSpace = true;
|
||||
pos = worldPosition;
|
||||
pos = position;
|
||||
Timer = lifeTime;
|
||||
Velocity = velocity;
|
||||
this.lifeTime = lifeTime;
|
||||
@@ -92,6 +106,8 @@ namespace Barotrauma
|
||||
|
||||
if (textAlignment.HasFlag(Alignment.Bottom))
|
||||
Origin.Y += size.Y * 0.5f;
|
||||
|
||||
Submarine = sub;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,6 +67,8 @@ namespace Barotrauma
|
||||
|
||||
private readonly Type type;
|
||||
|
||||
public Type MessageBoxType => type;
|
||||
|
||||
public static GUIComponent VisibleBox => MessageBoxes.LastOrDefault();
|
||||
|
||||
public GUIMessageBox(string headerText, string text, Vector2? relativeSize = null, Point? minSize = null)
|
||||
@@ -210,6 +212,29 @@ namespace Barotrauma
|
||||
}
|
||||
};
|
||||
|
||||
InputType? closeInput = null;
|
||||
if (GameMain.Config.KeyBind(InputType.Use).MouseButton == MouseButton.None)
|
||||
{
|
||||
closeInput = InputType.Use;
|
||||
}
|
||||
else if (GameMain.Config.KeyBind(InputType.Select).MouseButton == MouseButton.None)
|
||||
{
|
||||
closeInput = InputType.Select;
|
||||
}
|
||||
if (closeInput.HasValue)
|
||||
{
|
||||
Buttons[0].ToolTip = TextManager.ParseInputTypes($"{TextManager.Get("Close")} ([InputType.{closeInput.Value}])");
|
||||
Buttons[0].OnAddedToGUIUpdateList += (GUIComponent component) =>
|
||||
{
|
||||
if (!closing && openState >= 1.0f && PlayerInput.KeyHit(closeInput.Value))
|
||||
{
|
||||
GUIButton btn = component as GUIButton;
|
||||
btn?.OnClicked(btn, btn.UserData);
|
||||
btn?.Flash(GUI.Style.Green);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Header = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), headerText, wrap: true);
|
||||
GUI.Style.Apply(Header, "", this);
|
||||
Header.RectTransform.MinSize = new Point(0, Header.Rect.Height);
|
||||
@@ -291,7 +316,8 @@ namespace Barotrauma
|
||||
{
|
||||
if (Draggable)
|
||||
{
|
||||
if ((GUI.MouseOn == InnerFrame || InnerFrame.IsParentOf(GUI.MouseOn)) && !(GUI.MouseOn is GUIButton))
|
||||
GUIComponent parent = GUI.MouseOn?.Parent?.Parent;
|
||||
if ((GUI.MouseOn == InnerFrame || InnerFrame.IsParentOf(GUI.MouseOn)) && !(GUI.MouseOn is GUIButton || GUI.MouseOn is GUIColorPicker || GUI.MouseOn is GUITextBox || parent is GUITextBox))
|
||||
{
|
||||
GUI.MouseCursor = CursorState.Move;
|
||||
if (PlayerInput.PrimaryMouseButtonDown())
|
||||
|
||||
@@ -70,6 +70,7 @@ namespace Barotrauma
|
||||
public Color ColorInventoryHalf { get; private set; } = Color.Orange;
|
||||
public Color ColorInventoryFull { get; private set; } = Color.LightGreen;
|
||||
public Color ColorInventoryBackground { get; private set; } = Color.Gray;
|
||||
public Color ColorInventoryEmptyOverlay { get; private set; } = Color.Red;
|
||||
|
||||
public Color TextColor { get; private set; } = Color.White * 0.8f;
|
||||
public Color TextColorBright { get; private set; } = Color.White * 0.9f;
|
||||
@@ -150,6 +151,9 @@ namespace Barotrauma
|
||||
case "colorinventorybackground":
|
||||
ColorInventoryBackground = subElement.GetAttributeColor("color", ColorInventoryBackground);
|
||||
break;
|
||||
case "colorinventoryemptyoverlay":
|
||||
ColorInventoryEmptyOverlay = subElement.GetAttributeColor("color", ColorInventoryEmptyOverlay);
|
||||
break;
|
||||
case "textcolordark":
|
||||
TextColorDark = subElement.GetAttributeColor("color", TextColorDark);
|
||||
break;
|
||||
@@ -344,7 +348,7 @@ namespace Barotrauma
|
||||
if (GameMain.Config.Language.Equals(subElement.GetAttributeString("language", ""), StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
uint overrideFontSize = GetFontSize(subElement, 0);
|
||||
if (overrideFontSize > 0) { return overrideFontSize; }
|
||||
if (overrideFontSize > 0) { return (uint)Math.Round(overrideFontSize * GameSettings.TextScale); }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -354,10 +358,10 @@ namespace Barotrauma
|
||||
Point maxResolution = subElement.GetAttributePoint("maxresolution", new Point(int.MaxValue, int.MaxValue));
|
||||
if (GameMain.GraphicsWidth <= maxResolution.X && GameMain.GraphicsHeight <= maxResolution.Y)
|
||||
{
|
||||
return (uint)subElement.GetAttributeInt("size", 14);
|
||||
return (uint)Math.Round(subElement.GetAttributeInt("size", 14) * GameSettings.TextScale);
|
||||
}
|
||||
}
|
||||
return defaultSize;
|
||||
return (uint)Math.Round(defaultSize * GameSettings.TextScale);
|
||||
}
|
||||
|
||||
private string GetFontFilePath(XElement element)
|
||||
|
||||
@@ -240,20 +240,20 @@ namespace Barotrauma
|
||||
|
||||
public class StrikethroughSettings
|
||||
{
|
||||
private Color color = GUI.Style.Red;
|
||||
public Color Color { get; set; } = GUI.Style.Red;
|
||||
private int thickness;
|
||||
private int expand;
|
||||
|
||||
public StrikethroughSettings(Color? color = null, int thickness = 1, int expand = 0)
|
||||
{
|
||||
if (color != null) this.color = color.Value;
|
||||
if (color != null) { Color = color.Value; }
|
||||
this.thickness = thickness;
|
||||
this.expand = expand;
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, float textSizeHalf, float xPos, float yPos)
|
||||
{
|
||||
ShapeExtensions.DrawLine(spriteBatch, new Vector2(xPos - textSizeHalf - expand, yPos), new Vector2(xPos + textSizeHalf + expand, yPos), color, thickness);
|
||||
ShapeExtensions.DrawLine(spriteBatch, new Vector2(xPos - textSizeHalf - expand, yPos), new Vector2(xPos + textSizeHalf + expand, yPos), Color, thickness);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -251,7 +251,7 @@ namespace Barotrauma
|
||||
public bool Readonly { get; set; }
|
||||
|
||||
public GUITextBox(RectTransform rectT, string text = "", Color? textColor = null, ScalableFont font = null,
|
||||
Alignment textAlignment = Alignment.Left, bool wrap = false, string style = "", Color? color = null, bool createClearButton = false)
|
||||
Alignment textAlignment = Alignment.Left, bool wrap = false, string style = "", Color? color = null, bool createClearButton = false, bool createPenIcon = true)
|
||||
: base(style, rectT)
|
||||
{
|
||||
HoverCursor = CursorState.IBeam;
|
||||
@@ -283,7 +283,7 @@ namespace Barotrauma
|
||||
clearButtonWidth = (int)(clearButton.Rect.Width * 1.2f);
|
||||
}
|
||||
|
||||
if (this.style != null && this.style.ChildStyles.ContainsKey("textboxicon"))
|
||||
if (this.style != null && this.style.ChildStyles.ContainsKey("textboxicon") && createPenIcon)
|
||||
{
|
||||
icon = new GUIImage(new RectTransform(new Vector2(0.6f, 0.6f), frame.RectTransform, Anchor.CenterRight, scaleBasis: ScaleBasis.BothHeight) { AbsoluteOffset = new Point(5 + clearButtonWidth, 0) }, null, scaleToFit: true);
|
||||
icon.ApplyStyle(this.style.ChildStyles["textboxicon"]);
|
||||
@@ -457,6 +457,11 @@ namespace Barotrauma
|
||||
isSelecting = PlayerInput.KeyDown(Keys.LeftShift) || PlayerInput.KeyDown(Keys.RightShift);
|
||||
}
|
||||
|
||||
if (mouseHeldInside && !PlayerInput.PrimaryMouseButtonHeld())
|
||||
{
|
||||
mouseHeldInside = false;
|
||||
}
|
||||
|
||||
if (CaretEnabled)
|
||||
{
|
||||
if (textBlock.OverflowClipActive)
|
||||
|
||||
@@ -24,9 +24,17 @@ namespace Barotrauma
|
||||
private int buyTotal, sellTotal;
|
||||
|
||||
private GUITextBlock merchantBalanceBlock;
|
||||
private GUILayoutGroup valueChangeGroup;
|
||||
private GUITextBlock currentSellValueBlock, newSellValueBlock;
|
||||
private GUIImage sellValueChangeArrow;
|
||||
private GUIDropDown sortingDropDown;
|
||||
private GUITextBox searchBox;
|
||||
private GUIListBox storeDealsList, storeBuyList, storeSellList;
|
||||
private GUIListBox storeBuyList, storeSellList;
|
||||
/// <summary>
|
||||
/// Can be null when there are no deals at the current location
|
||||
/// </summary>
|
||||
private GUILayoutGroup storeDailySpecialsGroup, storeRequestedGoodGroup;
|
||||
private Color storeSpecialColor;
|
||||
|
||||
private GUIListBox shoppingCrateBuyList, shoppingCrateSellList;
|
||||
private GUITextBlock shoppingCrateTotal;
|
||||
@@ -49,7 +57,6 @@ namespace Barotrauma
|
||||
|
||||
private enum StoreTab
|
||||
{
|
||||
Deals,
|
||||
Buy,
|
||||
Sell
|
||||
}
|
||||
@@ -78,19 +85,19 @@ namespace Barotrauma
|
||||
CurrentLocation.Reputation.OnReputationValueChanged += () => { needsRefresh = true; };
|
||||
}
|
||||
campaignUI.Campaign.CargoManager.OnItemsInBuyCrateChanged += () => { needsBuyingRefresh = true; };
|
||||
campaignUI.Campaign.CargoManager.OnPurchasedItemsChanged += () => { needsBuyingRefresh = true; };
|
||||
campaignUI.Campaign.CargoManager.OnPurchasedItemsChanged += () => { needsRefresh = true; };
|
||||
campaignUI.Campaign.CargoManager.OnItemsInSellCrateChanged += () => { needsSellingRefresh = true; };
|
||||
campaignUI.Campaign.CargoManager.OnSoldItemsChanged += () =>
|
||||
{
|
||||
needsItemsToSellRefresh = true;
|
||||
needsSellingRefresh = true;
|
||||
needsRefresh = true;
|
||||
};
|
||||
}
|
||||
|
||||
public void Refresh()
|
||||
public void Refresh(bool updateOwned = true)
|
||||
{
|
||||
hadPermissions = HasPermissions;
|
||||
UpdateOwnedItems();
|
||||
if (updateOwned) { UpdateOwnedItems(); }
|
||||
RefreshBuying(updateOwned: false);
|
||||
RefreshSelling(updateOwned: false);
|
||||
needsRefresh = false;
|
||||
@@ -100,10 +107,8 @@ namespace Barotrauma
|
||||
{
|
||||
if (updateOwned) { UpdateOwnedItems(); }
|
||||
RefreshShoppingCrateBuyList();
|
||||
//RefreshStoreDealsList();
|
||||
RefreshStoreBuyList();
|
||||
var hasPermissions = HasPermissions;
|
||||
//storeDealsList.Enabled = hasPermissions;
|
||||
storeBuyList.Enabled = hasPermissions;
|
||||
shoppingCrateBuyList.Enabled = hasPermissions;
|
||||
needsBuyingRefresh = false;
|
||||
@@ -166,7 +171,12 @@ namespace Barotrauma
|
||||
};
|
||||
|
||||
// Merchant balance ------------------------------------------------
|
||||
var merchantBalanceContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.75f / 14.0f), storeContent.RectTransform))
|
||||
var balanceAndValueGroup = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.75f / 14.0f), storeContent.RectTransform), isHorizontal: true)
|
||||
{
|
||||
RelativeSpacing = 0.005f
|
||||
};
|
||||
|
||||
var merchantBalanceContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 1.0f), balanceAndValueGroup.RectTransform))
|
||||
{
|
||||
RelativeSpacing = 0.005f
|
||||
};
|
||||
@@ -177,29 +187,111 @@ namespace Barotrauma
|
||||
ForceUpperCase = true
|
||||
};
|
||||
merchantBalanceBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), merchantBalanceContainer.RectTransform),
|
||||
"", font: GUI.SubHeadingFont, textAlignment: Alignment.TopLeft)
|
||||
"", font: GUI.SubHeadingFont)
|
||||
{
|
||||
AutoScaleVertical = true,
|
||||
TextScale = 1.1f,
|
||||
TextGetter = () =>
|
||||
{
|
||||
var balance = CurrentLocation != null ? CurrentLocation.StoreCurrentBalance : 0;
|
||||
if (balance < (int)(0.25f * Location.StoreInitialBalance))
|
||||
if (CurrentLocation != null)
|
||||
{
|
||||
merchantBalanceBlock.TextColor = Color.Red;
|
||||
}
|
||||
else if (balance < (int)(0.5f * Location.StoreInitialBalance))
|
||||
{
|
||||
merchantBalanceBlock.TextColor = Color.Orange;
|
||||
merchantBalanceBlock.TextColor = CurrentLocation.BalanceColor;
|
||||
return GetCurrencyFormatted(CurrentLocation.StoreCurrentBalance);
|
||||
}
|
||||
else
|
||||
{
|
||||
merchantBalanceBlock.TextColor = Color.White;
|
||||
merchantBalanceBlock.TextColor = Color.Red;
|
||||
return GetCurrencyFormatted(0);
|
||||
}
|
||||
return GetCurrencyFormatted(balance);
|
||||
}
|
||||
};
|
||||
|
||||
// Item sell value ------------------------------------------------
|
||||
var sellValueContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 1.0f), balanceAndValueGroup.RectTransform))
|
||||
{
|
||||
CanBeFocused = false,
|
||||
RelativeSpacing = 0.005f
|
||||
};
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), sellValueContainer.RectTransform),
|
||||
TextManager.Get("campaignstore.sellvalue"), font: GUI.Font, textAlignment: Alignment.BottomLeft)
|
||||
{
|
||||
AutoScaleVertical = true,
|
||||
CanBeFocused = false,
|
||||
ForceUpperCase = true
|
||||
};
|
||||
|
||||
valueChangeGroup = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.5f), sellValueContainer.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft)
|
||||
{
|
||||
CanBeFocused = true,
|
||||
RelativeSpacing = 0.02f
|
||||
};
|
||||
float blockWidth = GUI.IsFourByThree() ? 0.32f : 0.28f;
|
||||
Point blockMaxSize = new Point((int)(GameSettings.TextScale * 60), valueChangeGroup.Rect.Height);
|
||||
currentSellValueBlock = new GUITextBlock(new RectTransform(new Vector2(blockWidth, 1.0f), valueChangeGroup.RectTransform) { MaxSize = blockMaxSize },
|
||||
"", font: GUI.SubHeadingFont)
|
||||
{
|
||||
AutoScaleVertical = true,
|
||||
CanBeFocused = false,
|
||||
TextScale = 1.1f,
|
||||
TextGetter = () =>
|
||||
{
|
||||
if (CurrentLocation != null)
|
||||
{
|
||||
int balanceAfterTransaction = IsBuying ?
|
||||
CurrentLocation.StoreCurrentBalance + buyTotal :
|
||||
CurrentLocation.StoreCurrentBalance - sellTotal;
|
||||
if (balanceAfterTransaction != CurrentLocation.StoreCurrentBalance)
|
||||
{
|
||||
var newStatus = Location.GetStoreBalanceStatus(balanceAfterTransaction);
|
||||
if (CurrentLocation.ActiveStoreBalanceStatus.SellPriceModifier != newStatus.SellPriceModifier)
|
||||
{
|
||||
string tooltipTag = newStatus.SellPriceModifier > CurrentLocation.ActiveStoreBalanceStatus.SellPriceModifier ?
|
||||
"campaingstore.valueincreasetooltip" : "campaingstore.valuedecreasetooltip";
|
||||
valueChangeGroup.ToolTip = TextManager.Get(tooltipTag);
|
||||
currentSellValueBlock.TextColor = newStatus.Color;
|
||||
sellValueChangeArrow.Color = newStatus.Color;
|
||||
sellValueChangeArrow.Visible = true;
|
||||
newSellValueBlock.TextColor = newStatus.Color;
|
||||
newSellValueBlock.Text = $"{(newStatus.SellPriceModifier * 100).FormatZeroDecimal()} %";
|
||||
return $"{(CurrentLocation.ActiveStoreBalanceStatus.SellPriceModifier * 100).FormatZeroDecimal()} %";
|
||||
}
|
||||
}
|
||||
valueChangeGroup.ToolTip = null;
|
||||
currentSellValueBlock.TextColor = CurrentLocation.BalanceColor;
|
||||
sellValueChangeArrow.Visible = false;
|
||||
newSellValueBlock.Text = null;
|
||||
return $"{(CurrentLocation.ActiveStoreBalanceStatus.SellPriceModifier * 100).FormatZeroDecimal()} %";
|
||||
}
|
||||
else
|
||||
{
|
||||
valueChangeGroup.ToolTip = null;
|
||||
sellValueChangeArrow.Visible = false;
|
||||
newSellValueBlock.Text = null;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
Vector4 newPadding = currentSellValueBlock.Padding;
|
||||
newPadding.Z = 0;
|
||||
currentSellValueBlock.Padding = newPadding;
|
||||
float relativeHeight = 0.45f;
|
||||
float relativeWidth = (relativeHeight * valueChangeGroup.Rect.Height) / valueChangeGroup.Rect.Width;
|
||||
sellValueChangeArrow = new GUIImage(new RectTransform(new Vector2(relativeWidth, relativeHeight), valueChangeGroup.RectTransform), "StoreArrow", scaleToFit: true)
|
||||
{
|
||||
CanBeFocused = false,
|
||||
Visible = false
|
||||
};
|
||||
newSellValueBlock = new GUITextBlock(new RectTransform(new Vector2(blockWidth, 1.0f), valueChangeGroup.RectTransform) { MaxSize = blockMaxSize },
|
||||
"", font: GUI.SubHeadingFont)
|
||||
{
|
||||
AutoScaleVertical = true,
|
||||
CanBeFocused = false,
|
||||
TextScale = 1.1f
|
||||
};
|
||||
newPadding = newSellValueBlock.Padding;
|
||||
newPadding.X = 0;
|
||||
newSellValueBlock.Padding = newPadding;
|
||||
|
||||
// Store mode buttons ------------------------------------------------
|
||||
var modeButtonFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.6f / 14.0f), storeContent.RectTransform), style: null);
|
||||
var modeButtonContainer = new GUILayoutGroup(new RectTransform(Vector2.One, modeButtonFrame.RectTransform), isHorizontal: true);
|
||||
@@ -209,8 +301,6 @@ namespace Barotrauma
|
||||
tabSortingMethods.Clear();
|
||||
foreach (StoreTab tab in tabs)
|
||||
{
|
||||
// TODO: Remove the row below once the deal page is implemented
|
||||
if (tab == StoreTab.Deals) { continue; }
|
||||
var tabButton = new GUIButton(new RectTransform(new Vector2(1.0f / (tabs.Length + 1), 1.0f), modeButtonContainer.RectTransform),
|
||||
text: TextManager.Get("campaignstoretab." + tab), style: "GUITabButton")
|
||||
{
|
||||
@@ -309,24 +399,22 @@ namespace Barotrauma
|
||||
searchBox.OnTextChanged += (textBox, text) => { FilterStoreItems(null, text); return true; };
|
||||
|
||||
var storeItemListContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.92f), sortFilterListContainer.RectTransform), style: null);
|
||||
storeDealsList = new GUIListBox(new RectTransform(Vector2.One, storeItemListContainer.RectTransform))
|
||||
{
|
||||
AutoHideScrollBar = false,
|
||||
Visible = false
|
||||
};
|
||||
tabLists.Clear();
|
||||
tabLists.Add(StoreTab.Deals, storeDealsList);
|
||||
|
||||
storeBuyList = new GUIListBox(new RectTransform(Vector2.One, storeItemListContainer.RectTransform))
|
||||
{
|
||||
AutoHideScrollBar = false,
|
||||
Visible = false
|
||||
};
|
||||
storeDailySpecialsGroup = CreateDealsGroup(storeBuyList);
|
||||
tabLists.Add(StoreTab.Buy, storeBuyList);
|
||||
|
||||
storeSellList = new GUIListBox(new RectTransform(Vector2.One, storeItemListContainer.RectTransform))
|
||||
{
|
||||
AutoHideScrollBar = false,
|
||||
Visible = false
|
||||
};
|
||||
storeRequestedGoodGroup = CreateDealsGroup(storeSellList);
|
||||
tabLists.Add(StoreTab.Sell, storeSellList);
|
||||
|
||||
// Shopping Crate ------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -428,6 +516,26 @@ namespace Barotrauma
|
||||
resolutionWhenCreated = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
|
||||
}
|
||||
|
||||
private GUILayoutGroup CreateDealsGroup(GUIListBox parentList)
|
||||
{
|
||||
var elementHeight = (int)(GUI.yScale * 80);
|
||||
var frame = new GUIFrame(new RectTransform(new Point(parentList.Content.Rect.Width, 4 * elementHeight + 3), parent: parentList.Content.RectTransform), style: null);
|
||||
frame.UserData = "deals";
|
||||
var dealsGroup = new GUILayoutGroup(new RectTransform(Vector2.One, frame.RectTransform, anchor: Anchor.Center), childAnchor: Anchor.TopCenter);
|
||||
var dealsHeader = new GUILayoutGroup(new RectTransform(new Point((int)(0.95f * parentList.Content.Rect.Width), elementHeight), parent: dealsGroup.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft);
|
||||
dealsHeader.UserData = "header";
|
||||
var iconWidth = (0.9f * dealsHeader.Rect.Height) / dealsHeader.Rect.Width;
|
||||
var dealsIcon = new GUIImage(new RectTransform(new Vector2(iconWidth, 0.9f), dealsHeader.RectTransform), "StoreDealIcon", scaleToFit: true);
|
||||
var text = TextManager.Get(parentList == storeBuyList ? "campaignstore.dailyspecials" : "campaignstore.requestedgoods");
|
||||
var dealsText = new GUITextBlock(new RectTransform(new Vector2(1.0f - iconWidth, 0.9f), dealsHeader.RectTransform), text, font: GUI.LargeFont);
|
||||
storeSpecialColor = dealsIcon.Color;
|
||||
dealsText.TextColor = storeSpecialColor;
|
||||
var divider = new GUIImage(new RectTransform(new Point(dealsGroup.Rect.Width, 3), dealsGroup.RectTransform), "HorizontalLine");
|
||||
divider.UserData = "divider";
|
||||
frame.CanBeFocused = dealsGroup.CanBeFocused = dealsHeader.CanBeFocused = dealsIcon.CanBeFocused = dealsText.CanBeFocused = divider.CanBeFocused = false;
|
||||
return dealsGroup;
|
||||
}
|
||||
|
||||
private void UpdateLocation(Location prevLocation, Location newLocation)
|
||||
{
|
||||
if (prevLocation == newLocation) { return; }
|
||||
@@ -464,17 +572,8 @@ namespace Barotrauma
|
||||
SetConfirmButtonBehavior();
|
||||
SetConfirmButtonStatus();
|
||||
FilterStoreItems();
|
||||
if (tab == StoreTab.Deals)
|
||||
if (tab == StoreTab.Buy)
|
||||
{
|
||||
storeBuyList.Visible = false;
|
||||
storeSellList.Visible = false;
|
||||
storeDealsList.Visible = true;
|
||||
shoppingCrateSellList.Visible = false;
|
||||
shoppingCrateBuyList.Visible = true;
|
||||
}
|
||||
else if (tab == StoreTab.Buy)
|
||||
{
|
||||
storeDealsList.Visible = false;
|
||||
storeSellList.Visible = false;
|
||||
storeBuyList.Visible = true;
|
||||
shoppingCrateSellList.Visible = false;
|
||||
@@ -482,7 +581,6 @@ namespace Barotrauma
|
||||
}
|
||||
else if (tab == StoreTab.Sell)
|
||||
{
|
||||
storeDealsList.Visible = false;
|
||||
storeBuyList.Visible = false;
|
||||
storeSellList.Visible = true;
|
||||
shoppingCrateBuyList.Visible = false;
|
||||
@@ -525,37 +623,71 @@ namespace Barotrauma
|
||||
|
||||
bool hasPermissions = HasPermissions;
|
||||
HashSet<GUIComponent> existingItemFrames = new HashSet<GUIComponent>();
|
||||
|
||||
if ((storeDailySpecialsGroup != null) != CurrentLocation.DailySpecials.Any())
|
||||
{
|
||||
if (storeDailySpecialsGroup == null)
|
||||
{
|
||||
storeDailySpecialsGroup = CreateDealsGroup(storeBuyList);
|
||||
storeDailySpecialsGroup.Parent.SetAsFirstChild();
|
||||
}
|
||||
else
|
||||
{
|
||||
storeBuyList.RemoveChild(storeDailySpecialsGroup.Parent);
|
||||
storeDailySpecialsGroup = null;
|
||||
}
|
||||
storeBuyList.RecalculateChildren();
|
||||
}
|
||||
|
||||
foreach (PurchasedItem item in CurrentLocation.StoreStock)
|
||||
{
|
||||
if (item.ItemPrefab.CanBeBoughtAtLocation(CurrentLocation, out PriceInfo priceInfo))
|
||||
CreateOrUpdateItemFrame(item.ItemPrefab, item.Quantity);
|
||||
}
|
||||
|
||||
foreach (ItemPrefab itemPrefab in CurrentLocation.DailySpecials)
|
||||
{
|
||||
var itemFrame = storeBuyList.Content.Children.FirstOrDefault(c => c.UserData is PurchasedItem pi && pi.ItemPrefab == item.ItemPrefab);
|
||||
var quantity = item.Quantity;
|
||||
if (CargoManager.PurchasedItems.Find(i => i.ItemPrefab == item.ItemPrefab) is PurchasedItem purchasedItem)
|
||||
if (CurrentLocation.StoreStock.Any(pi => pi.ItemPrefab == itemPrefab)) { continue; }
|
||||
CreateOrUpdateItemFrame(itemPrefab, 0);
|
||||
}
|
||||
|
||||
void CreateOrUpdateItemFrame(ItemPrefab itemPrefab, int quantity)
|
||||
{
|
||||
if (itemPrefab.CanBeBoughtAtLocation(CurrentLocation, out PriceInfo priceInfo))
|
||||
{
|
||||
var isDailySpecial = CurrentLocation.DailySpecials.Contains(itemPrefab);
|
||||
var itemFrame = isDailySpecial ?
|
||||
storeDailySpecialsGroup.FindChild(c => c.UserData is PurchasedItem pi && pi.ItemPrefab == itemPrefab) :
|
||||
storeBuyList.Content.FindChild(c => c.UserData is PurchasedItem pi && pi.ItemPrefab == itemPrefab);
|
||||
if (CargoManager.PurchasedItems.Find(i => i.ItemPrefab == itemPrefab) is PurchasedItem purchasedItem)
|
||||
{
|
||||
quantity = Math.Max(quantity - purchasedItem.Quantity, 0);
|
||||
}
|
||||
if (CargoManager.ItemsInBuyCrate.Find(i => i.ItemPrefab == item.ItemPrefab) is PurchasedItem itemInBuyCrate)
|
||||
if (CargoManager.ItemsInBuyCrate.Find(i => i.ItemPrefab == itemPrefab) is PurchasedItem itemInBuyCrate)
|
||||
{
|
||||
quantity = Math.Max(quantity - itemInBuyCrate.Quantity, 0);
|
||||
}
|
||||
if (itemFrame == null)
|
||||
{
|
||||
itemFrame = CreateItemFrame(new PurchasedItem(item.ItemPrefab, quantity), priceInfo, storeBuyList, forceDisable: !hasPermissions);
|
||||
var parentComponent = isDailySpecial ? storeDailySpecialsGroup : storeBuyList as GUIComponent;
|
||||
itemFrame = CreateItemFrame(new PurchasedItem(itemPrefab, quantity), priceInfo, parentComponent, forceDisable: !hasPermissions);
|
||||
}
|
||||
else
|
||||
{
|
||||
(itemFrame.UserData as PurchasedItem).Quantity = quantity;
|
||||
SetQuantityLabelText(StoreTab.Buy, itemFrame);
|
||||
SetOwnedLabelText(itemFrame);
|
||||
SetItemFrameStatus(itemFrame, hasPermissions && quantity > 0);
|
||||
}
|
||||
SetItemFrameStatus(itemFrame, hasPermissions && quantity > 0);
|
||||
existingItemFrames.Add(itemFrame);
|
||||
}
|
||||
}
|
||||
|
||||
var removedItemFrames = storeBuyList.Content.Children.Except(existingItemFrames).ToList();
|
||||
removedItemFrames.ForEach(f => storeBuyList.Content.RemoveChild(f));
|
||||
var removedItemFrames = storeBuyList.Content.Children.Where(c => c.UserData is PurchasedItem).Except(existingItemFrames).ToList();
|
||||
if (storeDailySpecialsGroup != null)
|
||||
{
|
||||
removedItemFrames.AddRange(storeDailySpecialsGroup.Children.Where(c => c.UserData is PurchasedItem).Except(existingItemFrames).ToList());
|
||||
}
|
||||
removedItemFrames.ForEach(f => f.RectTransform.Parent = null);
|
||||
if (IsBuying) { FilterStoreItems(); }
|
||||
SortItems(StoreTab.Buy);
|
||||
|
||||
@@ -567,36 +699,72 @@ namespace Barotrauma
|
||||
{
|
||||
float prevSellListScroll = storeSellList.BarScroll;
|
||||
float prevShoppingCrateScroll = shoppingCrateSellList.BarScroll;
|
||||
|
||||
bool hasPermissions = HasPermissions;
|
||||
HashSet<GUIComponent> existingItemFrames = new HashSet<GUIComponent>();
|
||||
foreach (PurchasedItem item in itemsToSell)
|
||||
|
||||
if ((storeRequestedGoodGroup != null) != CurrentLocation.RequestedGoods.Any())
|
||||
{
|
||||
PriceInfo priceInfo = item.ItemPrefab.GetPriceInfo(CurrentLocation);
|
||||
if (priceInfo == null) { continue; }
|
||||
var itemFrame = storeSellList.Content.FindChild(c => c.UserData is PurchasedItem i && i.ItemPrefab == item.ItemPrefab);
|
||||
var quantity = item.Quantity;
|
||||
if (CargoManager.ItemsInSellCrate.Find(i => i.ItemPrefab == item.ItemPrefab) is PurchasedItem itemInSellCrate)
|
||||
if (storeRequestedGoodGroup == null)
|
||||
{
|
||||
quantity = Math.Max(quantity - itemInSellCrate.Quantity, 0);
|
||||
}
|
||||
if (itemFrame == null)
|
||||
{
|
||||
itemFrame = CreateItemFrame(new PurchasedItem(item.ItemPrefab, quantity), priceInfo, storeSellList, forceDisable: !hasPermissions);
|
||||
storeRequestedGoodGroup = CreateDealsGroup(storeSellList);
|
||||
storeRequestedGoodGroup.Parent.SetAsFirstChild();
|
||||
}
|
||||
else
|
||||
{
|
||||
(itemFrame.UserData as PurchasedItem).Quantity = quantity;
|
||||
storeSellList.RemoveChild(storeRequestedGoodGroup.Parent);
|
||||
storeRequestedGoodGroup = null;
|
||||
}
|
||||
storeSellList.RecalculateChildren();
|
||||
}
|
||||
|
||||
foreach (PurchasedItem item in itemsToSell)
|
||||
{
|
||||
CreateOrUpdateItemFrame(item.ItemPrefab, item.Quantity);
|
||||
}
|
||||
|
||||
foreach (var requestedGood in CurrentLocation.RequestedGoods)
|
||||
{
|
||||
if (itemsToSell.Any(pi => pi.ItemPrefab == requestedGood)) { continue; }
|
||||
CreateOrUpdateItemFrame(requestedGood, 0);
|
||||
}
|
||||
|
||||
void CreateOrUpdateItemFrame(ItemPrefab itemPrefab, int itemQuantity)
|
||||
{
|
||||
PriceInfo priceInfo = itemPrefab.GetPriceInfo(CurrentLocation);
|
||||
if (priceInfo == null) { return; }
|
||||
var isRequestedGood = CurrentLocation.RequestedGoods.Contains(itemPrefab);
|
||||
var itemFrame = isRequestedGood ?
|
||||
storeRequestedGoodGroup.FindChild(c => c.UserData is PurchasedItem pi && pi.ItemPrefab == itemPrefab) :
|
||||
storeSellList.Content.FindChild(c => c.UserData is PurchasedItem pi && pi.ItemPrefab == itemPrefab);
|
||||
if (CargoManager.ItemsInSellCrate.Find(i => i.ItemPrefab == itemPrefab) is PurchasedItem itemInSellCrate)
|
||||
{
|
||||
itemQuantity = Math.Max(itemQuantity - itemInSellCrate.Quantity, 0);
|
||||
}
|
||||
if (itemFrame == null)
|
||||
{
|
||||
var parentComponent = isRequestedGood ? storeRequestedGoodGroup : storeSellList as GUIComponent;
|
||||
itemFrame = CreateItemFrame(new PurchasedItem(itemPrefab, itemQuantity), priceInfo, parentComponent, forceDisable: !hasPermissions);
|
||||
}
|
||||
else
|
||||
{
|
||||
(itemFrame.UserData as PurchasedItem).Quantity = itemQuantity;
|
||||
SetQuantityLabelText(StoreTab.Sell, itemFrame);
|
||||
SetOwnedLabelText(itemFrame);
|
||||
SetItemFrameStatus(itemFrame, hasPermissions);
|
||||
}
|
||||
if (quantity < 1) { itemFrame.Visible = false; }
|
||||
SetItemFrameStatus(itemFrame, hasPermissions && itemQuantity > 0);
|
||||
if (itemQuantity < 1 && !isRequestedGood)
|
||||
{
|
||||
itemFrame.Visible = false;
|
||||
}
|
||||
existingItemFrames.Add(itemFrame);
|
||||
}
|
||||
|
||||
var removedItemFrames = storeSellList.Content.Children.Except(existingItemFrames).ToList();
|
||||
removedItemFrames.ForEach(f => storeSellList.Content.RemoveChild(f));
|
||||
var removedItemFrames = storeSellList.Content.Children.Where(c => c.UserData is PurchasedItem).Except(existingItemFrames).ToList();
|
||||
if (storeRequestedGoodGroup != null)
|
||||
{
|
||||
removedItemFrames.AddRange(storeRequestedGoodGroup.Children.Where(c => c.UserData is PurchasedItem).Except(existingItemFrames).ToList());
|
||||
}
|
||||
removedItemFrames.ForEach(f => f.RectTransform.Parent = null);
|
||||
if (IsSelling) { FilterStoreItems(); }
|
||||
SortItems(StoreTab.Sell);
|
||||
|
||||
@@ -673,14 +841,11 @@ namespace Barotrauma
|
||||
}
|
||||
suppressBuySell = false;
|
||||
|
||||
if (priceInfo != null)
|
||||
{
|
||||
var price = listBox == shoppingCrateBuyList ?
|
||||
CurrentLocation.GetAdjustedItemBuyPrice(priceInfo) :
|
||||
CurrentLocation.GetAdjustedItemSellPrice(priceInfo);
|
||||
CurrentLocation.GetAdjustedItemBuyPrice(item.ItemPrefab, priceInfo: priceInfo) :
|
||||
CurrentLocation.GetAdjustedItemSellPrice(item.ItemPrefab, priceInfo: priceInfo);
|
||||
totalPrice += item.Quantity * price;
|
||||
}
|
||||
}
|
||||
|
||||
var removedItemFrames = listBox.Content.Children.Except(existingItemFrames).ToList();
|
||||
removedItemFrames.ForEach(f => listBox.Content.RemoveChild(f));
|
||||
@@ -711,32 +876,138 @@ namespace Barotrauma
|
||||
|
||||
if (sortingMethod == SortingMethod.AlphabeticalAsc || sortingMethod == SortingMethod.AlphabeticalDesc)
|
||||
{
|
||||
list.Content.RectTransform.SortChildren(
|
||||
(x, y) => (x.GUIComponent.UserData as PurchasedItem).ItemPrefab.Name.CompareTo((y.GUIComponent.UserData as PurchasedItem).ItemPrefab.Name));
|
||||
if (sortingMethod == SortingMethod.AlphabeticalDesc) { list.Content.RectTransform.ReverseChildren(); }
|
||||
list.Content.RectTransform.SortChildren(CompareByName);
|
||||
if (GetSpecialsGroup() is GUILayoutGroup specialsGroup)
|
||||
{
|
||||
specialsGroup.RectTransform.SortChildren(CompareByName);
|
||||
specialsGroup.Recalculate();
|
||||
}
|
||||
|
||||
int CompareByName(RectTransform x, RectTransform y)
|
||||
{
|
||||
if (x.GUIComponent.UserData is PurchasedItem itemX && y.GUIComponent.UserData is PurchasedItem itemY)
|
||||
{
|
||||
var sortResult = itemX.ItemPrefab.Name.CompareTo(itemY.ItemPrefab.Name);
|
||||
if (sortingMethod == SortingMethod.AlphabeticalDesc) { sortResult *= -1; }
|
||||
return sortResult;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CompareByElement(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sortingMethod == SortingMethod.PriceAsc || sortingMethod == SortingMethod.PriceDesc)
|
||||
{
|
||||
SortItems(list, SortingMethod.AlphabeticalAsc);
|
||||
if (list == storeSellList || list == shoppingCrateSellList)
|
||||
{
|
||||
list.Content.RectTransform.SortChildren(
|
||||
(x, y) => CurrentLocation.GetAdjustedItemSellPrice((x.GUIComponent.UserData as PurchasedItem).ItemPrefab).CompareTo(
|
||||
CurrentLocation.GetAdjustedItemSellPrice((y.GUIComponent.UserData as PurchasedItem).ItemPrefab)));
|
||||
list.Content.RectTransform.SortChildren(CompareBySellPrice);
|
||||
if (GetSpecialsGroup() is GUILayoutGroup specialsGroup)
|
||||
{
|
||||
specialsGroup.RectTransform.SortChildren(CompareBySellPrice);
|
||||
specialsGroup.Recalculate();
|
||||
}
|
||||
|
||||
int CompareBySellPrice(RectTransform x, RectTransform y)
|
||||
{
|
||||
if (x.GUIComponent.UserData is PurchasedItem itemX && y.GUIComponent.UserData is PurchasedItem itemY)
|
||||
{
|
||||
var sortResult = CurrentLocation.GetAdjustedItemSellPrice(itemX.ItemPrefab).CompareTo(
|
||||
CurrentLocation.GetAdjustedItemSellPrice(itemY.ItemPrefab));
|
||||
if (sortingMethod == SortingMethod.PriceDesc) { sortResult *= -1; }
|
||||
return sortResult;
|
||||
}
|
||||
else
|
||||
{
|
||||
list.Content.RectTransform.SortChildren(
|
||||
(x, y) => CurrentLocation.GetAdjustedItemBuyPrice((x.GUIComponent.UserData as PurchasedItem).ItemPrefab).CompareTo(
|
||||
CurrentLocation.GetAdjustedItemBuyPrice((y.GUIComponent.UserData as PurchasedItem).ItemPrefab)));
|
||||
return CompareByElement(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
list.Content.RectTransform.SortChildren(CompareByBuyPrice);
|
||||
if (GetSpecialsGroup() is GUILayoutGroup specialsGroup)
|
||||
{
|
||||
specialsGroup.RectTransform.SortChildren(CompareByBuyPrice);
|
||||
specialsGroup.Recalculate();
|
||||
}
|
||||
|
||||
int CompareByBuyPrice(RectTransform x, RectTransform y)
|
||||
{
|
||||
if (x.GUIComponent.UserData is PurchasedItem itemX && y.GUIComponent.UserData is PurchasedItem itemY)
|
||||
{
|
||||
var sortResult = CurrentLocation.GetAdjustedItemBuyPrice(itemX.ItemPrefab).CompareTo(
|
||||
CurrentLocation.GetAdjustedItemBuyPrice(itemY.ItemPrefab));
|
||||
if (sortingMethod == SortingMethod.PriceDesc) { sortResult *= -1; }
|
||||
return sortResult;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CompareByElement(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sortingMethod == SortingMethod.PriceDesc) { list.Content.RectTransform.ReverseChildren(); }
|
||||
}
|
||||
else if (sortingMethod == SortingMethod.CategoryAsc)
|
||||
{
|
||||
SortItems(list, SortingMethod.AlphabeticalAsc);
|
||||
list.Content.RectTransform.SortChildren((x, y) =>
|
||||
(x.GUIComponent.UserData as PurchasedItem).ItemPrefab.Category.CompareTo((y.GUIComponent.UserData as PurchasedItem).ItemPrefab.Category));
|
||||
list.Content.RectTransform.SortChildren(CompareByCategory);
|
||||
if (GetSpecialsGroup() is GUILayoutGroup specialsGroup)
|
||||
{
|
||||
specialsGroup.RectTransform.SortChildren(CompareByCategory);
|
||||
specialsGroup.Recalculate();
|
||||
}
|
||||
|
||||
static int CompareByCategory(RectTransform x, RectTransform y)
|
||||
{
|
||||
if (x.GUIComponent.UserData is PurchasedItem itemX && y.GUIComponent.UserData is PurchasedItem itemY)
|
||||
{
|
||||
return itemX.ItemPrefab.Category.CompareTo(itemY.ItemPrefab.Category);
|
||||
}
|
||||
else
|
||||
{
|
||||
return CompareByElement(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GUILayoutGroup GetSpecialsGroup()
|
||||
{
|
||||
if (list == storeBuyList)
|
||||
{
|
||||
return storeDailySpecialsGroup;
|
||||
}
|
||||
else if (list == storeSellList)
|
||||
{
|
||||
return storeRequestedGoodGroup;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static int CompareByElement(RectTransform x, RectTransform y)
|
||||
{
|
||||
if (ShouldBeOnTop(x) || ShouldBeOnBottom(y))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (ShouldBeOnBottom(x) || ShouldBeOnTop(y))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool ShouldBeOnTop(RectTransform rt) =>
|
||||
rt.GUIComponent.UserData is string id && (id == "deals" || id == "header");
|
||||
|
||||
static bool ShouldBeOnBottom(RectTransform rt) =>
|
||||
rt.GUIComponent.UserData is string id && id == "divider";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -750,7 +1021,7 @@ namespace Barotrauma
|
||||
|
||||
private void SortActiveTabItems(SortingMethod sortingMethod) => SortItems(activeTab, sortingMethod);
|
||||
|
||||
private GUIComponent CreateItemFrame(PurchasedItem pi, PriceInfo priceInfo, GUIListBox listBox, bool forceDisable = false)
|
||||
private GUIComponent CreateItemFrame(PurchasedItem pi, PriceInfo priceInfo, GUIComponent parentComponent, bool forceDisable = false)
|
||||
{
|
||||
var tooltip = pi.ItemPrefab.Name;
|
||||
if (!string.IsNullOrWhiteSpace(pi.ItemPrefab.Description))
|
||||
@@ -758,7 +1029,21 @@ namespace Barotrauma
|
||||
tooltip += "\n" + pi.ItemPrefab.Description;
|
||||
}
|
||||
|
||||
GUIFrame frame = new GUIFrame(new RectTransform(new Point(listBox.Content.Rect.Width, (int)(GUI.yScale * 80)), parent: listBox.Content.RectTransform), style: "ListBoxElement")
|
||||
GUIListBox parentListBox = parentComponent as GUIListBox;
|
||||
int width = 0;
|
||||
RectTransform parent = null;
|
||||
if (parentListBox != null)
|
||||
{
|
||||
width = parentListBox.Content.Rect.Width;
|
||||
parent = parentListBox.Content.RectTransform;
|
||||
}
|
||||
else
|
||||
{
|
||||
width = parentComponent.Rect.Width;
|
||||
parent = parentComponent.RectTransform;
|
||||
}
|
||||
|
||||
GUIFrame frame = new GUIFrame(new RectTransform(new Point(width, (int)(GUI.yScale * 80)), parent: parent), style: "ListBoxElement")
|
||||
{
|
||||
ToolTip = tooltip,
|
||||
UserData = pi
|
||||
@@ -788,33 +1073,58 @@ namespace Barotrauma
|
||||
img.RectTransform.MaxSize = img.Rect.Size;
|
||||
}
|
||||
|
||||
GUILayoutGroup nameAndQuantityGroup = new GUILayoutGroup(new RectTransform(new Vector2(nameAndIconRelativeWidth - iconRelativeWidth, 1.0f), mainGroup.RectTransform))
|
||||
GUIFrame nameAndQuantityFrame = new GUIFrame(new RectTransform(new Vector2(nameAndIconRelativeWidth - iconRelativeWidth, 1.0f), mainGroup.RectTransform), style: null)
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
GUILayoutGroup nameAndQuantityGroup = new GUILayoutGroup(new RectTransform(Vector2.One, nameAndQuantityFrame.RectTransform))
|
||||
{
|
||||
CanBeFocused = false,
|
||||
Stretch = true
|
||||
};
|
||||
var isSellingRelatedList = parentComponent == storeSellList || parentComponent == storeRequestedGoodGroup || parentComponent == shoppingCrateSellList;
|
||||
var locationHasDealOnItem = isSellingRelatedList ?
|
||||
CurrentLocation.RequestedGoods.Contains(pi.ItemPrefab) : CurrentLocation.DailySpecials.Contains(pi.ItemPrefab);
|
||||
GUITextBlock nameBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.4f), nameAndQuantityGroup.RectTransform),
|
||||
pi.ItemPrefab.Name, font: GUI.SubHeadingFont, textAlignment: Alignment.BottomLeft)
|
||||
{
|
||||
CanBeFocused = false,
|
||||
Shadow = locationHasDealOnItem,
|
||||
TextColor = Color.White * (forceDisable ? 0.5f : 1.0f),
|
||||
TextScale = 0.85f,
|
||||
UserData = "name"
|
||||
};
|
||||
if (locationHasDealOnItem)
|
||||
{
|
||||
var relativeWidth = (0.9f * nameAndQuantityFrame.Rect.Height) / nameAndQuantityFrame.Rect.Width;
|
||||
var dealIcon = new GUIImage(
|
||||
new RectTransform(new Vector2(relativeWidth, 0.9f), nameAndQuantityFrame.RectTransform, anchor: Anchor.CenterLeft)
|
||||
{
|
||||
AbsoluteOffset = new Point((int)nameBlock.Padding.X, 0)
|
||||
},
|
||||
"StoreDealIcon", scaleToFit: true)
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
dealIcon.SetAsFirstChild();
|
||||
}
|
||||
var isParentOnLeftSideOfInterface = parentComponent == storeBuyList || parentComponent == storeDailySpecialsGroup ||
|
||||
parentComponent == storeSellList || parentComponent == storeRequestedGoodGroup;
|
||||
GUILayoutGroup shoppingCrateAmountGroup = null;
|
||||
GUINumberInput amountInput = null;
|
||||
if (listBox == storeBuyList || listBox == storeSellList)
|
||||
if (isParentOnLeftSideOfInterface)
|
||||
{
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.3f), nameAndQuantityGroup.RectTransform),
|
||||
CreateQuantityLabelText(listBox == storeSellList ? StoreTab.Sell : StoreTab.Buy, pi.Quantity), font: GUI.Font, textAlignment: Alignment.BottomLeft)
|
||||
CreateQuantityLabelText(isSellingRelatedList ? StoreTab.Sell : StoreTab.Buy, pi.Quantity), font: GUI.Font, textAlignment: Alignment.BottomLeft)
|
||||
{
|
||||
CanBeFocused = false,
|
||||
Shadow = locationHasDealOnItem,
|
||||
TextColor = Color.White * (forceDisable ? 0.5f : 1.0f),
|
||||
TextScale = 0.85f,
|
||||
UserData = "quantitylabel"
|
||||
};
|
||||
}
|
||||
else if (listBox == shoppingCrateBuyList || listBox == shoppingCrateSellList)
|
||||
else if (!isParentOnLeftSideOfInterface)
|
||||
{
|
||||
var relativePadding = nameBlock.Padding.X / nameBlock.Rect.Width;
|
||||
shoppingCrateAmountGroup = new GUILayoutGroup(new RectTransform(new Vector2(1.0f - relativePadding, 0.6f), nameAndQuantityGroup.RectTransform) { RelativeOffset = new Vector2(relativePadding, 0) },
|
||||
@@ -825,7 +1135,7 @@ namespace Barotrauma
|
||||
amountInput = new GUINumberInput(new RectTransform(new Vector2(0.4f, 1.0f), shoppingCrateAmountGroup.RectTransform), GUINumberInput.NumberType.Int)
|
||||
{
|
||||
MinValueInt = 0,
|
||||
MaxValueInt = GetMaxAvailable(pi.ItemPrefab, listBox == shoppingCrateBuyList ? StoreTab.Buy : StoreTab.Sell),
|
||||
MaxValueInt = GetMaxAvailable(pi.ItemPrefab, isSellingRelatedList ? StoreTab.Sell : StoreTab.Buy),
|
||||
UserData = pi,
|
||||
IntValue = pi.Quantity
|
||||
};
|
||||
@@ -856,6 +1166,7 @@ namespace Barotrauma
|
||||
textAlignment: shoppingCrateAmountGroup == null ? Alignment.TopLeft : Alignment.CenterLeft)
|
||||
{
|
||||
CanBeFocused = false,
|
||||
Shadow = locationHasDealOnItem,
|
||||
TextColor = Color.White * (forceDisable ? 0.5f : 1.0f),
|
||||
TextScale = 0.85f,
|
||||
UserData = "owned"
|
||||
@@ -864,22 +1175,53 @@ namespace Barotrauma
|
||||
|
||||
var buttonRelativeWidth = (0.9f * mainGroup.Rect.Height) / mainGroup.Rect.Width;
|
||||
|
||||
var priceBlock = new GUITextBlock(new RectTransform(new Vector2(priceAndButtonRelativeWidth - buttonRelativeWidth, 1.0f), mainGroup.RectTransform), "", font: GUI.SubHeadingFont, textAlignment: Alignment.Right)
|
||||
var priceFrame = new GUIFrame(new RectTransform(new Vector2(priceAndButtonRelativeWidth - buttonRelativeWidth, 1.0f), mainGroup.RectTransform), style: null)
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
var priceBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), priceFrame.RectTransform, anchor: Anchor.Center),
|
||||
"0 MK", font: GUI.SubHeadingFont, textAlignment: Alignment.Right)
|
||||
{
|
||||
CanBeFocused = false,
|
||||
TextColor = Color.White * (forceDisable ? 0.5f : 1.0f),
|
||||
TextColor = locationHasDealOnItem ? storeSpecialColor : Color.White,
|
||||
UserData = "price"
|
||||
};
|
||||
if (listBox == storeSellList || listBox == shoppingCrateSellList)
|
||||
priceBlock.Color *= (forceDisable ? 0.5f : 1.0f);
|
||||
priceBlock.CalculateHeightFromText();
|
||||
if (isSellingRelatedList)
|
||||
{
|
||||
priceBlock.TextGetter = () => GetCurrencyFormatted(CurrentLocation?.GetAdjustedItemSellPrice(priceInfo) ?? 0);
|
||||
priceBlock.TextGetter = () => GetCurrencyFormatted(CurrentLocation?.GetAdjustedItemSellPrice(pi.ItemPrefab, priceInfo: priceInfo) ?? 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
priceBlock.TextGetter = () => GetCurrencyFormatted(CurrentLocation?.GetAdjustedItemBuyPrice(priceInfo) ?? 0);
|
||||
priceBlock.TextGetter = () => GetCurrencyFormatted(CurrentLocation?.GetAdjustedItemBuyPrice(pi.ItemPrefab, priceInfo: priceInfo) ?? 0);
|
||||
}
|
||||
if (locationHasDealOnItem)
|
||||
{
|
||||
var undiscounterPriceBlock = new GUITextBlock(
|
||||
new RectTransform(new Vector2(1.0f, 0.25f), priceFrame.RectTransform, anchor: Anchor.Center)
|
||||
{
|
||||
AbsoluteOffset = new Point(0, priceBlock.RectTransform.ScaledSize.Y)
|
||||
}, "", font: GUI.SmallFont, textAlignment: Alignment.Center)
|
||||
{
|
||||
CanBeFocused = false,
|
||||
Strikethrough = new GUITextBlock.StrikethroughSettings(color: priceBlock.TextColor, expand: 1),
|
||||
TextColor = priceBlock.TextColor,
|
||||
UserData = "undiscountedprice"
|
||||
};
|
||||
if (isSellingRelatedList)
|
||||
{
|
||||
undiscounterPriceBlock.TextGetter = () => GetCurrencyFormatted(
|
||||
CurrentLocation?.GetAdjustedItemSellPrice(pi.ItemPrefab, priceInfo: priceInfo, considerRequestedGoods: false) ?? 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
undiscounterPriceBlock.TextGetter = () => GetCurrencyFormatted(
|
||||
CurrentLocation?.GetAdjustedItemBuyPrice(pi.ItemPrefab, priceInfo: priceInfo, considerDailySpecials: false) ?? 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (listBox == storeDealsList || listBox == storeBuyList || listBox == storeSellList)
|
||||
if (isParentOnLeftSideOfInterface)
|
||||
{
|
||||
new GUIButton(new RectTransform(new Vector2(buttonRelativeWidth, 0.9f), mainGroup.RectTransform), style: "StoreAddToCrateButton")
|
||||
{
|
||||
@@ -902,7 +1244,14 @@ namespace Barotrauma
|
||||
};
|
||||
}
|
||||
|
||||
listBox.RecalculateChildren();
|
||||
if (parentListBox != null)
|
||||
{
|
||||
parentListBox.RecalculateChildren();
|
||||
}
|
||||
else if (parentComponent is GUILayoutGroup parentLayoutGroup)
|
||||
{
|
||||
parentLayoutGroup.Recalculate();
|
||||
}
|
||||
mainGroup.Recalculate();
|
||||
mainGroup.RectTransform.RecalculateChildren(true, true);
|
||||
amountInput?.LayoutGroup.Recalculate();
|
||||
@@ -923,15 +1272,20 @@ namespace Barotrauma
|
||||
.ForEach(i => AddToOwnedItems(i.Prefab));
|
||||
|
||||
// Add items in character inventories
|
||||
foreach (Character c in GameMain.GameSession.CrewManager.GetCharacters())
|
||||
foreach (var item in Item.ItemList)
|
||||
{
|
||||
Item.ItemList.Where(i => i != null && i.GetRootInventoryOwner() == c)
|
||||
.ForEach(i => AddToOwnedItems(i.Prefab));
|
||||
if (item == null || item.Removed) { continue; }
|
||||
var rootInventoryOwner = item.GetRootInventoryOwner();
|
||||
var ownedByCrewMember = GameMain.GameSession.CrewManager.GetCharacters().Any(c => c == rootInventoryOwner);
|
||||
if (!ownedByCrewMember) { continue; }
|
||||
AddToOwnedItems(item.Prefab);
|
||||
}
|
||||
|
||||
// Add items already purchased
|
||||
CargoManager?.PurchasedItems?.ForEach(pi => AddToOwnedItems(pi.ItemPrefab, amount: pi.Quantity));
|
||||
|
||||
ownedItemsUpdateTimer = 0.0f;
|
||||
|
||||
void AddToOwnedItems(ItemPrefab itemPrefab, int amount = 1)
|
||||
{
|
||||
if (OwnedItems.ContainsKey(itemPrefab))
|
||||
@@ -977,14 +1331,22 @@ namespace Barotrauma
|
||||
numberInput.Enabled = enabled;
|
||||
}
|
||||
|
||||
if (itemFrame.FindChild("owned", recursive: true) is GUITextBlock owned)
|
||||
if (itemFrame.FindChild("owned", recursive: true) is GUITextBlock ownedBlock)
|
||||
{
|
||||
owned.TextColor = color;
|
||||
ownedBlock.TextColor = color;
|
||||
}
|
||||
|
||||
if (itemFrame.FindChild("price", recursive: true) is GUITextBlock price)
|
||||
var isDiscounted = false;
|
||||
if (itemFrame.FindChild("undiscountedprice", recursive: true) is GUITextBlock undiscountedPriceBlock)
|
||||
{
|
||||
price.TextColor = color;
|
||||
undiscountedPriceBlock.TextColor = color;
|
||||
undiscountedPriceBlock.Strikethrough.Color = color;
|
||||
isDiscounted = true;
|
||||
}
|
||||
|
||||
if (itemFrame.FindChild("price", recursive: true) is GUITextBlock priceBlock)
|
||||
{
|
||||
priceBlock.TextColor = isDiscounted ? storeSpecialColor * (enabled ? 1.0f : 0.5f) : color;
|
||||
}
|
||||
|
||||
if (itemFrame.FindChild("addbutton", recursive: true) is GUIButton addButton)
|
||||
@@ -1101,7 +1463,7 @@ namespace Barotrauma
|
||||
itemsToRemove.Add(item);
|
||||
continue;
|
||||
}
|
||||
totalPrice += item.Quantity * CurrentLocation.GetAdjustedItemBuyPrice(priceInfo);
|
||||
totalPrice += item.Quantity * CurrentLocation.GetAdjustedItemBuyPrice(item.ItemPrefab, priceInfo: priceInfo);
|
||||
}
|
||||
itemsToRemove.ForEach(i => itemsToPurchase.Remove(i));
|
||||
|
||||
@@ -1135,7 +1497,7 @@ namespace Barotrauma
|
||||
}
|
||||
if (item.ItemPrefab.GetPriceInfo(CurrentLocation) is PriceInfo priceInfo)
|
||||
{
|
||||
totalValue += item.Quantity * CurrentLocation.GetAdjustedItemSellPrice(priceInfo);
|
||||
totalValue += item.Quantity * CurrentLocation.GetAdjustedItemSellPrice(item.ItemPrefab, priceInfo: priceInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1197,16 +1559,38 @@ namespace Barotrauma
|
||||
private void SetClearAllButtonStatus() => clearAllButton.Enabled =
|
||||
HasPermissions && ActiveShoppingCrateList.Content.RectTransform.Children.Any();
|
||||
|
||||
public void Update()
|
||||
private float ownedItemsUpdateTimer = 0.0f;
|
||||
private readonly float ownedItemsUpdateInterval = 1.5f;
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
if (GameMain.GraphicsWidth != resolutionWhenCreated.X || GameMain.GraphicsHeight != resolutionWhenCreated.Y)
|
||||
{
|
||||
CreateUI();
|
||||
needsRefresh = false;
|
||||
}
|
||||
if (needsRefresh || hadPermissions != HasPermissions) { Refresh(); }
|
||||
if (needsBuyingRefresh) { RefreshBuying(); }
|
||||
else
|
||||
{
|
||||
// Update the owned items at short intervals and check if the interface should be refreshed
|
||||
ownedItemsUpdateTimer += deltaTime;
|
||||
if (ownedItemsUpdateTimer >= ownedItemsUpdateInterval)
|
||||
{
|
||||
var prevOwnedItems = new Dictionary<ItemPrefab, int>(OwnedItems);
|
||||
UpdateOwnedItems();
|
||||
var refresh = (prevOwnedItems.Count != OwnedItems.Count) ||
|
||||
(prevOwnedItems.Select(kvp => kvp.Value).Sum() != OwnedItems.Select(kvp => kvp.Value).Sum()) ||
|
||||
(OwnedItems.Any(kvp => kvp.Value > 0 && !prevOwnedItems.ContainsKey(kvp.Key)) ||
|
||||
prevOwnedItems.Any(kvp => !OwnedItems.TryGetValue(kvp.Key, out var itemCount) || kvp.Value != itemCount));
|
||||
if (refresh)
|
||||
{
|
||||
needsItemsToSellRefresh = true;
|
||||
needsRefresh = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (needsItemsToSellRefresh) { RefreshItemsToSell(); }
|
||||
if (needsRefresh || hadPermissions != HasPermissions) { Refresh(updateOwned: ownedItemsUpdateTimer > 0.0f); }
|
||||
if (needsBuyingRefresh) { RefreshBuying(); }
|
||||
if (needsSellingRefresh) { RefreshSelling(); }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -610,8 +610,8 @@ namespace Barotrauma
|
||||
{
|
||||
if (GameMain.Client == null)
|
||||
{
|
||||
GameMain.GameSession.SwitchSubmarine(selectedSubmarine, deliveryFee);
|
||||
GameMain.GameSession.Campaign.UpgradeManager.RefundResetAndReload(selectedSubmarine);
|
||||
SubmarineInfo newSub = GameMain.GameSession.SwitchSubmarine(selectedSubmarine, deliveryFee);
|
||||
GameMain.GameSession.Campaign.UpgradeManager.RefundResetAndReload(newSub);
|
||||
RefreshSubmarineDisplay(true);
|
||||
}
|
||||
else
|
||||
@@ -645,8 +645,8 @@ namespace Barotrauma
|
||||
if (GameMain.Client == null)
|
||||
{
|
||||
GameMain.GameSession.PurchaseSubmarine(selectedSubmarine);
|
||||
GameMain.GameSession.SwitchSubmarine(selectedSubmarine, 0);
|
||||
GameMain.GameSession.Campaign.UpgradeManager.RefundResetAndReload(selectedSubmarine);
|
||||
SubmarineInfo newSub = GameMain.GameSession.SwitchSubmarine(selectedSubmarine, 0);
|
||||
GameMain.GameSession.Campaign.UpgradeManager.RefundResetAndReload(newSub);
|
||||
RefreshSubmarineDisplay(true);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Barotrauma
|
||||
private float sizeMultiplier = 1f;
|
||||
|
||||
private IEnumerable<Character> crew;
|
||||
private List<Character.TeamType> teamIDs;
|
||||
private List<CharacterTeamType> teamIDs;
|
||||
private const string inLobbyString = "\u2022 \u2022 \u2022";
|
||||
|
||||
public static Color OwnCharacterBGColor = Color.Gold * 0.7f;
|
||||
@@ -281,11 +281,11 @@ namespace Barotrauma
|
||||
// Show own team first when there's more than one team
|
||||
if (teamIDs.Count > 1 && GameMain.Client?.Character != null)
|
||||
{
|
||||
Character.TeamType ownTeam = GameMain.Client.Character.TeamID;
|
||||
CharacterTeamType ownTeam = GameMain.Client.Character.TeamID;
|
||||
teamIDs = teamIDs.OrderBy(i => i != ownTeam).ThenBy(i => i).ToList();
|
||||
}
|
||||
|
||||
if (!teamIDs.Any()) teamIDs.Add(Character.TeamType.None);
|
||||
if (!teamIDs.Any()) { teamIDs.Add(CharacterTeamType.None); }
|
||||
|
||||
var content = new GUILayoutGroup(new RectTransform(Vector2.One, crewFrame.RectTransform));
|
||||
|
||||
@@ -465,15 +465,14 @@ namespace Barotrauma
|
||||
{
|
||||
foreach (Character character in crew.Where(c => c.TeamID == teamIDs[i]))
|
||||
{
|
||||
if (!(character is AICharacter) && connectedClients.Find(c => c.Character == null && c.Name == character.Name) != null) continue;
|
||||
CreateMultiPlayerCharacterElement(character, GameMain.Client.ConnectedClients.Find(c => c.Character == character), i);
|
||||
if (!(character is AICharacter) && connectedClients.Any(c => c.Character == null && c.Name == character.Name)) { continue; }
|
||||
CreateMultiPlayerCharacterElement(character, GameMain.Client.PreviouslyConnectedClients.FirstOrDefault(c => c.Character == character), i);
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j < connectedClients.Count; j++)
|
||||
{
|
||||
Client client = connectedClients[j];
|
||||
|
||||
if (!client.InGame || client.Character == null || client.Character.IsDead)
|
||||
{
|
||||
CreateMultiPlayerClientElement(client);
|
||||
@@ -565,7 +564,7 @@ namespace Barotrauma
|
||||
|
||||
private int GetTeamIndex(Client client)
|
||||
{
|
||||
if (teamIDs.Count <= 1) return 0;
|
||||
if (teamIDs.Count <= 1) { return 0; }
|
||||
|
||||
if (client.Character != null)
|
||||
{
|
||||
@@ -707,7 +706,7 @@ namespace Barotrauma
|
||||
{
|
||||
GUIComponent paddedFrame;
|
||||
|
||||
if (client.Character == null)
|
||||
if (client.Character?.Info == null)
|
||||
{
|
||||
paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.874f, 0.58f), frame.RectTransform, Anchor.TopCenter) { RelativeOffset = new Vector2(0.0f, 0.05f) })
|
||||
{
|
||||
|
||||
@@ -625,13 +625,19 @@ namespace Barotrauma
|
||||
selectedUpgradeCategoryLayout?.ClearChildren();
|
||||
GUIFrame frame = new GUIFrame(rectT(1, 0.4f, selectedUpgradeCategoryLayout));
|
||||
GUIListBox prefabList = new GUIListBox(rectT(0.93f, 0.9f, frame, Anchor.Center)) { UserData = "prefablist" };
|
||||
|
||||
List<Item> entitiesOnSub = null;
|
||||
if (!category.IsWallUpgrade)
|
||||
{
|
||||
entitiesOnSub = submarine.GetItems(true).Where(i => submarine.IsEntityFoundOnThisSub(i, true)).ToList();
|
||||
}
|
||||
foreach (UpgradePrefab prefab in prefabs)
|
||||
{
|
||||
CreateUpgradeEntry(prefab, category, prefabList.Content);
|
||||
CreateUpgradeEntry(prefab, category, prefabList.Content, entitiesOnSub);
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateUpgradeEntry(UpgradePrefab prefab, UpgradeCategory category, GUIComponent parent)
|
||||
private void CreateUpgradeEntry(UpgradePrefab prefab, UpgradeCategory category, GUIComponent parent, List<Item> itemsOnSubmarine)
|
||||
{
|
||||
/* UPGRADE PREFAB ENTRY
|
||||
* |------------------------------------------------------------------|
|
||||
@@ -680,12 +686,14 @@ namespace Barotrauma
|
||||
progressLayout.Recalculate();
|
||||
buyButtonLayout.Recalculate();
|
||||
|
||||
if (!HasPermission)
|
||||
if (!HasPermission || itemsOnSubmarine != null && !itemsOnSubmarine.Any(it => category.CanBeApplied(it, prefab)))
|
||||
{
|
||||
prefabFrame.Enabled = false;
|
||||
description.Enabled = false;
|
||||
name.Enabled = false;
|
||||
icon.Color = Color.Gray;
|
||||
buyButton.Enabled = false;
|
||||
buyButtonLayout.UserData = null; // prevent UpdateUpgradeEntry() from enabling the button
|
||||
}
|
||||
|
||||
buyButton.OnClicked += (button, o) =>
|
||||
@@ -731,7 +739,7 @@ namespace Barotrauma
|
||||
// include pending upgrades into the tooltip
|
||||
foreach (var (prefab, category, level) in Campaign.UpgradeManager.PendingUpgrades)
|
||||
{
|
||||
if (entity is Item item && category.CanBeApplied(item) || entity is Structure && category.IsWallUpgrade)
|
||||
if (entity is Item item && category.CanBeApplied(item, prefab) || entity is Structure && category.IsWallUpgrade)
|
||||
{
|
||||
bool found = false;
|
||||
foreach (GUITextBlock textBlock in upgradeList.Content.Children.Where(c => c is GUITextBlock).Cast<GUITextBlock>())
|
||||
@@ -786,7 +794,7 @@ namespace Barotrauma
|
||||
|
||||
foreach (UpgradeCategory category in UpgradeCategory.Categories)
|
||||
{
|
||||
if (entitiesOnSub.Any(item => category.CanBeApplied(item) && !item.disallowedUpgrades.Contains(category.Identifier)))
|
||||
if (entitiesOnSub.Any(item => category.CanBeApplied(item, null)))
|
||||
{
|
||||
applicableCategories.Add(category);
|
||||
}
|
||||
@@ -826,7 +834,7 @@ namespace Barotrauma
|
||||
HoveredItem = item;
|
||||
if (PlayerInput.PrimaryMouseButtonClicked() && selectedUpgradTab == UpgradeTab.Upgrade && currentStoreLayout != null)
|
||||
{
|
||||
ScrollToCategory(data => data.Category.CanBeApplied(item));
|
||||
ScrollToCategory(data => data.Category.CanBeApplied(item, null));
|
||||
}
|
||||
found = true;
|
||||
break;
|
||||
@@ -895,7 +903,7 @@ namespace Barotrauma
|
||||
submarineInfoFrame.RectTransform.ScreenSpaceOffset = new Point(0, (int)(16 * GUI.Scale));
|
||||
|
||||
description.Padding = new Vector4(description.Padding.X, 24 * GUI.Scale, description.Padding.Z, description.Padding.W);
|
||||
List<Entity> pointsOfInterest = (from category in UpgradeCategory.Categories from item in submarine.GetItems(UpgradeManager.UpgradeAlsoConnectedSubs) where category.CanBeApplied(item) && !item.NonInteractable select item).Cast<Entity>().ToList();
|
||||
List<Entity> pointsOfInterest = (from category in UpgradeCategory.Categories from item in submarine.GetItems(UpgradeManager.UpgradeAlsoConnectedSubs) where category.CanBeApplied(item, null) && item.IsPlayerTeamInteractable select item).Cast<Entity>().ToList();
|
||||
|
||||
List<ushort> ids = GameMain.GameSession.SubmarineInfo?.LeftBehindDockingPortIDs ?? new List<ushort>();
|
||||
pointsOfInterest.AddRange(submarine.GetItems(UpgradeManager.UpgradeAlsoConnectedSubs).Where(item => ids.Contains(item.ID)));
|
||||
@@ -1112,7 +1120,7 @@ namespace Barotrauma
|
||||
List<GUIFrame> frames = new List<GUIFrame>();
|
||||
foreach (var (item, guiFrame) in itemPreviews)
|
||||
{
|
||||
if (category.CanBeApplied(item))
|
||||
if (category.CanBeApplied(item, null))
|
||||
{
|
||||
frames.Add(guiFrame);
|
||||
}
|
||||
|
||||
@@ -557,6 +557,7 @@ namespace Barotrauma
|
||||
|
||||
GameModePreset.Init();
|
||||
|
||||
SaveUtil.DeleteDownloadedSubs();
|
||||
SubmarineInfo.RefreshSavedSubs();
|
||||
|
||||
TitleScreen.LoadState = 65.0f;
|
||||
@@ -1113,7 +1114,6 @@ namespace Barotrauma
|
||||
{
|
||||
new Pair<string, string>(TextManager.Get("EditorDisclaimerWikiLink"), TextManager.Get("EditorDisclaimerWikiUrl")),
|
||||
new Pair<string, string>(TextManager.Get("EditorDisclaimerDiscordLink"), TextManager.Get("EditorDisclaimerDiscordUrl")),
|
||||
new Pair<string, string>(TextManager.Get("EditorDisclaimerForumLink"), TextManager.Get("EditorDisclaimerForumUrl")),
|
||||
};
|
||||
foreach (var link in links)
|
||||
{
|
||||
|
||||
@@ -39,63 +39,39 @@ namespace Barotrauma
|
||||
|
||||
private List<SoldEntity> SoldEntities { get; } = new List<SoldEntity>();
|
||||
|
||||
public List<Item> GetSellableItems(Character character)
|
||||
public IEnumerable<Item> GetSellableItems(Character character)
|
||||
{
|
||||
if (character == null) { return new List<Item>(); }
|
||||
|
||||
// Only consider items which have been:
|
||||
// a) sold in singleplayer or confirmed by server (SellStatus.Confirmed); or
|
||||
// b) sold locally in multiplayer (SellStatus.Local), but the client has not received a campaing state update yet after selling them
|
||||
var soldEntities = SoldEntities.Where(se => se.Status != SoldEntity.SellStatus.Unconfirmed);
|
||||
|
||||
var sellables = Item.ItemList.FindAll(i => i?.Prefab != null && !i.Removed &&
|
||||
i.GetRootInventoryOwner() == character &&
|
||||
!i.SpawnedInOutpost &&
|
||||
(i.ContainedItems == null || i.ContainedItems.None() || i.ContainedItems.All(ci => soldEntities.Any(se => se.Item == ci))) &&
|
||||
(i.Condition >= 0.9f * i.MaxCondition || i.Prefab.AllowSellingWhenBroken) && soldEntities.None(se => se.Item == i));
|
||||
|
||||
// Prevent selling items in equipment slots
|
||||
var confirmedSoldEntities = SoldEntities.Where(se => se.Status != SoldEntity.SellStatus.Unconfirmed);
|
||||
// The bag slot is intentionally left out since we want to be able to sell items from there
|
||||
var equipmentSlots = new List<InvSlotType>() { InvSlotType.Head, InvSlotType.InnerClothes, InvSlotType.OuterClothes, InvSlotType.Headset, InvSlotType.Card };
|
||||
return character.Inventory.FindAllItems(item =>
|
||||
{
|
||||
if (item.SpawnedInOutpost) { return false; }
|
||||
if (!item.Prefab.AllowSellingWhenBroken && item.ConditionPercentage < 90.0f) { return false; }
|
||||
if (confirmedSoldEntities.Any(it => it.Item == item)) { return false; }
|
||||
// There must be no contained items or the contained items must be confirmed as sold
|
||||
if (!item.ContainedItems.All(it => confirmedSoldEntities.Any(se => se.Item == it))) { return false; }
|
||||
// Item must be in a non-equipment slot if possible
|
||||
if (!item.AllowedSlots.All(s => equipmentSlots.Contains(s)) && IsInEquipmentSlot(item)) { return false; }
|
||||
// Item must not be contained inside an item in an equipment slot
|
||||
if (item.GetRootContainer() is Item rootContainer && IsInEquipmentSlot(rootContainer)) { return false; }
|
||||
return true;
|
||||
}, recursive: true).Distinct();
|
||||
|
||||
bool IsInEquipmentSlot(Item item)
|
||||
{
|
||||
foreach (InvSlotType slot in equipmentSlots)
|
||||
{
|
||||
var index = character.Inventory.FindLimbSlot(slot);
|
||||
if (character.Inventory.Items[index] is Item item)
|
||||
{
|
||||
// Don't prevent selling of items which can only be put in equipment slots (like diving suits)
|
||||
if (item.AllowedSlots.Contains(InvSlotType.Any))
|
||||
{
|
||||
sellables.Remove(item);
|
||||
if (character.Inventory.IsInLimbSlot(item, slot)) { return true; }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Prevent selling items contained inside equipped items
|
||||
foreach (InvSlotType slot in equipmentSlots)
|
||||
{
|
||||
var index = character.Inventory.FindLimbSlot(slot);
|
||||
if (character.Inventory.Items[index] is Item item &&
|
||||
item.ContainedItems != null && item.AllowedSlots.Contains(InvSlotType.Any))
|
||||
{
|
||||
RemoveContainedFromSellables(item);
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveContainedFromSellables(Item item)
|
||||
{
|
||||
foreach (Item containedItem in item.ContainedItems)
|
||||
{
|
||||
if (containedItem == null) { continue; }
|
||||
if (containedItem.ContainedItems != null)
|
||||
{
|
||||
RemoveContainedFromSellables(containedItem);
|
||||
}
|
||||
sellables.Remove(containedItem);
|
||||
}
|
||||
}
|
||||
|
||||
return sellables;
|
||||
}
|
||||
|
||||
public void SetItemsInBuyCrate(List<PurchasedItem> items)
|
||||
{
|
||||
ItemsInBuyCrate.Clear();
|
||||
@@ -149,15 +125,20 @@ namespace Barotrauma
|
||||
var canAddToRemoveQueue = campaign.IsSinglePlayer && Entity.Spawner != null;
|
||||
var sellerId = GameMain.Client?.ID ?? 0;
|
||||
|
||||
// Check all the prices before starting the transaction
|
||||
// to make sure the modifiers stay the same for the whole transaction
|
||||
Dictionary<ItemPrefab, int> sellValues = GetSellValuesAtCurrentLocation(itemsToSell.Select(i => i.ItemPrefab));
|
||||
|
||||
foreach (PurchasedItem item in itemsToSell)
|
||||
{
|
||||
var itemValue = GetSellValueAtCurrentLocation(item.ItemPrefab, quantity: item.Quantity);
|
||||
var itemValue = item.Quantity * sellValues[item.ItemPrefab];
|
||||
|
||||
// check if the store can afford the item
|
||||
if (Location.StoreCurrentBalance < itemValue) { continue; }
|
||||
|
||||
var matchingItems = itemsInInventory.FindAll(i => i.Prefab == item.ItemPrefab);
|
||||
if (matchingItems.Count <= item.Quantity)
|
||||
// TODO: Write logic for prioritizing certain items over others (e.g. lone Battery Cell should be preferred over one inside a Stun Baton)
|
||||
var matchingItems = itemsInInventory.Where(i => i.Prefab == item.ItemPrefab);
|
||||
if (matchingItems.Count() <= item.Quantity)
|
||||
{
|
||||
foreach (Item i in matchingItems)
|
||||
{
|
||||
@@ -170,7 +151,7 @@ namespace Barotrauma
|
||||
{
|
||||
for (int i = 0; i < item.Quantity; i++)
|
||||
{
|
||||
var matchingItem = matchingItems[i];
|
||||
var matchingItem = matchingItems.ElementAt(i);
|
||||
SoldItems.Add(new SoldItem(matchingItem.Prefab, matchingItem.ID, canAddToRemoveQueue, sellerId));
|
||||
SoldEntities.Add(campaign.IsSinglePlayer ? SoldEntity.CreateInSinglePlayer(matchingItem) : SoldEntity.CreateInMultiPlayer(matchingItem));
|
||||
if (canAddToRemoveQueue) { Entity.Spawner.AddToRemoveQueue(matchingItem); }
|
||||
|
||||
@@ -134,6 +134,7 @@ namespace Barotrauma
|
||||
isScrollBarOnDefaultSide: false)
|
||||
{
|
||||
AutoHideScrollBar = false,
|
||||
CanBeFocused = false,
|
||||
OnSelected = (component, userData) => false,
|
||||
SelectMultiple = false,
|
||||
Spacing = (int)(GUI.Scale * 10)
|
||||
@@ -232,7 +233,7 @@ namespace Barotrauma
|
||||
};
|
||||
}
|
||||
|
||||
var reports = Order.PrefabList.FindAll(o => o.IsReport && o.SymbolSprite != null);
|
||||
var reports = Order.PrefabList.FindAll(o => o.IsReport && o.SymbolSprite != null && !o.Hidden);
|
||||
if (reports.None())
|
||||
{
|
||||
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.");
|
||||
@@ -252,7 +253,7 @@ namespace Barotrauma
|
||||
//report buttons
|
||||
foreach (Order order in reports)
|
||||
{
|
||||
if (!order.IsReport || order.SymbolSprite == null) { continue; }
|
||||
if (!order.IsReport || order.SymbolSprite == null || order.Hidden) { continue; }
|
||||
var btn = new GUIButton(new RectTransform(new Point(ReportButtonFrame.Rect.Width), ReportButtonFrame.RectTransform), style: null)
|
||||
{
|
||||
OnClicked = (GUIButton button, object userData) =>
|
||||
@@ -602,11 +603,11 @@ namespace Barotrauma
|
||||
|
||||
private WifiComponent GetHeadset(Character character, bool requireEquipped)
|
||||
{
|
||||
if (character?.Inventory == null) return null;
|
||||
if (character?.Inventory == null) { return null; }
|
||||
|
||||
var radioItem = character.Inventory.Items.FirstOrDefault(it => it != null && it.GetComponent<WifiComponent>() != null);
|
||||
if (radioItem == null) return null;
|
||||
if (requireEquipped && !character.HasEquippedItem(radioItem)) return null;
|
||||
var radioItem = character.Inventory.AllItems.FirstOrDefault(it => it.GetComponent<WifiComponent>() != null);
|
||||
if (radioItem == null) { return null; }
|
||||
if (requireEquipped && !character.HasEquippedItem(radioItem)) { return null; }
|
||||
|
||||
return radioItem.GetComponent<WifiComponent>();
|
||||
}
|
||||
@@ -687,36 +688,24 @@ namespace Barotrauma
|
||||
else if(order.IsIgnoreOrder)
|
||||
{
|
||||
WallSection ws = null;
|
||||
if (order.TargetType == Order.OrderTargetType.Entity && order.TargetEntity is MapEntity me)
|
||||
if (order.TargetType == Order.OrderTargetType.Entity && order.TargetEntity is IIgnorable ignorable)
|
||||
{
|
||||
if (order.Identifier == "ignorethis")
|
||||
{
|
||||
me.SetIgnoreByAI(true);
|
||||
ignorable.OrderedToBeIgnored = order.Identifier == "ignorethis";
|
||||
AddOrder(new Order(order.Prefab ?? order, order.TargetEntity, order.TargetItemComponent, orderGiver), null);
|
||||
}
|
||||
else
|
||||
{
|
||||
me.SetIgnoreByAI(false);
|
||||
ActiveOrders.RemoveAll(p => p.First.Identifier == "ignorethis" && p.First.TargetEntity == order.TargetEntity);
|
||||
}
|
||||
}
|
||||
else if (order.TargetType == Order.OrderTargetType.WallSection && order.TargetEntity is Structure s)
|
||||
{
|
||||
var wallSectionIndex = order.WallSectionIndex ?? s.Sections.IndexOf(wallContext);
|
||||
ws = s.GetSection(wallSectionIndex);
|
||||
if (ws != null)
|
||||
{
|
||||
if (order.Identifier == "ignorethis")
|
||||
{
|
||||
ws.SetIgnoreByAI(true);
|
||||
ws.OrderedToBeIgnored = order.Identifier == "ignorethis";
|
||||
AddOrder(new Order(order.Prefab ?? order, s, wallSectionIndex, orderGiver), null);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ws.SetIgnoreByAI(false);
|
||||
ActiveOrders.RemoveAll(p => p.First.Identifier == "ignorethis" && p.First.TargetEntity == s && p.First.WallSectionIndex == wallSectionIndex);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (ws != null)
|
||||
@@ -781,7 +770,16 @@ namespace Barotrauma
|
||||
{
|
||||
currentOrderInfo = (OrderInfo)currentOrderIcon.UserData;
|
||||
// No need to recreate icons if the current order matches the new order
|
||||
if (currentOrderInfo.Value.MatchesOrder(order, option)) { return; }
|
||||
if (currentOrderInfo.Value.MatchesOrder(order, option))
|
||||
{
|
||||
currentOrderIcon.UserData = new OrderInfo(order, option);
|
||||
if (currentOrderIcon.FindChild(c => (string)c.UserData == "colorsource") is GUIImage image)
|
||||
{
|
||||
image.Sprite = GetOrderIconSprite(order, option);
|
||||
image.ToolTip = CreateOrderTooltip(order, option);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the current order icon
|
||||
@@ -826,7 +824,10 @@ namespace Barotrauma
|
||||
}
|
||||
};
|
||||
|
||||
CreateNodeIcon(orderFrame.RectTransform, order.SymbolSprite, order.Color, tooltip: order.Name);
|
||||
CreateNodeIcon(orderFrame.RectTransform,
|
||||
GetOrderIconSprite(order, option),
|
||||
order.Color,
|
||||
tooltip: CreateOrderTooltip(order, option));
|
||||
|
||||
new GUIImage(new RectTransform(Vector2.One, orderFrame.RectTransform), cancelIcon, scaleToFit: true)
|
||||
{
|
||||
@@ -870,11 +871,10 @@ namespace Barotrauma
|
||||
new RectTransform(new Vector2(0.8f), prevOrderFrame.RectTransform, anchor: Anchor.BottomLeft),
|
||||
style: null);
|
||||
|
||||
CreateNodeIcon(
|
||||
prevOrderIconFrame.RectTransform,
|
||||
previousOrderInfo.Order.SymbolSprite,
|
||||
CreateNodeIcon(prevOrderIconFrame.RectTransform,
|
||||
GetOrderIconSprite(previousOrderInfo),
|
||||
previousOrderInfo.Order.Color,
|
||||
tooltip: previousOrderInfo.Order.Name);
|
||||
tooltip: CreateOrderTooltip(previousOrderInfo));
|
||||
|
||||
foreach (GUIComponent c in prevOrderIconFrame.Children)
|
||||
{
|
||||
@@ -947,6 +947,48 @@ namespace Barotrauma
|
||||
private IEnumerable<GUIComponent> GetPreviousOrderIcons(GUILayoutGroup characterComponent) =>
|
||||
characterComponent?.FindChildren(c => c?.UserData is OrderInfo orderInfo && orderInfo.ComponentIdentifier == "previousorder");
|
||||
|
||||
private string CreateOrderTooltip(Order order, string option)
|
||||
{
|
||||
if (order == null) { return ""; }
|
||||
if (!string.IsNullOrEmpty(option))
|
||||
{
|
||||
return TextManager.GetWithVariables("crewlistordericontooltip",
|
||||
new string[2] { "[ordername]", "[orderoption]" },
|
||||
new string[2] { order.Name, order.GetOptionName(option) });
|
||||
}
|
||||
else if (order.TargetEntity is Item targetItem && order.MinimapIcons.ContainsKey(targetItem.Prefab.Identifier))
|
||||
{
|
||||
return TextManager.GetWithVariables("crewlistordericontooltip",
|
||||
new string[2] { "[ordername]", "[orderoption]" },
|
||||
new string[2] { order.Name, targetItem.Name });
|
||||
}
|
||||
else
|
||||
{
|
||||
return order.Name;
|
||||
}
|
||||
}
|
||||
|
||||
private string CreateOrderTooltip(OrderInfo orderInfo) =>
|
||||
CreateOrderTooltip(orderInfo.Order, orderInfo.OrderOption);
|
||||
|
||||
private Sprite GetOrderIconSprite(Order order, string option)
|
||||
{
|
||||
if (order == null) { return null; }
|
||||
Sprite sprite = null;
|
||||
if (option != null && order.Prefab.OptionSprites.Any())
|
||||
{
|
||||
order.Prefab.OptionSprites.TryGetValue(option, out sprite);
|
||||
}
|
||||
if (sprite == null && order.TargetEntity is Item targetItem && order.MinimapIcons.Any())
|
||||
{
|
||||
order.MinimapIcons.TryGetValue(targetItem.Prefab.Identifier, out sprite);
|
||||
}
|
||||
return sprite ?? order.SymbolSprite;
|
||||
}
|
||||
|
||||
private Sprite GetOrderIconSprite(OrderInfo orderInfo) =>
|
||||
GetOrderIconSprite(orderInfo.Order, orderInfo.OrderOption);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Updating and drawing the UI
|
||||
@@ -982,7 +1024,7 @@ namespace Barotrauma
|
||||
|
||||
public void CreateModerationContextMenu(Point mousePos, Client client)
|
||||
{
|
||||
if (IsSinglePlayer || client == null || (GameMain.NetworkMember?.ConnectedClients?.All(match => match != client) ?? true)) { return; }
|
||||
if (IsSinglePlayer || client == null || (!GameMain.Client?.PreviouslyConnectedClients?.Contains(client) ?? true)) { return; }
|
||||
|
||||
contextMenu = new GUIFrame(new RectTransform(new Vector2(0.1f, 0.15f), GUI.Canvas) { ScreenSpaceOffset = mousePos }, style: "GUIToolTip") { UserData = client };
|
||||
|
||||
@@ -1032,6 +1074,8 @@ namespace Barotrauma
|
||||
UserData = "promote"
|
||||
};
|
||||
|
||||
if (GameMain.Client.ConnectedClients.Contains(client))
|
||||
{
|
||||
new GUITextBlock(new RectTransform(Point.Zero, parent), TextManager.Get(client.MutedLocally ? "unmute" : "mute"), font: GUI.SmallFont)
|
||||
{
|
||||
Padding = new Vector4(4),
|
||||
@@ -1045,6 +1089,7 @@ namespace Barotrauma
|
||||
Enabled = client.ID != GameMain.Client?.ID && client.AllowKicking,
|
||||
UserData = canKick ? "kick" : "votekick"
|
||||
};
|
||||
}
|
||||
|
||||
new GUITextBlock(new RectTransform(Point.Zero, parent), TextManager.Get("ban"), font: GUI.SmallFont)
|
||||
{
|
||||
@@ -1363,23 +1408,13 @@ namespace Barotrauma
|
||||
isSelectionHighlighted = false;
|
||||
}
|
||||
|
||||
if (!CanIssueOrders)
|
||||
{
|
||||
DisableCommandUI();
|
||||
}
|
||||
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 ?? shortcutNodes.Find(n => GUI.IsMouseOn(n));
|
||||
// Make sure the node is for an option-less order or an order option
|
||||
if ((node.UserData is Order order && !order.HasOptions && (!order.MustSetTarget || itemContext != null)) || node.UserData is Tuple<Order, string>)
|
||||
{
|
||||
CreateAssignmentNodes(node);
|
||||
}
|
||||
}
|
||||
// When using Deselect to close the interface, make sure it's not a seconday mouse button click on a node
|
||||
// That should be reserved for opening manual assignment
|
||||
var hitDeselect = PlayerInput.KeyHit(InputType.Deselect) && (!PlayerInput.SecondaryMouseButtonClicked() ||
|
||||
(optionNodes.None(n => GUI.IsMouseOn(n.Item1)) && shortcutNodes.None(n => GUI.IsMouseOn(n))));
|
||||
// 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(Keys.Escape))
|
||||
if (hitDeselect || PlayerInput.KeyHit(Keys.Escape) || !CanIssueOrders ||
|
||||
(PlayerInput.KeyHit(InputType.Command) && selectedNode == null && !clicklessSelectionActive))
|
||||
{
|
||||
DisableCommandUI();
|
||||
}
|
||||
@@ -1437,8 +1472,15 @@ namespace Barotrauma
|
||||
{
|
||||
timeSelected += deltaTime;
|
||||
if (timeSelected >= selectionTime)
|
||||
{
|
||||
if (PlayerInput.IsShiftDown() && selectedNode.OnSecondaryClicked != null)
|
||||
{
|
||||
selectedNode.OnSecondaryClicked.Invoke(selectedNode, selectedNode.UserData);
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedNode.OnClicked?.Invoke(selectedNode, selectedNode.UserData);
|
||||
}
|
||||
ResetNodeSelection();
|
||||
}
|
||||
else if (timeSelected >= 0.15f && !isSelectionHighlighted)
|
||||
@@ -1463,7 +1505,15 @@ namespace Barotrauma
|
||||
{
|
||||
if (node.Item2 != Keys.None && PlayerInput.KeyHit(node.Item2))
|
||||
{
|
||||
(node.Item1 as GUIButton)?.OnClicked?.Invoke(node.Item1 as GUIButton, node.Item1.UserData);
|
||||
var b = node.Item1 as GUIButton;
|
||||
if (PlayerInput.IsShiftDown() && b?.OnSecondaryClicked != null)
|
||||
{
|
||||
b.OnSecondaryClicked.Invoke(node.Item1 as GUIButton, node.Item1.UserData);
|
||||
}
|
||||
else
|
||||
{
|
||||
b?.OnClicked?.Invoke(node.Item1 as GUIButton, node.Item1.UserData);
|
||||
}
|
||||
ResetNodeSelection();
|
||||
hotkeyHit = true;
|
||||
break;
|
||||
@@ -1947,7 +1997,12 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
// When the mini map is shown, always position the return node on the bottom
|
||||
var offset = node?.UserData is Order order && order.GetMatchingItems(true).Count > 1 ?
|
||||
List<Item> matchingItems = null;
|
||||
if (node?.UserData is Order order)
|
||||
{
|
||||
matchingItems = order.GetMatchingItems(true, interactableFor: characterContext ?? Character.Controlled);
|
||||
}
|
||||
var offset = matchingItems != null && matchingItems.Count > 1 ?
|
||||
new Point(0, (int)(returnNodeDistanceModifier * nodeDistance)) :
|
||||
node.RectTransform.AbsoluteOffset.Multiply(-returnNodeDistanceModifier);
|
||||
SetReturnNode(centerNode, offset);
|
||||
@@ -2027,6 +2082,7 @@ namespace Barotrauma
|
||||
SetCharacterTooltip(c, characterContext);
|
||||
}
|
||||
node.OnClicked = null;
|
||||
node.OnSecondaryClicked = null;
|
||||
centerNode = node;
|
||||
}
|
||||
|
||||
@@ -2042,6 +2098,7 @@ namespace Barotrauma
|
||||
c.ToolTip = TextManager.Get("commandui.return");
|
||||
}
|
||||
node.OnClicked = NavigateBackward;
|
||||
node.OnSecondaryClicked = null;
|
||||
returnNode = node;
|
||||
}
|
||||
|
||||
@@ -2071,20 +2128,26 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
private void RemoveOptionNodes()
|
||||
{
|
||||
if (commandFrame != null)
|
||||
{
|
||||
optionNodes.ForEach(node => commandFrame.RemoveChild(node.Item1));
|
||||
optionNodes.Clear();
|
||||
shortcutNodes.ForEach(node => commandFrame.RemoveChild(node));
|
||||
shortcutNodes.Clear();
|
||||
commandFrame.RemoveChild(expandNode);
|
||||
}
|
||||
optionNodes.Clear();
|
||||
shortcutNodes.Clear();
|
||||
expandNode = null;
|
||||
expandNodeHotkey = Keys.None;
|
||||
RemoveExtraOptionNodes();
|
||||
}
|
||||
|
||||
private void RemoveExtraOptionNodes()
|
||||
{
|
||||
if (commandFrame != null)
|
||||
{
|
||||
extraOptionNodes.ForEach(node => commandFrame.RemoveChild(node));
|
||||
}
|
||||
extraOptionNodes.Clear();
|
||||
}
|
||||
|
||||
@@ -2125,7 +2188,8 @@ namespace Barotrauma
|
||||
|
||||
shortcutNodes.Clear();
|
||||
|
||||
if (shortcutNodes.Count < maxShortCutNodeCount && sub.GetItems(false).Find(i => i.HasTag("reactor") && !i.NonInteractable)?.GetComponent<Reactor>() is Reactor reactor)
|
||||
if (shortcutNodes.Count < maxShortCutNodeCount &&
|
||||
sub.GetItems(false).Find(i => i.HasTag("reactor") && i.IsPlayerTeamInteractable)?.GetComponent<Reactor>() is Reactor reactor)
|
||||
{
|
||||
var reactorOutput = -reactor.CurrPowerConsumption;
|
||||
// If player is not an engineer AND the reactor is not powered up AND nobody is using the reactor
|
||||
@@ -2144,7 +2208,7 @@ namespace Barotrauma
|
||||
// If player is not a captain AND nobody is using the nav terminal AND the nav terminal is powered up
|
||||
// --> Create shortcut node for Steer order
|
||||
if (shortcutNodes.Count < maxShortCutNodeCount && (Character.Controlled == null || Character.Controlled.Info?.Job?.Prefab != JobPrefab.Get("captain")) &&
|
||||
sub.GetItems(false).Find(i => i.HasTag("navterminal") && !i.NonInteractable) is Item nav && characters.None(c => c.SelectedConstruction == nav) &&
|
||||
sub.GetItems(false).Find(i => i.HasTag("navterminal") && i.IsPlayerTeamInteractable) is Item nav && characters.None(c => c.SelectedConstruction == nav) &&
|
||||
nav.GetComponent<Steering>() is Steering steering && steering.Voltage > steering.MinVoltage)
|
||||
{
|
||||
shortcutNodes.Add(
|
||||
@@ -2195,7 +2259,7 @@ namespace Barotrauma
|
||||
(n.UserData is Tuple<Order, string> orderWithOption && orderWithOption.Item1.Identifier == orderIdentifier)) &&
|
||||
!orderPrefab.IsReport && orderPrefab.Category != null)
|
||||
{
|
||||
if (!orderPrefab.MustSetTarget || orderPrefab.GetMatchingItems(sub, true).Any())
|
||||
if (!orderPrefab.MustSetTarget || orderPrefab.GetMatchingItems(sub, true, interactableFor: characterContext ?? Character.Controlled).Any())
|
||||
{
|
||||
shortcutNodes.Add(CreateOrderNode(shortcutNodeSize, null, Point.Zero, orderPrefab, -1));
|
||||
}
|
||||
@@ -2245,7 +2309,8 @@ namespace Barotrauma
|
||||
{
|
||||
order = orders[i];
|
||||
disableNode = !CanSomeoneHearCharacter() ||
|
||||
(order.MustSetTarget && (order.ItemComponentType != null || order.TargetItems.Length > 0) && order.GetMatchingItems(true).None());
|
||||
(order.MustSetTarget && (order.ItemComponentType != null || order.TargetItems.Length > 0) &&
|
||||
order.GetMatchingItems(true, interactableFor: characterContext ?? Character.Controlled).None());
|
||||
optionNodes.Add(new Tuple<GUIComponent, Keys>(
|
||||
CreateOrderNode(nodeSize, commandFrame.RectTransform, offsets[i].ToPoint(), order, (i + 1) % 10, disableNode: disableNode, checkIfOrderCanBeHeard: false),
|
||||
!disableNode ? Keys.D0 + (i + 1) % 10 : Keys.None));
|
||||
@@ -2262,7 +2327,7 @@ namespace Barotrauma
|
||||
string orderIdentifier;
|
||||
|
||||
// Check if targeting an item or a hull
|
||||
if (itemContext != null && !itemContext.NonInteractable)
|
||||
if (itemContext != null && itemContext.IsPlayerTeamInteractable)
|
||||
{
|
||||
ItemComponent targetComponent;
|
||||
foreach (Order p in Order.PrefabList)
|
||||
@@ -2314,11 +2379,14 @@ namespace Barotrauma
|
||||
if (contextualOrders.None())
|
||||
{
|
||||
orderIdentifier = "cleanupitems";
|
||||
if (contextualOrders.None(o => o.Identifier.Equals(orderIdentifier)) && AIObjectiveCleanupItems.IsValidTarget(itemContext, Character.Controlled, checkInventory: false))
|
||||
if (contextualOrders.None(o => o.Identifier.Equals(orderIdentifier)))
|
||||
{
|
||||
if (AIObjectiveCleanupItems.IsValidTarget(itemContext, Character.Controlled, checkInventory: false) || AIObjectiveCleanupItems.IsValidContainer(itemContext, Character.Controlled))
|
||||
{
|
||||
contextualOrders.Add(new Order(Order.GetPrefab(orderIdentifier), itemContext, targetItem: null, Character.Controlled));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AddIgnoreOrder(itemContext);
|
||||
}
|
||||
@@ -2332,6 +2400,35 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
void AddIgnoreOrder(IIgnorable target)
|
||||
{
|
||||
var orderIdentifier = "ignorethis";
|
||||
if (!target.OrderedToBeIgnored && contextualOrders.None(o => o.Identifier == orderIdentifier))
|
||||
{
|
||||
AddOrder();
|
||||
}
|
||||
else
|
||||
{
|
||||
orderIdentifier = "unignorethis";
|
||||
if (target.OrderedToBeIgnored && contextualOrders.None(o => o.Identifier == orderIdentifier))
|
||||
{
|
||||
AddOrder();
|
||||
}
|
||||
}
|
||||
|
||||
void AddOrder()
|
||||
{
|
||||
if (target is WallSection ws)
|
||||
{
|
||||
contextualOrders.Add(new Order(Order.GetPrefab(orderIdentifier), ws.Wall, ws.Wall.Sections.IndexOf(ws), orderGiver: Character.Controlled));
|
||||
}
|
||||
else
|
||||
{
|
||||
contextualOrders.Add(new Order(Order.GetPrefab(orderIdentifier), target as Entity, null, Character.Controlled));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
orderIdentifier = "wait";
|
||||
if (contextualOrders.None(o => o.Identifier.Equals(orderIdentifier)))
|
||||
{
|
||||
@@ -2366,35 +2463,6 @@ namespace Barotrauma
|
||||
CreateOrderNode(nodeSize, commandFrame.RectTransform, offsets[i].ToPoint(), contextualOrders[i], (i + 1) % 10, disableNode: disableNode, checkIfOrderCanBeHeard: false),
|
||||
!disableNode ? Keys.D0 + (i + 1) % 10 : Keys.None));
|
||||
}
|
||||
|
||||
void AddIgnoreOrder(ISpatialEntity target)
|
||||
{
|
||||
var orderIdentifier = "ignorethis";
|
||||
if (!target.IgnoreByAI && contextualOrders.None(o => o.Identifier.Equals(orderIdentifier)))
|
||||
{
|
||||
AddOrder(orderIdentifier, target);
|
||||
}
|
||||
else
|
||||
{
|
||||
orderIdentifier = "unignorethis";
|
||||
if (target.IgnoreByAI && contextualOrders.None(o => o.Identifier.Equals(orderIdentifier)))
|
||||
{
|
||||
AddOrder(orderIdentifier, target);
|
||||
}
|
||||
}
|
||||
|
||||
void AddOrder(string id, ISpatialEntity target)
|
||||
{
|
||||
if (target is WallSection ws)
|
||||
{
|
||||
contextualOrders.Add(new Order(Order.GetPrefab(orderIdentifier), ws.Wall, ws.Wall.Sections.IndexOf(ws), orderGiver: Character.Controlled));
|
||||
}
|
||||
else
|
||||
{
|
||||
contextualOrders.Add(new Order(Order.GetPrefab(orderIdentifier), target as Entity, null, Character.Controlled));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: there's duplicate logic here and above -> would be better to refactor so that the conditions are only defined in one place
|
||||
@@ -2404,6 +2472,7 @@ namespace Barotrauma
|
||||
if (Order.PrefabList.Any(o => item.HasTag(o.TargetItems))) { return true; }
|
||||
if (Order.PrefabList.Any(o => o.TryGetTargetItemComponent(item, out _))) { return true; }
|
||||
if (AIObjectiveCleanupItems.IsValidTarget(item, Character.Controlled, checkInventory: false)) { return true; }
|
||||
if (AIObjectiveCleanupItems.IsValidContainer(item, Character.Controlled)) { return true; }
|
||||
|
||||
if (item.Repairables.Any(r => item.ConditionPercentage < r.RepairThreshold)) { return true; }
|
||||
var operateWeaponsPrefab = Order.GetPrefab("operateweapons");
|
||||
@@ -2435,7 +2504,7 @@ namespace Barotrauma
|
||||
// so we know to directly target that with the order
|
||||
if (!mustSetOptionOrTarget && order.MustSetTarget && itemContext == null)
|
||||
{
|
||||
var matchingItems = order.GetMatchingItems(GetTargetSubmarine(), true);
|
||||
var matchingItems = order.GetMatchingItems(GetTargetSubmarine(), true, interactableFor: characterContext ?? Character.Controlled);
|
||||
if (matchingItems.Count > 1)
|
||||
{
|
||||
mustSetOptionOrTarget = true;
|
||||
@@ -2470,9 +2539,14 @@ namespace Barotrauma
|
||||
}
|
||||
return true;
|
||||
};
|
||||
// TODO: Might need to edit the tooltip
|
||||
if (CanOpenManualAssignment(node))
|
||||
{
|
||||
node.OnSecondaryClicked = (button, _) => CreateAssignmentNodes(button);
|
||||
}
|
||||
var showAssignmentTooltip = !mustSetOptionOrTarget && characterContext == null && !order.MustManuallyAssign && !order.TargetAllCharacters;
|
||||
var orderName = GetOrderNameBasedOnContextuality(order);
|
||||
var icon = CreateNodeIcon(node.RectTransform, order.SymbolSprite, order.Color,
|
||||
tooltip: mustSetOptionOrTarget || characterContext != null ? order.Name : order.Name +
|
||||
tooltip: !showAssignmentTooltip ? orderName : orderName +
|
||||
"\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"));
|
||||
|
||||
@@ -2491,7 +2565,7 @@ namespace Barotrauma
|
||||
private void CreateOrderOptions(Order order)
|
||||
{
|
||||
Submarine submarine = GetTargetSubmarine();
|
||||
var matchingItems = (itemContext == null && order.MustSetTarget) ? order.GetMatchingItems(submarine, true) : new List<Item>();
|
||||
var matchingItems = (itemContext == null && order.MustSetTarget) ? order.GetMatchingItems(submarine, true, interactableFor: characterContext ?? Character.Controlled) : new List<Item>();
|
||||
|
||||
//more than one target item -> create a minimap-like selection with a pic of the sub
|
||||
if (itemContext == null && matchingItems.Count > 1)
|
||||
@@ -2572,15 +2646,14 @@ namespace Barotrauma
|
||||
Stretch = true
|
||||
};
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.3f), optionContainer.RectTransform), item != null ? item.Name : order.Name);
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.3f), optionContainer.RectTransform),
|
||||
item?.Name ?? GetOrderNameBasedOnContextuality(order));
|
||||
|
||||
for (int i = 0; i < order.Options.Length; i++)
|
||||
{
|
||||
optionNodes.Add(new Tuple<GUIComponent, Keys>(
|
||||
new GUIButton(
|
||||
var optionButton = new GUIButton(
|
||||
new RectTransform(new Vector2(1.0f, 0.2f), optionContainer.RectTransform),
|
||||
text: order.GetOptionName(i),
|
||||
style: "GUITextBox")
|
||||
text: order.GetOptionName(i), style: "GUITextBox")
|
||||
{
|
||||
UserData = new Tuple<Order, string>(
|
||||
item == null ? order : new Order(order, item, order.GetTargetItemComponent(item)),
|
||||
@@ -2594,8 +2667,12 @@ namespace Barotrauma
|
||||
DisableCommandUI();
|
||||
return true;
|
||||
}
|
||||
},
|
||||
Keys.None));
|
||||
};
|
||||
if (CanOpenManualAssignment(optionButton))
|
||||
{
|
||||
optionButton.OnSecondaryClicked = (button, _) => CreateAssignmentNodes(button);
|
||||
}
|
||||
optionNodes.Add(new Tuple<GUIComponent, Keys>(optionButton, Keys.None));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -2610,7 +2687,7 @@ namespace Barotrauma
|
||||
{
|
||||
UserData = userData,
|
||||
Font = GUI.SmallFont,
|
||||
ToolTip = item?.Name ?? order.Name,
|
||||
ToolTip = item?.Name ?? GetOrderNameBasedOnContextuality(order),
|
||||
OnClicked = (_, userData) =>
|
||||
{
|
||||
if (!CanIssueOrders) { return false; }
|
||||
@@ -2620,7 +2697,10 @@ namespace Barotrauma
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
if (CanOpenManualAssignment(optionElement))
|
||||
{
|
||||
optionElement.OnSecondaryClicked = (button, _) => CreateAssignmentNodes(button);
|
||||
}
|
||||
Sprite icon = null;
|
||||
order.MinimapIcons?.TryGetValue(item.Prefab.Identifier, out icon);
|
||||
if (item.Prefab.MinimapIcon != null)
|
||||
@@ -2677,11 +2757,16 @@ namespace Barotrauma
|
||||
return true;
|
||||
}
|
||||
};
|
||||
if (CanOpenManualAssignment(node))
|
||||
{
|
||||
node.OnSecondaryClicked = (button, _) => CreateAssignmentNodes(button);
|
||||
}
|
||||
node.RectTransform.MoveOverTime(offset, CommandNodeAnimDuration);
|
||||
|
||||
GUIImage icon = null;
|
||||
if (order.Prefab.OptionSprites.TryGetValue(option, out Sprite sprite))
|
||||
{
|
||||
var showAssignmentTooltip = characterContext == null && !order.MustManuallyAssign && !order.TargetAllCharacters;
|
||||
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") +
|
||||
@@ -2700,13 +2785,13 @@ namespace Barotrauma
|
||||
return node;
|
||||
}
|
||||
|
||||
private void CreateAssignmentNodes(GUIComponent node)
|
||||
private bool CreateAssignmentNodes(GUIComponent node)
|
||||
{
|
||||
var order = (node.UserData is Order) ?
|
||||
new Tuple<Order, string>(node.UserData as Order, null) :
|
||||
node.UserData as Tuple<Order, string>;
|
||||
var characters = GetCharactersForManualAssignment(order.Item1);
|
||||
if (characters.None()) { return; }
|
||||
if (characters.None()) { return false; }
|
||||
|
||||
if (!(optionNodes.Find(n => n.Item1 == node) is Tuple<GUIComponent, Keys> optionNode) || !optionNodes.Remove(optionNode))
|
||||
{
|
||||
@@ -2791,7 +2876,7 @@ namespace Barotrauma
|
||||
CreateHotkeyIcon(returnNode.RectTransform, hotkey % 10, true);
|
||||
returnNodeHotkey = Keys.D0 + hotkey % 10;
|
||||
expandNodeHotkey = Keys.None;
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
extraOptionCharacters.Clear();
|
||||
@@ -2816,6 +2901,7 @@ namespace Barotrauma
|
||||
expandNodeHotkey = Keys.D0 + hotkey % 10;
|
||||
CreateHotkeyIcon(returnNode.RectTransform, ++hotkey % 10, true);
|
||||
returnNodeHotkey = Keys.D0 + hotkey % 10;
|
||||
return true;
|
||||
}
|
||||
|
||||
private Vector2[] GetAssignmentNodeOffsets(int characters, bool firstRing = true)
|
||||
@@ -3083,7 +3169,7 @@ namespace Barotrauma
|
||||
if (Character.Controlled != null)
|
||||
{
|
||||
// Pick the second main sub when we have two teams (in combat mission)
|
||||
if (Character.Controlled.TeamID == Character.TeamType.Team2 && Submarine.MainSubs.Length > 1)
|
||||
if (Character.Controlled.TeamID == CharacterTeamType.Team2 && Submarine.MainSubs.Length > 1)
|
||||
{
|
||||
sub = Submarine.MainSubs[1];
|
||||
}
|
||||
@@ -3105,7 +3191,29 @@ namespace Barotrauma
|
||||
component.ToolTip = tooltip;
|
||||
}
|
||||
|
||||
private string GetOrderNameBasedOnContextuality(Order order)
|
||||
{
|
||||
if (order == null) { return ""; }
|
||||
if (isContextual) { return order.ContextualName; }
|
||||
return order.Name;
|
||||
}
|
||||
|
||||
#region Crew Member Assignment Logic
|
||||
private bool CanOpenManualAssignment(GUIComponent node)
|
||||
{
|
||||
if (node == null || characterContext != null) { return false; }
|
||||
if (node.UserData is Tuple<Order, string> orderInfo)
|
||||
{
|
||||
return !orderInfo.Item1.TargetAllCharacters;
|
||||
}
|
||||
if (node.UserData is Order order)
|
||||
{
|
||||
return !order.TargetAllCharacters && !order.HasOptions &&
|
||||
(!order.MustSetTarget || itemContext != null ||
|
||||
order.GetMatchingItems(GetTargetSubmarine(), true, interactableFor: Character.Controlled).Count < 2);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private Character GetCharacterForQuickAssignment(Order order)
|
||||
{
|
||||
@@ -3145,7 +3253,7 @@ namespace Barotrauma
|
||||
// 4. Prioritize bots over player controlled characters
|
||||
.ThenByDescending(c => c.IsBot)
|
||||
// 5. Use the priority value of the current objective
|
||||
.ThenBy(c => c.AIController?.ObjectiveManager.CurrentObjective?.Priority)
|
||||
.ThenBy(c => c.AIController is HumanAIController humanAI ? humanAI.ObjectiveManager.CurrentObjective?.Priority : 0)
|
||||
// 6. Prioritize those with the best skill for the order
|
||||
.ThenByDescending(c => c.GetSkillLevel(order.AppropriateSkill));
|
||||
}
|
||||
|
||||
@@ -450,7 +450,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (mb is GUIMessageBox msgBox)
|
||||
{
|
||||
if (mb.UserData is Pair<string, ushort> pair && pair.First.Equals("conversationaction", StringComparison.OrdinalIgnoreCase))
|
||||
if (ReadyCheck.IsReadyCheck(mb) || mb.UserData is Pair<string, ushort> pair && pair.First.Equals("conversationaction", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
msgBox.Close();
|
||||
}
|
||||
@@ -812,8 +812,7 @@ namespace Barotrauma
|
||||
return;
|
||||
}
|
||||
Load(doc.Root.Element("MultiPlayerCampaign"));
|
||||
SubmarineInfo selectedSub;
|
||||
GameMain.GameSession.OwnedSubmarines = SaveUtil.LoadOwnedSubmarines(doc, out selectedSub);
|
||||
GameMain.GameSession.OwnedSubmarines = SaveUtil.LoadOwnedSubmarines(doc, out SubmarineInfo selectedSub);
|
||||
GameMain.GameSession.SubmarineInfo = selectedSub;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@ namespace Barotrauma
|
||||
{
|
||||
class SinglePlayerCampaign : CampaignMode
|
||||
{
|
||||
public const int MinimumInitialMoney = 0;
|
||||
|
||||
public override bool Paused
|
||||
{
|
||||
get { return ForceMapUI || CoroutineManager.IsCoroutineRunning("LevelTransition") || ShowCampaignUI && CampaignUI.SelectedTab == InteractionType.Map; }
|
||||
@@ -105,7 +107,6 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
CampaignMetadata ??= new CampaignMetadata(this);
|
||||
|
||||
UpgradeManager ??= new UpgradeManager(this);
|
||||
|
||||
InitCampaignData();
|
||||
@@ -113,6 +114,9 @@ namespace Barotrauma
|
||||
InitUI();
|
||||
|
||||
Money = element.GetAttributeInt("money", 0);
|
||||
PurchasedLostShuttles = element.GetAttributeBool("purchasedlostshuttles", false);
|
||||
PurchasedHullRepairs = element.GetAttributeBool("purchasedhullrepairs", false);
|
||||
PurchasedItemRepairs = element.GetAttributeBool("purchaseditemrepairs", false);
|
||||
CheatsEnabled = element.GetAttributeBool("cheatsenabled", false);
|
||||
if (CheatsEnabled)
|
||||
{
|
||||
@@ -137,7 +141,7 @@ namespace Barotrauma
|
||||
/// <summary>
|
||||
/// Start a completely new single player campaign
|
||||
/// </summary>
|
||||
public static SinglePlayerCampaign StartNew(string mapSeed)
|
||||
public static SinglePlayerCampaign StartNew(string mapSeed, SubmarineInfo selectedSub)
|
||||
{
|
||||
var campaign = new SinglePlayerCampaign(mapSeed);
|
||||
return campaign;
|
||||
@@ -699,6 +703,9 @@ namespace Barotrauma
|
||||
{
|
||||
XElement modeElement = new XElement("SinglePlayerCampaign",
|
||||
new XAttribute("money", Money),
|
||||
new XAttribute("purchasedlostshuttles", PurchasedLostShuttles),
|
||||
new XAttribute("purchasedhullrepairs", PurchasedHullRepairs),
|
||||
new XAttribute("purchaseditemrepairs", PurchasedItemRepairs),
|
||||
new XAttribute("cheatsenabled", CheatsEnabled));
|
||||
|
||||
//save and remove all items that are in someone's inventory so they don't get included in the sub file as well
|
||||
|
||||
@@ -182,7 +182,7 @@ namespace Barotrauma.Tutorials
|
||||
+ " Equip a screwdriver by pulling it to either of the slots with a hand symbol, and then use it on the terminal by left clicking.");
|
||||
|
||||
while (Controlled.SelectedConstruction != steering.Item ||
|
||||
Controlled.SelectedItems.FirstOrDefault(i => i != null && i.Prefab.Identifier == "screwdriver") == null)
|
||||
Controlled.HeldItems.FirstOrDefault(i => i.Prefab.Identifier == "screwdriver") == null)
|
||||
{
|
||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
||||
}
|
||||
@@ -203,16 +203,16 @@ namespace Barotrauma.Tutorials
|
||||
|
||||
while ((Controlled.SelectedConstruction != junctionBox.Item &&
|
||||
Controlled.SelectedConstruction != steering.Item) ||
|
||||
Controlled.SelectedItems.FirstOrDefault(i => i != null && i.Prefab.Identifier == "screwdriver") == null)
|
||||
!Controlled.HeldItems.Any(i => i.Prefab.Identifier == "screwdriver"))
|
||||
{
|
||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
if (Controlled.SelectedItems.FirstOrDefault(i => i != null && i.GetComponent<Wire>() != null) == null)
|
||||
if (!Controlled.HeldItems.Any(i => i.GetComponent<Wire>() != null))
|
||||
{
|
||||
infoBox = CreateInfoFrame("", "Equip the wire by dragging it to one of the slots with a hand symbol.");
|
||||
|
||||
while (Controlled.SelectedItems.FirstOrDefault(i => i != null && i.GetComponent<Wire>() != null) == null)
|
||||
while (!Controlled.HeldItems.Any(i => i.GetComponent<Wire>() != null))
|
||||
{
|
||||
yield return Controlled.IsDead ? CoroutineStatus.Success : CoroutineStatus.Running;
|
||||
}
|
||||
@@ -501,7 +501,7 @@ namespace Barotrauma.Tutorials
|
||||
|
||||
do
|
||||
{
|
||||
var weldingTool = Controlled.Inventory.Items.FirstOrDefault(i => i != null && i.Prefab.Identifier == "weldingtool");
|
||||
var weldingTool = Controlled.Inventory.FindItemByIdentifier("weldingtool");
|
||||
if (weldingTool != null &&
|
||||
weldingTool.ContainedItems.FirstOrDefault(contained => contained != null && contained.Prefab.Identifier == "weldingfueltank") != null) break;
|
||||
|
||||
@@ -661,7 +661,10 @@ namespace Barotrauma.Tutorials
|
||||
//TODO: reimplement
|
||||
//enemy.Health = 50.0f;
|
||||
|
||||
enemy.AIController.State = AIState.Idle;
|
||||
if (enemy.AIController is EnemyAIController enemyAI)
|
||||
{
|
||||
enemyAI.State = AIState.Idle;
|
||||
}
|
||||
|
||||
Vector2 targetPos = Character.Controlled.WorldPosition + new Vector2(0.0f, 3000.0f);
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ namespace Barotrauma.Tutorials
|
||||
tutorial_submarineDoorLight = Item.ItemList.Find(i => i.HasTag("tutorial_submarinedoorlight")).GetComponent<LightComponent>();
|
||||
var medicInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, "", JobPrefab.Get("medicaldoctor"));
|
||||
captain_medic = Character.Create(medicInfo, captain_medicSpawnPos, "medicaldoctor");
|
||||
captain_medic.TeamID = Character.TeamType.Team1;
|
||||
captain_medic.TeamID = CharacterTeamType.Team1;
|
||||
captain_medic.GiveJobItems(null);
|
||||
captain_medic.CanSpeak = captain_medic.AIController.Enabled = false;
|
||||
SetDoorAccess(tutorial_submarineDoor, tutorial_submarineDoorLight, false);
|
||||
@@ -124,17 +124,17 @@ namespace Barotrauma.Tutorials
|
||||
|
||||
var mechanicInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, "", JobPrefab.Get("mechanic"));
|
||||
captain_mechanic = Character.Create(mechanicInfo, WayPoint.GetRandom(SpawnType.Human, mechanicInfo.Job, Submarine.MainSub).WorldPosition, "mechanic");
|
||||
captain_mechanic.TeamID = Character.TeamType.Team1;
|
||||
captain_mechanic.TeamID = CharacterTeamType.Team1;
|
||||
captain_mechanic.GiveJobItems();
|
||||
|
||||
var securityInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, "", JobPrefab.Get("securityofficer"));
|
||||
captain_security = Character.Create(securityInfo, WayPoint.GetRandom(SpawnType.Human, securityInfo.Job, Submarine.MainSub).WorldPosition, "securityofficer");
|
||||
captain_security.TeamID = Character.TeamType.Team1;
|
||||
captain_security.TeamID = CharacterTeamType.Team1;
|
||||
captain_security.GiveJobItems();
|
||||
|
||||
var engineerInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, "", JobPrefab.Get("engineer"));
|
||||
captain_engineer = Character.Create(engineerInfo, WayPoint.GetRandom(SpawnType.Human, engineerInfo.Job, Submarine.MainSub).WorldPosition, "engineer");
|
||||
captain_engineer.TeamID = Character.TeamType.Team1;
|
||||
captain_engineer.TeamID = CharacterTeamType.Team1;
|
||||
captain_engineer.GiveJobItems();
|
||||
|
||||
captain_mechanic.CanSpeak = captain_security.CanSpeak = captain_engineer.CanSpeak = false;
|
||||
|
||||
@@ -80,34 +80,34 @@ namespace Barotrauma.Tutorials
|
||||
|
||||
var assistantInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, "", JobPrefab.Get("assistant"));
|
||||
patient1 = Character.Create(assistantInfo, patientHull1.WorldPosition, "1");
|
||||
patient1.TeamID = Character.TeamType.Team1;
|
||||
patient1.TeamID = CharacterTeamType.Team1;
|
||||
patient1.GiveJobItems(null);
|
||||
patient1.CanSpeak = false;
|
||||
patient1.AddDamage(patient1.WorldPosition, new List<Affliction>() { new Affliction(AfflictionPrefab.Burn, 45.0f) }, stun: 0, playSound: false);
|
||||
patient1.AddDamage(patient1.WorldPosition, new List<Affliction>() { new Affliction(AfflictionPrefab.Burn, 15.0f) }, stun: 0, playSound: false);
|
||||
patient1.AIController.Enabled = false;
|
||||
|
||||
assistantInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, "", JobPrefab.Get("assistant"));
|
||||
patient2 = Character.Create(assistantInfo, patientHull2.WorldPosition, "2");
|
||||
patient2.TeamID = Character.TeamType.Team1;
|
||||
patient2.TeamID = CharacterTeamType.Team1;
|
||||
patient2.GiveJobItems(null);
|
||||
patient2.CanSpeak = false;
|
||||
patient2.AIController.Enabled = false;
|
||||
|
||||
var mechanicInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, "", JobPrefab.Get("engineer"));
|
||||
var subPatient1 = Character.Create(mechanicInfo, WayPoint.GetRandom(SpawnType.Human, mechanicInfo.Job, Submarine.MainSub).WorldPosition, "3");
|
||||
subPatient1.TeamID = Character.TeamType.Team1;
|
||||
subPatient1.TeamID = CharacterTeamType.Team1;
|
||||
subPatient1.AddDamage(patient1.WorldPosition, new List<Affliction>() { new Affliction(AfflictionPrefab.Burn, 40.0f) }, stun: 0, playSound: false);
|
||||
subPatients.Add(subPatient1);
|
||||
|
||||
var securityInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, "", JobPrefab.Get("securityofficer"));
|
||||
var subPatient2 = Character.Create(securityInfo, WayPoint.GetRandom(SpawnType.Human, securityInfo.Job, Submarine.MainSub).WorldPosition, "3");
|
||||
subPatient2.TeamID = Character.TeamType.Team1;
|
||||
subPatient2.TeamID = CharacterTeamType.Team1;
|
||||
subPatient2.AddDamage(patient1.WorldPosition, new List<Affliction>() { new Affliction(AfflictionPrefab.InternalDamage, 40.0f) }, stun: 0, playSound: false);
|
||||
subPatients.Add(subPatient2);
|
||||
|
||||
var engineerInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, "", JobPrefab.Get("engineer"));
|
||||
var subPatient3 = Character.Create(securityInfo, WayPoint.GetRandom(SpawnType.Human, engineerInfo.Job, Submarine.MainSub).WorldPosition, "3");
|
||||
subPatient3.TeamID = Character.TeamType.Team1;
|
||||
subPatient3.TeamID = CharacterTeamType.Team1;
|
||||
subPatient3.AddDamage(patient1.WorldPosition, new List<Affliction>() { new Affliction(AfflictionPrefab.Burn, 20.0f) }, stun: 0, playSound: false);
|
||||
subPatients.Add(subPatient3);
|
||||
|
||||
@@ -200,18 +200,18 @@ namespace Barotrauma.Tutorials
|
||||
|
||||
do
|
||||
{
|
||||
for (int i = 0; i < doctor_suppliesCabinet.Inventory.Items.Length; i++)
|
||||
for (int i = 0; i < doctor_suppliesCabinet.Inventory.Capacity; i++)
|
||||
{
|
||||
if (doctor_suppliesCabinet.Inventory.Items[i] != null)
|
||||
if (doctor_suppliesCabinet.Inventory.GetItemAt(i) != null)
|
||||
{
|
||||
HighlightInventorySlot(doctor_suppliesCabinet.Inventory, i, highlightColor, .5f, .5f, 0f);
|
||||
}
|
||||
}
|
||||
if (doctor.SelectedConstruction == doctor_suppliesCabinet.Item)
|
||||
{
|
||||
for (int i = 0; i < doctor.Inventory.slots.Length; i++)
|
||||
for (int i = 0; i < doctor.Inventory.Capacity; i++)
|
||||
{
|
||||
if (doctor.Inventory.Items[i] == null) HighlightInventorySlot(doctor.Inventory, i, highlightColor, .5f, .5f, 0f);
|
||||
if (doctor.Inventory.GetItemAt(i) == null) { HighlightInventorySlot(doctor.Inventory, i, highlightColor, .5f, .5f, 0f); }
|
||||
}
|
||||
}
|
||||
yield return null;
|
||||
@@ -309,16 +309,16 @@ namespace Barotrauma.Tutorials
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (doctor_medBayCabinet.Inventory.Items[i] != null)
|
||||
if (doctor_medBayCabinet.Inventory.GetItemAt(i) != null)
|
||||
{
|
||||
HighlightInventorySlot(doctor_medBayCabinet.Inventory, i, highlightColor, .5f, .5f, 0f);
|
||||
}
|
||||
}
|
||||
if (doctor.SelectedConstruction == doctor_medBayCabinet.Item)
|
||||
{
|
||||
for (int i = 0; i < doctor.Inventory.slots.Length; i++)
|
||||
for (int i = 0; i < doctor.Inventory.Capacity; i++)
|
||||
{
|
||||
if (doctor.Inventory.Items[i] == null) HighlightInventorySlot(doctor.Inventory, i, highlightColor, .5f, .5f, 0f);
|
||||
if (doctor.Inventory.GetItemAt(i) == null) { HighlightInventorySlot(doctor.Inventory, i, highlightColor, .5f, .5f, 0f); }
|
||||
}
|
||||
}
|
||||
yield return null;
|
||||
|
||||
@@ -247,30 +247,30 @@ namespace Barotrauma.Tutorials
|
||||
if (!firstSlotRemoved)
|
||||
{
|
||||
HighlightInventorySlot(engineer_equipmentCabinet.Inventory, 0, highlightColor, .5f, .5f, 0f);
|
||||
if (engineer_equipmentCabinet.Inventory.Items[0] == null) firstSlotRemoved = true;
|
||||
if (engineer_equipmentCabinet.Inventory.GetItemAt(0) == null) { firstSlotRemoved = true; }
|
||||
}
|
||||
|
||||
if (!secondSlotRemoved)
|
||||
{
|
||||
HighlightInventorySlot(engineer_equipmentCabinet.Inventory, 1, highlightColor, .5f, .5f, 0f);
|
||||
if (engineer_equipmentCabinet.Inventory.Items[1] == null) secondSlotRemoved = true;
|
||||
if (engineer_equipmentCabinet.Inventory.GetItemAt(1) == null) { secondSlotRemoved = true; }
|
||||
}
|
||||
|
||||
if (!thirdSlotRemoved)
|
||||
{
|
||||
HighlightInventorySlot(engineer_equipmentCabinet.Inventory, 2, highlightColor, .5f, .5f, 0f);
|
||||
if (engineer_equipmentCabinet.Inventory.Items[2] == null) thirdSlotRemoved = true;
|
||||
if (engineer_equipmentCabinet.Inventory.GetItemAt(2) == null) { thirdSlotRemoved = true; }
|
||||
}
|
||||
|
||||
if (!fourthSlotRemoved)
|
||||
{
|
||||
HighlightInventorySlot(engineer_equipmentCabinet.Inventory, 3, highlightColor, .5f, .5f, 0f);
|
||||
if (engineer_equipmentCabinet.Inventory.Items[2] == null) fourthSlotRemoved = true;
|
||||
if (engineer_equipmentCabinet.Inventory.GetItemAt(2) == null) { fourthSlotRemoved = true; }
|
||||
}
|
||||
|
||||
for (int i = 0; i < engineer.Inventory.slots.Length; i++)
|
||||
for (int i = 0; i < engineer.Inventory.visualSlots.Length; i++)
|
||||
{
|
||||
if (engineer.Inventory.Items[i] == null) HighlightInventorySlot(engineer.Inventory, i, highlightColor, .5f, .5f, 0f);
|
||||
if (engineer.Inventory.GetItemAt(i) == null) { HighlightInventorySlot(engineer.Inventory, i, highlightColor, .5f, .5f, 0f); }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -299,12 +299,12 @@ namespace Barotrauma.Tutorials
|
||||
} while (!engineer_reactor.PowerOn);
|
||||
do
|
||||
{
|
||||
if (IsSelectedItem(engineer_reactor.Item) && engineer_reactor.Item.OwnInventory.slots != null)
|
||||
if (IsSelectedItem(engineer_reactor.Item) && engineer_reactor.Item.OwnInventory.visualSlots != null)
|
||||
{
|
||||
engineer_reactor.AutoTemp = false;
|
||||
HighlightInventorySlot(engineer.Inventory, "fuelrod", highlightColor, 0.5f, 0.5f, 0f);
|
||||
|
||||
for (int i = 0; i < engineer_reactor.Item.OwnInventory.slots.Length; i++)
|
||||
for (int i = 0; i < engineer_reactor.Item.OwnInventory.visualSlots.Length; i++)
|
||||
{
|
||||
HighlightInventorySlot(engineer_reactor.Item.OwnInventory, i, highlightColor, 0.5f, 0.5f, 0f);
|
||||
}
|
||||
|
||||
@@ -165,21 +165,23 @@ namespace Barotrauma.Tutorials
|
||||
// Room 6
|
||||
mechanic_divingSuitObjectiveSensor = Item.ItemList.Find(i => i.HasTag("mechanic_divingsuitobjectivesensor")).GetComponent<MotionSensor>();
|
||||
mechanic_divingSuitContainer = Item.ItemList.Find(i => i.HasTag("mechanic_divingsuitcontainer")).GetComponent<ItemContainer>();
|
||||
for (int i = 0; i < mechanic_divingSuitContainer.Inventory.Items.Length; i++)
|
||||
foreach (Item item in mechanic_divingSuitContainer.Inventory.AllItems)
|
||||
{
|
||||
foreach (ItemComponent ic in mechanic_divingSuitContainer.Inventory.Items[i].Components)
|
||||
foreach (ItemComponent ic in item.Components)
|
||||
{
|
||||
ic.CanBePicked = true;
|
||||
}
|
||||
}
|
||||
|
||||
mechanic_oxygenContainer = Item.ItemList.Find(i => i.HasTag("mechanic_oxygencontainer")).GetComponent<ItemContainer>();
|
||||
for (int i = 0; i < mechanic_oxygenContainer.Inventory.Items.Length; i++)
|
||||
foreach (Item item in mechanic_oxygenContainer.Inventory.AllItems)
|
||||
{
|
||||
foreach (ItemComponent ic in mechanic_oxygenContainer.Inventory.Items[i].Components)
|
||||
foreach (ItemComponent ic in item.Components)
|
||||
{
|
||||
ic.CanBePicked = true;
|
||||
}
|
||||
}
|
||||
|
||||
tutorial_mechanicFinalDoor = Item.ItemList.Find(i => i.HasTag("tutorial_mechanicfinaldoor")).GetComponent<Door>();
|
||||
tutorial_mechanicFinalDoorLight = Item.ItemList.Find(i => i.HasTag("tutorial_mechanicfinaldoorlight")).GetComponent<LightComponent>();
|
||||
|
||||
@@ -266,24 +268,24 @@ namespace Barotrauma.Tutorials
|
||||
if (!firstSlotRemoved)
|
||||
{
|
||||
HighlightInventorySlot(mechanic_equipmentCabinet.Inventory, 0, highlightColor, .5f, .5f, 0f);
|
||||
if (mechanic_equipmentCabinet.Inventory.Items[0] == null) firstSlotRemoved = true;
|
||||
if (mechanic_equipmentCabinet.Inventory.GetItemAt(0) == null) { firstSlotRemoved = true; }
|
||||
}
|
||||
|
||||
if (!secondSlotRemoved)
|
||||
{
|
||||
HighlightInventorySlot(mechanic_equipmentCabinet.Inventory, 1, highlightColor, .5f, .5f, 0f);
|
||||
if (mechanic_equipmentCabinet.Inventory.Items[1] == null) secondSlotRemoved = true;
|
||||
if (mechanic_equipmentCabinet.Inventory.GetItemAt(1) == null) { secondSlotRemoved = true; }
|
||||
}
|
||||
|
||||
if (!thirdSlotRemoved)
|
||||
{
|
||||
HighlightInventorySlot(mechanic_equipmentCabinet.Inventory, 2, highlightColor, .5f, .5f, 0f);
|
||||
if (mechanic_equipmentCabinet.Inventory.Items[2] == null) thirdSlotRemoved = true;
|
||||
if (mechanic_equipmentCabinet.Inventory.GetItemAt(2) == null) { thirdSlotRemoved = true; }
|
||||
}
|
||||
|
||||
for (int i = 0; i < mechanic.Inventory.slots.Length; i++)
|
||||
for (int i = 0; i < mechanic.Inventory.Capacity; i++)
|
||||
{
|
||||
if (mechanic.Inventory.Items[i] == null) HighlightInventorySlot(mechanic.Inventory, i, highlightColor, .5f, .5f, 0f);
|
||||
if (mechanic.Inventory.GetItemAt(i) == null) { HighlightInventorySlot(mechanic.Inventory, i, highlightColor, .5f, .5f, 0f); }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -355,16 +357,16 @@ namespace Barotrauma.Tutorials
|
||||
{
|
||||
if (mechanic.SelectedConstruction == mechanic_craftingCabinet.Item)
|
||||
{
|
||||
for (int i = 0; i < mechanic.Inventory.slots.Length; i++)
|
||||
for (int i = 0; i < mechanic.Inventory.Capacity; i++)
|
||||
{
|
||||
if (mechanic.Inventory.Items[i] == null) HighlightInventorySlot(mechanic.Inventory, i, highlightColor, .5f, .5f, 0f);
|
||||
if (mechanic.Inventory.GetItemAt(i) == null) { HighlightInventorySlot(mechanic.Inventory, i, highlightColor, .5f, .5f, 0f); }
|
||||
}
|
||||
|
||||
if (mechanic.Inventory.FindItemByIdentifier("oxygentank") == null && mechanic.Inventory.FindItemByIdentifier("aluminium") == null)
|
||||
{
|
||||
for (int i = 0; i < mechanic_craftingCabinet.Inventory.Items.Length; i++)
|
||||
for (int i = 0; i < mechanic_craftingCabinet.Capacity; i++)
|
||||
{
|
||||
Item item = mechanic_craftingCabinet.Inventory.Items[i];
|
||||
Item item = mechanic_craftingCabinet.Inventory.GetItemAt(i);
|
||||
if (item != null && item.prefab.Identifier == "oxygentank")
|
||||
{
|
||||
HighlightInventorySlot(mechanic_craftingCabinet.Inventory, i, highlightColor, .5f, .5f, 0f);
|
||||
@@ -374,9 +376,9 @@ namespace Barotrauma.Tutorials
|
||||
|
||||
if (mechanic.Inventory.FindItemByIdentifier("sodium") == null)
|
||||
{
|
||||
for (int i = 0; i < mechanic_craftingCabinet.Inventory.Items.Length; i++)
|
||||
for (int i = 0; i < mechanic_craftingCabinet.Inventory.Capacity; i++)
|
||||
{
|
||||
Item item = mechanic_craftingCabinet.Inventory.Items[i];
|
||||
Item item = mechanic_craftingCabinet.Inventory.GetItemAt(i);
|
||||
if (item != null && item.prefab.Identifier == "sodium")
|
||||
{
|
||||
HighlightInventorySlot(mechanic_craftingCabinet.Inventory, i, highlightColor, .5f, .5f, 0f);
|
||||
@@ -408,9 +410,9 @@ namespace Barotrauma.Tutorials
|
||||
{
|
||||
HighlightInventorySlot(mechanic_deconstructor.OutputContainer.Inventory, "aluminium", highlightColor, .5f, .5f, 0f);
|
||||
|
||||
for (int i = 0; i < mechanic.Inventory.slots.Length; i++)
|
||||
for (int i = 0; i < mechanic.Inventory.Capacity; i++)
|
||||
{
|
||||
if (mechanic.Inventory.Items[i] == null) HighlightInventorySlot(mechanic.Inventory, i, highlightColor, .5f, .5f, 0f);
|
||||
if (mechanic.Inventory.GetItemAt(i) == null) { HighlightInventorySlot(mechanic.Inventory, i, highlightColor, .5f, .5f, 0f); }
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -418,15 +420,11 @@ namespace Barotrauma.Tutorials
|
||||
if (mechanic.Inventory.FindItemByIdentifier("oxygentank") != null && mechanic_deconstructor.InputContainer.Inventory.FindItemByIdentifier("oxygentank") == null)
|
||||
{
|
||||
HighlightInventorySlot(mechanic.Inventory, "oxygentank", highlightColor, .5f, .5f, 0f);
|
||||
|
||||
if (mechanic_deconstructor.InputContainer.Inventory.slots != null)
|
||||
{
|
||||
for (int i = 0; i < mechanic_deconstructor.InputContainer.Inventory.slots.Length; i++)
|
||||
for (int i = 0; i < mechanic_deconstructor.InputContainer.Inventory.Capacity; i++)
|
||||
{
|
||||
HighlightInventorySlot(mechanic_deconstructor.InputContainer.Inventory, i, highlightColor, .5f, .5f, 0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mechanic_deconstructor.InputContainer.Inventory.FindItemByIdentifier("oxygentank") != null && !mechanic_deconstructor.IsActive)
|
||||
{
|
||||
@@ -461,7 +459,7 @@ namespace Barotrauma.Tutorials
|
||||
{
|
||||
HighlightInventorySlot(mechanic_fabricator.OutputContainer.Inventory, "extinguisher", highlightColor, .5f, .5f, 0f);
|
||||
|
||||
/*for (int i = 0; i < mechanic.Inventory.slots.Length; i++)
|
||||
/*for (int i = 0; i < mechanic.Inventory.Capacity; i++)
|
||||
{
|
||||
if (mechanic.Inventory.Items[i] == null) HighlightInventorySlot(mechanic.Inventory, i, highlightColor, .5f, .5f, 0f);
|
||||
}*/
|
||||
@@ -478,12 +476,12 @@ namespace Barotrauma.Tutorials
|
||||
HighlightInventorySlot(mechanic.Inventory, "aluminium", highlightColor, .5f, .5f, 0f);
|
||||
HighlightInventorySlot(mechanic.Inventory, "sodium", highlightColor, .5f, .5f, 0f);
|
||||
|
||||
if (mechanic_fabricator.InputContainer.Inventory.Items[0] == null)
|
||||
if (mechanic_fabricator.InputContainer.Inventory.GetItemAt(0) == null)
|
||||
{
|
||||
HighlightInventorySlot(mechanic_fabricator.InputContainer.Inventory, 0, highlightColor, .5f, .5f, 0f);
|
||||
}
|
||||
|
||||
if (mechanic_fabricator.InputContainer.Inventory.Items[1] == null)
|
||||
if (mechanic_fabricator.InputContainer.Inventory.GetItemAt(1) == null)
|
||||
{
|
||||
HighlightInventorySlot(mechanic_fabricator.InputContainer.Inventory, 1, highlightColor, .5f, .5f, 0f);
|
||||
}
|
||||
@@ -524,9 +522,9 @@ namespace Barotrauma.Tutorials
|
||||
{
|
||||
if (IsSelectedItem(mechanic_divingSuitContainer.Item))
|
||||
{
|
||||
if (mechanic_divingSuitContainer.Inventory.slots != null)
|
||||
if (mechanic_divingSuitContainer.Inventory.visualSlots != null)
|
||||
{
|
||||
for (int i = 0; i < mechanic_divingSuitContainer.Inventory.slots.Length; i++)
|
||||
for (int i = 0; i < mechanic_divingSuitContainer.Inventory.Capacity; i++)
|
||||
{
|
||||
HighlightInventorySlot(mechanic_divingSuitContainer.Inventory, i, highlightColor, 0.5f, 0.5f, 0f);
|
||||
}
|
||||
|
||||
@@ -234,24 +234,24 @@ namespace Barotrauma.Tutorials
|
||||
if (!firstSlotRemoved)
|
||||
{
|
||||
HighlightInventorySlot(officer_equipmentCabinet.Inventory, 0, highlightColor, .5f, .5f, 0f);
|
||||
if (officer_equipmentCabinet.Inventory.Items[0] == null) firstSlotRemoved = true;
|
||||
if (officer_equipmentCabinet.Inventory.GetItemAt(0) == null) { firstSlotRemoved = true; }
|
||||
}
|
||||
|
||||
if (!secondSlotRemoved)
|
||||
{
|
||||
HighlightInventorySlot(officer_equipmentCabinet.Inventory, 1, highlightColor, .5f, .5f, 0f);
|
||||
if (officer_equipmentCabinet.Inventory.Items[1] == null) secondSlotRemoved = true;
|
||||
if (officer_equipmentCabinet.Inventory.GetItemAt(1) == null) { secondSlotRemoved = true; }
|
||||
}
|
||||
|
||||
if (!thirdSlotRemoved)
|
||||
{
|
||||
HighlightInventorySlot(officer_equipmentCabinet.Inventory, 2, highlightColor, .5f, .5f, 0f);
|
||||
if (officer_equipmentCabinet.Inventory.Items[2] == null) thirdSlotRemoved = true;
|
||||
if (officer_equipmentCabinet.Inventory.GetItemAt(2) == null) { thirdSlotRemoved = true; }
|
||||
}
|
||||
|
||||
for (int i = 0; i < officer.Inventory.slots.Length; i++)
|
||||
for (int i = 0; i < officer.Inventory.visualSlots.Length; i++)
|
||||
{
|
||||
if (officer.Inventory.Items[i] == null) HighlightInventorySlot(officer.Inventory, i, highlightColor, .5f, .5f, 0f);
|
||||
if (officer.Inventory.GetItemAt(i) == null) { HighlightInventorySlot(officer.Inventory, i, highlightColor, .5f, .5f, 0f); }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,7 +298,7 @@ namespace Barotrauma.Tutorials
|
||||
TriggerTutorialSegment(3); // Arm coilgun
|
||||
do
|
||||
{
|
||||
SetHighlight(officer_coilgunLoader.Item, officer_coilgunLoader.Inventory.Items[0] == null || officer_coilgunLoader.Inventory.Items[0].Condition == 0);
|
||||
SetHighlight(officer_coilgunLoader.Item, officer_coilgunLoader.Inventory.GetItemAt(0) == null || officer_coilgunLoader.Inventory.GetItemAt(0).Condition == 0);
|
||||
HighlightInventorySlot(officer_coilgunLoader.Inventory, 0, highlightColor, .5f, .5f, 0f);
|
||||
SetHighlight(officer_superCapacitor.Item, officer_superCapacitor.RechargeSpeed < superCapacitorRechargeRate);
|
||||
SetHighlight(officer_ammoShelf_1.Item, officer_coilgunLoader.Item.ExternalHighlight );
|
||||
@@ -308,7 +308,7 @@ namespace Barotrauma.Tutorials
|
||||
HighlightInventorySlot(officer.Inventory, "coilgunammobox", highlightColor, .5f, .5f, 0f);
|
||||
}
|
||||
yield return null;
|
||||
} while (officer_coilgunLoader.Inventory.Items[0] == null || officer_superCapacitor.RechargeSpeed < superCapacitorRechargeRate || officer_coilgunLoader.Inventory.Items[0].Condition == 0);
|
||||
} while (officer_coilgunLoader.Inventory.GetItemAt(0) == null || officer_superCapacitor.RechargeSpeed < superCapacitorRechargeRate || officer_coilgunLoader.Inventory.GetItemAt(0).Condition == 0);
|
||||
SetHighlight(officer_coilgunLoader.Item, false);
|
||||
SetHighlight(officer_superCapacitor.Item, false);
|
||||
SetHighlight(officer_ammoShelf_1.Item, false);
|
||||
@@ -371,12 +371,11 @@ namespace Barotrauma.Tutorials
|
||||
{
|
||||
if (IsSelectedItem(officer_rangedWeaponCabinet.Item))
|
||||
{
|
||||
if (officer_rangedWeaponCabinet.Inventory.slots != null)
|
||||
if (officer_rangedWeaponCabinet.Inventory.visualSlots != null)
|
||||
{
|
||||
for (int i = 0; i < officer_rangedWeaponCabinet.Inventory.Items.Length; i++)
|
||||
for (int i = 0; i < officer_rangedWeaponCabinet.Inventory.Capacity; i++)
|
||||
{
|
||||
if (officer_rangedWeaponCabinet.Inventory.Items[i] == null) continue;
|
||||
if (officer_rangedWeaponCabinet.Inventory.Items[i].Prefab.Identifier == "shotgunshell")
|
||||
if (officer_rangedWeaponCabinet.Inventory.GetItemAt(i)?.Prefab.Identifier == "shotgunshell")
|
||||
{
|
||||
HighlightInventorySlot(officer_rangedWeaponCabinet.Inventory, i, highlightColor, 0.5f, 0.5f, 0f);
|
||||
}
|
||||
@@ -384,10 +383,9 @@ namespace Barotrauma.Tutorials
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < officer.Inventory.Items.Length; i++)
|
||||
for (int i = 0; i < officer.Inventory.Capacity; i++)
|
||||
{
|
||||
if (officer.Inventory.Items[i] == null) continue;
|
||||
if (officer.Inventory.Items[i].Prefab.Identifier == "shotgunshell")
|
||||
if (officer.Inventory.GetItemAt(i)?.Prefab.Identifier == "shotgunshell")
|
||||
{
|
||||
HighlightInventorySlot(officer.Inventory, i, highlightColor, 0.5f, 0.5f, 0f);
|
||||
}
|
||||
@@ -398,7 +396,7 @@ namespace Barotrauma.Tutorials
|
||||
HighlightInventorySlot(officer.Inventory, "shotgun", highlightColor, 0.5f, 0.5f, 0f);
|
||||
}
|
||||
yield return null;
|
||||
} while (!shotGunChamber.Inventory.IsFull()); // Wait until all six harpoons loaded
|
||||
} while (!shotGunChamber.Inventory.IsFull(takeStacksIntoAccount: true)); // Wait until all six harpoons loaded
|
||||
RemoveCompletedObjective(segments[5]);
|
||||
SetHighlight(officer_rangedWeaponCabinet.Item, false);
|
||||
SetDoorAccess(officer_fourthDoor, officer_fourthDoorLight, true);
|
||||
@@ -425,8 +423,8 @@ namespace Barotrauma.Tutorials
|
||||
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Officer.Radio.Submarine"), ChatMessageType.Radio, null);
|
||||
do
|
||||
{
|
||||
SetHighlight(officer_subLoader_1.Item, officer_subLoader_1.Inventory.Items[0] == null || officer_subLoader_1.Inventory.Items[0].Condition == 0);
|
||||
SetHighlight(officer_subLoader_2.Item, officer_subLoader_2.Inventory.Items[0] == null || officer_subLoader_2.Inventory.Items[0].Condition == 0);
|
||||
SetHighlight(officer_subLoader_1.Item, officer_subLoader_1.Inventory.GetItemAt(0) == null || officer_subLoader_1.Inventory.GetItemAt(0).Condition == 0);
|
||||
SetHighlight(officer_subLoader_2.Item, officer_subLoader_2.Inventory.GetItemAt(0) == null || officer_subLoader_2.Inventory.GetItemAt(0).Condition == 0);
|
||||
HighlightInventorySlot(officer_subLoader_1.Inventory, 0, highlightColor, .5f, .5f, 0f);
|
||||
HighlightInventorySlot(officer_subLoader_2.Inventory, 0, highlightColor, .5f, .5f, 0f);
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ namespace Barotrauma.Tutorials
|
||||
}
|
||||
|
||||
character = Character.Create(charInfo, wayPoint.WorldPosition, "", isRemotePlayer: false, hasAi: false);
|
||||
character.TeamID = Character.TeamType.Team1;
|
||||
character.TeamID = CharacterTeamType.Team1;
|
||||
Character.Controlled = character;
|
||||
character.GiveJobItems(null);
|
||||
|
||||
|
||||
@@ -264,7 +264,7 @@ namespace Barotrauma.Tutorials
|
||||
|
||||
protected virtual void TriggerTutorialSegment(int index, params object[] args)
|
||||
{
|
||||
Inventory.draggingItem = null;
|
||||
Inventory.DraggingItems.Clear();
|
||||
ContentRunning = true;
|
||||
activeContentSegment = segments[index];
|
||||
segments[index].Args = args;
|
||||
@@ -410,7 +410,7 @@ namespace Barotrauma.Tutorials
|
||||
private void ReplaySegmentVideo(TutorialSegment segment)
|
||||
{
|
||||
if (ContentRunning) return;
|
||||
Inventory.draggingItem = null;
|
||||
Inventory.DraggingItems.Clear();
|
||||
ContentRunning = true;
|
||||
LoadVideo(segment);
|
||||
//videoPlayer.LoadContent(playableContentPath, new VideoPlayer.VideoSettings(segment.VideoContent), new VideoPlayer.TextSettings(segment.VideoContent), segment.Id, true, callback: () => ContentRunning = false);
|
||||
@@ -419,7 +419,7 @@ namespace Barotrauma.Tutorials
|
||||
private void ShowSegmentText(TutorialSegment segment)
|
||||
{
|
||||
if (ContentRunning) return;
|
||||
Inventory.draggingItem = null;
|
||||
Inventory.DraggingItems.Clear();
|
||||
ContentRunning = true;
|
||||
|
||||
string tutorialText = TextManager.GetFormatted(segment.TextContent.GetAttributeString("tag", ""), true, segment.Args);
|
||||
@@ -609,10 +609,10 @@ namespace Barotrauma.Tutorials
|
||||
#region Highlights
|
||||
protected void HighlightInventorySlot(Inventory inventory, string identifier, Color color, float fadeInDuration, float fadeOutDuration, float scaleUpAmount)
|
||||
{
|
||||
if (inventory.slots == null) { return; }
|
||||
for (int i = 0; i < inventory.Items.Length; i++)
|
||||
if (inventory.visualSlots == null) { return; }
|
||||
for (int i = 0; i < inventory.Capacity; i++)
|
||||
{
|
||||
if (inventory.Items[i] != null && inventory.Items[i].Prefab.Identifier == identifier)
|
||||
if (inventory.GetItemAt(i)?.Prefab.Identifier == identifier)
|
||||
{
|
||||
HighlightInventorySlot(inventory, i, color, fadeInDuration, fadeOutDuration, scaleUpAmount);
|
||||
}
|
||||
@@ -621,10 +621,10 @@ namespace Barotrauma.Tutorials
|
||||
|
||||
protected void HighlightInventorySlotWithTag(Inventory inventory, string tag, Color color, float fadeInDuration, float fadeOutDuration, float scaleUpAmount)
|
||||
{
|
||||
if (inventory.slots == null) { return; }
|
||||
for (int i = 0; i < inventory.Items.Length; i++)
|
||||
if (inventory.visualSlots == null) { return; }
|
||||
for (int i = 0; i < inventory.Capacity; i++)
|
||||
{
|
||||
if (inventory.Items[i] != null && inventory.Items[i].HasTag(tag))
|
||||
if (inventory.GetItemAt(i)?.HasTag(tag) ?? false)
|
||||
{
|
||||
HighlightInventorySlot(inventory, i, color, fadeInDuration, fadeOutDuration, scaleUpAmount);
|
||||
}
|
||||
@@ -633,8 +633,8 @@ namespace Barotrauma.Tutorials
|
||||
|
||||
protected void HighlightInventorySlot(Inventory inventory, int index, Color color, float fadeInDuration, float fadeOutDuration, float scaleUpAmount)
|
||||
{
|
||||
if (inventory.slots == null || index < 0 || inventory.slots[index].HighlightTimer > 0) return;
|
||||
inventory.slots[index].ShowBorderHighlight(color, fadeInDuration, fadeOutDuration, scaleUpAmount);
|
||||
if (inventory.visualSlots == null || index < 0 || inventory.visualSlots[index].HighlightTimer > 0) { return; }
|
||||
inventory.visualSlots[index].ShowBorderHighlight(color, fadeInDuration, fadeOutDuration, scaleUpAmount);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -33,6 +33,8 @@ namespace Barotrauma
|
||||
|
||||
public static DateTime lastReadyCheck = DateTime.MinValue;
|
||||
|
||||
public static bool IsReadyCheck(GUIComponent? msgBox) => msgBox?.UserData as string == PromptData || msgBox?.UserData as string == ResultData;
|
||||
|
||||
private void CreateMessageBox(string author)
|
||||
{
|
||||
Vector2 relativeSize = new Vector2(GUI.IsFourByThree() ? 0.3f : 0.2f, 0.15f);
|
||||
@@ -119,8 +121,11 @@ namespace Barotrauma
|
||||
// play click sound after a second has passed
|
||||
int second = (int) Math.Ceiling(time);
|
||||
if (second < lastSecond)
|
||||
{
|
||||
if (msgBox != null && !msgBox.Closed)
|
||||
{
|
||||
SoundPlayer.PlayUISound(GUISoundType.PopupMenu);
|
||||
}
|
||||
lastSecond = second;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,12 +87,12 @@ namespace Barotrauma
|
||||
TextManager.Get("crew"), textAlignment: Alignment.TopLeft, font: GUI.SubHeadingFont);
|
||||
crewHeader.RectTransform.MinSize = new Point(0, GUI.IntScale(crewHeader.Rect.Height * 2.0f));
|
||||
|
||||
CreateCrewList(crewContent, gameSession.CrewManager.GetCharacterInfos().Where(c => c.TeamID != Character.TeamType.Team2));
|
||||
CreateCrewList(crewContent, gameSession.CrewManager.GetCharacterInfos().Where(c => c.TeamID != CharacterTeamType.Team2));
|
||||
|
||||
//another crew frame for the 2nd team in combat missions
|
||||
if (gameSession.Mission is CombatMission)
|
||||
{
|
||||
crewHeader.Text = CombatMission.GetTeamName(Character.TeamType.Team1);
|
||||
crewHeader.Text = CombatMission.GetTeamName(CharacterTeamType.Team1);
|
||||
GUIFrame crewFrame2 = new GUIFrame(new RectTransform(new Vector2(0.35f, 0.55f), background.RectTransform, Anchor.TopCenter, minSize: new Point(minWidth, minHeight)));
|
||||
rightPanels.Add(crewFrame2);
|
||||
GUIFrame crewFrameInner2 = new GUIFrame(new RectTransform(new Point(crewFrame2.Rect.Width - padding * 2, crewFrame2.Rect.Height - padding * 2), crewFrame2.RectTransform, Anchor.Center), style: "InnerFrame");
|
||||
@@ -101,9 +101,9 @@ namespace Barotrauma
|
||||
Stretch = true
|
||||
};
|
||||
var crewHeader2 = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), crewContent2.RectTransform),
|
||||
CombatMission.GetTeamName(Character.TeamType.Team2), textAlignment: Alignment.TopLeft, font: GUI.SubHeadingFont);
|
||||
CombatMission.GetTeamName(CharacterTeamType.Team2), textAlignment: Alignment.TopLeft, font: GUI.SubHeadingFont);
|
||||
crewHeader2.RectTransform.MinSize = new Point(0, GUI.IntScale(crewHeader2.Rect.Height * 2.0f));
|
||||
CreateCrewList(crewContent2, gameSession.CrewManager.GetCharacterInfos().Where(c => c.TeamID == Character.TeamType.Team2));
|
||||
CreateCrewList(crewContent2, gameSession.CrewManager.GetCharacterInfos().Where(c => c.TeamID == CharacterTeamType.Team2));
|
||||
}
|
||||
|
||||
//header -------------------------------------------------------------------------------
|
||||
|
||||
@@ -68,6 +68,9 @@ namespace Barotrauma
|
||||
keyMapping[(int)InputType.PreviousFireMode] = new KeyOrMouse(MouseButton.MouseWheelDown);
|
||||
keyMapping[(int)InputType.NextFireMode] = new KeyOrMouse(MouseButton.MouseWheelUp);
|
||||
|
||||
keyMapping[(int)InputType.TakeHalfFromInventorySlot] = new KeyOrMouse(Keys.LeftShift);
|
||||
keyMapping[(int)InputType.TakeOneFromInventorySlot] = new KeyOrMouse(Keys.LeftControl);
|
||||
|
||||
if (Language == "French")
|
||||
{
|
||||
keyMapping[(int)InputType.Up] = new KeyOrMouse(Keys.Z);
|
||||
@@ -173,6 +176,13 @@ namespace Barotrauma
|
||||
{
|
||||
foreach (XAttribute attribute in element.Attributes())
|
||||
{
|
||||
//backwards compatibility
|
||||
if (attribute.Name.ToString() == "TakeAllFromInventorySlot")
|
||||
{
|
||||
keyMapping[(int)InputType.TakeHalfFromInventorySlot] = new KeyOrMouse(Keys.LeftShift);
|
||||
keyMapping[(int)InputType.TakeOneFromInventorySlot] = new KeyOrMouse(Keys.LeftControl);
|
||||
}
|
||||
|
||||
if (!Enum.TryParse(attribute.Name.ToString(), true, out InputType inputType)) { continue; }
|
||||
|
||||
if (int.TryParse(attribute.Value.ToString(), out int mouseButtonInt))
|
||||
@@ -223,6 +233,40 @@ namespace Barotrauma
|
||||
{
|
||||
LoadInventoryKeybinds(inventoryKeyMapping);
|
||||
}
|
||||
|
||||
XElement debugConsoleMapping = doc.Root.Element("debugconsolemapping");
|
||||
|
||||
if (debugConsoleMapping == null) { return; }
|
||||
|
||||
ConsoleKeybinds.Clear();
|
||||
DebugConsole.Keybinds.Clear();
|
||||
|
||||
foreach (XElement element in debugConsoleMapping.Elements())
|
||||
{
|
||||
string keyString = element.GetAttributeString("key", string.Empty);
|
||||
string command = element.GetAttributeString("command", string.Empty);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(keyString) || string.IsNullOrWhiteSpace(command)) { continue; }
|
||||
|
||||
if (Enum.TryParse(typeof(Keys), keyString, ignoreCase: true, out object @out) && @out is Keys key)
|
||||
{
|
||||
ConsoleKeybinds.TryAdd(key, command);
|
||||
}
|
||||
}
|
||||
|
||||
DebugConsole.Keybinds = new Dictionary<Keys, string>(ConsoleKeybinds);
|
||||
}
|
||||
|
||||
private void LoadSubEditorImages(XDocument doc)
|
||||
{
|
||||
XElement element = doc.Root?.Element("editorimages");
|
||||
if (element == null)
|
||||
{
|
||||
SubEditorScreen.ImageManager.Clear(alsoPending: true);
|
||||
return;
|
||||
}
|
||||
|
||||
SubEditorScreen.ImageManager.Load(element);
|
||||
}
|
||||
|
||||
public KeyOrMouse KeyBind(InputType inputType)
|
||||
@@ -242,7 +286,7 @@ namespace Barotrauma
|
||||
|
||||
private GUIListBox contentPackageList;
|
||||
|
||||
private bool ChangeSliderText(GUIScrollBar scrollBar, float barScroll)
|
||||
private bool ChangeSliderText(GUIScrollBar scrollBar, float scale)
|
||||
{
|
||||
UnsavedSettings = true;
|
||||
GUITextBlock text = scrollBar.UserData as GUITextBlock;
|
||||
@@ -261,7 +305,7 @@ namespace Barotrauma
|
||||
}
|
||||
label = text.Text.Substring(0, index);
|
||||
}
|
||||
text.Text = label + " " + (int)(barScroll * 100) + "%";
|
||||
text.Text = label + " " + (int)Math.Round(scale * 100) + "%";
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -705,6 +749,18 @@ namespace Barotrauma
|
||||
}
|
||||
};*/
|
||||
|
||||
new GUITickBox(new RectTransform(tickBoxScale, rightColumn.RectTransform), TextManager.Get("RadialDistortion"))
|
||||
{
|
||||
ToolTip = TextManager.Get("RadialDistortionToolTip"),
|
||||
Selected = EnableRadialDistortion,
|
||||
OnSelected = (tickBox) =>
|
||||
{
|
||||
EnableRadialDistortion = tickBox.Selected;
|
||||
UnsavedSettings = true;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
new GUITickBox(new RectTransform(tickBoxScale, rightColumn.RectTransform), TextManager.Get("ChromaticAberration"))
|
||||
{
|
||||
ToolTip = TextManager.Get("ChromaticAberrationToolTip"),
|
||||
@@ -725,13 +781,12 @@ namespace Barotrauma
|
||||
BarScroll = (HUDScale - MinHUDScale) / (MaxHUDScale - MinHUDScale),
|
||||
OnMoved = (scrollBar, scroll) =>
|
||||
{
|
||||
ChangeSliderText(scrollBar, scroll);
|
||||
HUDScale = MathHelper.Lerp(MinHUDScale, MaxHUDScale, scroll);
|
||||
UnsavedSettings = true;
|
||||
ChangeSliderText(scrollBar, HUDScale);
|
||||
OnHUDScaleChanged?.Invoke();
|
||||
return true;
|
||||
},
|
||||
Step = 0.05f
|
||||
Step = 0.02f
|
||||
};
|
||||
HUDScaleScrollBar.OnMoved(HUDScaleScrollBar, HUDScaleScrollBar.BarScroll);
|
||||
|
||||
@@ -743,15 +798,31 @@ namespace Barotrauma
|
||||
BarScroll = (InventoryScale - MinInventoryScale) / (MaxInventoryScale - MinInventoryScale),
|
||||
OnMoved = (scrollBar, scroll) =>
|
||||
{
|
||||
ChangeSliderText(scrollBar, scroll);
|
||||
InventoryScale = MathHelper.Lerp(MinInventoryScale, MaxInventoryScale, scroll);
|
||||
UnsavedSettings = true;
|
||||
ChangeSliderText(scrollBar, InventoryScale);
|
||||
return true;
|
||||
},
|
||||
Step = 0.05f
|
||||
Step = 0.02f
|
||||
};
|
||||
inventoryScaleScrollBar.OnMoved(inventoryScaleScrollBar, inventoryScaleScrollBar.BarScroll);
|
||||
|
||||
GUITextBlock textScaleText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform), TextManager.Get("TextScale"), font: GUI.SubHeadingFont);
|
||||
GUIScrollBar textScaleScrollBar = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform),
|
||||
style: "GUISlider", barSize: 0.1f)
|
||||
{
|
||||
UserData = textScaleText,
|
||||
BarScroll = (TextScale - MinTextScale) / (MaxTextScale - MinTextScale),
|
||||
OnMoved = (scrollBar, scroll) =>
|
||||
{
|
||||
TextScale = MathHelper.Lerp(MinTextScale, MaxTextScale, scroll);
|
||||
textScaleDirty = true;
|
||||
ChangeSliderText(scrollBar, TextScale);
|
||||
return true;
|
||||
},
|
||||
Step = 0.01f
|
||||
};
|
||||
textScaleScrollBar.OnMoved(textScaleScrollBar, textScaleScrollBar.BarScroll);
|
||||
|
||||
/// Audio tab ----------------------------------------------------------------
|
||||
|
||||
var audioContent = new GUILayoutGroup(new RectTransform(new Vector2(0.97f, 0.97f), tabs[(int)Tab.Audio].RectTransform, Anchor.Center), childAnchor: Anchor.TopCenter)
|
||||
@@ -809,8 +880,7 @@ namespace Barotrauma
|
||||
ChangeSliderText(scrollBar, scroll);
|
||||
SoundVolume = scroll;
|
||||
return true;
|
||||
},
|
||||
Step = 0.05f
|
||||
}
|
||||
};
|
||||
soundScrollBar.OnMoved(soundScrollBar, soundScrollBar.BarScroll);
|
||||
|
||||
@@ -825,8 +895,7 @@ namespace Barotrauma
|
||||
ChangeSliderText(scrollBar, scroll);
|
||||
MusicVolume = scroll;
|
||||
return true;
|
||||
},
|
||||
Step = 0.05f
|
||||
}
|
||||
};
|
||||
musicScrollBar.OnMoved(musicScrollBar, musicScrollBar.BarScroll);
|
||||
|
||||
@@ -835,8 +904,7 @@ namespace Barotrauma
|
||||
style: "GUISlider", barSize: 0.05f)
|
||||
{
|
||||
UserData = voiceChatVolumeText,
|
||||
Range = new Vector2(0.0f, 2.0f),
|
||||
Step = 0.05f
|
||||
Range = new Vector2(0.0f, 2.0f)
|
||||
};
|
||||
voiceChatScrollBar.BarScrollValue = VoiceChatVolume;
|
||||
voiceChatScrollBar.OnMoved = (scrollBar, scroll) =>
|
||||
@@ -1014,6 +1082,19 @@ namespace Barotrauma
|
||||
{
|
||||
Visible = VoiceSetting != VoiceMode.Disabled
|
||||
};
|
||||
GUITickBox localVoiceByDefault = new GUITickBox(
|
||||
new RectTransform(tickBoxScale, voiceActivityGroup.RectTransform), TextManager.Get("LocalVoiceByDefault"))
|
||||
{
|
||||
Visible = VoiceSetting == VoiceMode.Activity,
|
||||
Selected = UseLocalVoiceByDefault,
|
||||
ToolTip = TextManager.Get("LocalVoiceByDefaultTooltip"),
|
||||
OnSelected = (tickBox) =>
|
||||
{
|
||||
UseLocalVoiceByDefault = tickBox.Selected;
|
||||
UnsavedSettings = true;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
GUITextBlock noiseGateText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), voiceActivityGroup.RectTransform), TextManager.Get("NoiseGateThreshold"), font: GUI.SubHeadingFont)
|
||||
{
|
||||
Visible = VoiceSetting == VoiceMode.Activity,
|
||||
@@ -1140,6 +1221,7 @@ namespace Barotrauma
|
||||
|
||||
noiseGateText.Visible = (vMode == VoiceMode.Activity);
|
||||
noiseGateSlider.Visible = (vMode == VoiceMode.Activity);
|
||||
localVoiceByDefault.Visible = (vMode == VoiceMode.Activity);
|
||||
voiceActivityGroup.Visible = (vMode != VoiceMode.Disabled);
|
||||
voiceInputContainerHorizontal.Visible = (vMode == VoiceMode.PushToTalk);
|
||||
UnsavedSettings = true;
|
||||
@@ -1183,7 +1265,7 @@ namespace Barotrauma
|
||||
AimAssistAmount = MathHelper.Lerp(0.0f, 5.0f, scroll);
|
||||
return true;
|
||||
},
|
||||
Step = 0.1f
|
||||
Step = 0.01f
|
||||
};
|
||||
aimAssistSlider.OnMoved(aimAssistSlider, aimAssistSlider.BarScroll);
|
||||
|
||||
@@ -1199,19 +1281,21 @@ namespace Barotrauma
|
||||
}
|
||||
};
|
||||
|
||||
var inputFrame = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.75f), controlsLayoutGroup.RectTransform), isHorizontal: true)
|
||||
{ Stretch = true, RelativeSpacing = 0.03f };
|
||||
var controlListBox = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.75f), controlsLayoutGroup.RectTransform));
|
||||
|
||||
var inputFrame = new GUILayoutGroup(new RectTransform(Vector2.One, controlListBox.Content.RectTransform), isHorizontal: true)
|
||||
{ Stretch = true, RelativeSpacing = 0.01f };
|
||||
|
||||
var inputColumnLeft = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 1.0f), inputFrame.RectTransform))
|
||||
{ Stretch = true, RelativeSpacing = 0.02f };
|
||||
{ Stretch = true, RelativeSpacing = 0.005f };
|
||||
var inputColumnRight = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 1.0f), inputFrame.RectTransform))
|
||||
{ Stretch = true, RelativeSpacing = 0.02f };
|
||||
{ Stretch = true, RelativeSpacing = 0.005f };
|
||||
|
||||
var inputNames = Enum.GetValues(typeof(InputType));
|
||||
var inputNameBlocks = new List<GUITextBlock>();
|
||||
for (int i = 0; i < inputNames.Length; i++)
|
||||
{
|
||||
var inputContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.06f),(i <= (inputNames.Length / 2.2f) ? inputColumnLeft : inputColumnRight).RectTransform))
|
||||
var inputContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.06f),(i <= (inputNames.Length / 2) ? inputColumnLeft : inputColumnRight).RectTransform))
|
||||
{ Stretch = true, IsHorizontal = true, RelativeSpacing = 0.01f, Color = new Color(12, 14, 15, 215) };
|
||||
var inputName = new GUITextBlock(new RectTransform(new Vector2(0.6f, 1.0f), inputContainer.RectTransform, Anchor.TopLeft) { MinSize = new Point(100, 0) },
|
||||
TextManager.Get("InputType." + ((InputType)i)), font: GUI.SmallFont) { ForceUpperCase = true };
|
||||
@@ -1226,14 +1310,17 @@ namespace Barotrauma
|
||||
{
|
||||
keyBox.Text = ToolBox.LimitString(keyText, keyBox.Font, (int)(keyBox.Rect.Width - keyBox.Padding.X - keyBox.Padding.Z));
|
||||
};
|
||||
inputContainer.RectTransform.MinSize = keyBox.RectTransform.MinSize;
|
||||
keyBox.OnSelected += KeyBoxSelected;
|
||||
keyBox.SelectedColor = Color.Gold * 0.3f;
|
||||
}
|
||||
|
||||
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.06f), inputColumnRight.RectTransform, minSize: inputColumnRight.Children.First().RectTransform.MinSize), style: null);
|
||||
|
||||
for (int i = 0; i < inventoryHotkeyCount; i++)
|
||||
{
|
||||
var inputContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.06f), ((i + 1) <= inventoryHotkeyCount / 2 ? inputColumnLeft : inputColumnRight).RectTransform))
|
||||
{ Stretch = true, IsHorizontal = true, RelativeSpacing = 0.01f, Color = new Color(12, 14, 15, 215) };
|
||||
{ Stretch = true, IsHorizontal = true, RelativeSpacing = 0.01f, Color = new Color(12, 14, 15, 215), CanBeFocused = true };
|
||||
var inputName = new GUITextBlock(new RectTransform(new Vector2(0.6f, 1.0f), inputContainer.RectTransform, Anchor.TopLeft) { MinSize = new Point(100, 0) },
|
||||
TextManager.GetWithVariable("inventoryslotkeybind", "[slotnumber]", (i + 1).ToString()), font: GUI.SmallFont)
|
||||
{ ForceUpperCase = true };
|
||||
@@ -1244,11 +1331,20 @@ namespace Barotrauma
|
||||
UserData = i
|
||||
};
|
||||
keyBox.Text = ToolBox.LimitString(keyBox.Text, keyBox.Font, (int)(keyBox.Rect.Width - keyBox.Padding.X - keyBox.Padding.Z));
|
||||
inputContainer.RectTransform.MinSize = keyBox.RectTransform.MinSize;
|
||||
keyBox.OnSelected += InventoryKeyBoxSelected;
|
||||
keyBox.SelectedColor = Color.Gold * 0.3f;
|
||||
}
|
||||
|
||||
inputNameBlocks.First().RectTransform.SizeChanged += () =>
|
||||
{
|
||||
GUITextBlock.AutoScaleAndNormalize(inputNameBlocks);
|
||||
};
|
||||
|
||||
inputFrame.RectTransform.MinSize = new Point(0,
|
||||
(int)Math.Max(
|
||||
inputColumnLeft.Children.Sum(c => c.Rect.Height * (1.0f + inputColumnLeft.RelativeSpacing)),
|
||||
inputColumnRight.Children.Sum(c => c.Rect.Height * (1.0f + inputColumnLeft.RelativeSpacing))));
|
||||
|
||||
var resetControlsArea = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.07f), controlsLayoutGroup.RectTransform), style: null);
|
||||
var resetControlsHolder = new GUILayoutGroup(new RectTransform(new Vector2(buttonArea.RectTransform.RelativeSize.X / controlsLayoutGroup.RectTransform.RelativeSize.X / rightPanel.RectTransform.RelativeSize.X, 1.0f), resetControlsArea.RectTransform, Anchor.Center),
|
||||
@@ -1597,7 +1693,7 @@ namespace Barotrauma
|
||||
if (!EnabledRegularPackages.Contains(contentPackage)) { return; }
|
||||
}
|
||||
|
||||
ContentPackage.SortContentPackages(cp => listBox.Content.GetChildIndex(listBox.Content.GetChildByUserData(cp)), true);
|
||||
ContentPackage.SortContentPackages(cp => listBox.Content.GetChildIndex(listBox.Content.GetChildByUserData(cp)), true, this);
|
||||
|
||||
UnsavedSettings = true;
|
||||
}
|
||||
@@ -1617,6 +1713,8 @@ namespace Barotrauma
|
||||
DisableRegularPackage(contentPackage);
|
||||
}
|
||||
|
||||
ContentPackage.SortContentPackages(cp => contentPackageList.Content.GetChildIndex(contentPackageList.Content.GetChildByUserData(cp)), false, this);
|
||||
|
||||
UnsavedSettings = true;
|
||||
return true;
|
||||
}
|
||||
@@ -1707,22 +1805,11 @@ namespace Barotrauma
|
||||
|
||||
SettingsFrame.Flash(GUI.Style.Green);
|
||||
|
||||
if (GameMain.WindowMode != GameMain.Config.WindowMode || GameMain.Config.GraphicsWidth != GameMain.GraphicsWidth || GameMain.Config.GraphicsHeight != GameMain.GraphicsHeight)
|
||||
if (textScaleDirty || GameMain.WindowMode != GameMain.Config.WindowMode || GameMain.Config.GraphicsWidth != GameMain.GraphicsWidth || GameMain.Config.GraphicsHeight != GameMain.GraphicsHeight)
|
||||
{
|
||||
GameMain.Instance.ApplyGraphicsSettings();
|
||||
textScaleDirty = false;
|
||||
}
|
||||
|
||||
/*if (GameMain.GraphicsWidth != GameMain.Config.GraphicsWidth || GameMain.GraphicsHeight != GameMain.Config.GraphicsHeight)
|
||||
{
|
||||
#if OSX
|
||||
if (GameMain.Config.WindowMode != WindowMode.BorderlessWindowed)
|
||||
{
|
||||
#endif
|
||||
new GUIMessageBox(TextManager.Get("RestartRequiredLabel"), TextManager.Get("RestartRequiredResolution"));
|
||||
#if OSX
|
||||
}
|
||||
#endif
|
||||
}*/
|
||||
}
|
||||
|
||||
private bool ApplyClicked(GUIButton button, object userData)
|
||||
|
||||
@@ -94,8 +94,8 @@ namespace Barotrauma
|
||||
get { return personalSlotArea; }
|
||||
}
|
||||
|
||||
private GUIImage[] indicators = new GUIImage[5];
|
||||
private int[] indicatorIndexes = new int[5];
|
||||
private readonly GUIImage[] indicators = new GUIImage[5];
|
||||
private readonly int[] indicatorIndices = new int[5];
|
||||
private Vector2 indicatorSpriteSize;
|
||||
private GUILayoutGroup indicatorGroup;
|
||||
|
||||
@@ -117,11 +117,11 @@ namespace Barotrauma
|
||||
indicators[3] = new GUIImage(new RectTransform(Point.Zero, indicatorGroup.RectTransform), "EquipmentIndicatorHeadwear");
|
||||
indicators[4] = new GUIImage(new RectTransform(Point.Zero, indicatorGroup.RectTransform), "EquipmentIndicatorHeadphones");
|
||||
|
||||
indicatorIndexes[0] = FindLimbSlot(InvSlotType.OuterClothes);
|
||||
indicatorIndexes[1] = FindLimbSlot(InvSlotType.Card);
|
||||
indicatorIndexes[2] = FindLimbSlot(InvSlotType.InnerClothes);
|
||||
indicatorIndexes[3] = FindLimbSlot(InvSlotType.Head);
|
||||
indicatorIndexes[4] = FindLimbSlot(InvSlotType.Headset);
|
||||
indicatorIndices[0] = FindLimbSlot(InvSlotType.OuterClothes);
|
||||
indicatorIndices[1] = FindLimbSlot(InvSlotType.Card);
|
||||
indicatorIndices[2] = FindLimbSlot(InvSlotType.InnerClothes);
|
||||
indicatorIndices[3] = FindLimbSlot(InvSlotType.Head);
|
||||
indicatorIndices[4] = FindLimbSlot(InvSlotType.Headset);
|
||||
|
||||
for (int i = 0; i < indicators.Length; i++)
|
||||
{
|
||||
@@ -143,7 +143,7 @@ namespace Barotrauma
|
||||
|
||||
protected override ItemInventory GetActiveEquippedSubInventory(int slotIndex)
|
||||
{
|
||||
var item = Items[slotIndex];
|
||||
Item item = slots[slotIndex].FirstOrDefault();
|
||||
if (item == null) { return null; }
|
||||
|
||||
var container = item.GetComponent<ItemContainer>();
|
||||
@@ -162,38 +162,35 @@ namespace Barotrauma
|
||||
|
||||
public override void RemoveItem(Item item)
|
||||
{
|
||||
if (!Items.Contains(item)) { return; }
|
||||
if (!Contains(item)) { return; }
|
||||
base.RemoveItem(item);
|
||||
CreateSlots();
|
||||
}
|
||||
|
||||
public override void CreateSlots()
|
||||
{
|
||||
if (slots == null) { slots = new InventorySlot[capacity]; }
|
||||
if (visualSlots == null) { visualSlots = new VisualSlot[capacity]; }
|
||||
|
||||
float multiplier = !GUI.IsFourByThree() ? UIScale : UIScale * 0.925f;
|
||||
|
||||
for (int i = 0; i < capacity; i++)
|
||||
{
|
||||
InventorySlot prevSlot = slots[i];
|
||||
VisualSlot prevSlot = visualSlots[i];
|
||||
|
||||
Sprite slotSprite = SlotSpriteSmall;
|
||||
Rectangle slotRect = new Rectangle(
|
||||
(int)(SlotPositions[i].X),
|
||||
(int)(SlotPositions[i].Y),
|
||||
(int)SlotPositions[i].X,
|
||||
(int)SlotPositions[i].Y,
|
||||
(int)(slotSprite.size.X * multiplier), (int)(slotSprite.size.Y * multiplier));
|
||||
|
||||
if (Items[i] != null)
|
||||
{
|
||||
ItemContainer itemContainer = Items[i].GetComponent<ItemContainer>();
|
||||
ItemContainer itemContainer = slots[i].FirstOrDefault()?.GetComponent<ItemContainer>();
|
||||
if (itemContainer != null)
|
||||
{
|
||||
if (itemContainer.InventoryTopSprite != null) slotRect.Width = Math.Max(slotRect.Width, (int)(itemContainer.InventoryTopSprite.size.X * UIScale));
|
||||
if (itemContainer.InventoryBottomSprite != null) slotRect.Width = Math.Max(slotRect.Width, (int)(itemContainer.InventoryBottomSprite.size.X * UIScale));
|
||||
}
|
||||
}
|
||||
|
||||
slots[i] = new InventorySlot(slotRect)
|
||||
visualSlots[i] = new VisualSlot(slotRect)
|
||||
{
|
||||
SubInventoryDir = Math.Sign(GameMain.GraphicsHeight / 2 - slotRect.Center.Y),
|
||||
Disabled = false,
|
||||
@@ -202,13 +199,13 @@ namespace Barotrauma
|
||||
};
|
||||
if (prevSlot != null)
|
||||
{
|
||||
slots[i].DrawOffset = prevSlot.DrawOffset;
|
||||
slots[i].Color = prevSlot.Color;
|
||||
visualSlots[i].DrawOffset = prevSlot.DrawOffset;
|
||||
visualSlots[i].Color = prevSlot.Color;
|
||||
prevSlot.MoveBorderHighlight(visualSlots[i]);
|
||||
}
|
||||
|
||||
if (selectedSlot?.ParentInventory == this && selectedSlot.SlotIndex == i)
|
||||
{
|
||||
selectedSlot = new SlotReference(this, slots[i], i, selectedSlot.IsSubSlot, selectedSlot.Inventory);
|
||||
selectedSlot = new SlotReference(this, visualSlots[i], i, selectedSlot.IsSubSlot, selectedSlot.Inventory);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,9 +214,9 @@ namespace Barotrauma
|
||||
highlightedSubInventorySlots.RemoveWhere(s => s.Inventory.OpenState <= 0.0f);
|
||||
foreach (var subSlot in highlightedSubInventorySlots)
|
||||
{
|
||||
if (subSlot.ParentInventory == this && subSlot.SlotIndex > 0 && subSlot.SlotIndex < slots.Length)
|
||||
if (subSlot.ParentInventory == this && subSlot.SlotIndex > 0 && subSlot.SlotIndex < visualSlots.Length)
|
||||
{
|
||||
subSlot.Slot = slots[subSlot.SlotIndex];
|
||||
subSlot.Slot = visualSlots[subSlot.SlotIndex];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,10 +232,10 @@ namespace Barotrauma
|
||||
if (HideSlot(i)) continue;
|
||||
if (frame == Rectangle.Empty)
|
||||
{
|
||||
frame = slots[i].Rect;
|
||||
frame = visualSlots[i].Rect;
|
||||
continue;
|
||||
}
|
||||
frame = Rectangle.Union(frame, slots[i].Rect);
|
||||
frame = Rectangle.Union(frame, visualSlots[i].Rect);
|
||||
}
|
||||
frame.Inflate(10, 30);
|
||||
frame.Location -= new Point(0, 25);
|
||||
@@ -247,26 +244,25 @@ namespace Barotrauma
|
||||
|
||||
protected override bool HideSlot(int i)
|
||||
{
|
||||
if (slots[i].Disabled || (hideEmptySlot[i] && Items[i] == null)) return true;
|
||||
if (visualSlots[i].Disabled || (slots[i].HideIfEmpty && slots[i].Empty())) { return true; }
|
||||
|
||||
if (layout == Layout.Default)
|
||||
{
|
||||
if (PersonalSlots.HasFlag(SlotTypes[i]) && !personalSlotArea.Contains(slots[i].Rect.Center + slots[i].DrawOffset.ToPoint())) return true;
|
||||
if (PersonalSlots.HasFlag(SlotTypes[i]) && !personalSlotArea.Contains(visualSlots[i].Rect.Center + visualSlots[i].DrawOffset.ToPoint())) { return true; }
|
||||
}
|
||||
|
||||
Item item = slots[i].FirstOrDefault();
|
||||
|
||||
//no need to draw the right hand slot if the item is in both hands
|
||||
if (Items[i] != null && SlotTypes[i] == InvSlotType.RightHand && IsInLimbSlot(Items[i], InvSlotType.LeftHand))
|
||||
if (item != null && SlotTypes[i] == InvSlotType.RightHand && IsInLimbSlot(item, InvSlotType.LeftHand))
|
||||
{
|
||||
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)
|
||||
//don't show the limb-specific slot if the item is also in an Any slot
|
||||
if (item != null && SlotTypes[i] != InvSlotType.Any)
|
||||
{
|
||||
for (int j = 0; j < capacity; j++)
|
||||
{
|
||||
if (SlotTypes[j] == InvSlotType.Any && Items[j] == Items[i]) return true;
|
||||
}
|
||||
if (IsInLimbSlot(item, InvSlotType.Any)) { return true; }
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -308,7 +304,8 @@ namespace Barotrauma
|
||||
SlotSize = !isFourByThree ? (SlotSpriteSmall.size * UIScale).ToPoint() : (SlotSpriteSmall.size * UIScale * .925f).ToPoint();
|
||||
int bottomOffset = SlotSize.Y + Spacing * 2 + ContainedIndicatorHeight;
|
||||
|
||||
if (slots == null) { CreateSlots(); }
|
||||
if (visualSlots == null) { CreateSlots(); }
|
||||
if (visualSlots.None()) { return; }
|
||||
|
||||
hideButton.Visible = false;
|
||||
|
||||
@@ -359,7 +356,7 @@ namespace Barotrauma
|
||||
{
|
||||
int x = HUDLayoutSettings.InventoryAreaLower.Right;
|
||||
int personalSlotX = HUDLayoutSettings.InventoryAreaLower.Right - SlotSize.X - Spacing;
|
||||
for (int i = 0; i < slots.Length; i++)
|
||||
for (int i = 0; i < visualSlots.Length; i++)
|
||||
{
|
||||
if (HideSlot(i)) continue;
|
||||
if (PersonalSlots.HasFlag(SlotTypes[i]))
|
||||
@@ -380,12 +377,12 @@ namespace Barotrauma
|
||||
if (PersonalSlots.HasFlag(SlotTypes[i]))
|
||||
{
|
||||
SlotPositions[i] = new Vector2(personalSlotX, personalSlotY);
|
||||
personalSlotX -= slots[i].Rect.Width + Spacing;
|
||||
personalSlotX -= visualSlots[i].Rect.Width + Spacing;
|
||||
}
|
||||
else
|
||||
{
|
||||
SlotPositions[i] = new Vector2(x, GameMain.GraphicsHeight - bottomOffset);
|
||||
x += slots[i].Rect.Width + Spacing;
|
||||
x += visualSlots[i].Rect.Width + Spacing;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -393,7 +390,7 @@ namespace Barotrauma
|
||||
for (int i = 0; i < SlotPositions.Length; i++)
|
||||
{
|
||||
if (!HideSlot(i)) continue;
|
||||
x -= slots[i].Rect.Width + Spacing;
|
||||
x -= visualSlots[i].Rect.Width + Spacing;
|
||||
SlotPositions[i] = new Vector2(x, GameMain.GraphicsHeight - bottomOffset);
|
||||
}
|
||||
}
|
||||
@@ -410,19 +407,19 @@ namespace Barotrauma
|
||||
if (PersonalSlots.HasFlag(SlotTypes[i]))
|
||||
{
|
||||
SlotPositions[i] = new Vector2(personalSlotX, personalSlotY);
|
||||
personalSlotX += slots[i].Rect.Width + Spacing;
|
||||
personalSlotX += visualSlots[i].Rect.Width + Spacing;
|
||||
}
|
||||
else
|
||||
{
|
||||
SlotPositions[i] = new Vector2(x, GameMain.GraphicsHeight - bottomOffset);
|
||||
x += slots[i].Rect.Width + Spacing;
|
||||
x += visualSlots[i].Rect.Width + Spacing;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < SlotPositions.Length; i++)
|
||||
{
|
||||
if (!HideSlot(i)) continue;
|
||||
SlotPositions[i] = new Vector2(x, GameMain.GraphicsHeight - bottomOffset);
|
||||
x += slots[i].Rect.Width + Spacing;
|
||||
x += visualSlots[i].Rect.Width + Spacing;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -438,10 +435,10 @@ namespace Barotrauma
|
||||
if (SlotTypes[i] == InvSlotType.Card || SlotTypes[i] == InvSlotType.Headset || SlotTypes[i] == InvSlotType.InnerClothes)
|
||||
{
|
||||
SlotPositions[i] = new Vector2(x, y);
|
||||
x += slots[i].Rect.Width + Spacing;
|
||||
x += visualSlots[i].Rect.Width + Spacing;
|
||||
}
|
||||
}
|
||||
y += slots[0].Rect.Height + Spacing + ContainedIndicatorHeight + slots[0].EquipButtonRect.Height;
|
||||
y += visualSlots[0].Rect.Height + Spacing + ContainedIndicatorHeight + visualSlots[0].EquipButtonRect.Height;
|
||||
x = startX;
|
||||
int n = 0;
|
||||
for (int i = 0; i < SlotPositions.Length; i++)
|
||||
@@ -450,12 +447,12 @@ namespace Barotrauma
|
||||
if (SlotTypes[i] != InvSlotType.Card && SlotTypes[i] != InvSlotType.Headset && SlotTypes[i] != InvSlotType.InnerClothes)
|
||||
{
|
||||
SlotPositions[i] = new Vector2(x, y);
|
||||
x += slots[i].Rect.Width + Spacing;
|
||||
x += visualSlots[i].Rect.Width + Spacing;
|
||||
n++;
|
||||
if (n >= columns)
|
||||
{
|
||||
x = startX;
|
||||
y += slots[i].Rect.Height + Spacing + ContainedIndicatorHeight + slots[i].EquipButtonRect.Height;
|
||||
y += visualSlots[i].Rect.Height + Spacing + ContainedIndicatorHeight + visualSlots[i].EquipButtonRect.Height;
|
||||
n = 0;
|
||||
}
|
||||
}
|
||||
@@ -467,7 +464,7 @@ namespace Barotrauma
|
||||
CreateSlots();
|
||||
if (layout == Layout.Default)
|
||||
{
|
||||
HUDLayoutSettings.InventoryTopY = slots[0].EquipButtonRect.Y - (int)(15 * GUI.Scale);
|
||||
HUDLayoutSettings.InventoryTopY = visualSlots[0].EquipButtonRect.Y - (int)(15 * GUI.Scale);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -484,7 +481,8 @@ namespace Barotrauma
|
||||
|
||||
public override void Update(float deltaTime, Camera cam, bool isSubInventory = false)
|
||||
{
|
||||
if (!AccessibleWhenAlive && !character.IsDead)
|
||||
// Need to update the infiltrator's inventory because they use id cards to access the sub. TODO: We don't probably need to update everything.
|
||||
if (!AccessibleWhenAlive && !character.IsDead && (character.Params.AI == null || !character.Params.AI.Infiltrate))
|
||||
{
|
||||
syncItemsDelay = Math.Max(syncItemsDelay - deltaTime, 0.0f);
|
||||
return;
|
||||
@@ -493,7 +491,7 @@ namespace Barotrauma
|
||||
base.Update(deltaTime, cam);
|
||||
|
||||
bool hoverOnInventory = GUI.MouseOn == null &&
|
||||
((selectedSlot != null && selectedSlot.IsSubSlot) || (draggingItem != null && (draggingSlot == null || !draggingSlot.MouseOn())));
|
||||
((selectedSlot != null && selectedSlot.IsSubSlot) || (DraggingItems.Any() && (DraggingSlot == null || !DraggingSlot.MouseOn())));
|
||||
if (CharacterHealth.OpenHealthWindow != null) hoverOnInventory = true;
|
||||
|
||||
if (layout == Layout.Default && (Screen.Selected != GameMain.SubEditorScreen || Screen.Selected is SubEditorScreen editor && editor.WiringMode))
|
||||
@@ -508,16 +506,16 @@ namespace Barotrauma
|
||||
Math.Max(hidePersonalSlotsState - deltaTime * 5.0f, 0.0f);
|
||||
|
||||
bool personalSlotsMoving = hidePersonalSlotsState > 0 && hidePersonalSlotsState < 1f;
|
||||
for (int i = 0; i < slots.Length; i++)
|
||||
for (int i = 0; i < visualSlots.Length; i++)
|
||||
{
|
||||
if (!PersonalSlots.HasFlag(SlotTypes[i])) { continue; }
|
||||
if (HidePersonalSlots)
|
||||
{
|
||||
if (selectedSlot?.Slot == slots[i]) { selectedSlot = null; }
|
||||
highlightedSubInventorySlots.RemoveWhere(s => s.Slot == slots[i]);
|
||||
if (selectedSlot?.Slot == visualSlots[i]) { selectedSlot = null; }
|
||||
highlightedSubInventorySlots.RemoveWhere(s => s.Slot == visualSlots[i]);
|
||||
}
|
||||
slots[i].IsMoving = personalSlotsMoving;
|
||||
slots[i].DrawOffset = Vector2.Lerp(Vector2.Zero, new Vector2(personalSlotArea.Width, 0.0f), hidePersonalSlotsState);
|
||||
visualSlots[i].IsMoving = personalSlotsMoving;
|
||||
visualSlots[i].DrawOffset = Vector2.Lerp(Vector2.Zero, new Vector2(personalSlotArea.Width, 0.0f), hidePersonalSlotsState);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -530,13 +528,15 @@ namespace Barotrauma
|
||||
//force personal slots open if an item is running out of battery/fuel/oxygen/etc
|
||||
if (hidePersonalSlots)
|
||||
{
|
||||
for (int i = 0; i < slots.Length; i++)
|
||||
for (int i = 0; i < visualSlots.Length; i++)
|
||||
{
|
||||
if (Items[i]?.OwnInventory != null && Items[i].OwnInventory.Capacity == 1 && PersonalSlots.HasFlag(SlotTypes[i]))
|
||||
var item = slots[i].FirstOrDefault();
|
||||
if (item?.OwnInventory != null && item.OwnInventory.Capacity == 1 && PersonalSlots.HasFlag(SlotTypes[i]))
|
||||
{
|
||||
if (Items[i].OwnInventory.Items[0] != null &&
|
||||
Items[i].OwnInventory.Items[0].Condition > 0.0f &&
|
||||
Items[i].OwnInventory.Items[0].Condition / Items[i].OwnInventory.Items[0].MaxCondition < 0.15f)
|
||||
var containedItem = item.OwnInventory.AllItems.FirstOrDefault();
|
||||
if (containedItem != null &&
|
||||
containedItem.Condition > 0.0f &&
|
||||
containedItem.Condition / containedItem.MaxCondition < 0.15f)
|
||||
{
|
||||
hidePersonalSlots = false;
|
||||
}
|
||||
@@ -547,7 +547,7 @@ namespace Barotrauma
|
||||
List<SlotReference> hideSubInventories = new List<SlotReference>();
|
||||
highlightedSubInventorySlots.RemoveWhere(s =>
|
||||
s.ParentInventory == this &&
|
||||
((s.SlotIndex < 0 || s.SlotIndex >= Items.Length || Items[s.SlotIndex] == null) || (Character.Controlled != null && !Character.Controlled.CanAccessInventory(s.Inventory))));
|
||||
((s.SlotIndex < 0 || s.SlotIndex >= slots.Length || slots[s.SlotIndex] == null) || (Character.Controlled != null && !Character.Controlled.CanAccessInventory(s.Inventory))));
|
||||
foreach (var highlightedSubInventorySlot in highlightedSubInventorySlots)
|
||||
{
|
||||
if (highlightedSubInventorySlot.ParentInventory == this)
|
||||
@@ -558,7 +558,7 @@ namespace Barotrauma
|
||||
if (!highlightedSubInventorySlot.Inventory.IsInventoryHoverAvailable(character, null)) continue;
|
||||
|
||||
Rectangle hoverArea = GetSubInventoryHoverArea(highlightedSubInventorySlot);
|
||||
if (highlightedSubInventorySlot.Inventory?.slots == null || (!hoverArea.Contains(PlayerInput.MousePosition)))
|
||||
if (highlightedSubInventorySlot.Inventory?.visualSlots == null || (!hoverArea.Contains(PlayerInput.MousePosition)))
|
||||
{
|
||||
hideSubInventories.Add(highlightedSubInventorySlot);
|
||||
}
|
||||
@@ -585,19 +585,19 @@ namespace Barotrauma
|
||||
// In sub editor we cannot hover over the slot because they are not rendered so we override it here
|
||||
if (Screen.Selected is SubEditorScreen subEditor && !subEditor.WiringMode)
|
||||
{
|
||||
for (int i = 0; i < slots.Length; i++)
|
||||
for (int i = 0; i < visualSlots.Length; i++)
|
||||
{
|
||||
var subInventory = GetSubInventory(i);
|
||||
if (subInventory != null)
|
||||
{
|
||||
ShowSubInventory(new SlotReference(this, slots[i], i, false, Items[i].GetComponent<ItemContainer>().Inventory), deltaTime, cam, hideSubInventories, true);
|
||||
ShowSubInventory(new SlotReference(this, visualSlots[i], i, false, subInventory), deltaTime, cam, hideSubInventories, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var subInventorySlot in hideSubInventories)
|
||||
{
|
||||
if (subInventorySlot.Inventory == null) continue;
|
||||
if (subInventorySlot.Inventory == null) { continue; }
|
||||
subInventorySlot.Inventory.HideTimer -= deltaTime;
|
||||
if (subInventorySlot.Inventory.HideTimer < 0.25f)
|
||||
{
|
||||
@@ -614,10 +614,10 @@ namespace Barotrauma
|
||||
|
||||
for (int i = 0; i < capacity; i++)
|
||||
{
|
||||
var item = Items[i];
|
||||
var item = slots[i].FirstOrDefault();
|
||||
if (item != null)
|
||||
{
|
||||
if (HideSlot(i)) continue;
|
||||
if (HideSlot(i)) { continue; }
|
||||
if (character.HasEquippedItem(item)) // Keep a subinventory display open permanently when the container is equipped
|
||||
{
|
||||
var itemContainer = item.GetComponent<ItemContainer>();
|
||||
@@ -626,24 +626,32 @@ namespace Barotrauma
|
||||
character.CanAccessInventory(itemContainer.Inventory) &&
|
||||
!highlightedSubInventorySlots.Any(s => s.Inventory == itemContainer.Inventory))
|
||||
{
|
||||
ShowSubInventory(new SlotReference(this, slots[i], i, false, itemContainer.Inventory), deltaTime, cam, hideSubInventories, true);
|
||||
ShowSubInventory(new SlotReference(this, visualSlots[i], i, false, itemContainer.Inventory), deltaTime, cam, hideSubInventories, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (doubleClickedItem != null)
|
||||
if (doubleClickedItems.Any())
|
||||
{
|
||||
QuickUseItem(doubleClickedItem, true, true, true);
|
||||
var quickUseAction = GetQuickUseAction(doubleClickedItems.First(), true, true, true);
|
||||
foreach (Item doubleClickedItem in doubleClickedItems)
|
||||
{
|
||||
QuickUseItem(doubleClickedItem, true, true, true, quickUseAction, playSound: doubleClickedItem == doubleClickedItems.First());
|
||||
if (quickUseAction == QuickUseAction.Equip || quickUseAction == QuickUseAction.UseTreatment)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < capacity; i++)
|
||||
{
|
||||
var item = Items[i];
|
||||
var item = slots[i].FirstOrDefault();
|
||||
if (item != null)
|
||||
{
|
||||
var slot = slots[i];
|
||||
var slot = visualSlots[i];
|
||||
if (item.AllowedSlots.Any(a => a != InvSlotType.Any))
|
||||
{
|
||||
HandleButtonEquipStates(item, slot, deltaTime);
|
||||
@@ -652,10 +660,10 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
//cancel dragging if too far away from the container of the dragged item
|
||||
if (draggingItem != null)
|
||||
if (DraggingItems.Any())
|
||||
{
|
||||
var rootContainer = draggingItem.GetRootContainer();
|
||||
var rootInventory = draggingItem.ParentInventory;
|
||||
var rootContainer = DraggingItems.First().GetRootContainer();
|
||||
var rootInventory = DraggingItems.First().ParentInventory;
|
||||
|
||||
if (rootContainer != null)
|
||||
{
|
||||
@@ -673,27 +681,39 @@ namespace Barotrauma
|
||||
Character.Controlled.SelectedConstruction != null &&
|
||||
rootContainer.linkedTo.Contains(Character.Controlled.SelectedConstruction)))
|
||||
{
|
||||
draggingItem = null;
|
||||
DraggingItems.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
doubleClickedItem = null;
|
||||
doubleClickedItems.Clear();
|
||||
}
|
||||
|
||||
public void UpdateSlotInput()
|
||||
{
|
||||
for (int i = 0; i < capacity; i++)
|
||||
{
|
||||
if (Items[i] != null && Items[i] != draggingItem && Character.Controlled?.Inventory == this &&
|
||||
GUI.KeyboardDispatcher.Subscriber == null && !CrewManager.IsCommandInterfaceOpen && PlayerInput.InventoryKeyHit(slots[i].InventoryKeyIndex))
|
||||
var firstItem = slots[i].FirstOrDefault();
|
||||
if (firstItem != null && !DraggingItems.Contains(firstItem) && Character.Controlled?.Inventory == this &&
|
||||
GUI.KeyboardDispatcher.Subscriber == null && !CrewManager.IsCommandInterfaceOpen && PlayerInput.InventoryKeyHit(visualSlots[i].InventoryKeyIndex))
|
||||
{
|
||||
QuickUseItem(Items[i], true, false, true);
|
||||
#if LINUX
|
||||
// some window managers on Linux use windows key + number to change workspaces or perform other actions
|
||||
if (PlayerInput.KeyDown(Keys.RightWindows) || PlayerInput.KeyDown(Keys.LeftWindows)) { continue; }
|
||||
#endif
|
||||
var quickUseAction = GetQuickUseAction(firstItem, true, false, true);
|
||||
foreach (Item itemToUse in slots[i].Items.ToList())
|
||||
{
|
||||
QuickUseItem(itemToUse, true, true, true, quickUseAction, playSound: itemToUse == firstItem);
|
||||
if (quickUseAction == QuickUseAction.Equip || quickUseAction == QuickUseAction.UseTreatment)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleButtonEquipStates(Item item, InventorySlot slot, float deltaTime)
|
||||
private void HandleButtonEquipStates(Item item, VisualSlot slot, float deltaTime)
|
||||
{
|
||||
slot.EquipButtonState = slot.EquipButtonRect.Contains(PlayerInput.MousePosition) ?
|
||||
GUIComponent.ComponentState.Hover : GUIComponent.ComponentState.None;
|
||||
@@ -713,7 +733,7 @@ namespace Barotrauma
|
||||
if (quickUseAction != QuickUseAction.Drop)
|
||||
{
|
||||
slot.QuickUseButtonToolTip = quickUseAction == QuickUseAction.None ?
|
||||
"" : TextManager.GetWithVariable("QuickUseAction." + quickUseAction.ToString(), "[equippeditem]", character.SelectedItems.FirstOrDefault(i => i != null)?.Name);
|
||||
"" : TextManager.GetWithVariable("QuickUseAction." + quickUseAction.ToString(), "[equippeditem]", item?.Name);
|
||||
if (PlayerInput.PrimaryMouseButtonDown()) { slot.EquipButtonState = GUIComponent.ComponentState.Pressed; }
|
||||
if (PlayerInput.PrimaryMouseButtonClicked())
|
||||
{
|
||||
@@ -726,8 +746,8 @@ namespace Barotrauma
|
||||
{
|
||||
for (int i = 0; i < indicators.Length; i++)
|
||||
{
|
||||
if (indicatorIndexes[i] < 0) { continue; }
|
||||
Item item = Items[indicatorIndexes[i]];
|
||||
if (indicatorIndices[i] < 0) { continue; }
|
||||
Item item = slots[indicatorIndices[i]].FirstOrDefault();
|
||||
if (item != null)
|
||||
{
|
||||
Wearable wearable = item.GetComponent<Wearable>();
|
||||
@@ -795,12 +815,12 @@ namespace Barotrauma
|
||||
public void AssignQuickUseNumKeys()
|
||||
{
|
||||
int keyBindIndex = 0;
|
||||
for (int i = 0; i < slots.Length; i++)
|
||||
for (int i = 0; i < visualSlots.Length; i++)
|
||||
{
|
||||
if (HideSlot(i)) continue;
|
||||
if (SlotTypes[i] == InvSlotType.Any)
|
||||
{
|
||||
slots[i].InventoryKeyIndex = keyBindIndex;
|
||||
visualSlots[i].InventoryKeyIndex = keyBindIndex;
|
||||
keyBindIndex++;
|
||||
}
|
||||
}
|
||||
@@ -824,7 +844,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (item.Container == null || character.Inventory.FindIndex(item.Container) == -1) // Not a subinventory in the character's inventory
|
||||
{
|
||||
if (character.SelectedItems.Any(i => i?.OwnInventory != null && i.OwnInventory.CanBePut(item)))
|
||||
if (character.HeldItems.Any(i => i.OwnInventory != null && i.OwnInventory.CanBePut(item)))
|
||||
{
|
||||
return QuickUseAction.PutToEquippedItem;
|
||||
}
|
||||
@@ -875,7 +895,7 @@ namespace Barotrauma
|
||||
{
|
||||
return QuickUseAction.TakeFromCharacter;
|
||||
}
|
||||
else if (character.SelectedItems.Any(i => i?.OwnInventory != null && i.OwnInventory.CanBePut(item)) && allowInventorySwap)
|
||||
else if (character.HeldItems.Any(i => i.OwnInventory != null && i.OwnInventory.CanBePut(item)) && allowInventorySwap)
|
||||
{
|
||||
return QuickUseAction.PutToEquippedItem;
|
||||
}
|
||||
@@ -901,23 +921,20 @@ namespace Barotrauma
|
||||
return QuickUseAction.None;
|
||||
}
|
||||
|
||||
private void QuickUseItem(Item item, bool allowEquip, bool allowInventorySwap, bool allowApplyTreatment)
|
||||
private void QuickUseItem(Item item, bool allowEquip, bool allowInventorySwap, bool allowApplyTreatment, QuickUseAction? action = null, bool playSound = true)
|
||||
{
|
||||
if (Screen.Selected is SubEditorScreen editor && !editor.WiringMode && !Submarine.Unloading)
|
||||
{
|
||||
// Find the slot the item was contained in and flash it
|
||||
if (item.ParentInventory?.slots != null)
|
||||
if (item.ParentInventory?.visualSlots != null)
|
||||
{
|
||||
var invSlots = item.ParentInventory.slots;
|
||||
var invItems = item.ParentInventory.Items;
|
||||
var invSlots = item.ParentInventory.visualSlots;
|
||||
for (int i = 0; i < invSlots.Length; i++)
|
||||
{
|
||||
if (i < 0 || invSlots.Length <= i || i < 0 || invItems.Length <= i) { break; }
|
||||
if (i < 0 || invSlots.Length <= i || i < 0 || item.ParentInventory.Capacity <= i) { break; }
|
||||
|
||||
var slot = invSlots[i];
|
||||
var slotItem = invItems[i];
|
||||
|
||||
if (slotItem == item)
|
||||
if (item.ParentInventory.GetItemAt(i) == item)
|
||||
{
|
||||
slot.ShowBorderHighlight(GUI.Style.Red, 0.1f, 0.4f);
|
||||
SoundPlayer.PlayUISound(GUISoundType.PickItem);
|
||||
@@ -932,7 +949,7 @@ namespace Barotrauma
|
||||
return;
|
||||
}
|
||||
|
||||
var quickUseAction = GetQuickUseAction(item, allowEquip, allowInventorySwap, allowApplyTreatment);
|
||||
QuickUseAction quickUseAction = action ?? GetQuickUseAction(item, allowEquip, allowInventorySwap, allowApplyTreatment);
|
||||
bool success = false;
|
||||
switch (quickUseAction)
|
||||
{
|
||||
@@ -963,7 +980,7 @@ namespace Barotrauma
|
||||
//attempt to put in a free slot first
|
||||
for (int i = capacity - 1; i >= 0; i--)
|
||||
{
|
||||
if (Items[i] != null) { continue; }
|
||||
if (!slots[i].Empty()) { continue; }
|
||||
if (SlotTypes[i] == InvSlotType.Any || !item.AllowedSlots.Any(a => a.HasFlag(SlotTypes[i]))) { continue; }
|
||||
success = TryPutItem(item, i, true, false, Character.Controlled, true);
|
||||
if (success) { break; }
|
||||
@@ -975,9 +992,10 @@ namespace Barotrauma
|
||||
{
|
||||
if (SlotTypes[i] == InvSlotType.Any || !item.AllowedSlots.Any(a => a.HasFlag(SlotTypes[i]))) { continue; }
|
||||
// something else already equipped in a hand slot, attempt to unequip it so items aren't unnecessarily swapped to it
|
||||
if (Items[i] != null && Items[i].AllowedSlots.Contains(InvSlotType.Any) && (SlotTypes[i] == InvSlotType.LeftHand || SlotTypes[i] == InvSlotType.RightHand))
|
||||
if (!slots[i].Empty() && slots[i].First().AllowedSlots.Contains(InvSlotType.Any) &&
|
||||
(SlotTypes[i] == InvSlotType.LeftHand || SlotTypes[i] == InvSlotType.RightHand))
|
||||
{
|
||||
TryPutItem(Items[i], Character.Controlled, new List<InvSlotType>() { InvSlotType.Any }, true);
|
||||
TryPutItem(slots[i].First(), Character.Controlled, new List<InvSlotType>() { InvSlotType.Any }, true);
|
||||
}
|
||||
success = TryPutItem(item, i, true, false, Character.Controlled, true);
|
||||
if (success) { break; }
|
||||
@@ -1040,15 +1058,15 @@ namespace Barotrauma
|
||||
}
|
||||
break;
|
||||
case QuickUseAction.PutToEquippedItem:
|
||||
for (int i = 0; i < character.SelectedItems.Length; i++)
|
||||
foreach (Item heldItem in character.HeldItems)
|
||||
{
|
||||
if (character.SelectedItems[i]?.OwnInventory != null &&
|
||||
character.SelectedItems[i].OwnInventory.TryPutItem(item, Character.Controlled))
|
||||
if (heldItem.OwnInventory != null &&
|
||||
heldItem.OwnInventory.TryPutItem(item, Character.Controlled))
|
||||
{
|
||||
success = true;
|
||||
for (int j = 0; j < capacity; j++)
|
||||
{
|
||||
if (Items[j] == character.SelectedItems[i]) slots[j].ShowBorderHighlight(GUI.Style.Green, 0.1f, 0.4f);
|
||||
if (slots[j].Contains(heldItem)) { visualSlots[j].ShowBorderHighlight(GUI.Style.Green, 0.1f, 0.4f); }
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1060,18 +1078,21 @@ namespace Barotrauma
|
||||
{
|
||||
for (int i = 0; i < capacity; i++)
|
||||
{
|
||||
if (Items[i] == item) slots[i].ShowBorderHighlight(GUI.Style.Green, 0.1f, 0.4f);
|
||||
if (slots[i].Contains(item)) { visualSlots[i].ShowBorderHighlight(GUI.Style.Green, 0.1f, 0.4f); }
|
||||
}
|
||||
}
|
||||
|
||||
draggingItem = null;
|
||||
DraggingItems.Clear();
|
||||
if (playSound)
|
||||
{
|
||||
SoundPlayer.PlayUISound(success ? GUISoundType.PickItem : GUISoundType.PickItemFail);
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawOwn(SpriteBatch spriteBatch)
|
||||
{
|
||||
if (!AccessibleWhenAlive && !character.IsDead) { return; }
|
||||
if (slots == null) { CreateSlots(); }
|
||||
if (visualSlots == null) { CreateSlots(); }
|
||||
if (GameMain.GraphicsWidth != screenResolution.X ||
|
||||
GameMain.GraphicsHeight != screenResolution.Y ||
|
||||
prevUIScale != UIScale ||
|
||||
@@ -1096,12 +1117,10 @@ namespace Barotrauma
|
||||
{
|
||||
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]);
|
||||
bool drawItem = !DraggingItems.Any() || !slots[i].Items.All(it => DraggingItems.Contains(it)) || visualSlots[i].MouseOn();
|
||||
|
||||
DrawSlot(spriteBatch, this, visualSlots[i], slots[i].FirstOrDefault(), i, drawItem, SlotTypes[i]);
|
||||
}
|
||||
|
||||
if (hideButton != null && hideButton.Visible && !Locked)
|
||||
@@ -1109,48 +1128,48 @@ namespace Barotrauma
|
||||
hideButton.DrawManually(spriteBatch, alsoChildren: true);
|
||||
}
|
||||
|
||||
InventorySlot highlightedQuickUseSlot = null;
|
||||
VisualSlot highlightedQuickUseSlot = null;
|
||||
Rectangle inventoryArea = Rectangle.Empty;
|
||||
|
||||
for (int i = 0; i < capacity; i++)
|
||||
{
|
||||
if (HideSlot(i)) { continue; }
|
||||
|
||||
inventoryArea = inventoryArea == Rectangle.Empty ? slots[i].InteractRect : Rectangle.Union(inventoryArea, slots[i].InteractRect);
|
||||
inventoryArea = inventoryArea == Rectangle.Empty ? visualSlots[i].InteractRect : Rectangle.Union(inventoryArea, visualSlots[i].InteractRect);
|
||||
|
||||
if (Items[i] == null ||
|
||||
(draggingItem == Items[i] && !slots[i].InteractRect.Contains(PlayerInput.MousePosition)) ||
|
||||
!Items[i].AllowedSlots.Any(a => a != InvSlotType.Any))
|
||||
if (slots[i].Empty() ||
|
||||
(DraggingItems.Any(it => slots[i].Contains(it)) && !visualSlots[i].InteractRect.Contains(PlayerInput.MousePosition)) ||
|
||||
!slots[i].First().AllowedSlots.Any(a => a != InvSlotType.Any))
|
||||
{
|
||||
//draw limb icons on empty slots
|
||||
if (LimbSlotIcons.ContainsKey(SlotTypes[i]))
|
||||
{
|
||||
var icon = LimbSlotIcons[SlotTypes[i]];
|
||||
icon.Draw(spriteBatch, slots[i].Rect.Center.ToVector2() + slots[i].DrawOffset, GUI.Style.EquipmentSlotIconColor, origin: icon.size / 2, scale: slots[i].Rect.Width / icon.size.X);
|
||||
icon.Draw(spriteBatch, visualSlots[i].Rect.Center.ToVector2() + visualSlots[i].DrawOffset, GUI.Style.EquipmentSlotIconColor, origin: icon.size / 2, scale: visualSlots[i].Rect.Width / icon.size.X);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (draggingItem == Items[i] && !slots[i].IsHighlighted) { continue; }
|
||||
if (DraggingItems.Any(it => slots[i].Contains(it)) && !visualSlots[i].IsHighlighted) { continue; }
|
||||
|
||||
//draw hand icons if the item is equipped in a hand slot
|
||||
if (IsInLimbSlot(Items[i], InvSlotType.LeftHand))
|
||||
if (IsInLimbSlot(slots[i].First(), 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);
|
||||
icon.Draw(spriteBatch, new Vector2(visualSlots[i].Rect.X, visualSlots[i].Rect.Bottom) + visualSlots[i].DrawOffset, Color.White * 0.6f, origin: new Vector2(icon.size.X * 0.35f, icon.size.Y * 0.75f), scale: visualSlots[i].Rect.Width / icon.size.X * 0.7f);
|
||||
}
|
||||
if (IsInLimbSlot(Items[i], InvSlotType.RightHand))
|
||||
if (IsInLimbSlot(slots[i].First(), 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);
|
||||
icon.Draw(spriteBatch, new Vector2(visualSlots[i].Rect.Right, visualSlots[i].Rect.Bottom) + visualSlots[i].DrawOffset, Color.White * 0.6f, origin: new Vector2(icon.size.X * 0.65f, icon.size.Y * 0.75f), scale: visualSlots[i].Rect.Width / icon.size.X * 0.7f);
|
||||
}
|
||||
|
||||
GUIComponent.ComponentState state = slots[i].EquipButtonState;
|
||||
GUIComponent.ComponentState state = visualSlots[i].EquipButtonState;
|
||||
if (state == GUIComponent.ComponentState.Hover)
|
||||
{
|
||||
highlightedQuickUseSlot = slots[i];
|
||||
highlightedQuickUseSlot = visualSlots[i];
|
||||
}
|
||||
|
||||
if (!Items[i].AllowedSlots.Any(a => a == InvSlotType.Any))
|
||||
if (!slots[i].First().AllowedSlots.Any(a => a == InvSlotType.Any))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -1161,20 +1180,20 @@ namespace Barotrauma
|
||||
color *= 0.5f;
|
||||
}
|
||||
|
||||
if (character.HasEquippedItem(Items[i]))
|
||||
if (character.HasEquippedItem(slots[i].First()))
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case GUIComponent.ComponentState.None:
|
||||
EquippedIndicator.Draw(spriteBatch, slots[i].EquipButtonRect.Center.ToVector2(), color, EquippedIndicator.Origin, 0, UIScale * IndicatorScaleAdjustment);
|
||||
EquippedIndicator.Draw(spriteBatch, visualSlots[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);
|
||||
EquippedHoverIndicator.Draw(spriteBatch, visualSlots[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);
|
||||
EquippedClickedIndicator.Draw(spriteBatch, visualSlots[i].EquipButtonRect.Center.ToVector2(), color, EquippedIndicator.Origin, 0, UIScale * IndicatorScaleAdjustment);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1183,15 +1202,15 @@ namespace Barotrauma
|
||||
switch (state)
|
||||
{
|
||||
case GUIComponent.ComponentState.None:
|
||||
UnequippedIndicator.Draw(spriteBatch, slots[i].EquipButtonRect.Center.ToVector2(), color, EquippedIndicator.Origin, 0, UIScale * IndicatorScaleAdjustment);
|
||||
UnequippedIndicator.Draw(spriteBatch, visualSlots[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);
|
||||
UnequippedHoverIndicator.Draw(spriteBatch, visualSlots[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);
|
||||
UnequippedClickedIndicator.Draw(spriteBatch, visualSlots[i].EquipButtonRect.Center.ToVector2(), color, EquippedIndicator.Origin, 0, UIScale * IndicatorScaleAdjustment);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,8 +12,6 @@ namespace Barotrauma.Items.Components
|
||||
get { return item.Rect.Size.ToVector2(); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, bool editing, float itemDepth = -1)
|
||||
{
|
||||
if (!IsActive || picker == null || !CanBeAttached(picker) || !picker.IsKeyDown(InputType.Aim) || picker != Character.Controlled)
|
||||
@@ -49,7 +47,7 @@ namespace Barotrauma.Items.Components
|
||||
attachPos += item.Submarine.Position;
|
||||
}
|
||||
|
||||
Submarine.DrawGrid(spriteBatch, 14, gridPos, roundedGridPos, alpha: 0.7f);
|
||||
Submarine.DrawGrid(spriteBatch, 14, gridPos, roundedGridPos, alpha: 0.4f);
|
||||
|
||||
item.Sprite.Draw(
|
||||
spriteBatch,
|
||||
|
||||
@@ -130,7 +130,7 @@ namespace Barotrauma.Items.Components
|
||||
if (body.UserData is Item item)
|
||||
{
|
||||
var door = item.GetComponent<Door>();
|
||||
if (door != null && door.IsOpen || door.IsBroken) continue;
|
||||
if (door != null && door.CanBeTraversed) { continue; }
|
||||
}
|
||||
|
||||
targetHull = null;
|
||||
@@ -239,7 +239,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (targetSections.Count == 0) { return; }
|
||||
|
||||
Item liquidItem = liquidContainer?.Inventory.Items[0];
|
||||
Item liquidItem = liquidContainer?.Inventory.FirstOrDefault();
|
||||
if (liquidItem == null) { return; }
|
||||
|
||||
bool isCleaning = false;
|
||||
|
||||
@@ -15,7 +15,8 @@ namespace Barotrauma.Items.Components
|
||||
Random,
|
||||
CharacterSpecific,
|
||||
ItemSpecific,
|
||||
All
|
||||
All,
|
||||
Manual
|
||||
}
|
||||
|
||||
class ItemSound
|
||||
@@ -259,6 +260,7 @@ namespace Barotrauma.Items.Components
|
||||
loopingSoundChannel = null;
|
||||
loopingSound = null;
|
||||
}
|
||||
|
||||
if (loopingSoundChannel == null || !loopingSoundChannel.IsPlaying)
|
||||
{
|
||||
loopingSoundChannel = loopingSound.RoundSound.Sound.Play(
|
||||
@@ -271,6 +273,21 @@ namespace Barotrauma.Items.Components
|
||||
loopingSoundChannel.Near = loopingSound.Range * 0.4f;
|
||||
loopingSoundChannel.Far = loopingSound.Range;
|
||||
}
|
||||
|
||||
// Looping sound with manual selection mode should be changed if value of ManuallySelectedSound has changed
|
||||
// Otherwise the sound won't change until the sound condition (such as being active) is disabled and re-enabled
|
||||
if (loopingSoundChannel != null && loopingSoundChannel.IsPlaying && soundSelectionModes[type] == SoundSelectionMode.Manual)
|
||||
{
|
||||
var playingIndex = sounds[type].IndexOf(loopingSound);
|
||||
var shouldBePlayingIndex = Math.Clamp(ManuallySelectedSound, 0, sounds[type].Count);
|
||||
if (playingIndex != shouldBePlayingIndex)
|
||||
{
|
||||
loopingSoundChannel.FadeOutAndDispose();
|
||||
loopingSoundChannel = null;
|
||||
loopingSound = null;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -295,6 +312,10 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (soundSelectionMode == SoundSelectionMode.Manual)
|
||||
{
|
||||
index = Math.Clamp(ManuallySelectedSound, 0, matchingSounds.Count);
|
||||
}
|
||||
else
|
||||
{
|
||||
index = Rand.Int(matchingSounds.Count);
|
||||
@@ -335,7 +356,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
float volume = GetSoundVolume(itemSound);
|
||||
if (volume <= 0.0001f) { return; }
|
||||
var channel = SoundPlayer.PlaySound(itemSound.RoundSound.Sound, position, volume, itemSound.Range, itemSound.RoundSound.GetRandomFrequencyMultiplier(), item.CurrentHull);
|
||||
var channel = SoundPlayer.PlaySound(itemSound.RoundSound.Sound, position, volume, itemSound.Range, itemSound.RoundSound.GetRandomFrequencyMultiplier(), item.CurrentHull, ignoreMuffling: itemSound.RoundSound.IgnoreMuffling);
|
||||
if (channel != null) { playingOneshotSoundChannels.Add(channel); }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
@@ -32,6 +33,12 @@ namespace Barotrauma.Items.Components
|
||||
private set;
|
||||
}
|
||||
|
||||
public Sprite ContainedStateIndicatorEmpty
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
[Editable]
|
||||
#endif
|
||||
@@ -55,6 +62,11 @@ namespace Barotrauma.Items.Components
|
||||
[Serialize(null, false, description: "An optional text displayed above the item's inventory.")]
|
||||
public string UILabel { get; set; }
|
||||
|
||||
public GUIComponentStyle IndicatorStyle { get; set; }
|
||||
|
||||
[Serialize(null, false)]
|
||||
public string ContainedStateIndicatorStyle { get; set; }
|
||||
|
||||
[Serialize(true, false, description: "Should an indicator displaying the state of the contained items be displayed on this item's inventory slot. "+
|
||||
"If this item can only contain one item, the indicator will display the condition of the contained item, otherwise it will indicate how full the item is.")]
|
||||
public bool ShowContainedStateIndicator { get; set; }
|
||||
@@ -98,6 +110,26 @@ namespace Barotrauma.Items.Components
|
||||
case "containedstateindicator":
|
||||
ContainedStateIndicator = new Sprite(subElement);
|
||||
break;
|
||||
case "containedstateindicatorempty":
|
||||
ContainedStateIndicatorEmpty = new Sprite(subElement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(ContainedStateIndicatorStyle))
|
||||
{
|
||||
//if neither a style or a custom sprite is defined, use default style
|
||||
if (ContainedStateIndicator == null)
|
||||
{
|
||||
IndicatorStyle = GUI.Style.GetComponentStyle("ContainedStateIndicator.Default");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IndicatorStyle = GUI.Style.GetComponentStyle("ContainedStateIndicator." + ContainedStateIndicatorStyle);
|
||||
if (ContainedStateIndicator != null || ContainedStateIndicatorEmpty != null)
|
||||
{
|
||||
DebugConsole.AddWarning($"Item \"{item.Name}\" defines both a contained state indicator style and a custom indicator sprite. Will use the custom sprite...");
|
||||
}
|
||||
}
|
||||
if (GuiFrame == null)
|
||||
@@ -173,16 +205,10 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
//if holding 2 different "always open" items in different hands, don't force them to stay open
|
||||
if (character.SelectedItems[0] != null &&
|
||||
character.SelectedItems[1] != null &&
|
||||
character.SelectedItems[0] != character.SelectedItems[1])
|
||||
{
|
||||
if ((character.SelectedItems[0].GetComponent<ItemContainer>()?.KeepOpenWhenEquipped ?? false) &&
|
||||
(character.SelectedItems[1].GetComponent<ItemContainer>()?.KeepOpenWhenEquipped ?? false))
|
||||
if (character.HeldItems.Count() > 1 && character.HeldItems.All(it => it.GetComponent<ItemContainer>()?.KeepOpenWhenEquipped ?? false))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -260,10 +286,8 @@ namespace Barotrauma.Items.Components
|
||||
bool isWiringMode = SubEditorScreen.TransparentWiringMode && SubEditorScreen.IsWiringMode();
|
||||
|
||||
int i = 0;
|
||||
foreach (Item containedItem in Inventory.Items)
|
||||
foreach (Item containedItem in Inventory.AllItems)
|
||||
{
|
||||
if (containedItem == null) continue;
|
||||
|
||||
if (AutoInteractWithContained)
|
||||
{
|
||||
containedItem.IsHighlighted = item.IsHighlighted;
|
||||
@@ -313,7 +337,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public override void UpdateHUD(Character character, float deltaTime, Camera cam)
|
||||
{
|
||||
if (item.NonInteractable) { return; }
|
||||
if (!item.IsInteractable(character)) { return; }
|
||||
if (Inventory.RectTransform != null)
|
||||
{
|
||||
guiCustomComponent.RectTransform.Parent = Inventory.RectTransform;
|
||||
|
||||
@@ -21,11 +21,17 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private float[] charWidths;
|
||||
|
||||
private Vector4 padding;
|
||||
|
||||
[Serialize("0,0,0,0", true, description: "The amount of padding around the text in pixels (left,top,right,bottom).")]
|
||||
public Vector4 Padding
|
||||
{
|
||||
get { return TextBlock.Padding; }
|
||||
set { TextBlock.Padding = value; }
|
||||
get { return padding; }
|
||||
set
|
||||
{
|
||||
padding = value;
|
||||
TextBlock.Padding = value * item.Scale;
|
||||
}
|
||||
}
|
||||
|
||||
private string text;
|
||||
@@ -43,13 +49,20 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
text = value;
|
||||
DisplayText = TextManager.Get(text, returnNull: true) ?? value;
|
||||
TextBlock.Text = DisplayText;
|
||||
if (Screen.Selected == GameMain.SubEditorScreen && Scrollable)
|
||||
{
|
||||
TextBlock.Text = ToolBox.LimitString(DisplayText, textBlock.Font, item.Rect.Width);
|
||||
SetDisplayText(value);
|
||||
}
|
||||
SetScrollingText();
|
||||
}
|
||||
|
||||
private bool ignoreLocalization;
|
||||
|
||||
[Editable, Serialize(false, true, "Whether or not to skip localization and always display the raw value.")]
|
||||
public bool IgnoreLocalization
|
||||
{
|
||||
get => ignoreLocalization;
|
||||
set
|
||||
{
|
||||
ignoreLocalization = value;
|
||||
SetDisplayText(Text);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,13 +120,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (textBlock == null)
|
||||
{
|
||||
textBlock = new GUITextBlock(new RectTransform(item.Rect.Size), "",
|
||||
textColor: textColor, font: GUI.UnscaledSmallFont, textAlignment: scrollable ? Alignment.CenterLeft : Alignment.Center, wrap: true, style: null)
|
||||
{
|
||||
TextDepth = item.SpriteDepth - 0.00001f,
|
||||
RoundToNearestPixel = false,
|
||||
TextScale = TextScale
|
||||
};
|
||||
RecreateTextBlock();
|
||||
}
|
||||
return textBlock;
|
||||
}
|
||||
@@ -126,7 +133,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private void SetScrollingText()
|
||||
{
|
||||
if (!scrollable) return;
|
||||
if (!scrollable) { return; }
|
||||
|
||||
float totalWidth = textBlock.Font.MeasureString(DisplayText).X;
|
||||
float textAreaWidth = Math.Max(textBlock.Rect.Width - textBlock.Padding.X - textBlock.Padding.Z, 0);
|
||||
@@ -143,6 +150,7 @@ namespace Barotrauma.Items.Components
|
||||
//whole text can fit in the textblock, no need to scroll
|
||||
needsScrolling = false;
|
||||
scrollingText = DisplayText;
|
||||
scrollPadding = 0;
|
||||
scrollAmount = 0.0f;
|
||||
scrollIndex = 0;
|
||||
return;
|
||||
@@ -161,16 +169,40 @@ namespace Barotrauma.Items.Components
|
||||
scrollIndex = MathHelper.Clamp(scrollIndex, 0, DisplayText.Length);
|
||||
}
|
||||
|
||||
private void SetDisplayText(string value)
|
||||
{
|
||||
DisplayText = IgnoreLocalization ? value : TextManager.Get(value, returnNull: true) ?? value;
|
||||
TextBlock.Text = DisplayText;
|
||||
if (Screen.Selected == GameMain.SubEditorScreen && Scrollable)
|
||||
{
|
||||
TextBlock.Text = ToolBox.LimitString(DisplayText, TextBlock.Font, item.Rect.Width);
|
||||
}
|
||||
|
||||
SetScrollingText();
|
||||
}
|
||||
|
||||
private void RecreateTextBlock()
|
||||
{
|
||||
textBlock = new GUITextBlock(new RectTransform(item.Rect.Size), "",
|
||||
textColor: textColor, font: GUI.UnscaledSmallFont, textAlignment: scrollable ? Alignment.CenterLeft : Alignment.Center, wrap: !scrollable, style: null)
|
||||
{
|
||||
TextDepth = item.SpriteDepth - 0.00001f,
|
||||
RoundToNearestPixel = false,
|
||||
TextScale = TextScale,
|
||||
Padding = padding * item.Scale
|
||||
};
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
if (!scrollable) return;
|
||||
if (!scrollable) { return; }
|
||||
|
||||
if (scrollingText == null)
|
||||
{
|
||||
SetScrollingText();
|
||||
}
|
||||
|
||||
if (!needsScrolling) return;
|
||||
if (!needsScrolling) { return; }
|
||||
|
||||
scrollAmount -= deltaTime * ScrollSpeed;
|
||||
|
||||
@@ -207,8 +239,30 @@ namespace Barotrauma.Items.Components
|
||||
TextBlock.Text = sb.ToString();
|
||||
}
|
||||
|
||||
public override void OnScaleChanged()
|
||||
{
|
||||
RecreateTextBlock();
|
||||
SetDisplayText(Text);
|
||||
prevScale = item.Scale;
|
||||
prevRect = item.Rect;
|
||||
}
|
||||
|
||||
private float prevScale;
|
||||
private Rectangle prevRect;
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, bool editing = false, float itemDepth = -1)
|
||||
{
|
||||
if (editing)
|
||||
{
|
||||
if (!MathUtils.NearlyEqual(prevScale, item.Scale) || prevRect != item.Rect)
|
||||
{
|
||||
RecreateTextBlock();
|
||||
SetDisplayText(Text);
|
||||
prevScale = item.Scale;
|
||||
prevRect = item.Rect;
|
||||
}
|
||||
}
|
||||
|
||||
var drawPos = new Vector2(
|
||||
item.DrawPosition.X - item.Rect.Width / 2.0f,
|
||||
-(item.DrawPosition.Y + item.Rect.Height / 2.0f));
|
||||
@@ -223,7 +277,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
textBlock.TextDepth = item.SpriteDepth - 0.0001f;
|
||||
textBlock.TextOffset = drawPos - textBlock.Rect.Location.ToVector2() + new Vector2(scrollAmount + scrollPadding, 0.0f);
|
||||
textBlock.TextOffset = drawPos - textBlock.Rect.Location.ToVector2() + (editing ? Vector2.Zero : new Vector2(scrollAmount + scrollPadding, 0.0f));
|
||||
textBlock.DrawManually(spriteBatch);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,12 +38,6 @@ namespace Barotrauma.Items.Components
|
||||
light.Color = LightColor.Multiply(brightness);
|
||||
}
|
||||
|
||||
public override void OnItemLoaded()
|
||||
{
|
||||
base.OnItemLoaded();
|
||||
SetLightSourceState(IsActive, lightBrightness);
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, bool editing = false, float itemDepth = -1)
|
||||
{
|
||||
if (light.LightSprite != null && (item.body == null || item.body.Enabled) && lightBrightness > 0.0f && IsOn)
|
||||
@@ -51,7 +45,7 @@ namespace Barotrauma.Items.Components
|
||||
Vector2 origin = light.LightSprite.Origin;
|
||||
if ((light.LightSpriteEffect & SpriteEffects.FlipHorizontally) == SpriteEffects.FlipHorizontally) { origin.X = light.LightSprite.SourceRect.Width - origin.X; }
|
||||
if ((light.LightSpriteEffect & SpriteEffects.FlipVertically) == SpriteEffects.FlipVertically) { origin.Y = light.LightSprite.SourceRect.Height - origin.Y; }
|
||||
light.LightSprite.Draw(spriteBatch, new Vector2(item.DrawPosition.X, -item.DrawPosition.Y), lightColor * lightBrightness, origin, -light.Rotation, item.Scale, light.LightSpriteEffect, item.SpriteDepth - 0.0001f);
|
||||
light.LightSprite.Draw(spriteBatch, new Vector2(item.DrawPosition.X, -item.DrawPosition.Y), lightColor * lightBrightness, origin, -light.Rotation, item.Scale, light.LightSpriteEffect, itemDepth - 0.0001f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -95,11 +95,11 @@ namespace Barotrauma.Items.Components
|
||||
// TODO, This works fine as of now but if GUI.PreventElementOverlap ever gets fixed this block of code may become obsolete or detrimental.
|
||||
// Only do this if there's only one linked component. If you link more containers then may
|
||||
// GUI.PreventElementOverlap have mercy on your HUD layout
|
||||
if (GuiFrame != null && item.linkedTo.Count(entity => entity is Item item && item.DisplaySideBySideWhenLinked) == 1)
|
||||
if (GuiFrame != null && item.linkedTo.Count(entity => entity is Item { DisplaySideBySideWhenLinked: true }) == 1)
|
||||
{
|
||||
foreach (MapEntity linkedTo in item.linkedTo)
|
||||
{
|
||||
if (!(linkedTo is Item linkedItem) || !linkedItem.DisplaySideBySideWhenLinked) { continue; }
|
||||
if (!(linkedTo is Item { DisplaySideBySideWhenLinked: true } linkedItem)) { continue; }
|
||||
if (!linkedItem.Components.Any()) { continue; }
|
||||
|
||||
var itemContainer = linkedItem.GetComponent<ItemContainer>();
|
||||
@@ -108,8 +108,8 @@ namespace Barotrauma.Items.Components
|
||||
// how much spacing do we want between the components
|
||||
var padding = (int) (8 * GUI.Scale);
|
||||
// Move the linked container to the right and move the deconstructor to the left
|
||||
itemContainer.GuiFrame.RectTransform.AbsoluteOffset = new Point(100, 0);
|
||||
GuiFrame.RectTransform.AbsoluteOffset = new Point(-100, 0);
|
||||
itemContainer.GuiFrame.RectTransform.AbsoluteOffset = new Point(GuiFrame.Rect.Width / -2 - padding, 0);
|
||||
GuiFrame.RectTransform.AbsoluteOffset = new Point(itemContainer.GuiFrame.Rect.Width / 2 + padding, 0);
|
||||
}
|
||||
}
|
||||
return base.Select(character);
|
||||
@@ -126,7 +126,7 @@ namespace Barotrauma.Items.Components
|
||||
private void DrawOverLay(SpriteBatch spriteBatch, GUICustomComponent overlayComponent)
|
||||
{
|
||||
overlayComponent.RectTransform.SetAsLastChild();
|
||||
var lastSlot = inputContainer.Inventory.slots.Last();
|
||||
var lastSlot = inputContainer.Inventory.visualSlots.Last();
|
||||
|
||||
GUI.DrawRectangle(spriteBatch,
|
||||
new Rectangle(
|
||||
|
||||
@@ -144,16 +144,15 @@ namespace Barotrauma.Items.Components
|
||||
Vector2 drawPos = item.DrawPosition;
|
||||
drawPos += PropellerPos;
|
||||
drawPos.Y = -drawPos.Y;
|
||||
|
||||
propellerSprite.Draw(spriteBatch, (int)Math.Floor(spriteIndex), drawPos, Color.White, propellerSprite.Origin, 0.0f, Vector2.One);
|
||||
}
|
||||
|
||||
if (editing && !GUI.DisableHUD)
|
||||
if (editing && !DisablePropellerDamage && propellerDamage != null && !GUI.DisableHUD)
|
||||
{
|
||||
Vector2 drawPos = item.DrawPosition;
|
||||
drawPos += PropellerPos;
|
||||
drawPos += PropellerPos * item.Scale;
|
||||
drawPos.Y = -drawPos.Y;
|
||||
GUI.DrawRectangle(spriteBatch, drawPos - Vector2.One * 10, Vector2.One * 20, GUI.Style.Red);
|
||||
spriteBatch.DrawCircle(drawPos, propellerDamage.DamageRange * item.Scale, 16, GUI.Style.Red, thickness: 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -190,7 +190,7 @@ namespace Barotrauma.Items.Components
|
||||
};
|
||||
}
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.85f, 1f), container.RectTransform), fi.DisplayName)
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.85f, 1f), container.RectTransform), GetRecipeNameAndAmount(fi))
|
||||
{
|
||||
Padding = Vector4.Zero,
|
||||
AutoScaleVertical = true,
|
||||
@@ -199,6 +199,21 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
private string GetRecipeNameAndAmount(FabricationRecipe fabricationRecipe)
|
||||
{
|
||||
if (fabricationRecipe == null) { return ""; }
|
||||
if (fabricationRecipe.Amount > 1)
|
||||
{
|
||||
return TextManager.GetWithVariables("fabricationrecipenamewithamount",
|
||||
new string[2] { "[name]", "[amount]" },
|
||||
new string[2] { fabricationRecipe.DisplayName, fabricationRecipe.Amount.ToString() });
|
||||
}
|
||||
else
|
||||
{
|
||||
return fabricationRecipe.DisplayName;
|
||||
}
|
||||
}
|
||||
|
||||
partial void OnItemLoadedProjSpecific()
|
||||
{
|
||||
inputContainer.AllowUIOverlap = true;
|
||||
@@ -212,11 +227,11 @@ namespace Barotrauma.Items.Components
|
||||
// TODO, This works fine as of now but if GUI.PreventElementOverlap ever gets fixed this block of code may become obsolete or detrimental.
|
||||
// Only do this if there's only one linked component. If you link more containers then may
|
||||
// GUI.PreventElementOverlap have mercy on your HUD layout
|
||||
if (GuiFrame != null && item.linkedTo.Count(entity => entity is Item item && item.DisplaySideBySideWhenLinked) == 1)
|
||||
if (GuiFrame != null && item.linkedTo.Count(entity => entity is Item { DisplaySideBySideWhenLinked: true }) == 1)
|
||||
{
|
||||
foreach (MapEntity linkedTo in item.linkedTo)
|
||||
{
|
||||
if (!(linkedTo is Item linkedItem) || !linkedItem.DisplaySideBySideWhenLinked) { continue; }
|
||||
if (!(linkedTo is Item { DisplaySideBySideWhenLinked: true } linkedItem)) { continue; }
|
||||
if (!linkedItem.Components.Any()) { continue; }
|
||||
|
||||
var itemContainer = linkedItem.GetComponent<ItemContainer>();
|
||||
@@ -225,8 +240,8 @@ namespace Barotrauma.Items.Components
|
||||
// how much spacing do we want between the components
|
||||
var padding = (int) (8 * GUI.Scale);
|
||||
// Move the linked container to the right and move the fabricator to the left
|
||||
itemContainer.GuiFrame.RectTransform.AbsoluteOffset = new Point(-100, 0);
|
||||
GuiFrame.RectTransform.AbsoluteOffset = new Point(100, 0);
|
||||
itemContainer.GuiFrame.RectTransform.AbsoluteOffset = new Point(GuiFrame.Rect.Width / -2 - padding, 0);
|
||||
GuiFrame.RectTransform.AbsoluteOffset = new Point(itemContainer.GuiFrame.Rect.Width / 2 + padding, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,9 +302,8 @@ namespace Barotrauma.Items.Components
|
||||
missingItems.Add(requiredItem);
|
||||
}
|
||||
}
|
||||
foreach (Item item in inputContainer.Inventory.Items)
|
||||
foreach (Item item in inputContainer.Inventory.AllItems)
|
||||
{
|
||||
if (item == null) { continue; }
|
||||
missingItems.Remove(missingItems.FirstOrDefault(mi => mi.ItemPrefabs.Contains(item.prefab)));
|
||||
}
|
||||
|
||||
@@ -297,7 +311,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
foreach (FabricationRecipe.RequiredItem requiredItem in missingItems)
|
||||
{
|
||||
while (slotIndex < inputContainer.Capacity && inputContainer.Inventory.Items[slotIndex] != null)
|
||||
while (slotIndex < inputContainer.Capacity && inputContainer.Inventory.GetItemAt(slotIndex) != null)
|
||||
{
|
||||
slotIndex++;
|
||||
}
|
||||
@@ -307,17 +321,17 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (item.ParentInventory != inputContainer.Inventory && IsItemValidIngredient(item, requiredItem))
|
||||
{
|
||||
int availableSlotIndex = Array.IndexOf(item.ParentInventory.Items, item);
|
||||
int availableSlotIndex = item.ParentInventory.FindIndex(item);
|
||||
//slots are null if the inventory has never been displayed
|
||||
//(linked item, but the UI is not set to be displayed at the same time)
|
||||
if (item.ParentInventory.slots != null)
|
||||
if (item.ParentInventory.visualSlots != null)
|
||||
{
|
||||
if (item.ParentInventory.slots[availableSlotIndex].HighlightTimer <= 0.0f)
|
||||
if (item.ParentInventory.visualSlots[availableSlotIndex].HighlightTimer <= 0.0f)
|
||||
{
|
||||
item.ParentInventory.slots[availableSlotIndex].ShowBorderHighlight(GUI.Style.Green, 0.5f, 0.5f, 0.2f);
|
||||
item.ParentInventory.visualSlots[availableSlotIndex].ShowBorderHighlight(GUI.Style.Green, 0.5f, 0.5f, 0.2f);
|
||||
if (slotIndex < inputContainer.Capacity)
|
||||
{
|
||||
inputContainer.Inventory.slots[slotIndex].ShowBorderHighlight(GUI.Style.Green, 0.5f, 0.5f, 0.2f);
|
||||
inputContainer.Inventory.visualSlots[slotIndex].ShowBorderHighlight(GUI.Style.Green, 0.5f, 0.5f, 0.2f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -327,7 +341,7 @@ namespace Barotrauma.Items.Components
|
||||
if (slotIndex >= inputContainer.Capacity) { break; }
|
||||
|
||||
var itemIcon = requiredItem.ItemPrefabs.First().InventoryIcon ?? requiredItem.ItemPrefabs.First().sprite;
|
||||
Rectangle slotRect = inputContainer.Inventory.slots[slotIndex].Rect;
|
||||
Rectangle slotRect = inputContainer.Inventory.visualSlots[slotIndex].Rect;
|
||||
itemIcon.Draw(
|
||||
spriteBatch,
|
||||
slotRect.Center.ToVector2(),
|
||||
@@ -367,14 +381,12 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
overlayComponent.RectTransform.SetAsLastChild();
|
||||
|
||||
if (outputContainer.Inventory.Items.First() != null) { return; }
|
||||
|
||||
FabricationRecipe targetItem = fabricatedItem ?? selectedItem;
|
||||
if (targetItem != null)
|
||||
{
|
||||
var itemIcon = targetItem.TargetItem.InventoryIcon ?? targetItem.TargetItem.sprite;
|
||||
|
||||
Rectangle slotRect = outputContainer.Inventory.slots[0].Rect;
|
||||
Rectangle slotRect = outputContainer.Inventory.visualSlots[0].Rect;
|
||||
|
||||
if (fabricatedItem != null)
|
||||
{
|
||||
@@ -449,8 +461,10 @@ namespace Barotrauma.Items.Components
|
||||
Color = selectedItem.TargetItem.InventoryIconColor
|
||||
};
|
||||
}*/
|
||||
|
||||
|
||||
var nameBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedFrame.RectTransform),
|
||||
selectedItem.TargetItem.Name, textAlignment: Alignment.CenterLeft, textColor: Color.Aqua, font: GUI.SubHeadingFont)
|
||||
GetRecipeNameAndAmount(selectedItem), textAlignment: Alignment.CenterLeft, textColor: Color.Aqua, font: GUI.SubHeadingFont)
|
||||
{
|
||||
AutoScaleHorizontal = true
|
||||
};
|
||||
@@ -539,7 +553,7 @@ namespace Barotrauma.Items.Components
|
||||
private bool StartButtonClicked(GUIButton button, object obj)
|
||||
{
|
||||
if (selectedItem == null) { return false; }
|
||||
if (!outputContainer.Inventory.IsEmpty())
|
||||
if (fabricatedItem == null && !outputContainer.Inventory.CanBePut(selectedItem.TargetItem))
|
||||
{
|
||||
outputSlot.Flash(GUI.Style.Red);
|
||||
return false;
|
||||
|
||||
@@ -71,10 +71,14 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private float showDirectionalIndicatorTimer;
|
||||
|
||||
private List<LevelObject> nearbyObjects = new List<LevelObject>();
|
||||
private readonly List<LevelObject> nearbyObjects = new List<LevelObject>();
|
||||
private const float NearbyObjectUpdateInterval = 1.0f;
|
||||
float nearbyObjectUpdateTimer;
|
||||
|
||||
private List<Submarine> connectedSubs = new List<Submarine>();
|
||||
private const float ConnectedSubUpdateInterval = 1.0f;
|
||||
float connectedSubUpdateTimer;
|
||||
|
||||
//Vector2 = vector from the ping source to the position of the disruption
|
||||
//float = strength of the disruption, between 0-1
|
||||
private readonly List<Pair<Vector2, float>> disruptedDirections = new List<Pair<Vector2, float>>();
|
||||
@@ -135,6 +139,8 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private bool isConnectedToSteering;
|
||||
|
||||
private static string caveLabel;
|
||||
|
||||
private bool AllowUsingMineralScanner =>
|
||||
HasMineralScanner && !isConnectedToSteering;
|
||||
|
||||
@@ -143,6 +149,10 @@ namespace Barotrauma.Items.Components
|
||||
System.Diagnostics.Debug.Assert(Enum.GetValues(typeof(BlipType)).Cast<BlipType>().All(t => blipColorGradient.ContainsKey(t)));
|
||||
sonarBlips = new List<SonarBlip>();
|
||||
|
||||
caveLabel =
|
||||
TextManager.Get("cave", returnNull: true) ??
|
||||
TextManager.Get("missiontype.nest");
|
||||
|
||||
foreach (XElement subElement in element.Elements())
|
||||
{
|
||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||
@@ -413,6 +423,26 @@ namespace Barotrauma.Items.Components
|
||||
networkUpdateTimer -= deltaTime;
|
||||
}
|
||||
|
||||
connectedSubUpdateTimer -= deltaTime;
|
||||
if (connectedSubUpdateTimer <= 0.0f)
|
||||
{
|
||||
connectedSubs.Clear();
|
||||
if (UseTransducers)
|
||||
{
|
||||
foreach (var transducer in connectedTransducers)
|
||||
{
|
||||
if (transducer.Transducer.Item.Submarine == null) { continue; }
|
||||
if (connectedSubs.Contains(transducer.Transducer.Item.Submarine)) { continue; }
|
||||
connectedSubs = transducer.Transducer.Item.Submarine?.GetConnectedSubs();
|
||||
}
|
||||
}
|
||||
else if (item.Submarine != null)
|
||||
{
|
||||
connectedSubs = item.Submarine?.GetConnectedSubs();
|
||||
}
|
||||
connectedSubUpdateTimer = ConnectedSubUpdateInterval;
|
||||
}
|
||||
|
||||
if (sonarView.Rect.Contains(PlayerInput.MousePosition))
|
||||
{
|
||||
float scrollSpeed = PlayerInput.ScrollWheelSpeed / 1000.0f;
|
||||
@@ -848,10 +878,22 @@ namespace Barotrauma.Items.Components
|
||||
displayScale, center, DisplayRadius);
|
||||
}
|
||||
|
||||
for (int i = 0; i < Level.Loaded.Caves.Count; i++)
|
||||
{
|
||||
var cave = Level.Loaded.Caves[i];
|
||||
if (!cave.DisplayOnSonar) { continue; }
|
||||
DrawMarker(spriteBatch,
|
||||
caveLabel,
|
||||
"cave",
|
||||
"cave" + i,
|
||||
cave.StartPos.ToVector2(), transducerCenter,
|
||||
displayScale, center, DisplayRadius);
|
||||
}
|
||||
|
||||
foreach (AITarget aiTarget in AITarget.List)
|
||||
{
|
||||
if (!aiTarget.Enabled) continue;
|
||||
if (string.IsNullOrEmpty(aiTarget.SonarLabel) || aiTarget.SoundRange <= 0.0f) continue;
|
||||
if (!aiTarget.Enabled) { continue; }
|
||||
if (string.IsNullOrEmpty(aiTarget.SonarLabel) || aiTarget.SoundRange <= 0.0f) { continue; }
|
||||
|
||||
if (Vector2.DistanceSquared(aiTarget.WorldPosition, transducerCenter) < aiTarget.SoundRange * aiTarget.SoundRange)
|
||||
{
|
||||
@@ -902,12 +944,7 @@ namespace Barotrauma.Items.Components
|
||||
foreach (Submarine sub in Submarine.Loaded)
|
||||
{
|
||||
if (!sub.ShowSonarMarker) { continue; }
|
||||
if (UseTransducers ?
|
||||
connectedTransducers.Any(t => sub == t.Transducer.Item.Submarine || sub.DockedTo.Contains(t.Transducer.Item.Submarine)) :
|
||||
(sub == item.Submarine || sub.DockedTo.Contains(item.Submarine)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (connectedSubs.Contains(sub)) { continue; }
|
||||
if (sub.WorldPosition.Y > Level.Loaded.Size.Y) { continue; }
|
||||
|
||||
DrawMarker(spriteBatch,
|
||||
@@ -931,10 +968,8 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
foreach (Submarine submarine in Submarine.Loaded)
|
||||
{
|
||||
if (UseTransducers ?
|
||||
!connectedTransducers.Any(t => submarine == t.Transducer.Item.Submarine || submarine.DockedTo.Contains(t.Transducer.Item.Submarine)) :
|
||||
submarine != item.Submarine && !submarine.DockedTo.Contains(item.Submarine)) continue;
|
||||
if (submarine.HullVertices == null) continue;
|
||||
if (!connectedSubs.Contains(submarine)) { continue; }
|
||||
if (submarine.HullVertices == null) { continue; }
|
||||
|
||||
Vector2 offset = ConvertUnits.ToSimUnits(submarine.WorldPosition - transducerCenter);
|
||||
|
||||
@@ -1018,8 +1053,8 @@ namespace Barotrauma.Items.Components
|
||||
//don't show the docking ports of the opposing team on the sonar
|
||||
if (item.Submarine != null)
|
||||
{
|
||||
if ((dockingPort.Item.Submarine.TeamID == Character.TeamType.Team1 && item.Submarine.TeamID == Character.TeamType.Team2) ||
|
||||
(dockingPort.Item.Submarine.TeamID == Character.TeamType.Team2 && item.Submarine.TeamID == Character.TeamType.Team1))
|
||||
if ((dockingPort.Item.Submarine.TeamID == CharacterTeamType.Team1 && item.Submarine.TeamID == CharacterTeamType.Team2) ||
|
||||
(dockingPort.Item.Submarine.TeamID == CharacterTeamType.Team2 && item.Submarine.TeamID == CharacterTeamType.Team1))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -1226,19 +1261,10 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
foreach (Submarine submarine in Submarine.Loaded)
|
||||
{
|
||||
if (submarine.HullVertices == null) continue;
|
||||
if (submarine.HullVertices == null) { continue; }
|
||||
if (!DetectSubmarineWalls)
|
||||
{
|
||||
if (UseTransducers)
|
||||
{
|
||||
if (connectedTransducers.Any(t => submarine == t.Transducer.Item.Submarine ||
|
||||
submarine.DockedTo.Contains(t.Transducer.Item.Submarine))) continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (item.Submarine == submarine) continue;
|
||||
if (item.Submarine != null && item.Submarine.DockedTo.Contains(submarine)) continue;
|
||||
}
|
||||
if (connectedSubs.Contains(submarine)) { continue; }
|
||||
}
|
||||
|
||||
for (int i = 0; i < submarine.HullVertices.Count; i++)
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private GUIComponent steerArea;
|
||||
|
||||
private GUITextBlock pressureWarningText;
|
||||
private GUITextBlock pressureWarningText, iceSpireWarningText;
|
||||
|
||||
private GUITextBlock tipContainer;
|
||||
|
||||
@@ -311,6 +311,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
Vector2 vel = controlledSub == null ? Vector2.Zero : controlledSub.Velocity;
|
||||
var realWorldVel = ConvertUnits.ToDisplayUnits(vel.X * Physics.DisplayToRealWorldRatio) * 3.6f;
|
||||
if (controlledSub != null && controlledSub.FlippedX) { realWorldVel *= -1; }
|
||||
return ((int)realWorldVel).ToString();
|
||||
};
|
||||
break;
|
||||
@@ -440,8 +441,13 @@ namespace Barotrauma.Items.Components
|
||||
(spriteBatch, guiCustomComponent) => { DrawHUD(spriteBatch, guiCustomComponent.Rect); }, null);
|
||||
steerRadius = steerArea.Rect.Width / 2;
|
||||
|
||||
pressureWarningText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.25f), steerArea.RectTransform, Anchor.Center, Pivot.TopCenter),
|
||||
TextManager.Get("SteeringDepthWarning"), Color.Red, GUI.LargeFont, Alignment.Center)
|
||||
iceSpireWarningText = new GUITextBlock(new RectTransform(new Vector2(0.5f, 0.25f), steerArea.RectTransform, Anchor.Center, Pivot.TopCenter),
|
||||
TextManager.Get("NavTerminalIceSpireWarning"), GUI.Style.Red, GUI.SubHeadingFont, Alignment.Center, color: Color.Black * 0.8f, wrap: true)
|
||||
{
|
||||
Visible = false
|
||||
};
|
||||
pressureWarningText = new GUITextBlock(new RectTransform(new Vector2(0.5f, 0.25f), steerArea.RectTransform, Anchor.Center, Pivot.TopCenter),
|
||||
TextManager.Get("SteeringDepthWarning"), GUI.Style.Red, GUI.SubHeadingFont, Alignment.Center, color: Color.Black * 0.8f)
|
||||
{
|
||||
Visible = false
|
||||
};
|
||||
@@ -471,7 +477,11 @@ namespace Barotrauma.Items.Components
|
||||
public void AttachToSonarHUD(GUICustomComponent sonarView)
|
||||
{
|
||||
steerArea.Visible = false;
|
||||
sonarView.OnDraw += (spriteBatch, guiCustomComponent) => { DrawHUD(spriteBatch, guiCustomComponent.Rect); };
|
||||
sonarView.OnDraw += (spriteBatch, guiCustomComponent) =>
|
||||
{
|
||||
DrawHUD(spriteBatch, guiCustomComponent.Rect);
|
||||
steerArea.DrawChildren(spriteBatch, recursive: true);
|
||||
};
|
||||
}
|
||||
|
||||
public void DrawHUD(SpriteBatch spriteBatch, Rectangle rect)
|
||||
@@ -712,12 +722,13 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
pressureWarningText.Visible = item.Submarine != null && item.Submarine.AtDamageDepth && Timing.TotalTime % 1.0f < 0.5f;
|
||||
pressureWarningText.Visible = item.Submarine != null && item.Submarine.AtDamageDepth && Timing.TotalTime % 1.0f < 0.8f;
|
||||
iceSpireWarningText.Visible = item.Submarine != null && !pressureWarningText.Visible && showIceSpireWarning && Timing.TotalTime % 1.0f < 0.8f;
|
||||
|
||||
if (Vector2.DistanceSquared(PlayerInput.MousePosition, steerArea.Rect.Center.ToVector2()) < steerRadius * steerRadius)
|
||||
{
|
||||
if (PlayerInput.PrimaryMouseButtonHeld() && !CrewManager.IsCommandInterfaceOpen && !GameSession.IsTabMenuOpen &&
|
||||
(!GameMain.GameSession?.Campaign?.ShowCampaignUI ?? true) && !GUIMessageBox.MessageBoxes.Any())
|
||||
(!GameMain.GameSession?.Campaign?.ShowCampaignUI ?? true) && !GUIMessageBox.MessageBoxes.Any(msgBox => msgBox is GUIMessageBox { MessageBoxType: GUIMessageBox.Type.Default }))
|
||||
{
|
||||
Vector2 inputPos = PlayerInput.MousePosition - steerArea.Rect.Center.ToVector2();
|
||||
inputPos.Y = -inputPos.Y;
|
||||
|
||||
@@ -113,7 +113,9 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
partial void FixItemProjSpecific(Character user, float deltaTime, Item targetItem)
|
||||
partial void FixItemProjSpecific(Character user, float deltaTime, Item targetItem, bool showProgressBar)
|
||||
{
|
||||
if (showProgressBar)
|
||||
{
|
||||
float progressBarState = targetItem.ConditionPercentage / 100.0f;
|
||||
if (!MathUtils.NearlyEqual(progressBarState, prevProgressBarState) || prevProgressBarTarget != targetItem)
|
||||
@@ -133,6 +135,7 @@ namespace Barotrauma.Items.Components
|
||||
prevProgressBarState = progressBarState;
|
||||
prevProgressBarTarget = targetItem;
|
||||
}
|
||||
}
|
||||
|
||||
Vector2 particlePos = ConvertUnits.ToDisplayUnits(pickedPosition);
|
||||
if (targetItem.Submarine != null) particlePos += targetItem.Submarine.DrawPosition;
|
||||
|
||||
@@ -53,13 +53,9 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
//if the Character using the panel has a wire item equipped
|
||||
//and the wire hasn't been connected yet, draw it on the panel
|
||||
for (int i = 0; i < character.SelectedItems.Length; i++)
|
||||
foreach (Item item in character.HeldItems)
|
||||
{
|
||||
Item selectedItem = character.SelectedItems[i];
|
||||
|
||||
if (selectedItem == null) { continue; }
|
||||
|
||||
Wire wireComponent = selectedItem.GetComponent<Wire>();
|
||||
Wire wireComponent = item.GetComponent<Wire>();
|
||||
if (wireComponent != null)
|
||||
{
|
||||
equippedWire = wireComponent;
|
||||
@@ -94,7 +90,8 @@ namespace Barotrauma.Items.Components
|
||||
int linkIndex = c.FindWireIndex(DraggingConnected.Item);
|
||||
if (linkIndex > -1 || panel.DisconnectedWires.Contains(DraggingConnected))
|
||||
{
|
||||
Inventory.draggingItem = DraggingConnected.Item;
|
||||
Inventory.DraggingItems.Clear();
|
||||
Inventory.DraggingItems.Add(DraggingConnected.Item);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -182,7 +179,11 @@ namespace Barotrauma.Items.Components
|
||||
new Vector2(x + width / 2, y + height),
|
||||
null, panel, "");
|
||||
|
||||
if (DraggingConnected == equippedWire) { Inventory.draggingItem = equippedWire.Item; }
|
||||
if (DraggingConnected == equippedWire)
|
||||
{
|
||||
Inventory.DraggingItems.Clear();
|
||||
Inventory.DraggingItems.Add(equippedWire.Item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,7 +208,7 @@ namespace Barotrauma.Items.Components
|
||||
//(so we don't drop the item when dropping the wire on a connection)
|
||||
if (mouseInRect || (GUI.MouseOn?.UserData is ConnectionPanel && GUI.MouseOn.MouseRect.Contains(PlayerInput.MousePosition)))
|
||||
{
|
||||
Inventory.draggingItem = null;
|
||||
Inventory.DraggingItems.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,7 +237,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
float connectorSpriteScale = (35.0f / connectionSprite.SourceRect.Width) * panel.Scale;
|
||||
|
||||
for (int i = 0; i < MaxLinked; i++)
|
||||
for (int i = 0; i < MaxWires; i++)
|
||||
{
|
||||
if (wires[i] == null || wires[i].Hidden || (DraggingConnected == wires[i] && (mouseIn || Screen.Selected == GameMain.SubEditorScreen))) { continue; }
|
||||
if (wires[i].HiddenInGame && Screen.Selected == GameMain.GameScreen) { continue; }
|
||||
|
||||
@@ -122,7 +122,7 @@ namespace Barotrauma.Items.Components
|
||||
msg.ReadUInt16(); //user ID
|
||||
foreach (Connection connection in Connections)
|
||||
{
|
||||
for (int i = 0; i < Connection.MaxLinked; i++)
|
||||
for (int i = 0; i < connection.MaxWires; i++)
|
||||
{
|
||||
msg.ReadUInt16();
|
||||
}
|
||||
@@ -168,7 +168,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
foreach (Connection connection in Connections)
|
||||
{
|
||||
for (int i = 0; i < Connection.MaxLinked; i++)
|
||||
for (int i = 0; i < connection.MaxWires; i++)
|
||||
{
|
||||
ushort wireId = msg.ReadUInt16();
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
@@ -15,7 +14,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private Point ElementMaxSize => new Point(uiElementContainer.Rect.Width, (int)(65 * GUI.yScale));
|
||||
|
||||
partial void InitProjSpecific(XElement element)
|
||||
partial void InitProjSpecific()
|
||||
{
|
||||
CreateGUI();
|
||||
}
|
||||
@@ -37,7 +36,7 @@ namespace Barotrauma.Items.Components
|
||||
float elementSize = Math.Min(1.0f / visibleElements.Count(), 1);
|
||||
foreach (CustomInterfaceElement ciElement in visibleElements)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(ciElement.PropertyName))
|
||||
if (ciElement.HasPropertyName)
|
||||
{
|
||||
var layoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, elementSize), uiElementContainer.RectTransform), isHorizontal: true)
|
||||
{
|
||||
@@ -46,7 +45,9 @@ namespace Barotrauma.Items.Components
|
||||
};
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), layoutGroup.RectTransform),
|
||||
TextManager.Get(ciElement.Label, returnNull: true) ?? ciElement.Label);
|
||||
var textBox = new GUITextBox(new RectTransform(new Vector2(0.5f, 1.0f), layoutGroup.RectTransform), "", style: "GUITextBoxNoIcon")
|
||||
if (!ciElement.IsIntegerInput)
|
||||
{
|
||||
var textBox = new GUITextBox(new RectTransform(new Vector2(0.5f, 1.0f), layoutGroup.RectTransform), ciElement.Signal, style: "GUITextBoxNoIcon")
|
||||
{
|
||||
OverflowClip = true,
|
||||
UserData = ciElement
|
||||
@@ -73,6 +74,33 @@ namespace Barotrauma.Items.Components
|
||||
};
|
||||
uiElements.Add(textBox);
|
||||
}
|
||||
else
|
||||
{
|
||||
int.TryParse(ciElement.Signal, out int signal);
|
||||
var numberInput = new GUINumberInput(new RectTransform(new Vector2(0.5f, 1.0f), layoutGroup.RectTransform), GUINumberInput.NumberType.Int)
|
||||
{
|
||||
UserData = ciElement,
|
||||
MinValueInt = ciElement.NumberInputMin,
|
||||
MaxValueInt = ciElement.NumberInputMax,
|
||||
IntValue = Math.Clamp(signal, ciElement.NumberInputMin, ciElement.NumberInputMax)
|
||||
};
|
||||
//reset size restrictions set by the Style to make sure the elements can fit the interface
|
||||
numberInput.RectTransform.MinSize = numberInput.LayoutGroup.RectTransform.MinSize = new Point(0, 0);
|
||||
numberInput.RectTransform.MaxSize = numberInput.LayoutGroup.RectTransform.MaxSize = new Point(int.MaxValue, int.MaxValue);
|
||||
numberInput.OnValueChanged += (ni) =>
|
||||
{
|
||||
if (GameMain.Client == null)
|
||||
{
|
||||
ValueChanged(ni.UserData as CustomInterfaceElement, ni.IntValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
item.CreateClientEvent(this);
|
||||
}
|
||||
};
|
||||
uiElements.Add(numberInput);
|
||||
}
|
||||
}
|
||||
else if (ciElement.ContinuousSignal)
|
||||
{
|
||||
var tickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, elementSize), uiElementContainer.RectTransform)
|
||||
@@ -175,7 +203,7 @@ namespace Barotrauma.Items.Components
|
||||
foreach (var uiElement in uiElements)
|
||||
{
|
||||
if (!(uiElement.UserData is CustomInterfaceElement element)) { continue; }
|
||||
bool visible = Screen.Selected == GameMain.SubEditorScreen || element.StatusEffects.Any() || !string.IsNullOrEmpty(element.PropertyName) || (element.Connection != null && element.Connection.Wires.Any(w => w != null));
|
||||
bool visible = Screen.Selected == GameMain.SubEditorScreen || element.StatusEffects.Any() || element.HasPropertyName || (element.Connection != null && element.Connection.Wires.Any(w => w != null));
|
||||
if (visible) { visibleElementCount++; }
|
||||
if (uiElement.Visible != visible)
|
||||
{
|
||||
@@ -203,34 +231,27 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (uiElements[i] is GUIButton button)
|
||||
{
|
||||
button.Text = string.IsNullOrWhiteSpace(customInterfaceElementList[i].Label) ?
|
||||
TextManager.GetWithVariable("connection.signaloutx", "[num]", (i + 1).ToString()) :
|
||||
customInterfaceElementList[i].Label;
|
||||
button.Text = CreateLabelText(i);
|
||||
button.TextBlock.Wrap = button.Text.Contains(' ');
|
||||
}
|
||||
else if (uiElements[i] is GUITickBox tickBox)
|
||||
{
|
||||
tickBox.Text = string.IsNullOrWhiteSpace(customInterfaceElementList[i].Label) ?
|
||||
TextManager.GetWithVariable("connection.signaloutx", "[num]", (i + 1).ToString()) :
|
||||
customInterfaceElementList[i].Label;
|
||||
tickBox.Text = CreateLabelText(i);
|
||||
tickBox.TextBlock.Wrap = tickBox.Text.Contains(' ');
|
||||
}
|
||||
if (uiElements[i] is GUITextBox textBox)
|
||||
else if (uiElements[i] is GUITextBox || uiElements[i] is GUINumberInput)
|
||||
{
|
||||
var textBlock = textBox.Parent.GetChild<GUITextBlock>();
|
||||
textBlock.Text = string.IsNullOrWhiteSpace(customInterfaceElementList[i].Label) ?
|
||||
TextManager.GetWithVariable("connection.signaloutx", "[num]", (i + 1).ToString()) :
|
||||
customInterfaceElementList[i].Label;
|
||||
var textBlock = uiElements[i].Parent.GetChild<GUITextBlock>();
|
||||
textBlock.Text = CreateLabelText(i);
|
||||
textBlock.Wrap = textBlock.Text.Contains(' ');
|
||||
}
|
||||
}
|
||||
|
||||
foreach (ISerializableEntity e in item.AllPropertyObjects)
|
||||
string CreateLabelText(int elementIndex)
|
||||
{
|
||||
if (e.SerializableProperties.ContainsKey(customInterfaceElementList[i].PropertyName))
|
||||
{
|
||||
textBox.Text = e.SerializableProperties[customInterfaceElementList[i].PropertyName].GetValue(e) as string;
|
||||
}
|
||||
}
|
||||
}
|
||||
return string.IsNullOrWhiteSpace(customInterfaceElementList[elementIndex].Label) ?
|
||||
TextManager.GetWithVariable("connection.signaloutx", "[num]", (elementIndex + 1).ToString()) :
|
||||
customInterfaceElementList[elementIndex].Label;
|
||||
}
|
||||
|
||||
uiElementContainer.Recalculate();
|
||||
@@ -258,15 +279,41 @@ namespace Barotrauma.Items.Components
|
||||
GUITextBlock.AutoScaleAndNormalize(textBlocks);
|
||||
}
|
||||
|
||||
partial void UpdateSignalsProjSpecific()
|
||||
{
|
||||
for (int i = 0; i < signals.Length && i < uiElements.Count; i++)
|
||||
{
|
||||
if (uiElements[i] is GUITextBox tb)
|
||||
{
|
||||
tb.Text = customInterfaceElementList[i].Signal;
|
||||
}
|
||||
else if (uiElements[i] is GUINumberInput ni)
|
||||
{
|
||||
if (ni.InputType == GUINumberInput.NumberType.Int)
|
||||
{
|
||||
int.TryParse(customInterfaceElementList[i].Signal, out int value);
|
||||
ni.IntValue = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ClientWrite(IWriteMessage msg, object[] extraData = null)
|
||||
{
|
||||
//extradata contains an array of buttons clicked by the player (or nothing if the player didn't click anything)
|
||||
for (int i = 0; i < customInterfaceElementList.Count; i++)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(customInterfaceElementList[i].PropertyName))
|
||||
if (customInterfaceElementList[i].HasPropertyName)
|
||||
{
|
||||
if (!customInterfaceElementList[i].IsIntegerInput)
|
||||
{
|
||||
msg.Write(((GUITextBox)uiElements[i]).Text);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.Write(((GUINumberInput)uiElements[i]).IntValue.ToString());
|
||||
}
|
||||
}
|
||||
else if (customInterfaceElementList[i].ContinuousSignal)
|
||||
{
|
||||
msg.Write(((GUITickBox)uiElements[i]).Selected);
|
||||
@@ -282,11 +329,19 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
for (int i = 0; i < customInterfaceElementList.Count; i++)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(customInterfaceElementList[i].PropertyName))
|
||||
if (customInterfaceElementList[i].HasPropertyName)
|
||||
{
|
||||
if (!customInterfaceElementList[i].IsIntegerInput)
|
||||
{
|
||||
TextChanged(customInterfaceElementList[i], msg.ReadString());
|
||||
}
|
||||
else
|
||||
{
|
||||
int.TryParse(msg.ReadString(), out int value);
|
||||
ValueChanged(customInterfaceElementList[i], value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool elementState = msg.ReadBoolean();
|
||||
if (customInterfaceElementList[i].ContinuousSignal)
|
||||
@@ -300,6 +355,8 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UpdateSignalsProjSpecific();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,7 +214,10 @@ namespace Barotrauma.Items.Components
|
||||
roundedGridPos += item.Submarine.Position;
|
||||
}
|
||||
|
||||
Submarine.DrawGrid(spriteBatch, 14, gridPos, roundedGridPos, alpha: 0.7f);
|
||||
if (!SubEditorScreen.IsSubEditor() || !SubEditorScreen.ShouldDrawGrid)
|
||||
{
|
||||
Submarine.DrawGrid(spriteBatch, 14, gridPos, roundedGridPos, alpha: 0.25f);
|
||||
}
|
||||
|
||||
WireSection.Draw(
|
||||
spriteBatch, this,
|
||||
@@ -287,9 +290,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
var doubleClicked = PlayerInput.DoubleClicked();
|
||||
|
||||
Wire equippedWire =
|
||||
Character.Controlled?.SelectedItems[0]?.GetComponent<Wire>() ??
|
||||
Character.Controlled?.SelectedItems[1]?.GetComponent<Wire>();
|
||||
Wire equippedWire = Character.Controlled.HeldItems.FirstOrDefault(it => it.GetComponent<Wire>() != null)?.GetComponent<Wire>();
|
||||
if (equippedWire != null && GUI.MouseOn == null)
|
||||
{
|
||||
if (PlayerInput.PrimaryMouseButtonClicked() && Character.Controlled.SelectedConstruction == null)
|
||||
@@ -329,6 +330,9 @@ namespace Barotrauma.Items.Components
|
||||
nodeWorldPos = nodeWorldPos - sub.HiddenSubPosition - sub.Position;
|
||||
}
|
||||
|
||||
if (selectedNodeIndex.HasValue && selectedNodeIndex.Value >= draggingWire.nodes.Count) { selectedNodeIndex = null; }
|
||||
if (highlightedNodeIndex.HasValue && highlightedNodeIndex.Value >= draggingWire.nodes.Count) { highlightedNodeIndex = null; }
|
||||
|
||||
if (selectedNodeIndex.HasValue)
|
||||
{
|
||||
if (!PlayerInput.IsShiftDown())
|
||||
@@ -342,14 +346,15 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((highlightedNodeIndex.HasValue && Vector2.DistanceSquared(nodeWorldPos, draggingWire.nodes[(int)highlightedNodeIndex]) > Submarine.GridSize.X * Submarine.GridSize.X) ||
|
||||
float dragDistance = Submarine.GridSize.X * Submarine.GridSize.Y;
|
||||
dragDistance *= 0.5f;
|
||||
if ((highlightedNodeIndex.HasValue && Vector2.DistanceSquared(nodeWorldPos, draggingWire.nodes[(int)highlightedNodeIndex]) >= dragDistance) ||
|
||||
PlayerInput.IsShiftDown())
|
||||
{
|
||||
selectedNodeIndex = highlightedNodeIndex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MapEntity.SelectEntity(draggingWire.item);
|
||||
}
|
||||
|
||||
@@ -396,6 +401,13 @@ namespace Barotrauma.Items.Components
|
||||
if (closestIndex > -1)
|
||||
{
|
||||
highlightedNodeIndex = closestIndex;
|
||||
|
||||
Vector2 nudge = MapEntity.GetNudgeAmount(doHold: false);
|
||||
if (nudge != Vector2.Zero && closestIndex < selectedWire.nodes.Count)
|
||||
{
|
||||
selectedWire.MoveNode(closestIndex, nudge);
|
||||
}
|
||||
|
||||
//start dragging the node
|
||||
if (PlayerInput.PrimaryMouseButtonHeld())
|
||||
{
|
||||
|
||||
@@ -148,21 +148,21 @@ namespace Barotrauma.Items.Components
|
||||
List<string> texts = new List<string>();
|
||||
List<Color> textColors = new List<Color>();
|
||||
|
||||
if (target.Info != null)
|
||||
{
|
||||
texts.Add(target.Name);
|
||||
texts.Add(target.Info == null ? target.DisplayName : target.Info.DisplayName);
|
||||
textColors.Add(GUI.Style.TextColor);
|
||||
}
|
||||
|
||||
if (target.IsDead)
|
||||
{
|
||||
texts.Add(TextManager.Get("Deceased"));
|
||||
textColors.Add(GUI.Style.Red);
|
||||
if (target.CauseOfDeath != null)
|
||||
{
|
||||
texts.Add(
|
||||
target.CauseOfDeath.Affliction?.CauseOfDeathDescription ??
|
||||
TextManager.AddPunctuation(':', TextManager.Get("CauseOfDeath"), TextManager.Get("CauseOfDeath." + target.CauseOfDeath.Type.ToString())));
|
||||
textColors.Add(GUI.Style.Red);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!string.IsNullOrEmpty(target.customInteractHUDText) && target.AllowCustomInteract)
|
||||
@@ -170,6 +170,21 @@ namespace Barotrauma.Items.Components
|
||||
texts.Add(target.customInteractHUDText);
|
||||
textColors.Add(GUI.Style.Green);
|
||||
}
|
||||
if (!target.IsIncapacitated && target.IsPet)
|
||||
{
|
||||
texts.Add(CharacterHUD.GetCachedHudText("PlayHint", GameMain.Config.KeyBindText(InputType.Use)));
|
||||
textColors.Add(GUI.Style.Green);
|
||||
}
|
||||
if (target.CharacterHealth.UseHealthWindow && equipper?.FocusedCharacter == target && equipper.CanInteractWith(target, 160f, false))
|
||||
{
|
||||
texts.Add(CharacterHUD.GetCachedHudText("HealHint", GameMain.Config.KeyBindText(InputType.Health)));
|
||||
textColors.Add(GUI.Style.Green);
|
||||
}
|
||||
if (target.CanBeDragged)
|
||||
{
|
||||
texts.Add(CharacterHUD.GetCachedHudText("GrabHint", GameMain.Config.KeyBindText(InputType.Grab)));
|
||||
textColors.Add(GUI.Style.Green);
|
||||
}
|
||||
|
||||
if (target.IsUnconscious)
|
||||
{
|
||||
|
||||
@@ -181,14 +181,14 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (moveSoundChannel == null && startMoveSound != null)
|
||||
{
|
||||
moveSoundChannel = SoundPlayer.PlaySound(startMoveSound.Sound, item.WorldPosition, startMoveSound.Volume, startMoveSound.Range);
|
||||
moveSoundChannel = SoundPlayer.PlaySound(startMoveSound.Sound, item.WorldPosition, startMoveSound.Volume, startMoveSound.Range, ignoreMuffling: startMoveSound.IgnoreMuffling);
|
||||
}
|
||||
else if (moveSoundChannel == null || !moveSoundChannel.IsPlaying)
|
||||
{
|
||||
if (moveSound != null)
|
||||
{
|
||||
moveSoundChannel.FadeOutAndDispose();
|
||||
moveSoundChannel = SoundPlayer.PlaySound(moveSound.Sound, item.WorldPosition, moveSound.Volume, moveSound.Range);
|
||||
moveSoundChannel = SoundPlayer.PlaySound(moveSound.Sound, item.WorldPosition, moveSound.Volume, moveSound.Range, ignoreMuffling: moveSound.IgnoreMuffling);
|
||||
if (moveSoundChannel != null) moveSoundChannel.Looping = true;
|
||||
}
|
||||
}
|
||||
@@ -200,7 +200,7 @@ namespace Barotrauma.Items.Components
|
||||
if (endMoveSound != null && moveSoundChannel.Sound != endMoveSound.Sound)
|
||||
{
|
||||
moveSoundChannel.FadeOutAndDispose();
|
||||
moveSoundChannel = SoundPlayer.PlaySound(endMoveSound.Sound, item.WorldPosition, endMoveSound.Volume, endMoveSound.Range);
|
||||
moveSoundChannel = SoundPlayer.PlaySound(endMoveSound.Sound, item.WorldPosition, endMoveSound.Volume, endMoveSound.Range, ignoreMuffling: endMoveSound.IgnoreMuffling);
|
||||
if (moveSoundChannel != null) moveSoundChannel.Looping = false;
|
||||
}
|
||||
else if (!moveSoundChannel.IsPlaying)
|
||||
@@ -286,40 +286,26 @@ namespace Barotrauma.Items.Components
|
||||
rotation + MathHelper.PiOver2, item.Scale,
|
||||
SpriteEffects.None, item.SpriteDepth + (barrelSprite.Depth - item.Sprite.Depth));
|
||||
|
||||
if (!GameMain.DebugDraw && (!editing || GUI.DisableHUD || !item.IsSelected)) { return; }
|
||||
if (!editing || GUI.DisableHUD || !item.IsSelected) { return; }
|
||||
|
||||
const float widgetRadius = 60.0f;
|
||||
|
||||
Vector2 center = new Vector2((float)Math.Cos((maxRotation + minRotation) / 2), (float)Math.Sin((maxRotation + minRotation) / 2));
|
||||
GUI.DrawLine(spriteBatch,
|
||||
drawPos,
|
||||
drawPos + new Vector2((float)Math.Cos((maxRotation + minRotation) / 2), (float)Math.Sin((maxRotation + minRotation) / 2)) * widgetRadius,
|
||||
drawPos + center * widgetRadius,
|
||||
Color.LightGreen);
|
||||
|
||||
if (GameMain.DebugDraw)
|
||||
{
|
||||
center = new Vector2((float)Math.Cos(targetRotation), (float)Math.Sin(targetRotation));
|
||||
GUI.DrawLine(spriteBatch,
|
||||
drawPos,
|
||||
drawPos + center * widgetRadius,
|
||||
Color.Red);
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
center = new Vector2((float)Math.Cos(rotation + (angularVelocity * 0.05f * i)), (float)Math.Sin(rotation + (angularVelocity * 0.05f * i)));
|
||||
GUI.DrawLine(spriteBatch,
|
||||
drawPos,
|
||||
drawPos + center * widgetRadius,
|
||||
Color.Lerp(Color.Black, Color.Yellow, i * 0.25f));
|
||||
}
|
||||
}
|
||||
|
||||
const float coneRadius = 300.0f;
|
||||
float radians = maxRotation - minRotation;
|
||||
float circleRadius = coneRadius / Screen.Selected.Cam.Zoom * GUI.Scale;
|
||||
float lineThickness = 1f / Screen.Selected.Cam.Zoom;
|
||||
|
||||
if (radians > Math.PI * 2)
|
||||
if (Math.Abs(minRotation - maxRotation) < 0.02f)
|
||||
{
|
||||
spriteBatch.DrawLine(drawPos, drawPos + center * circleRadius, GUI.Style.Green, thickness: lineThickness);
|
||||
}
|
||||
else if (radians > Math.PI * 2)
|
||||
{
|
||||
spriteBatch.DrawCircle(drawPos, circleRadius, 180, GUI.Style.Red, thickness: lineThickness);
|
||||
}
|
||||
@@ -510,13 +496,8 @@ namespace Barotrauma.Items.Components
|
||||
List<Item> availableAmmo = new List<Item>();
|
||||
foreach (MapEntity e in item.linkedTo)
|
||||
{
|
||||
var linkedItem = e as Item;
|
||||
if (linkedItem == null) continue;
|
||||
|
||||
var itemContainer = linkedItem.GetComponent<ItemContainer>();
|
||||
if (itemContainer?.Inventory?.Items == null) continue;
|
||||
|
||||
availableAmmo.AddRange(itemContainer.Inventory.Items);
|
||||
if (!(e is Item linkedItem)) { continue; }
|
||||
availableAmmo.AddRange(linkedItem.ContainedItems);
|
||||
}
|
||||
|
||||
float chargeRate =
|
||||
@@ -558,7 +539,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
// 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)),
|
||||
new VisualSlot(new Rectangle(invSlotPos + new Point((i % slotsPerRow) * (slotSize.X + spacing), (int)Math.Floor(i / (float)slotsPerRow) * (slotSize.Y + spacing)), slotSize)),
|
||||
availableAmmo[i], -1, true);
|
||||
}
|
||||
if (flashNoAmmo)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,6 +8,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Barotrauma.Extensions;
|
||||
using Barotrauma.MapCreatures.Behavior;
|
||||
using FarseerPhysics.Dynamics;
|
||||
using FarseerPhysics.Dynamics.Contacts;
|
||||
|
||||
@@ -15,7 +16,7 @@ namespace Barotrauma
|
||||
{
|
||||
partial class Item : MapEntity, IDamageable, ISerializableEntity, IServerSerializable, IClientSerializable
|
||||
{
|
||||
public static bool ShowItems = true;
|
||||
public static bool ShowItems = true, ShowWires = true;
|
||||
|
||||
private readonly List<PosInfo> positionBuffer = new List<PosInfo>();
|
||||
|
||||
@@ -29,6 +30,7 @@ namespace Barotrauma
|
||||
private bool editingHUDRefreshPending;
|
||||
private float editingHUDRefreshTimer;
|
||||
|
||||
private ContainedItemSprite activeContainedSprite;
|
||||
|
||||
private readonly Dictionary<DecorativeSprite, DecorativeSprite.State> spriteAnimState = new Dictionary<DecorativeSprite, DecorativeSprite.State>();
|
||||
|
||||
@@ -103,15 +105,12 @@ namespace Barotrauma
|
||||
Color color = spriteColor;
|
||||
if (Prefab.UseContainedSpriteColor && ownInventory != null)
|
||||
{
|
||||
for (int i = 0; i < ownInventory.Items.Length; i++)
|
||||
foreach (Item item in ContainedItems)
|
||||
{
|
||||
if (ownInventory.Items[i] != null)
|
||||
{
|
||||
color = ownInventory.Items[i].ContainerColor;
|
||||
color = item.ContainerColor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
@@ -120,21 +119,19 @@ namespace Barotrauma
|
||||
Color color = InventoryIconColor;
|
||||
if (Prefab.UseContainedInventoryIconColor && ownInventory != null)
|
||||
{
|
||||
for (int i = 0; i < ownInventory.Items.Length; i++)
|
||||
foreach (Item item in ContainedItems)
|
||||
{
|
||||
if (ownInventory.Items[i] != null)
|
||||
{
|
||||
color = ownInventory.Items[i].ContainerColor;
|
||||
color = item.ContainerColor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
partial void SetActiveSpriteProjSpecific()
|
||||
{
|
||||
activeSprite = prefab.sprite;
|
||||
activeContainedSprite = null;
|
||||
Holdable holdable = GetComponent<Holdable>();
|
||||
if (holdable != null && holdable.Attached)
|
||||
{
|
||||
@@ -142,7 +139,9 @@ namespace Barotrauma
|
||||
{
|
||||
if (containedSprite.UseWhenAttached)
|
||||
{
|
||||
activeContainedSprite = containedSprite;
|
||||
activeSprite = containedSprite.Sprite;
|
||||
UpdateSpriteStates(0.0f);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -154,7 +153,9 @@ namespace Barotrauma
|
||||
{
|
||||
if (containedSprite.MatchesContainer(Container))
|
||||
{
|
||||
activeContainedSprite = containedSprite;
|
||||
activeSprite = containedSprite.Sprite;
|
||||
UpdateSpriteStates(0.0f);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -187,6 +188,7 @@ namespace Barotrauma
|
||||
decorativeSprite.Sprite.EnsureLazyLoaded();
|
||||
spriteAnimState.Add(decorativeSprite, new DecorativeSprite.State());
|
||||
}
|
||||
SetActiveSprite();
|
||||
UpdateSpriteStates(0.0f);
|
||||
}
|
||||
|
||||
@@ -240,7 +242,15 @@ namespace Barotrauma
|
||||
public override void Draw(SpriteBatch spriteBatch, bool editing, bool back = true)
|
||||
{
|
||||
if (!Visible || (!editing && HiddenInGame)) { return; }
|
||||
if (editing && !ShowItems) { return; }
|
||||
|
||||
if (editing)
|
||||
{
|
||||
if (isWire)
|
||||
{
|
||||
if (!ShowWires) { return; }
|
||||
}
|
||||
else if (!ShowItems) { return; }
|
||||
}
|
||||
|
||||
Color color = IsHighlighted && !GUI.DisableItemHighlights && Screen.Selected != GameMain.GameScreen ? GUI.Style.Orange : GetSpriteColor();
|
||||
//if (IsSelected && editing) color = Color.Lerp(color, Color.Gold, 0.5f);
|
||||
@@ -305,7 +315,7 @@ namespace Barotrauma
|
||||
foreach (var decorativeSprite in Prefab.DecorativeSprites)
|
||||
{
|
||||
if (!spriteAnimState[decorativeSprite].IsActive) { continue; }
|
||||
Vector2 offset = decorativeSprite.GetOffset(ref spriteAnimState[decorativeSprite].OffsetState, -rotationRad) * Scale;
|
||||
Vector2 offset = decorativeSprite.GetOffset(ref spriteAnimState[decorativeSprite].OffsetState, spriteAnimState[decorativeSprite].RandomOffsetMultiplier, -rotationRad) * Scale;
|
||||
if (flippedX && Prefab.CanSpriteFlipX) { offset.X = -offset.X; }
|
||||
if (flippedY && Prefab.CanSpriteFlipY) { offset.Y = -offset.Y; }
|
||||
decorativeSprite.Sprite.DrawTiled(spriteBatch,
|
||||
@@ -328,7 +338,7 @@ namespace Barotrauma
|
||||
}
|
||||
activeSprite.Draw(spriteBatch, new Vector2(DrawPosition.X, -DrawPosition.Y) + drawOffset, color, origin, rotationRad, Scale, activeSprite.effects, depth);
|
||||
fadeInBrokenSprite?.Sprite.Draw(spriteBatch, new Vector2(DrawPosition.X, -DrawPosition.Y) + fadeInBrokenSprite.Offset.ToVector2() * Scale, color * fadeInBrokenSpriteAlpha, origin, rotationRad, Scale, activeSprite.effects, depth - 0.000001f);
|
||||
if (Infector != null && Infector.ParentBallastFlora.HasBrokenThrough)
|
||||
if (Infector != null && (Infector.ParentBallastFlora.HasBrokenThrough || BallastFloraBehavior.AlwaysShowBallastFloraSprite))
|
||||
{
|
||||
Prefab.InfectedSprite?.Draw(spriteBatch, new Vector2(DrawPosition.X, -DrawPosition.Y) + drawOffset, color, Prefab.InfectedSprite.Origin, rotationRad, Scale, activeSprite.effects, depth - 0.001f);
|
||||
Prefab.DamagedInfectedSprite?.Draw(spriteBatch, new Vector2(DrawPosition.X, -DrawPosition.Y) + drawOffset, Infector.HealthColor, Prefab.DamagedInfectedSprite.Origin, rotationRad, Scale, activeSprite.effects, depth - 0.002f);
|
||||
@@ -336,12 +346,12 @@ namespace Barotrauma
|
||||
foreach (var decorativeSprite in Prefab.DecorativeSprites)
|
||||
{
|
||||
if (!spriteAnimState[decorativeSprite].IsActive) { continue; }
|
||||
float rot = decorativeSprite.GetRotation(ref spriteAnimState[decorativeSprite].RotationState);
|
||||
Vector2 offset = decorativeSprite.GetOffset(ref spriteAnimState[decorativeSprite].OffsetState, -rotationRad) * Scale;
|
||||
float rot = decorativeSprite.GetRotation(ref spriteAnimState[decorativeSprite].RotationState, spriteAnimState[decorativeSprite].RandomRotationFactor);
|
||||
Vector2 offset = decorativeSprite.GetOffset(ref spriteAnimState[decorativeSprite].OffsetState, spriteAnimState[decorativeSprite].RandomOffsetMultiplier, -rotationRad) * Scale;
|
||||
if (flippedX && Prefab.CanSpriteFlipX) { offset.X = -offset.X; }
|
||||
if (flippedY && Prefab.CanSpriteFlipY) { offset.Y = -offset.Y; }
|
||||
decorativeSprite.Sprite.Draw(spriteBatch, new Vector2(DrawPosition.X + offset.X, -(DrawPosition.Y + offset.Y)), color,
|
||||
rotationRad + rot, decorativeSprite.Scale * Scale, activeSprite.effects,
|
||||
rotationRad + rot, decorativeSprite.GetScale(spriteAnimState[decorativeSprite].RandomScaleFactor) * Scale, activeSprite.effects,
|
||||
depth: Math.Min(depth + (decorativeSprite.Sprite.Depth - activeSprite.Depth), 0.999f));
|
||||
}
|
||||
}
|
||||
@@ -353,7 +363,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (!back) { return; }
|
||||
float depthStep = 0.000001f;
|
||||
if (holdable.Picker.SelectedItems[0] == this)
|
||||
if (holdable.Picker.Inventory?.GetItemInLimbSlot(InvSlotType.RightHand) == this)
|
||||
{
|
||||
Limb holdLimb = holdable.Picker.AnimController.GetLimb(LimbType.RightHand);
|
||||
if (holdLimb?.ActiveSprite != null)
|
||||
@@ -365,7 +375,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (holdable.Picker.SelectedItems[1] == this)
|
||||
else if (holdable.Picker.Inventory?.GetItemInLimbSlot(InvSlotType.LeftHand) == this)
|
||||
{
|
||||
Limb holdLimb = holdable.Picker.AnimController.GetLimb(LimbType.LeftHand);
|
||||
if (holdLimb?.ActiveSprite != null)
|
||||
@@ -384,8 +394,8 @@ namespace Barotrauma
|
||||
foreach (var decorativeSprite in Prefab.DecorativeSprites)
|
||||
{
|
||||
if (!spriteAnimState[decorativeSprite].IsActive) { continue; }
|
||||
float rotation = decorativeSprite.GetRotation(ref spriteAnimState[decorativeSprite].RotationState);
|
||||
Vector2 offset = decorativeSprite.GetOffset(ref spriteAnimState[decorativeSprite].OffsetState, -rotationRad) * Scale;
|
||||
float rotation = decorativeSprite.GetRotation(ref spriteAnimState[decorativeSprite].RotationState, spriteAnimState[decorativeSprite].RandomRotationFactor);
|
||||
Vector2 offset = decorativeSprite.GetOffset(ref spriteAnimState[decorativeSprite].OffsetState, spriteAnimState[decorativeSprite].RandomOffsetMultiplier, -rotationRad) * Scale;
|
||||
if (flippedX && Prefab.CanSpriteFlipX) { offset.X = -offset.X; }
|
||||
if (flippedY && Prefab.CanSpriteFlipY) { offset.Y = -offset.Y; }
|
||||
var ca = (float)Math.Cos(-body.Rotation);
|
||||
@@ -393,7 +403,7 @@ namespace Barotrauma
|
||||
Vector2 transformedOffset = new Vector2(ca * offset.X + sa * offset.Y, -sa * offset.X + ca * offset.Y);
|
||||
|
||||
decorativeSprite.Sprite.Draw(spriteBatch, new Vector2(DrawPosition.X + transformedOffset.X, -(DrawPosition.Y + transformedOffset.Y)), color,
|
||||
-body.Rotation + rotation, decorativeSprite.Scale * Scale, activeSprite.effects,
|
||||
-body.Rotation + rotation, decorativeSprite.GetScale(spriteAnimState[decorativeSprite].RandomScaleFactor) * Scale, activeSprite.effects,
|
||||
depth: depth + (decorativeSprite.Sprite.Depth - activeSprite.Depth));
|
||||
}
|
||||
}
|
||||
@@ -405,12 +415,12 @@ namespace Barotrauma
|
||||
foreach (var decorativeSprite in upgradeSprites)
|
||||
{
|
||||
if (!spriteAnimState[decorativeSprite].IsActive) { continue; }
|
||||
float rotation = decorativeSprite.GetRotation(ref spriteAnimState[decorativeSprite].RotationState);
|
||||
Vector2 offset = decorativeSprite.GetOffset(ref spriteAnimState[decorativeSprite].OffsetState, -rotationRad) * Scale;
|
||||
float rotation = decorativeSprite.GetRotation(ref spriteAnimState[decorativeSprite].RotationState, spriteAnimState[decorativeSprite].RandomRotationFactor);
|
||||
Vector2 offset = decorativeSprite.GetOffset(ref spriteAnimState[decorativeSprite].OffsetState, spriteAnimState[decorativeSprite].RandomOffsetMultiplier, -rotationRad) * Scale;
|
||||
if (flippedX && Prefab.CanSpriteFlipX) { offset.X = -offset.X; }
|
||||
if (flippedY && Prefab.CanSpriteFlipY) { offset.Y = -offset.Y; }
|
||||
decorativeSprite.Sprite.Draw(spriteBatch, new Vector2(DrawPosition.X + offset.X, -(DrawPosition.Y + offset.Y)), color,
|
||||
rotation, decorativeSprite.Scale * Scale, activeSprite.effects,
|
||||
rotation, decorativeSprite.GetScale(spriteAnimState[decorativeSprite].RandomScaleFactor) * Scale, activeSprite.effects,
|
||||
depth: depth + (decorativeSprite.Sprite.Depth - activeSprite.Depth));
|
||||
}
|
||||
|
||||
@@ -505,12 +515,39 @@ namespace Barotrauma
|
||||
|
||||
public void UpdateSpriteStates(float deltaTime)
|
||||
{
|
||||
if (activeContainedSprite != null)
|
||||
{
|
||||
if (activeContainedSprite.DecorativeSpriteBehavior == ContainedItemSprite.DecorativeSpriteBehaviorType.HideWhenVisible)
|
||||
{
|
||||
foreach (DecorativeSprite decorativeSprite in Prefab.DecorativeSprites)
|
||||
{
|
||||
var spriteState = spriteAnimState[decorativeSprite];
|
||||
spriteState.IsActive = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var containedSprite in Prefab.ContainedSprites)
|
||||
{
|
||||
if (containedSprite.Sprite != activeSprite && containedSprite.DecorativeSpriteBehavior == ContainedItemSprite.DecorativeSpriteBehaviorType.HideWhenNotVisible)
|
||||
{
|
||||
foreach (DecorativeSprite decorativeSprite in Prefab.DecorativeSprites)
|
||||
{
|
||||
var spriteState = spriteAnimState[decorativeSprite];
|
||||
spriteState.IsActive = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DecorativeSprite.UpdateSpriteStates(Prefab.DecorativeSpriteGroups, spriteAnimState, ID, deltaTime, ConditionalMatches);
|
||||
|
||||
foreach (var upgrade in Upgrades)
|
||||
{
|
||||
var upgradeSprites = GetUpgradeSprites(upgrade);
|
||||
|
||||
foreach (var decorativeSprite in upgradeSprites)
|
||||
{
|
||||
var spriteState = spriteAnimState[decorativeSprite];
|
||||
@@ -1035,6 +1072,28 @@ namespace Barotrauma
|
||||
// Always create the texts if they have not yet been created
|
||||
if (texts.Any() && !recreateHudTexts) { return texts; }
|
||||
texts.Clear();
|
||||
|
||||
string nameText = Name;
|
||||
if (Prefab.Identifier == "idcard" || Tags.Contains("despawncontainer"))
|
||||
{
|
||||
string[] readTags = Tags.Split(',');
|
||||
string idName = null;
|
||||
foreach (string tag in readTags)
|
||||
{
|
||||
string[] s = tag.Split(':');
|
||||
if (s[0] == "name")
|
||||
{
|
||||
idName = s[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (idName != null)
|
||||
{
|
||||
nameText += $" ({idName})";
|
||||
}
|
||||
}
|
||||
texts.Add(new ColoredText(nameText, GUI.Style.TextColor, false, false));
|
||||
|
||||
foreach (ItemComponent ic in components)
|
||||
{
|
||||
if (string.IsNullOrEmpty(ic.DisplayMsg)) { continue; }
|
||||
@@ -1259,7 +1318,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (GameMain.Client == null) { return; }
|
||||
|
||||
if (parentInventory != null || body == null || !body.Enabled || Removed)
|
||||
if (parentInventory != null || body == null || !body.Enabled || Removed || (GetComponent<Projectile>()?.IsStuckToTarget ?? false))
|
||||
{
|
||||
positionBuffer.Clear();
|
||||
return;
|
||||
@@ -1267,12 +1326,7 @@ namespace Barotrauma
|
||||
|
||||
isActive = true;
|
||||
|
||||
Vector2 newVelocity = body.LinearVelocity;
|
||||
Vector2 newPosition = body.SimPosition;
|
||||
float newAngularVelocity = body.AngularVelocity;
|
||||
float newRotation = body.Rotation;
|
||||
body.CorrectPosition(positionBuffer, out newPosition, out newVelocity, out newRotation, out newAngularVelocity);
|
||||
|
||||
body.CorrectPosition(positionBuffer, out Vector2 newPosition, out Vector2 newVelocity, out float newRotation, out float newAngularVelocity);
|
||||
body.LinearVelocity = newVelocity;
|
||||
body.AngularVelocity = newAngularVelocity;
|
||||
if (Vector2.DistanceSquared(newPosition, body.SimPosition) > 0.0001f ||
|
||||
@@ -1490,7 +1544,7 @@ namespace Barotrauma
|
||||
|
||||
foreach (WifiComponent wifiComponent in item.GetComponents<WifiComponent>())
|
||||
{
|
||||
wifiComponent.TeamID = (Character.TeamType)teamID;
|
||||
wifiComponent.TeamID = (CharacterTeamType)teamID;
|
||||
}
|
||||
if (descriptionChanged) { item.Description = itemDesc; }
|
||||
if (tagsChanged) { item.Tags = tags; }
|
||||
@@ -1521,10 +1575,10 @@ namespace Barotrauma
|
||||
|
||||
partial void RemoveProjSpecific()
|
||||
{
|
||||
if (Inventory.draggingItem == this)
|
||||
if (Inventory.DraggingItems.Contains(this))
|
||||
{
|
||||
Inventory.draggingItem = null;
|
||||
Inventory.draggingSlot = null;
|
||||
Inventory.DraggingItems.Clear();
|
||||
Inventory.DraggingSlot = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,14 +24,14 @@ namespace Barotrauma
|
||||
|
||||
protected override void CalculateBackgroundFrame()
|
||||
{
|
||||
var firstSlot = slots.FirstOrDefault();
|
||||
var firstSlot = visualSlots.FirstOrDefault();
|
||||
if (firstSlot == null) { return; }
|
||||
Rectangle frame = firstSlot.Rect;
|
||||
frame.Location += firstSlot.DrawOffset.ToPoint();
|
||||
for (int i = 1; i < capacity; i++)
|
||||
{
|
||||
Rectangle slotRect = slots[i].Rect;
|
||||
slotRect.Location += slots[i].DrawOffset.ToPoint();
|
||||
Rectangle slotRect = visualSlots[i].Rect;
|
||||
slotRect.Location += visualSlots[i].DrawOffset.ToPoint();
|
||||
frame = Rectangle.Union(frame, slotRect);
|
||||
}
|
||||
BackgroundFrame = new Rectangle(
|
||||
@@ -43,7 +43,7 @@ namespace Barotrauma
|
||||
|
||||
public override void Draw(SpriteBatch spriteBatch, bool subInventory = false)
|
||||
{
|
||||
if (slots != null && slots.Length > 0)
|
||||
if (visualSlots != null && visualSlots.Length > 0)
|
||||
{
|
||||
CalculateBackgroundFrame();
|
||||
if (container.InventoryBackSprite == null)
|
||||
@@ -70,7 +70,7 @@ namespace Barotrauma
|
||||
if (container.InventoryBottomSprite != null && !subInventory)
|
||||
{
|
||||
container.InventoryBottomSprite.Draw(spriteBatch,
|
||||
new Vector2(BackgroundFrame.Center.X, BackgroundFrame.Bottom) + slots[0].DrawOffset,
|
||||
new Vector2(BackgroundFrame.Center.X, BackgroundFrame.Bottom) + visualSlots[0].DrawOffset,
|
||||
0.0f, UIScale);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,8 +27,14 @@ namespace Barotrauma
|
||||
|
||||
class ContainedItemSprite
|
||||
{
|
||||
public enum DecorativeSpriteBehaviorType
|
||||
{
|
||||
None, HideWhenVisible, HideWhenNotVisible
|
||||
}
|
||||
|
||||
public readonly Sprite Sprite;
|
||||
public readonly bool UseWhenAttached;
|
||||
public readonly DecorativeSpriteBehaviorType DecorativeSpriteBehavior;
|
||||
public readonly string[] AllowedContainerIdentifiers;
|
||||
public readonly string[] AllowedContainerTags;
|
||||
|
||||
@@ -36,6 +42,7 @@ namespace Barotrauma
|
||||
{
|
||||
Sprite = new Sprite(element, path, lazyLoad: lazyLoad);
|
||||
UseWhenAttached = element.GetAttributeBool("usewhenattached", false);
|
||||
Enum.TryParse(element.GetAttributeString("decorativespritebehavior", "None"), ignoreCase: true, out DecorativeSpriteBehavior);
|
||||
AllowedContainerIdentifiers = element.GetAttributeStringArray("allowedcontaineridentifiers", new string[0], convertToLowerInvariant: true);
|
||||
AllowedContainerTags = element.GetAttributeStringArray("allowedcontainertags", new string[0], convertToLowerInvariant: true);
|
||||
}
|
||||
|
||||
@@ -65,6 +65,8 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
public readonly List<DamageParticle> DamageParticles = new List<DamageParticle>();
|
||||
public readonly List<DamageParticle> DeathParticles = new List<DamageParticle>();
|
||||
|
||||
public static bool AlwaysShowBallastFloraSprite = false;
|
||||
|
||||
partial void LoadPrefab(XElement element)
|
||||
{
|
||||
string? branchAtlasPath = element.GetAttributeString("branchatlas", null);
|
||||
@@ -125,7 +127,7 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
float particleAmount = Rand.Range(16, 32);
|
||||
for (int i = 0; i < particleAmount; i++)
|
||||
{
|
||||
GameMain.ParticleManager.CreateParticle("shrapnel", pos, Rand.Vector(Rand.Range(-50f, 50.0f)));
|
||||
GameMain.ParticleManager.CreateParticle("shrapnel", pos, Rand.Vector(Rand.Range(0f, 250.0f)), Rand.Range(0f, 360.0f));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,10 +43,10 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawFront(SpriteBatch spriteBatch, Camera cam)
|
||||
public void DrawDebugOverlay(SpriteBatch spriteBatch, Camera cam)
|
||||
{
|
||||
if (renderer == null) { return; }
|
||||
renderer.Draw(spriteBatch, cam);
|
||||
renderer.DrawDebugOverlay(spriteBatch, cam);
|
||||
|
||||
if (GameMain.DebugDraw && Screen.Selected.Cam.Zoom > 0.1f)
|
||||
{
|
||||
@@ -114,10 +114,13 @@ namespace Barotrauma
|
||||
|
||||
graphics.Clear(BackgroundColor);
|
||||
|
||||
if (renderer == null) return;
|
||||
renderer.DrawBackground(spriteBatch, cam, LevelObjectManager, backgroundCreatureManager);
|
||||
renderer?.DrawBackground(spriteBatch, cam, LevelObjectManager, backgroundCreatureManager);
|
||||
}
|
||||
|
||||
public void DrawFront(SpriteBatch spriteBatch, Camera cam)
|
||||
{
|
||||
renderer?.DrawForeground(spriteBatch, cam, LevelObjectManager);
|
||||
}
|
||||
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
||||
{
|
||||
bool isGlobalUpdate = msg.ReadBoolean();
|
||||
|
||||
@@ -241,6 +241,7 @@ namespace Barotrauma
|
||||
|
||||
private void UpdateDeformations(float deltaTime)
|
||||
{
|
||||
if (ActivePrefab.DeformableSprite == null) { return; }
|
||||
foreach (SpriteDeformation deformation in spriteDeformations)
|
||||
{
|
||||
if (deformation is PositionalDeformation positionalDeformation)
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace Barotrauma
|
||||
partial class LevelObjectManager
|
||||
{
|
||||
private readonly List<LevelObject> visibleObjectsBack = new List<LevelObject>();
|
||||
private readonly List<LevelObject> visibleObjectsMid = new List<LevelObject>();
|
||||
private readonly List<LevelObject> visibleObjectsFront = new List<LevelObject>();
|
||||
|
||||
private double NextRefreshTime;
|
||||
@@ -26,6 +27,10 @@ namespace Barotrauma
|
||||
{
|
||||
obj.Update(deltaTime);
|
||||
}
|
||||
foreach (LevelObject obj in visibleObjectsMid)
|
||||
{
|
||||
obj.Update(deltaTime);
|
||||
}
|
||||
foreach (LevelObject obj in visibleObjectsFront)
|
||||
{
|
||||
obj.Update(deltaTime);
|
||||
@@ -34,7 +39,7 @@ namespace Barotrauma
|
||||
|
||||
public IEnumerable<LevelObject> GetVisibleObjects()
|
||||
{
|
||||
return visibleObjectsBack.Union(visibleObjectsFront);
|
||||
return visibleObjectsBack.Union(visibleObjectsMid).Union(visibleObjectsFront);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -43,6 +48,7 @@ namespace Barotrauma
|
||||
private void RefreshVisibleObjects(Rectangle currentIndices, float zoom)
|
||||
{
|
||||
visibleObjectsBack.Clear();
|
||||
visibleObjectsMid.Clear();
|
||||
visibleObjectsFront.Clear();
|
||||
|
||||
float minSizeToDraw = MathHelper.Lerp(10.0f, 5.0f, Math.Min(zoom * 20.0f, 1.0f));
|
||||
@@ -70,7 +76,10 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
var objectList = obj.Position.Z >= 0 ? visibleObjectsBack : visibleObjectsFront;
|
||||
var objectList =
|
||||
obj.Position.Z >= 0 ?
|
||||
visibleObjectsBack :
|
||||
(obj.Position.Z < -1 ? visibleObjectsFront : visibleObjectsMid);
|
||||
int drawOrderIndex = 0;
|
||||
for (int i = 0; i < objectList.Count; i++)
|
||||
{
|
||||
@@ -102,8 +111,31 @@ namespace Barotrauma
|
||||
currentGridIndices = currentIndices;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draw the objects behind the level walls
|
||||
/// </summary>
|
||||
public void DrawObjectsBack(SpriteBatch spriteBatch, Camera cam)
|
||||
{
|
||||
DrawObjects(spriteBatch, cam, visibleObjectsBack);
|
||||
}
|
||||
|
||||
public void DrawObjects(SpriteBatch spriteBatch, Camera cam, bool drawFront)
|
||||
/// <summary>
|
||||
/// Draw the objects in front of the level walls, but behind characters
|
||||
/// </summary>
|
||||
public void DrawObjectsMid(SpriteBatch spriteBatch, Camera cam)
|
||||
{
|
||||
DrawObjects(spriteBatch, cam, visibleObjectsMid);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draw the objects in front of the level walls and characters
|
||||
/// </summary>
|
||||
public void DrawObjectsFront(SpriteBatch spriteBatch, Camera cam)
|
||||
{
|
||||
DrawObjects(spriteBatch, cam, visibleObjectsFront);
|
||||
}
|
||||
|
||||
private void DrawObjects(SpriteBatch spriteBatch, Camera cam, List<LevelObject> objectList)
|
||||
{
|
||||
Rectangle indices = Rectangle.Empty;
|
||||
indices.X = (int)Math.Floor(cam.WorldView.X / (float)GridSize);
|
||||
@@ -132,7 +164,6 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
var objectList = drawFront ? visibleObjectsFront : visibleObjectsBack;
|
||||
foreach (LevelObject obj in objectList)
|
||||
{
|
||||
Vector2 camDiff = new Vector2(obj.Position.X, obj.Position.Y) - cam.WorldViewCenter;
|
||||
|
||||
@@ -220,7 +220,7 @@ namespace Barotrauma
|
||||
SamplerState.LinearWrap, DepthStencilState.DepthRead, null, null,
|
||||
cam.Transform);
|
||||
|
||||
backgroundSpriteManager?.DrawObjects(spriteBatch, cam, drawFront: false);
|
||||
backgroundSpriteManager?.DrawObjectsBack(spriteBatch, cam);
|
||||
if (cam.Zoom > 0.05f)
|
||||
{
|
||||
backgroundCreatureManager?.Draw(spriteBatch, cam);
|
||||
@@ -262,8 +262,6 @@ namespace Barotrauma
|
||||
color: Color.White * alpha, textureScale: new Vector2(texScale));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
spriteBatch.End();
|
||||
|
||||
RenderWalls(GameMain.Instance.GraphicsDevice, cam);
|
||||
@@ -272,11 +270,21 @@ namespace Barotrauma
|
||||
BlendState.NonPremultiplied,
|
||||
SamplerState.LinearClamp, DepthStencilState.DepthRead, null, null,
|
||||
cam.Transform);
|
||||
if (backgroundSpriteManager != null) backgroundSpriteManager.DrawObjects(spriteBatch, cam, drawFront: true);
|
||||
backgroundSpriteManager?.DrawObjectsMid(spriteBatch, cam);
|
||||
spriteBatch.End();
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, Camera cam)
|
||||
public void DrawForeground(SpriteBatch spriteBatch, Camera cam, LevelObjectManager backgroundSpriteManager = null)
|
||||
{
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred,
|
||||
BlendState.NonPremultiplied,
|
||||
SamplerState.LinearClamp, DepthStencilState.DepthRead, null, null,
|
||||
cam.Transform);
|
||||
backgroundSpriteManager?.DrawObjectsFront(spriteBatch, cam);
|
||||
spriteBatch.End();
|
||||
}
|
||||
|
||||
public void DrawDebugOverlay(SpriteBatch spriteBatch, Camera cam)
|
||||
{
|
||||
if (GameMain.DebugDraw && cam.Zoom > 0.1f)
|
||||
{
|
||||
|
||||
@@ -391,7 +391,7 @@ namespace Barotrauma.Lights
|
||||
if (GUI.DisableItemHighlights) { return false; }
|
||||
|
||||
highlightedEntities.Clear();
|
||||
if (Character.Controlled != null && (!Character.Controlled.IsKeyDown(InputType.Aim) || Character.Controlled.SelectedItems.Any(it => it?.GetComponent<Sprayer>() == null)))
|
||||
if (Character.Controlled != null && (!Character.Controlled.IsKeyDown(InputType.Aim) || Character.Controlled.HeldItems.Any(it => it.GetComponent<Sprayer>() == null)))
|
||||
{
|
||||
if (Character.Controlled.FocusedItem != null)
|
||||
{
|
||||
|
||||
@@ -222,7 +222,7 @@ namespace Barotrauma
|
||||
return !tileDiscovered[MathHelper.Clamp(x, 0, tileDiscovered.Length), MathHelper.Clamp(y, 0, tileDiscovered.Length)];
|
||||
}
|
||||
|
||||
partial void ChangeLocationType(Location location, string prevName, LocationTypeChange change)
|
||||
partial void ChangeLocationTypeProjSpecific(Location location, string prevName, LocationTypeChange change)
|
||||
{
|
||||
if (change.Messages.Any())
|
||||
{
|
||||
@@ -383,11 +383,11 @@ namespace Barotrauma
|
||||
Level.Loaded.DebugSetEndLocation(null);
|
||||
|
||||
CurrentLocation.Discovered = true;
|
||||
CurrentLocation.CreateStore();
|
||||
OnLocationChanged?.Invoke(prevLocation, CurrentLocation);
|
||||
SelectLocation(-1);
|
||||
if (GameMain.Client == null)
|
||||
{
|
||||
CurrentLocation.CreateStore();
|
||||
ProgressWorld();
|
||||
}
|
||||
else
|
||||
@@ -550,7 +550,7 @@ namespace Barotrauma
|
||||
|
||||
location.Type.Sprite.Draw(spriteBatch, pos, color,
|
||||
scale: generationParams.LocationIconSize / location.Type.Sprite.size.X * iconScale * zoom);
|
||||
if (location.TypeChangeTimer <= 0 && !string.IsNullOrEmpty(location.LastTypeChangeMessage) && generationParams.TypeChangeIcon != null)
|
||||
if (location.TimeSinceLastTypeChange < 1 && !string.IsNullOrEmpty(location.LastTypeChangeMessage) && generationParams.TypeChangeIcon != null)
|
||||
{
|
||||
Vector2 typeChangeIconPos = pos + new Vector2(1.35f, -0.35f) * generationParams.LocationIconSize * 0.5f * zoom;
|
||||
float typeChangeIconScale = 18.0f / generationParams.TypeChangeIcon.SourceRect.Width;
|
||||
@@ -610,7 +610,7 @@ namespace Barotrauma
|
||||
Vector2 nameSize = GUI.LargeFont.MeasureString(HighlightedLocation.Name);
|
||||
Vector2 typeSize = GUI.Font.MeasureString(HighlightedLocation.Type.Name);
|
||||
Vector2 size = new Vector2(Math.Max(nameSize.X, typeSize.X), nameSize.Y + typeSize.Y);
|
||||
bool showReputation = HighlightedLocation.Discovered && HighlightedLocation.Type.HasOutpost && HighlightedLocation.Reputation != null;
|
||||
bool showReputation = hudVisibility > 0.0f && HighlightedLocation.Discovered && HighlightedLocation.Type.HasOutpost && HighlightedLocation.Reputation != null;
|
||||
string repLabelText = null, repValueText = null;
|
||||
Vector2 repLabelSize = Vector2.Zero, repBarSize = Vector2.Zero;
|
||||
if (showReputation)
|
||||
|
||||
@@ -214,7 +214,7 @@ namespace Barotrauma
|
||||
}
|
||||
else if (PlayerInput.KeyHit(Keys.V))
|
||||
{
|
||||
Paste(cam.WorldViewCenter);
|
||||
Paste(cam.ScreenToWorld(PlayerInput.MousePosition));
|
||||
}
|
||||
else if (PlayerInput.KeyHit(Keys.G))
|
||||
{
|
||||
@@ -279,31 +279,10 @@ namespace Barotrauma
|
||||
|
||||
if (GUI.KeyboardDispatcher.Subscriber == null)
|
||||
{
|
||||
int up = PlayerInput.KeyDown(Keys.Up) ? 1 : 0,
|
||||
down = PlayerInput.KeyDown(Keys.Down) ? -1 : 0,
|
||||
left = PlayerInput.KeyDown(Keys.Left) ? -1 : 0,
|
||||
right = PlayerInput.KeyDown(Keys.Right) ? 1 : 0;
|
||||
|
||||
int xKeysDown = (left + right);
|
||||
int yKeysDown = (up + down);
|
||||
|
||||
if (xKeysDown != 0 || yKeysDown != 0) { keyDelay += (float) Timing.Step; } else { keyDelay = 0; }
|
||||
|
||||
Vector2 nudgeAmount = Vector2.Zero;
|
||||
|
||||
if (keyDelay >= 0.5f)
|
||||
Vector2 nudge = GetNudgeAmount();
|
||||
if (nudge != Vector2.Zero)
|
||||
{
|
||||
nudgeAmount.Y = yKeysDown;
|
||||
nudgeAmount.X = xKeysDown;
|
||||
}
|
||||
|
||||
if (PlayerInput.KeyHit(Keys.Up)) nudgeAmount.Y = 1f;
|
||||
if (PlayerInput.KeyHit(Keys.Down)) nudgeAmount.Y = -1f;
|
||||
if (PlayerInput.KeyHit(Keys.Left)) nudgeAmount.X = -1f;
|
||||
if (PlayerInput.KeyHit(Keys.Right)) nudgeAmount.X = 1f;
|
||||
if (nudgeAmount != Vector2.Zero)
|
||||
{
|
||||
foreach (MapEntity entityToNudge in selectedList) { entityToNudge.Move(nudgeAmount); }
|
||||
foreach (MapEntity entityToNudge in selectedList) { entityToNudge.Move(nudge); }
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -476,6 +455,8 @@ namespace Barotrauma
|
||||
{
|
||||
if (PlayerInput.PrimaryMouseButtonHeld() &&
|
||||
PlayerInput.KeyUp(Keys.Space) &&
|
||||
PlayerInput.KeyUp(Keys.LeftAlt) &&
|
||||
PlayerInput.KeyUp(Keys.RightAlt) &&
|
||||
(highlightedListBox == null || (GUI.MouseOn != highlightedListBox && !highlightedListBox.IsParentOf(GUI.MouseOn))))
|
||||
{
|
||||
//if clicking a selected entity, start moving it
|
||||
@@ -491,6 +472,37 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public static Vector2 GetNudgeAmount(bool doHold = true)
|
||||
{
|
||||
Vector2 nudgeAmount = Vector2.Zero;
|
||||
if (doHold)
|
||||
{
|
||||
int up = PlayerInput.KeyDown(Keys.Up) ? 1 : 0,
|
||||
down = PlayerInput.KeyDown(Keys.Down) ? -1 : 0,
|
||||
left = PlayerInput.KeyDown(Keys.Left) ? -1 : 0,
|
||||
right = PlayerInput.KeyDown(Keys.Right) ? 1 : 0;
|
||||
|
||||
int xKeysDown = (left + right);
|
||||
int yKeysDown = (up + down);
|
||||
|
||||
if (xKeysDown != 0 || yKeysDown != 0) { keyDelay += (float) Timing.Step; } else { keyDelay = 0; }
|
||||
|
||||
|
||||
if (keyDelay >= 0.5f)
|
||||
{
|
||||
nudgeAmount.Y = yKeysDown;
|
||||
nudgeAmount.X = xKeysDown;
|
||||
}
|
||||
}
|
||||
|
||||
if (PlayerInput.KeyHit(Keys.Up)) nudgeAmount.Y = 1f;
|
||||
if (PlayerInput.KeyHit(Keys.Down)) nudgeAmount.Y = -1f;
|
||||
if (PlayerInput.KeyHit(Keys.Left)) nudgeAmount.X = -1f;
|
||||
if (PlayerInput.KeyHit(Keys.Right)) nudgeAmount.X = 1f;
|
||||
|
||||
return nudgeAmount;
|
||||
}
|
||||
|
||||
public MapEntity GetReplacementOrThis()
|
||||
{
|
||||
return ReplacedBy?.GetReplacementOrThis() ?? this;
|
||||
@@ -511,7 +523,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (entities == null)
|
||||
{
|
||||
if (potentialContainer.OwnInventory != null && potentialContainer.ParentInventory == null && !potentialContainer.OwnInventory.IsFull())
|
||||
if (potentialContainer.OwnInventory != null && potentialContainer.ParentInventory == null && !potentialContainer.OwnInventory.IsFull(takeStacksIntoAccount: true))
|
||||
{
|
||||
targetContainer = potentialContainer;
|
||||
break;
|
||||
|
||||
@@ -45,8 +45,11 @@ namespace Barotrauma
|
||||
{
|
||||
CreateInstance(newRect);
|
||||
placePosition = Vector2.Zero;
|
||||
if (!PlayerInput.IsShiftDown())
|
||||
{
|
||||
selected = null;
|
||||
}
|
||||
}
|
||||
|
||||
newRect.Y = -newRect.Y;
|
||||
}
|
||||
|
||||
@@ -191,10 +191,11 @@ namespace Barotrauma
|
||||
Vector2 max = new Vector2(worldRect.Right, worldRect.Y);
|
||||
foreach (DecorativeSprite decorativeSprite in Prefab.DecorativeSprites)
|
||||
{
|
||||
min.X = Math.Min(worldPos.X - decorativeSprite.Sprite.size.X * decorativeSprite.Sprite.RelativeOrigin.X * decorativeSprite.Scale * Scale, min.X);
|
||||
max.X = Math.Max(worldPos.X + decorativeSprite.Sprite.size.X * (1.0f - decorativeSprite.Sprite.RelativeOrigin.X) * decorativeSprite.Scale * Scale, max.X);
|
||||
min.Y = Math.Min(worldPos.Y - decorativeSprite.Sprite.size.Y * (1.0f - decorativeSprite.Sprite.RelativeOrigin.Y) * decorativeSprite.Scale * Scale, min.Y);
|
||||
max.Y = Math.Max(worldPos.Y + decorativeSprite.Sprite.size.Y * decorativeSprite.Sprite.RelativeOrigin.Y * decorativeSprite.Scale * Scale, max.Y);
|
||||
float scale = decorativeSprite.GetScale(spriteAnimState[decorativeSprite].RandomScaleFactor) * Scale;
|
||||
min.X = Math.Min(worldPos.X - decorativeSprite.Sprite.size.X * decorativeSprite.Sprite.RelativeOrigin.X * scale, min.X);
|
||||
max.X = Math.Max(worldPos.X + decorativeSprite.Sprite.size.X * (1.0f - decorativeSprite.Sprite.RelativeOrigin.X) * scale, max.X);
|
||||
min.Y = Math.Min(worldPos.Y - decorativeSprite.Sprite.size.Y * (1.0f - decorativeSprite.Sprite.RelativeOrigin.Y) * scale, min.Y);
|
||||
max.Y = Math.Max(worldPos.Y + decorativeSprite.Sprite.size.Y * decorativeSprite.Sprite.RelativeOrigin.Y * scale, max.Y);
|
||||
}
|
||||
|
||||
if (min.X > worldView.Right || max.X < worldView.X) { return false; }
|
||||
@@ -220,9 +221,14 @@ namespace Barotrauma
|
||||
Draw(spriteBatch, editing, false, damageEffect);
|
||||
}
|
||||
|
||||
private float GetRealDepth()
|
||||
{
|
||||
return SpriteDepthOverrideIsSet ? SpriteOverrideDepth : prefab.sprite.Depth;
|
||||
}
|
||||
|
||||
public float GetDrawDepth()
|
||||
{
|
||||
return GetDrawDepth(SpriteDepthOverrideIsSet ? SpriteOverrideDepth : prefab.sprite.Depth, prefab.sprite);
|
||||
return GetDrawDepth(GetRealDepth(), prefab.sprite);
|
||||
}
|
||||
|
||||
private void Draw(SpriteBatch spriteBatch, bool editing, bool back = true, Effect damageEffect = null)
|
||||
@@ -320,7 +326,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
if (back == depth > 0.5f)
|
||||
if (back == GetRealDepth() > 0.5f)
|
||||
{
|
||||
SpriteEffects oldEffects = prefab.sprite.effects;
|
||||
prefab.sprite.effects ^= SpriteEffects;
|
||||
@@ -377,10 +383,10 @@ namespace Barotrauma
|
||||
foreach (var decorativeSprite in Prefab.DecorativeSprites)
|
||||
{
|
||||
if (!spriteAnimState[decorativeSprite].IsActive) { continue; }
|
||||
float rotation = decorativeSprite.GetRotation(ref spriteAnimState[decorativeSprite].RotationState);
|
||||
Vector2 offset = decorativeSprite.GetOffset(ref spriteAnimState[decorativeSprite].OffsetState) * Scale;
|
||||
float rotation = decorativeSprite.GetRotation(ref spriteAnimState[decorativeSprite].RotationState, spriteAnimState[decorativeSprite].RandomRotationFactor);
|
||||
Vector2 offset = decorativeSprite.GetOffset(ref spriteAnimState[decorativeSprite].OffsetState, spriteAnimState[decorativeSprite].RandomOffsetMultiplier) * Scale;
|
||||
decorativeSprite.Sprite.Draw(spriteBatch, new Vector2(DrawPosition.X + offset.X, -(DrawPosition.Y + offset.Y)), color,
|
||||
rotation, decorativeSprite.Scale * Scale, prefab.sprite.effects,
|
||||
rotation, decorativeSprite.GetScale(spriteAnimState[decorativeSprite].RandomScaleFactor) * Scale, prefab.sprite.effects,
|
||||
depth: Math.Min(depth + (decorativeSprite.Sprite.Depth - prefab.sprite.Depth), 0.999f));
|
||||
}
|
||||
prefab.sprite.effects = oldEffects;
|
||||
|
||||
@@ -62,7 +62,11 @@ namespace Barotrauma
|
||||
};
|
||||
|
||||
SubEditorScreen.StoreCommand(new AddOrDeleteCommand(new List<MapEntity> { structure }, false));
|
||||
placePosition = Vector2.Zero;
|
||||
if (!PlayerInput.IsShiftDown())
|
||||
{
|
||||
selected = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@ namespace Barotrauma
|
||||
public readonly float Range;
|
||||
public readonly Vector2 FrequencyMultiplierRange;
|
||||
public readonly bool Stream;
|
||||
public readonly bool IgnoreMuffling;
|
||||
|
||||
|
||||
public string Filename
|
||||
{
|
||||
@@ -55,7 +57,7 @@ namespace Barotrauma
|
||||
{
|
||||
DebugConsole.ThrowError($"Loaded frequency range exceeds max value: {FrequencyMultiplierRange} (original string was \"{freqMultAttr}\")");
|
||||
}
|
||||
sound.IgnoreMuffling = element.GetAttributeBool("dontmuffle", false);
|
||||
IgnoreMuffling = element.GetAttributeBool("dontmuffle", false);
|
||||
}
|
||||
|
||||
public float GetRandomFrequencyMultiplier()
|
||||
@@ -376,22 +378,19 @@ namespace Barotrauma
|
||||
|
||||
public static void DrawGrid(SpriteBatch spriteBatch, int gridCells, Vector2 gridCenter, Vector2 roundedGridCenter, float alpha = 1.0f)
|
||||
{
|
||||
var horizontalLine = GUI.Style.GetComponentStyle("HorizontalLine").GetDefaultSprite();
|
||||
var verticalLine = GUI.Style.GetComponentStyle("VerticalLine").GetDefaultSprite();
|
||||
|
||||
Vector2 topLeft = roundedGridCenter - Vector2.One * GridSize * gridCells / 2;
|
||||
Vector2 bottomRight = roundedGridCenter + Vector2.One * GridSize * gridCells / 2;
|
||||
|
||||
for (int i = 0; i < gridCells; i++)
|
||||
{
|
||||
float distFromGridX = (MathUtils.RoundTowardsClosest(gridCenter.X, GridSize.X) - gridCenter.X) / GridSize.X;
|
||||
float distFromGridY = (MathUtils.RoundTowardsClosest(gridCenter.X, GridSize.Y) - gridCenter.X) / GridSize.Y;
|
||||
float distFromGridY = (MathUtils.RoundTowardsClosest(gridCenter.Y, GridSize.Y) - gridCenter.Y) / GridSize.Y;
|
||||
|
||||
float normalizedDistX = Math.Abs(i + distFromGridX - gridCells / 2) / (gridCells / 2);
|
||||
float normalizedDistY = Math.Abs(i - distFromGridY - gridCells / 2) / (gridCells / 2);
|
||||
|
||||
float expandX = MathHelper.Lerp(30.0f, 0.0f, normalizedDistX);
|
||||
float expandY = MathHelper.Lerp(30.0f, 0.0f, normalizedDistY);
|
||||
float expandX = MathHelper.Lerp(30.0f, 0.0f, normalizedDistY);
|
||||
float expandY = MathHelper.Lerp(30.0f, 0.0f, normalizedDistX);
|
||||
|
||||
GUI.DrawLine(spriteBatch,
|
||||
new Vector2(topLeft.X - expandX, -bottomRight.Y + i * GridSize.Y),
|
||||
@@ -420,9 +419,10 @@ namespace Barotrauma
|
||||
parent.RectTransform, Anchor.Center),
|
||||
style: null);
|
||||
|
||||
var connectedSubs = GetConnectedSubs();
|
||||
foreach (Hull hull in Hull.hullList)
|
||||
{
|
||||
if (hull.Submarine != this && !(DockedTo.Contains(hull.Submarine))) continue;
|
||||
if (hull.Submarine != this && !connectedSubs.Contains(hull.Submarine)) { continue; }
|
||||
if (ignoreOutpost && !IsEntityFoundOnThisSub(hull, true)) { continue; }
|
||||
|
||||
Vector2 relativeHullPos = new Vector2(
|
||||
@@ -533,11 +533,11 @@ namespace Barotrauma
|
||||
for (int i = 0; i < item.Connections.Count; i++)
|
||||
{
|
||||
int wireCount = item.Connections[i].Wires.Count(w => w != null);
|
||||
if (doorLinks + wireCount > Connection.MaxLinked)
|
||||
if (doorLinks + wireCount > item.Connections[i].MaxWires)
|
||||
{
|
||||
errorMsgs.Add(TextManager.GetWithVariables("InsufficientFreeConnectionsWarning",
|
||||
new string[] { "[doorcount]", "[freeconnectioncount]" },
|
||||
new string[] { doorLinks.ToString(), (Connection.MaxLinked - wireCount).ToString() }));
|
||||
new string[] { doorLinks.ToString(), (item.Connections[i].MaxWires - wireCount).ToString() }));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
public string Name;
|
||||
public string PreferredJob;
|
||||
public CharacterTeamType PreferredTeam;
|
||||
public UInt16 NameID;
|
||||
public UInt64 SteamID;
|
||||
public byte ID;
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
private byte myID;
|
||||
|
||||
private List<Client> otherClients;
|
||||
private readonly List<Client> otherClients;
|
||||
|
||||
public readonly List<SubmarineInfo> ServerSubmarines = new List<SubmarineInfo>();
|
||||
|
||||
@@ -94,13 +94,13 @@ namespace Barotrauma.Networking
|
||||
|
||||
private UInt16 lastSentChatMsgID = 0; //last message this client has successfully sent
|
||||
private UInt16 lastQueueChatMsgID = 0; //last message added to the queue
|
||||
private List<ChatMessage> chatMsgQueue = new List<ChatMessage>();
|
||||
private readonly List<ChatMessage> chatMsgQueue = new List<ChatMessage>();
|
||||
|
||||
public UInt16 LastSentEntityEventID;
|
||||
|
||||
private ClientEntityEventManager entityEventManager;
|
||||
private readonly ClientEntityEventManager entityEventManager;
|
||||
|
||||
private FileReceiver fileReceiver;
|
||||
private readonly FileReceiver fileReceiver;
|
||||
|
||||
#if DEBUG
|
||||
public void PrintReceiverTransters()
|
||||
@@ -138,6 +138,12 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
private readonly List<Client> previouslyConnectedClients = new List<Client>();
|
||||
public IEnumerable<Client> PreviouslyConnectedClients
|
||||
{
|
||||
get { return previouslyConnectedClients; }
|
||||
}
|
||||
|
||||
public FileReceiver FileReceiver
|
||||
{
|
||||
get { return fileReceiver; }
|
||||
@@ -153,9 +159,9 @@ namespace Barotrauma.Networking
|
||||
get { return entityEventManager; }
|
||||
}
|
||||
|
||||
private object serverEndpoint;
|
||||
private int ownerKey;
|
||||
private bool steamP2POwner;
|
||||
private readonly object serverEndpoint;
|
||||
private readonly int ownerKey;
|
||||
private readonly bool steamP2POwner;
|
||||
|
||||
public bool IsServerOwner
|
||||
{
|
||||
@@ -852,7 +858,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
endMessage = inc.ReadString();
|
||||
bool missionSuccessful = inc.ReadBoolean();
|
||||
Character.TeamType winningTeam = (Character.TeamType)inc.ReadByte();
|
||||
CharacterTeamType winningTeam = (CharacterTeamType)inc.ReadByte();
|
||||
if (missionSuccessful && GameMain.GameSession?.Mission != null)
|
||||
{
|
||||
GameMain.GameSession.WinningTeam = winningTeam;
|
||||
@@ -1634,7 +1640,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
if (Submarine.MainSubs[i] == null) { break; }
|
||||
|
||||
var teamID = i == 0 ? Character.TeamType.Team1 : Character.TeamType.Team2;
|
||||
var teamID = i == 0 ? CharacterTeamType.Team1 : CharacterTeamType.Team2;
|
||||
Submarine.MainSubs[i].TeamID = teamID;
|
||||
foreach (Item item in Item.ItemList)
|
||||
{
|
||||
@@ -1828,6 +1834,7 @@ namespace Barotrauma.Networking
|
||||
UInt16 nameId = inc.ReadUInt16();
|
||||
string name = inc.ReadString();
|
||||
string preferredJob = inc.ReadString();
|
||||
byte preferredTeam = inc.ReadByte();
|
||||
UInt16 characterID = inc.ReadUInt16();
|
||||
float karma = inc.ReadSingle();
|
||||
bool muted = inc.ReadBoolean();
|
||||
@@ -1844,6 +1851,7 @@ namespace Barotrauma.Networking
|
||||
SteamID = steamId,
|
||||
Name = name,
|
||||
PreferredJob = preferredJob,
|
||||
PreferredTeam = (CharacterTeamType)preferredTeam,
|
||||
CharacterID = characterID,
|
||||
Karma = karma,
|
||||
Muted = muted,
|
||||
@@ -1878,6 +1886,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
existingClient.NameID = tc.NameID;
|
||||
existingClient.PreferredJob = tc.PreferredJob;
|
||||
existingClient.PreferredTeam = tc.PreferredTeam;
|
||||
existingClient.Character = null;
|
||||
existingClient.Karma = tc.Karma;
|
||||
existingClient.Muted = tc.Muted;
|
||||
@@ -1917,6 +1926,17 @@ namespace Barotrauma.Networking
|
||||
refreshCampaignUI = true;
|
||||
}
|
||||
}
|
||||
foreach (Client client in ConnectedClients)
|
||||
{
|
||||
if (!previouslyConnectedClients.Any(c => c.ID == client.ID))
|
||||
{
|
||||
while (previouslyConnectedClients.Count > 100)
|
||||
{
|
||||
previouslyConnectedClients.RemoveAt(0);
|
||||
}
|
||||
previouslyConnectedClients.Add(client);
|
||||
}
|
||||
}
|
||||
if (updateClientListId) { LastClientListUpdateID = listId; }
|
||||
|
||||
if (clientPeer is SteamP2POwnerPeer)
|
||||
@@ -2142,6 +2162,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
break;
|
||||
case ServerNetObject.ENTITY_POSITION:
|
||||
bool isItem = inc.ReadBoolean();
|
||||
UInt16 id = inc.ReadUInt16();
|
||||
uint msgLength = inc.ReadVariableUInt32();
|
||||
int msgEndPos = (int)(inc.BitPosition + msgLength * 8);
|
||||
@@ -2155,9 +2176,16 @@ namespace Barotrauma.Networking
|
||||
|
||||
entities.Add(entity);
|
||||
if (entity != null && (entity is Item || entity is Character || entity is Submarine))
|
||||
{
|
||||
if (entity is Item != isItem)
|
||||
{
|
||||
DebugConsole.AddWarning($"Received a potentially invalid ENTITY_POSITION message. Entity type does not match (server entity is {(isItem ? "an item" : "not an item")}, client entity is {(entity?.GetType().ToString() ?? "null")}). Ignoring the message...");
|
||||
}
|
||||
else
|
||||
{
|
||||
entity.ClientRead(objHeader.Value, inc, sendingTime);
|
||||
}
|
||||
}
|
||||
|
||||
//force to the correct position in case the entity doesn't exist
|
||||
//or the message wasn't read correctly for whatever reason
|
||||
@@ -2230,9 +2258,9 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameClient.ReadInGameUpdate", GameAnalyticsSDK.Net.EGAErrorSeverity.Critical, string.Join("\n", errorLines));
|
||||
|
||||
DebugConsole.ThrowError("Writing object data to \"crashreport_object.log\", please send this file to us at http://github.com/Regalis11/Barotrauma/issues");
|
||||
DebugConsole.ThrowError("Writing object data to \"networkerror_data.log\", please send this file to us at http://github.com/Regalis11/Barotrauma/issues");
|
||||
|
||||
using (FileStream fl = File.Open("crashreport_object.log", System.IO.FileMode.Create))
|
||||
using (FileStream fl = File.Open("networkerror_data.log", System.IO.FileMode.Create))
|
||||
{
|
||||
using (System.IO.BinaryWriter bw = new System.IO.BinaryWriter(fl))
|
||||
using (System.IO.StreamWriter sw = new System.IO.StreamWriter(fl))
|
||||
@@ -2245,7 +2273,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new Exception("Read error: please send us \"crashreport_object.bin\"!");
|
||||
throw new Exception("Read error: please send us \"networkerror_data.log\"!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2269,6 +2297,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
outmsg.Write("");
|
||||
}
|
||||
outmsg.Write((byte)GameMain.Config.TeamPreference);
|
||||
|
||||
if (!(GameMain.GameSession?.GameMode is MultiPlayerCampaign campaign) || campaign.LastSaveID == 0)
|
||||
{
|
||||
@@ -3241,12 +3270,12 @@ namespace Barotrauma.Networking
|
||||
|
||||
public virtual bool SelectCrewCharacter(Character character, GUIComponent frame)
|
||||
{
|
||||
if (character == null) return false;
|
||||
if (character == null) { return false; }
|
||||
|
||||
if (character != myCharacter)
|
||||
{
|
||||
var client = GameMain.NetworkMember.ConnectedClients.Find(c => c.Character == character);
|
||||
if (client == null) return false;
|
||||
var client = previouslyConnectedClients.Find(c => c.Character == character);
|
||||
if (client == null) { return false; }
|
||||
|
||||
CreateSelectionRelatedButtons(client, frame);
|
||||
}
|
||||
@@ -3256,7 +3285,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
public virtual bool SelectCrewClient(Client client, GUIComponent frame)
|
||||
{
|
||||
if (client == null || client.ID == ID) return false;
|
||||
if (client == null || client.ID == ID) { return false; }
|
||||
CreateSelectionRelatedButtons(client, frame);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ namespace Barotrauma
|
||||
CreateLabeledSlider(parent, 0.0f, 1.0f, 0.01f, nameof(DamageEnemyKarmaIncrease));
|
||||
CreateLabeledSlider(parent, 0.0f, 1.0f, 0.01f, nameof(ItemRepairKarmaIncrease));
|
||||
CreateLabeledSlider(parent, 0.0f, 10.0f, 0.05f, nameof(ExtinguishFireKarmaIncrease));
|
||||
CreateLabeledSlider(parent, 0.0f, 1.0f, 0.01f, nameof(BallastFloraKarmaIncrease));
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.12f), parent.RectTransform), TextManager.Get("Karma.NegativeActions"),
|
||||
textAlignment: Alignment.Center, font: GUI.SubHeadingFont)
|
||||
@@ -61,7 +62,6 @@ namespace Barotrauma
|
||||
CreateLabeledNumberInput(parent, 0, 20, nameof(AllowedWireDisconnectionsPerMinute));
|
||||
CreateLabeledSlider(parent, 0.0f, 20.0f, 0.5f, nameof(WireDisconnectionKarmaDecrease));
|
||||
CreateLabeledSlider(parent, 0.0f, 30.0f, 1.0f, nameof(SpamFilterKarmaDecrease));
|
||||
CreateLabeledSlider(parent, 0.0f, 1.0f, 0.01f, nameof(BallastFloraKarmaIncrease));
|
||||
|
||||
//hide these for now if a localized text is not available
|
||||
if (TextManager.ContainsTag("Karma." + nameof(DangerousItemStealKarmaDecrease)))
|
||||
|
||||
@@ -226,7 +226,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
else
|
||||
{
|
||||
long msgPosition = msg.BitPosition;
|
||||
int msgPosition = msg.BitPosition;
|
||||
if (GameSettings.VerboseLogging)
|
||||
{
|
||||
DebugConsole.NewMessage("received msg " + thisEventID + " (" + entity.ToString() + ")",
|
||||
@@ -242,9 +242,9 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
string errorMsg = "Message byte position incorrect after reading an event for the entity \"" + entity.ToString()
|
||||
+ "\". Read " + (msg.BitPosition - msgPosition) + " bits, expected message length was " + (msgLength * 8) + " bits.";
|
||||
#if DEBUG
|
||||
|
||||
DebugConsole.ThrowError(errorMsg);
|
||||
#endif
|
||||
|
||||
GameAnalyticsManager.AddErrorEventOnce("ClientEntityEventManager.Read:BitPosMismatch", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||
|
||||
//TODO: force the BitPosition to correct place? Having some entity in a potentially incorrect state is not as bad as a desync kick
|
||||
|
||||
@@ -168,7 +168,19 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
Close(disableReconnect: true);
|
||||
|
||||
string missingModNames = "\n- " + string.Join("\n\n- ", missingPackages.Select(p => GetPackageStr(p))) + "\n\n";
|
||||
string missingModNames = "\n";
|
||||
int displayedModCount = 0;
|
||||
foreach (ServerContentPackage missingPackage in missingPackages)
|
||||
{
|
||||
missingModNames += "\n- " + GetPackageStr(missingPackage);
|
||||
displayedModCount++;
|
||||
if (GUI.Font.MeasureString(missingModNames).Y > GameMain.GraphicsHeight * 0.5f)
|
||||
{
|
||||
missingModNames += "\n\n" + TextManager.GetWithVariable("workshopitemdownloadprompttruncated", "[number]", (missingPackages.Count - displayedModCount).ToString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
missingModNames += "\n\n";
|
||||
|
||||
var msgBox = new GUIMessageBox(
|
||||
TextManager.Get("WorkshopItemDownloadTitle"),
|
||||
@@ -189,6 +201,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (!contentPackageOrderReceived)
|
||||
{
|
||||
GameMain.Config.BackUpModOrder();
|
||||
GameMain.Config.SwapPackages(corePackage.CorePackage, regularPackages.Select(p => p.RegularPackage).ToList());
|
||||
contentPackageOrderReceived = true;
|
||||
}
|
||||
|
||||
@@ -195,10 +195,11 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
foreach (var data in line.RichData)
|
||||
{
|
||||
UInt64 id = 0;
|
||||
if (!UInt64.TryParse(data.Metadata, out id)) { return; }
|
||||
Client client = GameMain.Client.ConnectedClients.Find(c => c.SteamID == id);
|
||||
client ??= GameMain.Client.ConnectedClients.Find(c => c.ID == id);
|
||||
if (!UInt64.TryParse(data.Metadata, out ulong id)) { return; }
|
||||
Client client = GameMain.Client.ConnectedClients.Find(c => c.SteamID == id)
|
||||
?? GameMain.Client.ConnectedClients.Find(c => c.ID == id)
|
||||
?? GameMain.Client.PreviouslyConnectedClients.FirstOrDefault(c => c.SteamID == id)
|
||||
?? GameMain.Client.PreviouslyConnectedClients.FirstOrDefault(c => c.ID == id);
|
||||
if (client != null && client.Karma < 40.0f)
|
||||
{
|
||||
textContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.0f), listBox.Content.RectTransform),
|
||||
@@ -243,10 +244,11 @@ namespace Barotrauma.Networking
|
||||
Data = data,
|
||||
OnClick = (component, area) =>
|
||||
{
|
||||
UInt64 id = 0;
|
||||
if (!UInt64.TryParse(area.Data.Metadata, out id)) { return; }
|
||||
Client client = GameMain.Client.ConnectedClients.Find(c => c.SteamID == id);
|
||||
client ??= GameMain.Client.ConnectedClients.Find(c => c.ID == id);
|
||||
if (!UInt64.TryParse(area.Data.Metadata, out UInt64 id)) { return; }
|
||||
Client client = GameMain.Client.ConnectedClients.Find(c => c.SteamID == id)
|
||||
?? GameMain.Client.ConnectedClients.Find(c => c.ID == id)
|
||||
?? GameMain.Client.PreviouslyConnectedClients.FirstOrDefault(c => c.SteamID == id)
|
||||
?? GameMain.Client.PreviouslyConnectedClients.FirstOrDefault(c => c.ID == id);
|
||||
if (client == null) { return; }
|
||||
GameMain.NetLobbyScreen.SelectPlayer(client);
|
||||
}
|
||||
|
||||
@@ -269,14 +269,13 @@ namespace Barotrauma.Steam
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: find a better strategy to fetch all lobbies, this is gonna take forever if we actually have 10000 lobbies
|
||||
Steamworks.Data.LobbyQuery lobbyQuery = Steamworks.SteamMatchmaking.CreateLobbyQuery().FilterDistanceWorldwide().WithMaxResults(10000);
|
||||
|
||||
Steamworks.Dispatch.OnDebugCallback = (callbackType, contents, isServer) =>
|
||||
{
|
||||
DebugConsole.NewMessage($"{callbackType}: " + contents, Color.Yellow);
|
||||
};
|
||||
TaskPool.Add("LobbyQueryRequest", lobbyQuery.RequestAsync(),
|
||||
|
||||
TaskPool.Add("LobbyQueryRequest", LobbyQueryRequest(),
|
||||
(t) =>
|
||||
{
|
||||
Steamworks.Dispatch.OnDebugCallback = null;
|
||||
@@ -286,7 +285,7 @@ namespace Barotrauma.Steam
|
||||
taskDone();
|
||||
return;
|
||||
}
|
||||
var lobbies = ((Task<Steamworks.Data.Lobby[]>)t).Result;
|
||||
var lobbies = ((Task<List<Steamworks.Data.Lobby>>)t).Result;
|
||||
if (lobbies != null)
|
||||
{
|
||||
foreach (var lobby in lobbies)
|
||||
@@ -373,6 +372,32 @@ namespace Barotrauma.Steam
|
||||
return true;
|
||||
}
|
||||
|
||||
public static async Task<List<Steamworks.Data.Lobby>> LobbyQueryRequest()
|
||||
{
|
||||
List<Steamworks.Data.Lobby> allLobbies = new List<Steamworks.Data.Lobby>();
|
||||
Steamworks.Data.LobbyQuery lobbyQuery = Steamworks.SteamMatchmaking.CreateLobbyQuery()
|
||||
.FilterDistanceWorldwide()
|
||||
.WithMaxResults(50);
|
||||
//steamworks seems to unable to retrieve more than 50
|
||||
//lobbies per request; to work around this, we'll make
|
||||
//up to 10 requests, asking to ignore all previous results
|
||||
//in each subsequent request
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
Steamworks.Data.Lobby[] lobbies = await lobbyQuery.RequestAsync();
|
||||
if (lobbies == null) { break; }
|
||||
foreach (var l in lobbies)
|
||||
{
|
||||
lobbyQuery = lobbyQuery
|
||||
.WithoutKeyValue("lobbyowner", l.GetData("lobbyowner"));
|
||||
}
|
||||
allLobbies.AddRange(lobbies);
|
||||
}
|
||||
|
||||
//make sure all returned lobbies are distinct, don't want any duplicates here
|
||||
return allLobbies.Select(l => l.Id).Distinct().Select(i => allLobbies.Find(l => l.Id == i)).ToList();
|
||||
}
|
||||
|
||||
public static void AssignLobbyDataToServerInfo(Steamworks.Data.Lobby lobby, ServerInfo serverInfo)
|
||||
{
|
||||
serverInfo.OwnerVerified = true;
|
||||
@@ -1173,7 +1198,7 @@ namespace Barotrauma.Steam
|
||||
|
||||
foreach (ContentFile contentFile in contentPackage.Files)
|
||||
{
|
||||
contentFile.Path = contentFile.Path.CleanUpPath();
|
||||
contentFile.Path = contentFile.Path.CleanUpPathCrossPlatform(correctFilenameCase: true, item?.Directory);
|
||||
string sourceFile = Path.Combine(item?.Directory, contentFile.Path);
|
||||
if (!File.Exists(sourceFile))
|
||||
{
|
||||
|
||||
@@ -239,7 +239,7 @@ namespace Barotrauma.Networking
|
||||
bool allowEnqueue = false;
|
||||
if (GameMain.WindowActive)
|
||||
{
|
||||
ForceLocal = captureTimer > 0 ? ForceLocal : false;
|
||||
ForceLocal = captureTimer > 0 ? ForceLocal : GameMain.Config.UseLocalVoiceByDefault;
|
||||
bool pttDown = false;
|
||||
if ((PlayerInput.KeyDown(InputType.Voice) || PlayerInput.KeyDown(InputType.LocalVoice)) &&
|
||||
GUI.KeyboardDispatcher.Subscriber == null)
|
||||
|
||||
@@ -101,7 +101,7 @@ namespace Barotrauma.Networking
|
||||
var messageType = !client.VoipQueue.ForceLocal && ChatMessage.CanUseRadio(client.Character, out radio) ? ChatMessageType.Radio : ChatMessageType.Default;
|
||||
client.Character.ShowSpeechBubble(1.25f, ChatMessage.MessageColor[(int)messageType]);
|
||||
|
||||
client.VoipSound.UseRadioFilter = messageType == ChatMessageType.Radio;
|
||||
client.VoipSound.UseRadioFilter = messageType == ChatMessageType.Radio && !GameMain.Config.DisableVoiceChatFilters;
|
||||
if (client.VoipSound.UseRadioFilter)
|
||||
{
|
||||
client.VoipSound.SetRange(radio.Range * 0.8f, radio.Range);
|
||||
@@ -110,7 +110,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
client.VoipSound.SetRange(ChatMessage.SpeakRange * 0.4f, ChatMessage.SpeakRange);
|
||||
}
|
||||
if (!client.VoipSound.UseRadioFilter && Character.Controlled != null)
|
||||
if (!client.VoipSound.UseRadioFilter && Character.Controlled != null && !GameMain.Config.DisableVoiceChatFilters)
|
||||
{
|
||||
client.VoipSound.UseMuffleFilter = SoundPlayer.ShouldMuffleSound(Character.Controlled, client.Character.WorldPosition, ChatMessage.SpeakRange, client.Character.CurrentHull);
|
||||
}
|
||||
|
||||
@@ -11,15 +11,15 @@ namespace Barotrauma
|
||||
{
|
||||
class CampaignSetupUI
|
||||
{
|
||||
private GUIComponent newGameContainer, loadGameContainer;
|
||||
private readonly GUIComponent newGameContainer, loadGameContainer;
|
||||
|
||||
private GUIListBox subList;
|
||||
private GUIListBox saveList;
|
||||
private List<GUITickBox> subTickBoxes;
|
||||
|
||||
private GUITextBox saveNameBox, seedBox;
|
||||
private readonly GUITextBox saveNameBox, seedBox;
|
||||
|
||||
private GUILayoutGroup subPreviewContainer;
|
||||
private readonly GUILayoutGroup subPreviewContainer;
|
||||
|
||||
private GUIButton loadGameButton, deleteMpSaveButton;
|
||||
|
||||
@@ -35,6 +35,12 @@ namespace Barotrauma
|
||||
private set;
|
||||
}
|
||||
|
||||
public GUITextBlock InitialMoneyText
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
private readonly bool isMultiplayer;
|
||||
|
||||
public CampaignSetupUI(bool isMultiplayer, GUIComponent newGameContainer, GUIComponent loadGameContainer, IEnumerable<SubmarineInfo> submarines, IEnumerable<string> saveFiles = null)
|
||||
@@ -122,10 +128,10 @@ namespace Barotrauma
|
||||
};
|
||||
|
||||
var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.12f),
|
||||
(isMultiplayer ? leftColumn : rightColumn).RectTransform) { MaxSize = new Point(int.MaxValue, 60) }, childAnchor: Anchor.TopRight);
|
||||
(isMultiplayer ? leftColumn : rightColumn).RectTransform) { MaxSize = new Point(int.MaxValue, 60) }, childAnchor: Anchor.BottomRight, isHorizontal: true);
|
||||
if (!isMultiplayer) { buttonContainer.IgnoreLayoutGroups = true; }
|
||||
|
||||
StartButton = new GUIButton(new RectTransform(new Vector2(0.45f, 1f), buttonContainer.RectTransform, Anchor.BottomRight) { MaxSize = new Point(350, 60) }, TextManager.Get("StartCampaignButton"))
|
||||
StartButton = new GUIButton(new RectTransform(new Vector2(0.4f, 1f), buttonContainer.RectTransform, Anchor.BottomRight) { MaxSize = new Point(350, 60) }, TextManager.Get("StartCampaignButton"))
|
||||
{
|
||||
OnClicked = (GUIButton btn, object userData) =>
|
||||
{
|
||||
@@ -224,6 +230,27 @@ namespace Barotrauma
|
||||
}
|
||||
};
|
||||
|
||||
InitialMoneyText = new GUITextBlock(new RectTransform(new Vector2(0.6f, 1f), buttonContainer.RectTransform), "",
|
||||
font: isMultiplayer ? GUI.Style.SmallFont : GUI.Style.Font, textColor: GUI.Style.Green)
|
||||
{
|
||||
TextGetter = () =>
|
||||
{
|
||||
int initialMoney = CampaignMode.InitialMoney;
|
||||
if (isMultiplayer)
|
||||
{
|
||||
if (GameMain.NetLobbyScreen.SelectedSub != null)
|
||||
{
|
||||
initialMoney -= GameMain.NetLobbyScreen.SelectedSub.Price;
|
||||
}
|
||||
}
|
||||
else if (subList.SelectedData is SubmarineInfo subInfo)
|
||||
{
|
||||
initialMoney -= subInfo.Price;
|
||||
}
|
||||
initialMoney = Math.Max(initialMoney, isMultiplayer ? MultiPlayerCampaign.MinimumInitialMoney : 0);
|
||||
return TextManager.GetWithVariable("campaignstartingmoney", "[money]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", initialMoney));
|
||||
}
|
||||
};
|
||||
|
||||
if (!isMultiplayer)
|
||||
{
|
||||
@@ -366,7 +393,7 @@ namespace Barotrauma
|
||||
|
||||
if (!(obj is SubmarineInfo sub)) { return true; }
|
||||
#if !DEBUG
|
||||
if (!isMultiplayer && sub.Price > CampaignMode.MaxInitialSubmarinePrice && !GameMain.DebugDraw)
|
||||
if (!isMultiplayer && sub.Price > CampaignMode.InitialMoney && !GameMain.DebugDraw)
|
||||
{
|
||||
StartButton.Enabled = false;
|
||||
return false;
|
||||
@@ -419,13 +446,14 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
subsToShow = submarines.Where(s => s.IsCampaignCompatibleIgnoreClass).ToList();
|
||||
string downloadFolder = Path.GetFullPath(SaveUtil.SubmarineDownloadFolder);
|
||||
subsToShow = submarines.Where(s => s.IsCampaignCompatibleIgnoreClass && Path.GetDirectoryName(Path.GetFullPath(s.FilePath)) != downloadFolder).ToList();
|
||||
}
|
||||
|
||||
subsToShow.Sort((s1, s2) =>
|
||||
{
|
||||
int p1 = s1.Price > CampaignMode.MaxInitialSubmarinePrice ? 10 : 0;
|
||||
int p2 = s2.Price > CampaignMode.MaxInitialSubmarinePrice ? 10 : 0;
|
||||
int p1 = s1.Price > CampaignMode.InitialMoney ? 10 : 0;
|
||||
int p2 = s2.Price > CampaignMode.InitialMoney ? 10 : 0;
|
||||
return p1.CompareTo(p2) * 100 + s1.Name.CompareTo(s2.Name);
|
||||
});
|
||||
|
||||
@@ -450,13 +478,13 @@ namespace Barotrauma
|
||||
var priceText = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), textBlock.RectTransform, Anchor.CenterRight),
|
||||
TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", sub.Price)), textAlignment: Alignment.CenterRight, font: GUI.SmallFont)
|
||||
{
|
||||
TextColor = sub.Price > CampaignMode.MaxInitialSubmarinePrice ? GUI.Style.Red : textBlock.TextColor * 0.8f,
|
||||
TextColor = sub.Price > CampaignMode.InitialMoney ? GUI.Style.Red : textBlock.TextColor * 0.8f,
|
||||
ToolTip = textBlock.ToolTip
|
||||
};
|
||||
#if !DEBUG
|
||||
if (!GameMain.DebugDraw)
|
||||
{
|
||||
if (sub.Price > CampaignMode.MaxInitialSubmarinePrice || !sub.IsCampaignCompatible)
|
||||
if (sub.Price > CampaignMode.InitialMoney || !sub.IsCampaignCompatible)
|
||||
{
|
||||
textBlock.CanBeFocused = false;
|
||||
textBlock.TextColor *= 0.5f;
|
||||
@@ -466,7 +494,7 @@ namespace Barotrauma
|
||||
}
|
||||
if (SubmarineInfo.SavedSubmarines.Any())
|
||||
{
|
||||
var validSubs = subsToShow.Where(s => s.IsCampaignCompatible && s.Price <= CampaignMode.MaxInitialSubmarinePrice).ToList();
|
||||
var validSubs = subsToShow.Where(s => s.IsCampaignCompatible && s.Price <= CampaignMode.InitialMoney).ToList();
|
||||
if (validSubs.Count > 0)
|
||||
{
|
||||
subList.Select(validSubs[Rand.Int(validSubs.Count)]);
|
||||
|
||||
@@ -326,7 +326,7 @@ namespace Barotrauma
|
||||
break;
|
||||
|
||||
case CampaignMode.InteractionType.Store:
|
||||
Store?.Update();
|
||||
Store?.Update(deltaTime);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -820,6 +820,7 @@ namespace Barotrauma.CharacterEditor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spriteBatch.End();
|
||||
|
||||
// Lights
|
||||
@@ -859,12 +860,9 @@ namespace Barotrauma.CharacterEditor
|
||||
DrawSpritesheetEditor(spriteBatch, (float)deltaTime);
|
||||
}
|
||||
if (isDrawingLimb)
|
||||
{
|
||||
if (spriteSheetRect.Contains(PlayerInput.MousePosition))
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch, newLimbRect, Color.Yellow);
|
||||
}
|
||||
}
|
||||
if (jointCreationMode != JointCreationMode.None)
|
||||
{
|
||||
var textPos = new Vector2(GameMain.GraphicsWidth / 2 - 240, GameMain.GraphicsHeight / 4);
|
||||
@@ -1131,8 +1129,6 @@ namespace Barotrauma.CharacterEditor
|
||||
{
|
||||
SetToggle(limbsToggle, true);
|
||||
}
|
||||
if (spriteSheetRect.Contains(PlayerInput.MousePosition))
|
||||
{
|
||||
if (PlayerInput.PrimaryMouseButtonHeld())
|
||||
{
|
||||
if (newLimbRect == Rectangle.Empty)
|
||||
@@ -1155,11 +1151,6 @@ namespace Barotrauma.CharacterEditor
|
||||
newLimbRect = Rectangle.Empty;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
newLimbRect = Rectangle.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
private void CopyLimb(Limb limb)
|
||||
{
|
||||
@@ -1449,7 +1440,11 @@ namespace Barotrauma.CharacterEditor
|
||||
{
|
||||
if (allFiles == null)
|
||||
{
|
||||
#if DEBUG
|
||||
allFiles = CharacterPrefab.ConfigFilePaths.OrderBy(p => p).ToList();
|
||||
#else
|
||||
allFiles = CharacterPrefab.ConfigFilePaths.Where(p => !p.Contains("variant", StringComparison.OrdinalIgnoreCase)).OrderBy(p => p).ToList();
|
||||
#endif
|
||||
allFiles.ForEach(f => DebugConsole.NewMessage(f, Color.White));
|
||||
}
|
||||
return allFiles;
|
||||
@@ -1780,7 +1775,7 @@ namespace Barotrauma.CharacterEditor
|
||||
|
||||
// Animations
|
||||
AnimationParams.ClearCache();
|
||||
string animFolder = AnimationParams.GetFolder(name, contentPackage);
|
||||
string animFolder = AnimationParams.GetFolder(name);
|
||||
if (animations != null)
|
||||
{
|
||||
if (!Directory.Exists(animFolder))
|
||||
@@ -1791,7 +1786,7 @@ namespace Barotrauma.CharacterEditor
|
||||
{
|
||||
XElement element = animation.MainElement;
|
||||
element.SetAttributeValue("type", name);
|
||||
string fullPath = AnimationParams.GetDefaultFile(name, animation.AnimationType, contentPackage);
|
||||
string fullPath = AnimationParams.GetDefaultFile(name, animation.AnimationType);
|
||||
element.Name = AnimationParams.GetDefaultFileName(name, animation.AnimationType);
|
||||
#if DEBUG
|
||||
element.Save(fullPath);
|
||||
@@ -1816,7 +1811,7 @@ namespace Barotrauma.CharacterEditor
|
||||
default: continue;
|
||||
}
|
||||
Type type = AnimationParams.GetParamTypeFromAnimType(animType, isHumanoid);
|
||||
string fullPath = AnimationParams.GetDefaultFile(name, animType, contentPackage);
|
||||
string fullPath = AnimationParams.GetDefaultFile(name, animType);
|
||||
AnimationParams.Create(fullPath, name, animType, type);
|
||||
}
|
||||
}
|
||||
@@ -1836,9 +1831,8 @@ namespace Barotrauma.CharacterEditor
|
||||
private void ShowWearables()
|
||||
{
|
||||
if (character.Inventory == null) { return; }
|
||||
foreach (var item in character.Inventory.Items)
|
||||
foreach (var item in character.Inventory.AllItems)
|
||||
{
|
||||
if (item == null) { continue; }
|
||||
// Temp condition, todo: remove
|
||||
if (item.AllowedSlots.Contains(InvSlotType.Head) || item.AllowedSlots.Contains(InvSlotType.Headset)) { continue; }
|
||||
item.Equip(character);
|
||||
@@ -1847,7 +1841,7 @@ namespace Barotrauma.CharacterEditor
|
||||
|
||||
private void HideWearables()
|
||||
{
|
||||
character.Inventory?.Items.ForEachMod(i => i?.Unequip(character));
|
||||
character.Inventory?.AllItemsMod.ForEach(i => i.Unequip(character));
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -2787,8 +2781,10 @@ namespace Barotrauma.CharacterEditor
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
// Spacing
|
||||
new GUIFrame(new RectTransform(buttonSize / 2, layoutGroup.RectTransform), style: null) { CanBeFocused = false };
|
||||
|
||||
Vector2 messageBoxRelSize = new Vector2(0.5f, 0.7f);
|
||||
var saveRagdollButton = new GUIButton(new RectTransform(buttonSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("SaveRagdoll"));
|
||||
saveRagdollButton.OnClicked += (button, userData) =>
|
||||
@@ -3573,15 +3569,33 @@ namespace Barotrauma.CharacterEditor
|
||||
return rect;
|
||||
}
|
||||
|
||||
// TODO: refactor this so that it can be used in all cases
|
||||
private void UpdateSourceRect(Limb limb, Rectangle newRect)
|
||||
private void UpdateSourceRect(Limb limb, Rectangle newRect, bool resize)
|
||||
{
|
||||
limb.ActiveSprite.SourceRect = newRect;
|
||||
Sprite activeSprite = limb.ActiveSprite;
|
||||
activeSprite.SourceRect = newRect;
|
||||
if (limb.DamagedSprite != null)
|
||||
{
|
||||
limb.DamagedSprite.SourceRect = limb.ActiveSprite.SourceRect;
|
||||
limb.DamagedSprite.SourceRect = activeSprite.SourceRect;
|
||||
}
|
||||
Vector2 colliderSize = new Vector2(ConvertUnits.ToSimUnits(newRect.Width), ConvertUnits.ToSimUnits(newRect.Height));
|
||||
if (resize)
|
||||
{
|
||||
if (recalculateCollider)
|
||||
{
|
||||
RecalculateCollider(limb, colliderSize);
|
||||
}
|
||||
}
|
||||
var spritePos = new Vector2(spriteSheetOffsetX, GetOffsetY(activeSprite));
|
||||
var originWidget = GetLimbEditWidget($"{limb.Params.ID}_origin", limb);
|
||||
if (!resize && originWidget != null)
|
||||
{
|
||||
Vector2 newOrigin = (originWidget.DrawPos - spritePos - activeSprite.SourceRect.Location.ToVector2() * spriteSheetZoom) / spriteSheetZoom;
|
||||
RecalculateOrigin(limb, newOrigin);
|
||||
}
|
||||
else
|
||||
{
|
||||
RecalculateOrigin(limb);
|
||||
}
|
||||
TryUpdateLimbParam(limb, "sourcerect", newRect);
|
||||
if (limbPairEditing)
|
||||
{
|
||||
@@ -3592,30 +3606,25 @@ namespace Barotrauma.CharacterEditor
|
||||
{
|
||||
otherLimb.DamagedSprite.SourceRect = newRect;
|
||||
}
|
||||
TryUpdateLimbParam(otherLimb, "sourcerect", newRect);
|
||||
if (resize)
|
||||
{
|
||||
if (recalculateCollider)
|
||||
{
|
||||
RecalculateCollider(otherLimb, colliderSize);
|
||||
}
|
||||
}
|
||||
if (!resize && originWidget != null)
|
||||
{
|
||||
Vector2 newOrigin = (originWidget.DrawPos - spritePos - activeSprite.SourceRect.Location.ToVector2() * spriteSheetZoom) / spriteSheetZoom;
|
||||
RecalculateOrigin(otherLimb, newOrigin);
|
||||
}
|
||||
else
|
||||
{
|
||||
RecalculateOrigin(otherLimb);
|
||||
}
|
||||
TryUpdateLimbParam(otherLimb, "sourcerect", newRect);
|
||||
});
|
||||
};
|
||||
|
||||
void RecalculateOrigin(Limb l)
|
||||
{
|
||||
// Keeps the relative origin unchanged. The absolute origin will be recalculated.
|
||||
l.ActiveSprite.RelativeOrigin = l.ActiveSprite.RelativeOrigin;
|
||||
|
||||
// TODO:
|
||||
//if (lockSpriteOrigin)
|
||||
//{
|
||||
// // Keeps the absolute origin unchanged. The relative origin will be recalculated.
|
||||
// var spritePos = new Vector2(spriteSheetOffsetX, GetOffsetY(l));
|
||||
// l.ActiveSprite.Origin = (originWidget.DrawPos - spritePos - l.ActiveSprite.SourceRect.Location.ToVector2() * spriteSheetZoom) / spriteSheetZoom;
|
||||
// TryUpdateLimbParam(l, "origin", l.ActiveSprite.RelativeOrigin);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// // Keeps the relative origin unchanged. The absolute origin will be recalculated.
|
||||
// l.ActiveSprite.RelativeOrigin = l.ActiveSprite.RelativeOrigin;
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
private void CalculateSpritesheetZoom()
|
||||
@@ -4765,7 +4774,7 @@ namespace Barotrauma.CharacterEditor
|
||||
w.refresh();
|
||||
w.MouseHeld += dTime =>
|
||||
{
|
||||
var spritePos = new Vector2(spriteSheetOffsetX, GetOffsetY(limb));
|
||||
var spritePos = new Vector2(spriteSheetOffsetX, GetOffsetY(limb.ActiveSprite));
|
||||
w.DrawPos = PlayerInput.MousePosition.Clamp(spritePos + GetTopLeft() * spriteSheetZoom, spritePos + GetBottomRight() * spriteSheetZoom);
|
||||
sprite.Origin = (w.DrawPos - spritePos - sprite.SourceRect.Location.ToVector2() * spriteSheetZoom) / spriteSheetZoom;
|
||||
if (limb.DamagedSprite != null)
|
||||
@@ -4796,14 +4805,14 @@ namespace Barotrauma.CharacterEditor
|
||||
};
|
||||
w.PreDraw += (sb, dTime) =>
|
||||
{
|
||||
var spritePos = new Vector2(spriteSheetOffsetX, GetOffsetY(limb));
|
||||
var spritePos = new Vector2(spriteSheetOffsetX, GetOffsetY(limb.ActiveSprite));
|
||||
w.DrawPos = (spritePos + (sprite.Origin + sprite.SourceRect.Location.ToVector2()) * spriteSheetZoom)
|
||||
.Clamp(spritePos + GetTopLeft() * spriteSheetZoom, spritePos + GetBottomRight() * spriteSheetZoom);
|
||||
w.refresh();
|
||||
};
|
||||
});
|
||||
originWidget.Draw(spriteBatch, deltaTime);
|
||||
if (!lockSpritePosition)
|
||||
if (!lockSpritePosition && (limb.type != LimbType.Head || !character.IsHuman))
|
||||
{
|
||||
var positionWidget = GetLimbEditWidget($"{limb.Params.ID}_position", limb, widgetSize, Widget.Shape.Rectangle, initMethod: w =>
|
||||
{
|
||||
@@ -4812,17 +4821,20 @@ namespace Barotrauma.CharacterEditor
|
||||
w.MouseHeld += dTime =>
|
||||
{
|
||||
w.DrawPos = PlayerInput.MousePosition;
|
||||
var newRect = limb.ActiveSprite.SourceRect;
|
||||
Sprite activeSprite = limb.ActiveSprite;
|
||||
var newRect = activeSprite.SourceRect;
|
||||
newRect.Location = new Point(
|
||||
(int)((PlayerInput.MousePosition.X + halfSize - spriteSheetOffsetX) / spriteSheetZoom),
|
||||
(int)((PlayerInput.MousePosition.Y + halfSize - GetOffsetY(limb)) / spriteSheetZoom));
|
||||
limb.ActiveSprite.SourceRect = newRect;
|
||||
(int)((PlayerInput.MousePosition.Y + halfSize - GetOffsetY(activeSprite)) / spriteSheetZoom));
|
||||
activeSprite.SourceRect = newRect;
|
||||
if (limb.DamagedSprite != null)
|
||||
{
|
||||
limb.DamagedSprite.SourceRect = limb.ActiveSprite.SourceRect;
|
||||
limb.DamagedSprite.SourceRect = activeSprite.SourceRect;
|
||||
}
|
||||
RecalculateOrigin(limb);
|
||||
TryUpdateLimbParam(limb, "sourcerect", newRect);
|
||||
var spritePos = new Vector2(spriteSheetOffsetX, GetOffsetY(activeSprite));
|
||||
Vector2 newOrigin = (originWidget.DrawPos - spritePos - activeSprite.SourceRect.Location.ToVector2() * spriteSheetZoom) / spriteSheetZoom;
|
||||
RecalculateOrigin(limb, newOrigin);
|
||||
if (limbPairEditing)
|
||||
{
|
||||
UpdateOtherLimbs(limb, otherLimb =>
|
||||
@@ -4833,24 +4845,9 @@ namespace Barotrauma.CharacterEditor
|
||||
otherLimb.DamagedSprite.SourceRect = newRect;
|
||||
}
|
||||
TryUpdateLimbParam(otherLimb, "sourcerect", newRect);
|
||||
RecalculateOrigin(otherLimb);
|
||||
RecalculateOrigin(otherLimb, newOrigin);
|
||||
});
|
||||
};
|
||||
void RecalculateOrigin(Limb l)
|
||||
{
|
||||
if (lockSpriteOrigin)
|
||||
{
|
||||
// Keeps the absolute origin unchanged. The relative origin will be recalculated.
|
||||
var spritePos = new Vector2(spriteSheetOffsetX, GetOffsetY(l));
|
||||
l.ActiveSprite.Origin = (originWidget.DrawPos - spritePos - l.ActiveSprite.SourceRect.Location.ToVector2() * spriteSheetZoom) / spriteSheetZoom;
|
||||
TryUpdateLimbParam(l, "origin", l.ActiveSprite.RelativeOrigin);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Keeps the relative origin unchanged. The absolute origin will be recalculated.
|
||||
l.ActiveSprite.RelativeOrigin = l.ActiveSprite.RelativeOrigin;
|
||||
}
|
||||
}
|
||||
};
|
||||
w.PreDraw += (sb, dTime) => w.refresh();
|
||||
});
|
||||
@@ -4860,7 +4857,7 @@ namespace Barotrauma.CharacterEditor
|
||||
}
|
||||
positionWidget.Draw(spriteBatch, deltaTime);
|
||||
}
|
||||
if (!lockSpriteSize)
|
||||
if (!lockSpriteSize && (limb.type != LimbType.Head || !character.IsHuman))
|
||||
{
|
||||
var sizeWidget = GetLimbEditWidget($"{limb.Params.ID}_size", limb, widgetSize, Widget.Shape.Rectangle, initMethod: w =>
|
||||
{
|
||||
@@ -4869,22 +4866,24 @@ namespace Barotrauma.CharacterEditor
|
||||
w.MouseHeld += dTime =>
|
||||
{
|
||||
w.DrawPos = PlayerInput.MousePosition;
|
||||
var newRect = limb.ActiveSprite.SourceRect;
|
||||
float offset_y = limb.ActiveSprite.SourceRect.Y * spriteSheetZoom + GetOffsetY(limb);
|
||||
float offset_x = limb.ActiveSprite.SourceRect.X * spriteSheetZoom + spriteSheetOffsetX;
|
||||
Sprite activeSprite = limb.ActiveSprite;
|
||||
Rectangle newRect = activeSprite.SourceRect;
|
||||
float offset_y = activeSprite.SourceRect.Y * spriteSheetZoom + GetOffsetY(activeSprite);
|
||||
float offset_x = activeSprite.SourceRect.X * spriteSheetZoom + spriteSheetOffsetX;
|
||||
int width = (int)((PlayerInput.MousePosition.X - halfSize - offset_x) / spriteSheetZoom);
|
||||
int height = (int)((PlayerInput.MousePosition.Y - halfSize - offset_y) / spriteSheetZoom);
|
||||
newRect.Size = new Point(width, height);
|
||||
limb.ActiveSprite.SourceRect = newRect;
|
||||
limb.ActiveSprite.size = new Vector2(width, height);
|
||||
activeSprite.SourceRect = newRect;
|
||||
activeSprite.size = new Vector2(width, height);
|
||||
Vector2 colliderSize = new Vector2(ConvertUnits.ToSimUnits(width), ConvertUnits.ToSimUnits(height));
|
||||
if (recalculateCollider)
|
||||
{
|
||||
RecalculateCollider(limb);
|
||||
RecalculateCollider(limb, colliderSize);
|
||||
}
|
||||
RecalculateOrigin(limb);
|
||||
if (limb.DamagedSprite != null)
|
||||
{
|
||||
limb.DamagedSprite.SourceRect = limb.ActiveSprite.SourceRect;
|
||||
limb.DamagedSprite.SourceRect = activeSprite.SourceRect;
|
||||
}
|
||||
TryUpdateLimbParam(limb, "sourcerect", newRect);
|
||||
if (limbPairEditing)
|
||||
@@ -4895,7 +4894,7 @@ namespace Barotrauma.CharacterEditor
|
||||
RecalculateOrigin(otherLimb);
|
||||
if (recalculateCollider)
|
||||
{
|
||||
RecalculateCollider(otherLimb);
|
||||
RecalculateCollider(otherLimb, colliderSize);
|
||||
}
|
||||
if (otherLimb.DamagedSprite != null)
|
||||
{
|
||||
@@ -4904,29 +4903,6 @@ namespace Barotrauma.CharacterEditor
|
||||
TryUpdateLimbParam(otherLimb, "sourcerect", newRect);
|
||||
});
|
||||
};
|
||||
void RecalculateCollider(Limb l)
|
||||
{
|
||||
// We want the collider to be slightly smaller than the source rect, because the source rect is usually a bit bigger than the graphic.
|
||||
float multiplier = 0.9f;
|
||||
l.body.SetSize(new Vector2(ConvertUnits.ToSimUnits(width), ConvertUnits.ToSimUnits(height)) * l.Scale * RagdollParams.TextureScale * multiplier);
|
||||
TryUpdateLimbParam(l, "radius", ConvertUnits.ToDisplayUnits(l.body.radius / l.Params.Scale / RagdollParams.LimbScale / RagdollParams.TextureScale));
|
||||
TryUpdateLimbParam(l, "width", ConvertUnits.ToDisplayUnits(l.body.width / l.Params.Scale / RagdollParams.LimbScale / RagdollParams.TextureScale));
|
||||
TryUpdateLimbParam(l, "height", ConvertUnits.ToDisplayUnits(l.body.height / l.Params.Scale / RagdollParams.LimbScale / RagdollParams.TextureScale));
|
||||
}
|
||||
void RecalculateOrigin(Limb l)
|
||||
{
|
||||
if (lockSpriteOrigin)
|
||||
{
|
||||
// Keeps the absolute origin unchanged. The relative origin will be recalculated.
|
||||
l.ActiveSprite.Origin = l.ActiveSprite.Origin;
|
||||
TryUpdateLimbParam(l, "origin", l.ActiveSprite.RelativeOrigin);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Keeps the relative origin unchanged. The absolute origin will be recalculated.
|
||||
l.ActiveSprite.RelativeOrigin = l.ActiveSprite.RelativeOrigin;
|
||||
}
|
||||
}
|
||||
};
|
||||
w.PreDraw += (sb, dTime) => w.refresh();
|
||||
});
|
||||
@@ -4955,10 +4931,11 @@ namespace Barotrauma.CharacterEditor
|
||||
}
|
||||
offsetY += (int)(texture.Height * spriteSheetZoom);
|
||||
}
|
||||
}
|
||||
|
||||
int GetTextureHeight(Limb limb)
|
||||
private int GetTextureHeight(Sprite sprite)
|
||||
{
|
||||
int textureIndex = Textures.IndexOf(limb.ActiveSprite.Texture);
|
||||
int textureIndex = Textures.IndexOf(sprite.Texture);
|
||||
int height = 0;
|
||||
foreach (var t in Textures)
|
||||
{
|
||||
@@ -4970,7 +4947,32 @@ namespace Barotrauma.CharacterEditor
|
||||
return (int)(height * spriteSheetZoom);
|
||||
}
|
||||
|
||||
int GetOffsetY(Limb limb) => spriteSheetOffsetY + GetTextureHeight(limb);
|
||||
private int GetOffsetY(Sprite sprite) => spriteSheetOffsetY + GetTextureHeight(sprite);
|
||||
|
||||
private void RecalculateCollider(Limb l, Vector2 size)
|
||||
{
|
||||
// We want the collider to be slightly smaller than the source rect, because the source rect is usually a bit bigger than the graphic.
|
||||
float multiplier = 0.9f;
|
||||
l.body.SetSize(new Vector2(size.X, size.Y) * l.Scale * RagdollParams.TextureScale * multiplier);
|
||||
TryUpdateLimbParam(l, "radius", ConvertUnits.ToDisplayUnits(l.body.radius / l.Params.Scale / RagdollParams.LimbScale / RagdollParams.TextureScale));
|
||||
TryUpdateLimbParam(l, "width", ConvertUnits.ToDisplayUnits(l.body.width / l.Params.Scale / RagdollParams.LimbScale / RagdollParams.TextureScale));
|
||||
TryUpdateLimbParam(l, "height", ConvertUnits.ToDisplayUnits(l.body.height / l.Params.Scale / RagdollParams.LimbScale / RagdollParams.TextureScale));
|
||||
}
|
||||
|
||||
private void RecalculateOrigin(Limb l, Vector2? newOrigin = null)
|
||||
{
|
||||
Sprite activeSprite = l.ActiveSprite;
|
||||
if (lockSpriteOrigin)
|
||||
{
|
||||
// Keeps the absolute origin unchanged. The relative origin will be recalculated.
|
||||
activeSprite.Origin = newOrigin ?? activeSprite.Origin;
|
||||
TryUpdateLimbParam(l, "origin", activeSprite.RelativeOrigin);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Keeps the relative origin unchanged. The absolute origin will be recalculated.
|
||||
activeSprite.RelativeOrigin = activeSprite.RelativeOrigin;
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawSpritesheetJointEditor(SpriteBatch spriteBatch, float deltaTime, Limb limb, Vector2 limbScreenPos, float spriteRotation = 0)
|
||||
@@ -5175,61 +5177,81 @@ namespace Barotrauma.CharacterEditor
|
||||
case Keys.Left:
|
||||
foreach (var limb in selectedLimbs)
|
||||
{
|
||||
// Can't edit human heads
|
||||
if (limb.type == LimbType.Head && character.IsHuman) { continue; }
|
||||
var newRect = limb.ActiveSprite.SourceRect;
|
||||
if (PlayerInput.KeyDown(Keys.LeftControl))
|
||||
bool resize = PlayerInput.KeyDown(Keys.LeftControl);
|
||||
if (resize)
|
||||
{
|
||||
if (lockSpriteSize) { return; }
|
||||
newRect.Width--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lockSpritePosition) { return; }
|
||||
newRect.X--;
|
||||
}
|
||||
UpdateSourceRect(limb, newRect);
|
||||
UpdateSourceRect(limb, newRect, resize);
|
||||
}
|
||||
break;
|
||||
case Keys.Right:
|
||||
foreach (var limb in selectedLimbs)
|
||||
{
|
||||
// Can't edit human heads
|
||||
if (limb.type == LimbType.Head && character.IsHuman) { continue; }
|
||||
var newRect = limb.ActiveSprite.SourceRect;
|
||||
if (PlayerInput.KeyDown(Keys.LeftControl))
|
||||
bool resize = PlayerInput.KeyDown(Keys.LeftControl);
|
||||
if (resize)
|
||||
{
|
||||
if (lockSpriteSize) { return; }
|
||||
newRect.Width++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lockSpritePosition) { return; }
|
||||
newRect.X++;
|
||||
}
|
||||
UpdateSourceRect(limb, newRect);
|
||||
UpdateSourceRect(limb, newRect, resize);
|
||||
}
|
||||
break;
|
||||
case Keys.Down:
|
||||
foreach (var limb in selectedLimbs)
|
||||
{
|
||||
// Can't edit human heads
|
||||
if (limb.type == LimbType.Head && character.IsHuman) { continue; }
|
||||
var newRect = limb.ActiveSprite.SourceRect;
|
||||
if (PlayerInput.KeyDown(Keys.LeftControl))
|
||||
bool resize = PlayerInput.KeyDown(Keys.LeftControl);
|
||||
if (resize)
|
||||
{
|
||||
if (lockSpriteSize) { return; }
|
||||
newRect.Height++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lockSpritePosition) { return; }
|
||||
newRect.Y++;
|
||||
}
|
||||
UpdateSourceRect(limb, newRect);
|
||||
UpdateSourceRect(limb, newRect, resize);
|
||||
}
|
||||
break;
|
||||
case Keys.Up:
|
||||
foreach (var limb in selectedLimbs)
|
||||
{
|
||||
// Can't edit human heads
|
||||
if (limb.type == LimbType.Head && character.IsHuman) { continue; }
|
||||
var newRect = limb.ActiveSprite.SourceRect;
|
||||
if (PlayerInput.KeyDown(Keys.LeftControl))
|
||||
bool resize = PlayerInput.KeyDown(Keys.LeftControl);
|
||||
if (resize)
|
||||
{
|
||||
if (lockSpriteSize) { return; }
|
||||
newRect.Height--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lockSpritePosition) { return; }
|
||||
newRect.Y--;
|
||||
}
|
||||
UpdateSourceRect(limb, newRect);
|
||||
UpdateSourceRect(limb, newRect, resize);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
571
Barotrauma/BarotraumaClient/ClientSource/Screens/EditorImage.cs
Normal file
571
Barotrauma/BarotraumaClient/ClientSource/Screens/EditorImage.cs
Normal file
@@ -0,0 +1,571 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
class EditorImageManager
|
||||
{
|
||||
private struct EditorImageContainer
|
||||
{
|
||||
public float Rotation;
|
||||
public float Scale;
|
||||
public Vector2 Position;
|
||||
public string Path;
|
||||
public float Opacity;
|
||||
public EditorImage.DrawTargetType DrawTarget;
|
||||
|
||||
public EditorImage CreateImage()
|
||||
{
|
||||
return new EditorImage(Path, Position)
|
||||
{
|
||||
Position = Position,
|
||||
Scale = Scale,
|
||||
Opacity = Opacity,
|
||||
Rotation = Rotation,
|
||||
DrawTarget = DrawTarget
|
||||
};
|
||||
}
|
||||
|
||||
public static EditorImageContainer? Load(XElement element)
|
||||
{
|
||||
string path = element.GetAttributeString("path", "");
|
||||
if (string.IsNullOrWhiteSpace(path)) { return null; }
|
||||
|
||||
Vector2 pos = element.GetAttributeVector2("pos", Vector2.Zero);
|
||||
float scale = element.GetAttributeFloat("scale", 1f);
|
||||
float rotation = element.GetAttributeFloat("rotation", 0f);
|
||||
float opacity = element.GetAttributeFloat("opacity", 1f);
|
||||
string drawTargetString = element.GetAttributeString("drawtarget", "");
|
||||
if (!Enum.TryParse<EditorImage.DrawTargetType>(drawTargetString, out var drawTarget))
|
||||
{
|
||||
drawTarget = EditorImage.DrawTargetType.World;
|
||||
}
|
||||
|
||||
return new EditorImageContainer
|
||||
{
|
||||
Path = path,
|
||||
Rotation = rotation,
|
||||
Opacity = opacity,
|
||||
Position = pos,
|
||||
Scale = scale,
|
||||
DrawTarget = drawTarget
|
||||
};
|
||||
}
|
||||
|
||||
public static EditorImageContainer ImageToContainer(EditorImage img)
|
||||
{
|
||||
return new EditorImageContainer
|
||||
{
|
||||
Path = img.ImagePath,
|
||||
Rotation = img.Rotation,
|
||||
Position = img.Position,
|
||||
Opacity = img.Opacity,
|
||||
Scale = img.Scale,
|
||||
DrawTarget = img.DrawTarget
|
||||
};
|
||||
}
|
||||
|
||||
public static XElement SerializeImage(EditorImageContainer image)
|
||||
{
|
||||
return new XElement("image",
|
||||
new XAttribute("pos", XMLExtensions.Vector2ToString(image.Position)),
|
||||
new XAttribute("rotation", image.Rotation),
|
||||
new XAttribute("opacity", image.Opacity),
|
||||
new XAttribute("path", image.Path),
|
||||
new XAttribute("scale", image.Scale),
|
||||
new XAttribute("drawtarget", image.DrawTarget.ToString()));
|
||||
}
|
||||
}
|
||||
|
||||
private readonly List<EditorImageContainer> PendingImages = new List<EditorImageContainer>();
|
||||
|
||||
public readonly List<EditorImage> Images = new List<EditorImage>();
|
||||
|
||||
private readonly List<EditorImage> screenImages = new List<EditorImage>(),
|
||||
worldImages = new List<EditorImage>();
|
||||
|
||||
public bool EditorMode;
|
||||
|
||||
private string editModeText = "";
|
||||
private Vector2 textSize = Vector2.Zero;
|
||||
|
||||
public void Save(XElement element)
|
||||
{
|
||||
XElement saveElement = new XElement("editorimages");
|
||||
foreach (EditorImage image in Images)
|
||||
{
|
||||
EditorImageContainer container = EditorImageContainer.ImageToContainer(image);
|
||||
saveElement.Add(EditorImageContainer.SerializeImage(container));
|
||||
}
|
||||
|
||||
foreach (EditorImageContainer container in PendingImages)
|
||||
{
|
||||
saveElement.Add(EditorImageContainer.SerializeImage(container));
|
||||
}
|
||||
|
||||
element.Add(saveElement);
|
||||
}
|
||||
|
||||
public void Load(XElement element)
|
||||
{
|
||||
Clear(alsoPending: true);
|
||||
|
||||
foreach (XElement subElement in element.Elements())
|
||||
{
|
||||
EditorImageContainer? tempImage = EditorImageContainer.Load(subElement);
|
||||
if (tempImage != null)
|
||||
{
|
||||
PendingImages.Add(tempImage.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnEditorSelected()
|
||||
{
|
||||
editModeText = TextManager.Get("SubEditor.ImageEditingMode");
|
||||
textSize = GUI.LargeFont.MeasureString(editModeText);
|
||||
|
||||
TryLoadPendingImages();
|
||||
}
|
||||
|
||||
private void TryLoadPendingImages()
|
||||
{
|
||||
if (PendingImages.Count == 0) { return; }
|
||||
|
||||
Clear(alsoPending: false);
|
||||
|
||||
foreach (EditorImageContainer pendingImage in PendingImages)
|
||||
{
|
||||
EditorImage img = pendingImage.CreateImage();
|
||||
if (img.Image == null) { continue; }
|
||||
Images.Add(img);
|
||||
img.UpdateRectangle();
|
||||
}
|
||||
|
||||
UpdateImageCategories();
|
||||
PendingImages.Clear();
|
||||
}
|
||||
|
||||
public void Clear(bool alsoPending = false)
|
||||
{
|
||||
foreach (EditorImage img in Images)
|
||||
{
|
||||
img.Image?.Dispose();
|
||||
}
|
||||
|
||||
Images.Clear();
|
||||
screenImages.Clear();
|
||||
worldImages.Clear();
|
||||
if (alsoPending)
|
||||
{
|
||||
PendingImages.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
if (!EditorMode) { return; }
|
||||
|
||||
foreach (EditorImage image in Images)
|
||||
{
|
||||
image.Update(deltaTime);
|
||||
}
|
||||
|
||||
if (PlayerInput.PrimaryMouseButtonDown())
|
||||
{
|
||||
EditorImage? hover = Images.FirstOrDefault(img => img.IsMouseOn());
|
||||
if (hover != null)
|
||||
{
|
||||
foreach (EditorImage image in Images)
|
||||
{
|
||||
image.Selected = false;
|
||||
}
|
||||
|
||||
hover.Selected = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (PlayerInput.KeyHit(Keys.Delete) || (PlayerInput.IsCtrlDown() && PlayerInput.KeyHit(Keys.D)))
|
||||
{
|
||||
Images.RemoveAll(img => img.Selected);
|
||||
UpdateImageCategories();
|
||||
}
|
||||
|
||||
if (PlayerInput.KeyHit(Keys.Space))
|
||||
{
|
||||
foreach (EditorImage image in Images)
|
||||
{
|
||||
if (image.Selected)
|
||||
{
|
||||
if (image.DrawTarget == EditorImage.DrawTargetType.World)
|
||||
{
|
||||
Vector2 pos = image.Position;
|
||||
pos.Y = -pos.Y;
|
||||
pos = Screen.Selected.Cam.WorldToScreen(pos);
|
||||
if (PlayerInput.IsShiftDown())
|
||||
{
|
||||
pos = new Vector2(GameMain.GraphicsWidth / 2f, GameMain.GraphicsHeight / 2f);
|
||||
}
|
||||
|
||||
image.Position = pos;
|
||||
image.DrawTarget = EditorImage.DrawTargetType.Camera;
|
||||
image.Scale *= Screen.Selected.Cam.Zoom;
|
||||
image.UpdateRectangle();
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector2 pos = Screen.Selected.Cam.ScreenToWorld(image.Position);
|
||||
pos.Y = -pos.Y;
|
||||
image.Position = pos;
|
||||
image.DrawTarget = EditorImage.DrawTargetType.World;
|
||||
image.Scale /= Screen.Selected.Cam.Zoom;
|
||||
image.UpdateRectangle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UpdateImageCategories();
|
||||
}
|
||||
|
||||
MapEntity.DisableSelect = true;
|
||||
}
|
||||
|
||||
private void UpdateImageCategories()
|
||||
{
|
||||
screenImages.Clear();
|
||||
worldImages.Clear();
|
||||
|
||||
foreach (EditorImage image in Images)
|
||||
{
|
||||
switch (image.DrawTarget)
|
||||
{
|
||||
case EditorImage.DrawTargetType.World:
|
||||
worldImages.Add(image);
|
||||
break;
|
||||
default:
|
||||
screenImages.Add(image);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void CreateImageWizard(Vector2 positon)
|
||||
{
|
||||
string home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
|
||||
if (!Directory.Exists(home)) { return; }
|
||||
|
||||
FileSelection.OnFileSelected = file =>
|
||||
{
|
||||
Vector2 pos = Screen.Selected.Cam.ScreenToWorld(positon);
|
||||
pos.Y = -pos.Y;
|
||||
Images.Add(new EditorImage(file, pos) { DrawTarget = EditorImage.DrawTargetType.World });
|
||||
UpdateImageCategories();
|
||||
GameMain.Config.SaveNewPlayerConfig();
|
||||
};
|
||||
|
||||
FileSelection.ClearFileTypeFilters();
|
||||
FileSelection.AddFileTypeFilter("PNG", "*.png");
|
||||
FileSelection.AddFileTypeFilter("JPEG", "*.jpg, *.jpeg");
|
||||
FileSelection.AddFileTypeFilter("All files", "*.*");
|
||||
FileSelection.SelectFileTypeFilter("*.png");
|
||||
FileSelection.CurrentDirectory = home;
|
||||
FileSelection.Open = true;
|
||||
}
|
||||
|
||||
public void DrawEditing(SpriteBatch spriteBatch, Camera cam)
|
||||
{
|
||||
if (!EditorMode) { return; }
|
||||
|
||||
DrawImages(spriteBatch, cam);
|
||||
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState);
|
||||
Vector2 textPos = new Vector2(GameMain.GraphicsWidth / 2f - (textSize.X / 2f), GameMain.GraphicsHeight / 10f - (textSize.Y / 2f));
|
||||
GUI.DrawString(spriteBatch, textPos, editModeText, GUI.Style.Yellow, Color.Black * 0.4f, 8, GUI.LargeFont);
|
||||
spriteBatch.End();
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, Camera cam)
|
||||
{
|
||||
if (EditorMode) { return; }
|
||||
|
||||
DrawImages(spriteBatch, cam);
|
||||
}
|
||||
|
||||
private void DrawImages(SpriteBatch spriteBatch, Camera cam)
|
||||
{
|
||||
if (screenImages.Count > 0)
|
||||
{
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState);
|
||||
foreach (EditorImage image in screenImages)
|
||||
{
|
||||
image.Draw(spriteBatch);
|
||||
if (EditorMode) { image.DrawEditing(spriteBatch, cam); }
|
||||
}
|
||||
|
||||
spriteBatch.End();
|
||||
}
|
||||
|
||||
if (worldImages.Count > 0)
|
||||
{
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, transformMatrix: cam.Transform);
|
||||
foreach (EditorImage image in worldImages)
|
||||
{
|
||||
image.Draw(spriteBatch);
|
||||
if (EditorMode) { image.DrawEditing(spriteBatch, cam); }
|
||||
}
|
||||
|
||||
spriteBatch.End();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class EditorImage
|
||||
{
|
||||
public enum DrawTargetType
|
||||
{
|
||||
Camera,
|
||||
World
|
||||
}
|
||||
|
||||
public Texture2D? Image;
|
||||
public string ImagePath;
|
||||
public Vector2 Position;
|
||||
public float Rotation;
|
||||
public float Opacity = 1f;
|
||||
public float Scale = 1f;
|
||||
public DrawTargetType DrawTarget;
|
||||
public bool Selected;
|
||||
|
||||
public Rectangle Bounds;
|
||||
private float prevAngle;
|
||||
private bool disableMove;
|
||||
private bool isDragging;
|
||||
|
||||
private readonly Dictionary<string, Widget> widgets = new Dictionary<string, Widget>();
|
||||
|
||||
public EditorImage(string path, Vector2 pos)
|
||||
{
|
||||
Image = Sprite.LoadTexture(path, out Sprite _, compress: false);
|
||||
ImagePath = path;
|
||||
Position = pos;
|
||||
UpdateRectangle();
|
||||
}
|
||||
|
||||
public bool IsMouseOn() => Bounds.Contains(GetMousePos());
|
||||
|
||||
public Vector2 GetMousePos()
|
||||
{
|
||||
switch (DrawTarget)
|
||||
{
|
||||
case DrawTargetType.Camera:
|
||||
return PlayerInput.MousePosition;
|
||||
case DrawTargetType.World:
|
||||
Vector2 pos = Screen.Selected.Cam.ScreenToWorld(PlayerInput.MousePosition);
|
||||
pos.Y = -pos.Y;
|
||||
return pos;
|
||||
default:
|
||||
return PlayerInput.MousePosition;
|
||||
}
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
if (!Selected) { return; }
|
||||
|
||||
if (widgets.Values.Any(w => w.IsSelected)) { return; }
|
||||
|
||||
if (PlayerInput.PrimaryMouseButtonDown() && !disableMove && IsMouseOn())
|
||||
{
|
||||
isDragging = true;
|
||||
}
|
||||
|
||||
if (isDragging)
|
||||
{
|
||||
Camera cam = Screen.Selected.Cam;
|
||||
if (PlayerInput.MouseSpeed != Vector2.Zero)
|
||||
{
|
||||
Vector2 mouseSpeed = PlayerInput.MouseSpeed;
|
||||
if (DrawTarget == DrawTargetType.World)
|
||||
{
|
||||
mouseSpeed /= cam.Zoom;
|
||||
}
|
||||
|
||||
Position += mouseSpeed;
|
||||
UpdateRectangle();
|
||||
}
|
||||
}
|
||||
|
||||
if (PlayerInput.KeyDown(Keys.OemPlus) || PlayerInput.KeyDown(Keys.Up))
|
||||
{
|
||||
Opacity += 0.01f;
|
||||
}
|
||||
|
||||
if (PlayerInput.KeyDown(Keys.OemMinus) || PlayerInput.KeyDown(Keys.Down))
|
||||
{
|
||||
Opacity -= 0.01f;
|
||||
}
|
||||
|
||||
if (PlayerInput.KeyHit(Keys.D0))
|
||||
{
|
||||
Opacity = 1f;
|
||||
}
|
||||
|
||||
Opacity = Math.Clamp(Opacity, 0, 1f);
|
||||
|
||||
if (!PlayerInput.PrimaryMouseButtonHeld())
|
||||
{
|
||||
isDragging = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawWidgets(SpriteBatch spriteBatch)
|
||||
{
|
||||
float widgetSize = Image == null ? 100f : Math.Max(Image.Width, Image.Height) / 2f;
|
||||
|
||||
int width = 3;
|
||||
int size = 32;
|
||||
if (DrawTarget == DrawTargetType.World)
|
||||
{
|
||||
width = Math.Max(width, (int) (width / Screen.Selected.Cam.Zoom));
|
||||
}
|
||||
|
||||
Widget currentWidget = GetWidget("transform", size, width, widget =>
|
||||
{
|
||||
widget.MouseDown += () =>
|
||||
{
|
||||
widget.color = GUI.Style.Green;
|
||||
prevAngle = Rotation;
|
||||
disableMove = true;
|
||||
};
|
||||
widget.Deselected += () =>
|
||||
{
|
||||
widget.color = Color.Yellow;
|
||||
disableMove = false;
|
||||
};
|
||||
widget.MouseHeld += (deltaTime) =>
|
||||
{
|
||||
Rotation = GetRotationAngle(Position) + (float) Math.PI / 2f;
|
||||
float distance = Vector2.Distance(Position, GetMousePos());
|
||||
Scale = Math.Abs(distance) / widgetSize;
|
||||
if (PlayerInput.IsShiftDown())
|
||||
{
|
||||
const float rotationStep = (float) (Math.PI / 4f);
|
||||
Rotation = (float) Math.Round(Rotation / rotationStep) * rotationStep;
|
||||
}
|
||||
|
||||
if (PlayerInput.IsCtrlDown())
|
||||
{
|
||||
const float scaleStep = 0.1f;
|
||||
Scale = (float) Math.Round(Scale / scaleStep) * scaleStep;
|
||||
}
|
||||
|
||||
UpdateRectangle();
|
||||
};
|
||||
widget.PreUpdate += (deltaTime) =>
|
||||
{
|
||||
if (DrawTarget != DrawTargetType.World) { return; }
|
||||
|
||||
widget.DrawPos = new Vector2(widget.DrawPos.X, -widget.DrawPos.Y);
|
||||
widget.DrawPos = Screen.Selected.Cam.WorldToScreen(widget.DrawPos);
|
||||
};
|
||||
widget.PostUpdate += (deltaTime) =>
|
||||
{
|
||||
if (DrawTarget != DrawTargetType.World) { return; }
|
||||
|
||||
widget.DrawPos = Screen.Selected.Cam.ScreenToWorld(widget.DrawPos);
|
||||
widget.DrawPos = new Vector2(widget.DrawPos.X, -widget.DrawPos.Y);
|
||||
};
|
||||
widget.PreDraw += (sprtBtch, deltaTime) =>
|
||||
{
|
||||
widget.tooltip = $"Scale: {Math.Round(Scale, 2)}\n" +
|
||||
$"Rotation: {(int) MathHelper.ToDegrees(Rotation)}";
|
||||
float rotation = Rotation - (float) Math.PI / 2f;
|
||||
widget.DrawPos = Position + new Vector2((float) Math.Cos(rotation), (float) Math.Sin(rotation)) * (Scale * widgetSize);
|
||||
widget.Update(deltaTime);
|
||||
};
|
||||
});
|
||||
|
||||
currentWidget.Draw(spriteBatch, (float) Timing.Step);
|
||||
GUI.DrawLine(spriteBatch, Position, currentWidget.DrawPos, GUI.Style.Green, width: width);
|
||||
}
|
||||
|
||||
private float GetRotationAngle(Vector2 drawPosition)
|
||||
{
|
||||
Vector2 rotationVector = GetMousePos() - drawPosition;
|
||||
rotationVector.Normalize();
|
||||
double angle = Math.Atan2(MathHelper.ToRadians(rotationVector.Y), MathHelper.ToRadians(rotationVector.X));
|
||||
if (angle < 0)
|
||||
{
|
||||
angle = Math.Abs(angle - prevAngle) < Math.Abs((angle + Math.PI * 2) - prevAngle) ? angle : angle + Math.PI * 2;
|
||||
}
|
||||
else if (angle > 0)
|
||||
{
|
||||
angle = Math.Abs(angle - prevAngle) < Math.Abs((angle - Math.PI * 2) - prevAngle) ? angle : angle - Math.PI * 2;
|
||||
}
|
||||
|
||||
angle = MathHelper.Clamp((float) angle, -((float) Math.PI * 2), (float) Math.PI * 2);
|
||||
prevAngle = (float) angle;
|
||||
return (float) angle;
|
||||
}
|
||||
|
||||
private Widget GetWidget(string id, int size, float thickness = 1f, Action<Widget>? initMethod = null)
|
||||
{
|
||||
if (!widgets.TryGetValue(id, out Widget? widget))
|
||||
{
|
||||
widget = new Widget(id, size, Widget.Shape.Rectangle)
|
||||
{
|
||||
color = Color.Yellow,
|
||||
RequireMouseOn = false
|
||||
};
|
||||
widgets.Add(id, widget);
|
||||
initMethod?.Invoke(widget);
|
||||
}
|
||||
|
||||
widget.size = size;
|
||||
widget.thickness = thickness;
|
||||
return widget;
|
||||
}
|
||||
|
||||
public void UpdateRectangle()
|
||||
{
|
||||
if (Image == null)
|
||||
{
|
||||
Bounds = new Rectangle((int) Position.X, (int) Position.Y, 512, 512);
|
||||
return;
|
||||
}
|
||||
|
||||
Vector2 size = new Vector2(Image.Width * Scale, Image.Height * Scale);
|
||||
Bounds = new Rectangle((Position - size / 2f).ToPoint(), size.ToPoint());
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
if (Image == null) { return; }
|
||||
|
||||
spriteBatch.Draw(Image, Position, null, Color.White * Opacity, Rotation, new Vector2(Image.Width / 2f, Image.Height / 2f), scale: Scale, SpriteEffects.None, 0f);
|
||||
}
|
||||
|
||||
public void DrawEditing(SpriteBatch spriteBatch, Camera cam)
|
||||
{
|
||||
Rectangle bounds = Bounds;
|
||||
int width = 4;
|
||||
if (DrawTarget == DrawTargetType.World)
|
||||
{
|
||||
width = (int) (width / cam.Zoom);
|
||||
}
|
||||
|
||||
GUI.DrawRectangle(spriteBatch, bounds, Selected ? GUI.Style.Red : GUI.Style.Green, thickness: width);
|
||||
if (Selected)
|
||||
{
|
||||
DrawWidgets(spriteBatch);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -399,7 +399,7 @@ namespace Barotrauma
|
||||
else
|
||||
{
|
||||
newNode = new CustomNode(subElement.Name.ToString()) { Position = new Vector2(ident, 0), ID = CreateID() };
|
||||
foreach (XAttribute attribute in subElement.Attributes())
|
||||
foreach (XAttribute attribute in subElement.Attributes().Where(attribute => !attribute.ToString().StartsWith("_")))
|
||||
{
|
||||
newNode.Connections.Add(new NodeConnection(newNode, NodeConnectionType.Value, attribute.Name.ToString(), typeof(string)));
|
||||
}
|
||||
@@ -525,6 +525,7 @@ namespace Barotrauma
|
||||
|
||||
public override void Select()
|
||||
{
|
||||
GUI.PreventPauseMenuToggle = false;
|
||||
projectName = TextManager.Get("EventEditor.Unnamed");
|
||||
base.Select();
|
||||
}
|
||||
|
||||
@@ -77,9 +77,8 @@ namespace Barotrauma
|
||||
}
|
||||
if (Character.Controlled?.Inventory != null)
|
||||
{
|
||||
foreach (Item item in Character.Controlled.Inventory.Items)
|
||||
foreach (Item item in Character.Controlled.Inventory.AllItems)
|
||||
{
|
||||
if (item == null) { continue; }
|
||||
if (Character.Controlled.HasEquippedItem(item))
|
||||
{
|
||||
item.AddToGUIUpdateList();
|
||||
@@ -249,6 +248,8 @@ namespace Barotrauma
|
||||
}
|
||||
spriteBatch.End();
|
||||
|
||||
Level.Loaded?.DrawFront(spriteBatch, cam);
|
||||
|
||||
//draw the rendertarget and particles that are only supposed to be drawn in water into renderTargetWater
|
||||
graphics.SetRenderTarget(renderTargetWater);
|
||||
|
||||
@@ -317,10 +318,8 @@ namespace Barotrauma
|
||||
{
|
||||
c.DrawFront(spriteBatch, cam);
|
||||
}
|
||||
if (Level.Loaded != null)
|
||||
{
|
||||
Level.Loaded.DrawFront(spriteBatch, cam);
|
||||
}
|
||||
|
||||
Level.Loaded?.DrawDebugOverlay(spriteBatch, cam);
|
||||
if (GameMain.DebugDraw)
|
||||
{
|
||||
MapEntity.mapEntityList.ForEach(me => me.AiTarget?.Draw(spriteBatch));
|
||||
@@ -374,7 +373,10 @@ namespace Barotrauma
|
||||
{
|
||||
BlurStrength = Character.Controlled.BlurStrength * 0.005f;
|
||||
DistortStrength = Character.Controlled.DistortStrength;
|
||||
if (GameMain.Config.EnableRadialDistortion)
|
||||
{
|
||||
chromaticAberrationStrength -= Vector3.One * Character.Controlled.RadialDistortStrength;
|
||||
}
|
||||
chromaticAberrationStrength += new Vector3(-0.03f, -0.015f, 0.0f) * Character.Controlled.ChromaticAberrationStrength;
|
||||
}
|
||||
else
|
||||
@@ -438,8 +440,8 @@ namespace Barotrauma
|
||||
|
||||
if (!PlayerInput.PrimaryMouseButtonHeld())
|
||||
{
|
||||
Inventory.draggingSlot = null;
|
||||
Inventory.draggingItem = null;
|
||||
Inventory.DraggingSlot = null;
|
||||
Inventory.DraggingItems.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -714,8 +714,9 @@ namespace Barotrauma
|
||||
if (Level.Loaded != null)
|
||||
{
|
||||
Level.Loaded.DrawBack(graphics, spriteBatch, cam);
|
||||
spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.NonPremultiplied, SamplerState.LinearWrap, DepthStencilState.DepthRead, transformMatrix: cam.Transform);
|
||||
Level.Loaded.DrawFront(spriteBatch, cam);
|
||||
spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.NonPremultiplied, SamplerState.LinearWrap, DepthStencilState.DepthRead, transformMatrix: cam.Transform);
|
||||
Level.Loaded.DrawDebugOverlay(spriteBatch, cam);
|
||||
Submarine.Draw(spriteBatch, false);
|
||||
Submarine.DrawFront(spriteBatch);
|
||||
Submarine.DrawDamageable(spriteBatch, null);
|
||||
@@ -817,6 +818,13 @@ namespace Barotrauma
|
||||
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
if (lightingEnabled.Selected)
|
||||
{
|
||||
foreach (Item item in Item.ItemList)
|
||||
{
|
||||
item?.GetComponent<Items.Components.LightComponent>()?.Update((float)deltaTime, cam);
|
||||
}
|
||||
}
|
||||
GameMain.LightManager?.Update((float)deltaTime);
|
||||
|
||||
pointerLightSource.Position = cam.ScreenToWorld(PlayerInput.MousePosition);
|
||||
@@ -886,16 +894,16 @@ namespace Barotrauma
|
||||
{
|
||||
foreach (XElement subElement in element.Elements())
|
||||
{
|
||||
string id = element.GetAttributeString("identifier", null) ?? element.Name.ToString();
|
||||
string id = subElement.GetAttributeString("identifier", null) ?? subElement.Name.ToString();
|
||||
if (!id.Equals(genParams.Name, StringComparison.OrdinalIgnoreCase)) { continue; }
|
||||
SerializableProperty.SerializeProperties(genParams, element, true);
|
||||
genParams.Save(subElement);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string id = element.GetAttributeString("identifier", null) ?? element.Name.ToString();
|
||||
if (!id.Equals(genParams.Name, StringComparison.OrdinalIgnoreCase)) { continue; }
|
||||
SerializableProperty.SerializeProperties(genParams, element, true);
|
||||
genParams.Save(element);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -679,7 +679,7 @@ namespace Barotrauma
|
||||
}
|
||||
#endregion
|
||||
|
||||
public void QuickStart(bool fixedSeed = false)
|
||||
public void QuickStart(bool fixedSeed = false, string sub = null)
|
||||
{
|
||||
if (fixedSeed)
|
||||
{
|
||||
@@ -688,7 +688,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
SubmarineInfo selectedSub = null;
|
||||
string subName = GameMain.Config.QuickStartSubmarineName;
|
||||
string subName = sub ?? GameMain.Config.QuickStartSubmarineName;
|
||||
if (!string.IsNullOrEmpty(subName))
|
||||
{
|
||||
DebugConsole.NewMessage($"Loading the predefined quick start sub \"{subName}\"", Color.White);
|
||||
@@ -834,6 +834,39 @@ namespace Barotrauma
|
||||
return true;
|
||||
}
|
||||
|
||||
private void TryStartServer()
|
||||
{
|
||||
if (SubmarineInfo.SavedSubmarines.Any(s => s.CalculatingHash))
|
||||
{
|
||||
var waitBox = new GUIMessageBox(TextManager.Get("pleasewait"), TextManager.Get("waitforsubmarinehashcalculations"), new string[] { TextManager.Get("cancel") });
|
||||
var waitCoroutine = CoroutineManager.StartCoroutine(WaitForSubmarineHashCalculations(waitBox), "WaitForSubmarineHashCalculations");
|
||||
waitBox.Buttons[0].OnClicked += (btn, userdata) =>
|
||||
{
|
||||
CoroutineManager.StopCoroutines(waitCoroutine);
|
||||
return true;
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
StartServer();
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<object> WaitForSubmarineHashCalculations(GUIMessageBox messageBox)
|
||||
{
|
||||
string originalText = messageBox.Text.Text;
|
||||
int doneCount = 0;
|
||||
do
|
||||
{
|
||||
doneCount = SubmarineInfo.SavedSubmarines.Count(s => !s.CalculatingHash);
|
||||
messageBox.Text.Text = originalText + $" ({doneCount}/{SubmarineInfo.SavedSubmarines.Count()})";
|
||||
yield return CoroutineStatus.Running;
|
||||
} while (doneCount < SubmarineInfo.SavedSubmarines.Count());
|
||||
messageBox.Close();
|
||||
StartServer();
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
|
||||
private void StartServer()
|
||||
{
|
||||
string name = serverNameBox.Text;
|
||||
@@ -1095,12 +1128,13 @@ namespace Barotrauma
|
||||
StartNewGame = StartGame
|
||||
};
|
||||
|
||||
var startButtonContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.05f), innerNewGame.RectTransform, Anchor.Center), style: null);
|
||||
var startButtonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.05f), innerNewGame.RectTransform, Anchor.Center), isHorizontal: true, childAnchor: Anchor.BottomRight);
|
||||
campaignSetupUI.StartButton.RectTransform.Parent = startButtonContainer.RectTransform;
|
||||
campaignSetupUI.StartButton.RectTransform.MinSize = new Point(
|
||||
(int)(campaignSetupUI.StartButton.TextBlock.TextSize.X * 1.5f),
|
||||
campaignSetupUI.StartButton.RectTransform.MinSize.Y);
|
||||
startButtonContainer.RectTransform.MinSize = new Point(0, campaignSetupUI.StartButton.RectTransform.MinSize.Y);
|
||||
campaignSetupUI.InitialMoneyText.RectTransform.Parent = startButtonContainer.RectTransform;
|
||||
}
|
||||
|
||||
private void CreateHostServerFields()
|
||||
@@ -1340,7 +1374,7 @@ namespace Barotrauma
|
||||
new string[] { TextManager.Get("yes"), TextManager.Get("no") });
|
||||
msgBox.Buttons[0].OnClicked += (_, __) =>
|
||||
{
|
||||
StartServer();
|
||||
TryStartServer();
|
||||
msgBox.Close();
|
||||
return true;
|
||||
};
|
||||
@@ -1348,7 +1382,7 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
StartServer();
|
||||
TryStartServer();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user