Unstable v0.1300.0.0 (February 19th 2021)
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);
|
||||
|
||||
Zoom = MathHelper.Lerp(Zoom, targetZoom, deltaTime * 10.0f);
|
||||
if (!PlayerInput.KeyDown(Keys.F)) Position = mouseInWorld - (diffViewCenter / Zoom);
|
||||
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); }
|
||||
}
|
||||
}
|
||||
else if (allowMove)
|
||||
|
||||
@@ -11,6 +11,9 @@ namespace Barotrauma
|
||||
{
|
||||
if (!ShowAITargets) { return; }
|
||||
var pos = new Vector2(WorldPosition.X, -WorldPosition.Y);
|
||||
float thickness = 1 / Screen.Selected.Cam.Zoom;
|
||||
|
||||
float offset = MathUtils.VectorToAngle(new Vector2(sectorDir.X, -sectorDir.Y)) - (sectorRad / 2f);
|
||||
if (soundRange > 0.0f)
|
||||
{
|
||||
Color color;
|
||||
@@ -26,8 +29,16 @@ namespace Barotrauma
|
||||
{
|
||||
color = Color.OrangeRed;
|
||||
}
|
||||
ShapeExtensions.DrawCircle(spriteBatch, pos, SoundRange, 100, color, thickness: 1 / Screen.Selected.Cam.Zoom);
|
||||
ShapeExtensions.DrawCircle(spriteBatch, pos, 3, 8, color, thickness: 2 / Screen.Selected.Cam.Zoom);
|
||||
|
||||
if (sectorRad < MathHelper.TwoPi)
|
||||
{
|
||||
spriteBatch.DrawSector(pos, SoundRange, sectorRad, 100, color, offset: offset, thickness: thickness);
|
||||
}
|
||||
else
|
||||
{
|
||||
spriteBatch.DrawCircle(pos, SoundRange, 100, color, thickness: thickness);
|
||||
}
|
||||
spriteBatch.DrawCircle(pos, 3, 8, color, thickness: 2 / Screen.Selected.Cam.Zoom);
|
||||
GUI.DrawLine(spriteBatch, pos, pos + Vector2.UnitY * SoundRange, color, width: (int)(1 / Screen.Selected.Cam.Zoom) + 1);
|
||||
}
|
||||
if (sightRange > 0.0f)
|
||||
@@ -47,7 +58,14 @@ namespace Barotrauma
|
||||
// disable the indicators for structures and hulls, because they clutter the debug view
|
||||
return;
|
||||
}
|
||||
ShapeExtensions.DrawCircle(spriteBatch, pos, SightRange, 100, color, thickness: 1 / Screen.Selected.Cam.Zoom);
|
||||
if (sectorRad < MathHelper.TwoPi)
|
||||
{
|
||||
spriteBatch.DrawSector(pos, SightRange, sectorRad, 100, color, offset: offset, thickness: thickness);
|
||||
}
|
||||
else
|
||||
{
|
||||
spriteBatch.DrawCircle(pos, SightRange, 100, color, thickness: thickness);
|
||||
}
|
||||
ShapeExtensions.DrawCircle(spriteBatch, pos, 6, 8, color, thickness: 2 / Screen.Selected.Cam.Zoom);
|
||||
GUI.DrawLine(spriteBatch, pos, pos + Vector2.UnitY * SightRange, color, width: (int)(1 / Screen.Selected.Cam.Zoom) + 1);
|
||||
}
|
||||
|
||||
@@ -1,22 +1,12 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using FarseerPhysics;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class HumanAIController : AIController
|
||||
{
|
||||
public static bool debugai;
|
||||
|
||||
partial void InitProjSpecific()
|
||||
{
|
||||
/*if (GameMain.GameSession != null && GameMain.GameSession.CrewManager != null)
|
||||
{
|
||||
CurrentOrder = Order.GetPrefab("dismissed");
|
||||
objectiveManager.SetOrder(CurrentOrder, "", null);
|
||||
GameMain.GameSession.CrewManager.SetCharacterOrder(Character, CurrentOrder, null, null);
|
||||
}*/
|
||||
}
|
||||
|
||||
public override void DebugDraw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)
|
||||
{
|
||||
if (Character == Character.Controlled) { return; }
|
||||
@@ -24,6 +14,7 @@ namespace Barotrauma
|
||||
Vector2 pos = Character.WorldPosition;
|
||||
pos.Y = -pos.Y;
|
||||
Vector2 textOffset = new Vector2(-40, -160);
|
||||
textOffset.Y -= Math.Max(ObjectiveManager.CurrentOrders.Count - 1, 0) * 20;
|
||||
|
||||
if (SelectedAiTarget?.Entity != null)
|
||||
{
|
||||
@@ -31,61 +22,57 @@ namespace Barotrauma
|
||||
//GUI.DrawString(spriteBatch, pos + textOffset, $"AI TARGET: {SelectedAiTarget.Entity.ToString()}", Color.White, Color.Black);
|
||||
}
|
||||
|
||||
GUI.DrawString(spriteBatch, pos + textOffset, Character.Name, Color.White, Color.Black);
|
||||
Vector2 stringDrawPos = pos + textOffset;
|
||||
GUI.DrawString(spriteBatch, stringDrawPos, Character.Name, Color.White, Color.Black);
|
||||
|
||||
if (ObjectiveManager != null)
|
||||
var currentOrder = ObjectiveManager.CurrentOrder;
|
||||
if (ObjectiveManager.CurrentOrders.Any())
|
||||
{
|
||||
var currentOrder = ObjectiveManager.CurrentOrder;
|
||||
if (currentOrder != null)
|
||||
var currentOrders = ObjectiveManager.CurrentOrders;
|
||||
currentOrders.Sort((x, y) => y.ManualPriority.CompareTo(x.ManualPriority));
|
||||
for (int i = 0; i < currentOrders.Count; i++)
|
||||
{
|
||||
GUI.DrawString(spriteBatch, pos + textOffset + new Vector2(0, 20), $"ORDER: {currentOrder.DebugTag} ({currentOrder.Priority.FormatZeroDecimal()})", Color.White, Color.Black);
|
||||
stringDrawPos += new Vector2(0, 20);
|
||||
var order = currentOrders[i];
|
||||
GUI.DrawString(spriteBatch, stringDrawPos, $"ORDER {i + 1}: {order.Objective.DebugTag} ({order.Objective.Priority.FormatZeroDecimal()})", Color.White, Color.Black);
|
||||
}
|
||||
else if (ObjectiveManager.WaitTimer > 0)
|
||||
}
|
||||
else if (ObjectiveManager.WaitTimer > 0)
|
||||
{
|
||||
stringDrawPos += new Vector2(0, 20);
|
||||
GUI.DrawString(spriteBatch, stringDrawPos - textOffset, $"Waiting... {ObjectiveManager.WaitTimer.FormatZeroDecimal()}", Color.White, Color.Black);
|
||||
}
|
||||
var currentObjective = ObjectiveManager.CurrentObjective;
|
||||
if (currentObjective != null)
|
||||
{
|
||||
int offset = currentOrder != null ? 20 + ((ObjectiveManager.CurrentOrders.Count - 1) * 20) : 0;
|
||||
if (currentOrder == null || currentOrder.Priority <= 0)
|
||||
{
|
||||
GUI.DrawString(spriteBatch, pos + new Vector2(0, 20), $"Waiting... {ObjectiveManager.WaitTimer.FormatZeroDecimal()}", Color.White, Color.Black);
|
||||
stringDrawPos += new Vector2(0, 20);
|
||||
GUI.DrawString(spriteBatch, stringDrawPos, $"MAIN OBJECTIVE: {currentObjective.DebugTag} ({currentObjective.Priority.FormatZeroDecimal()})", Color.White, Color.Black);
|
||||
}
|
||||
var currentObjective = ObjectiveManager.CurrentObjective;
|
||||
if (currentObjective != null)
|
||||
var subObjective = currentObjective.CurrentSubObjective;
|
||||
if (subObjective != null)
|
||||
{
|
||||
int offset = currentOrder != null ? 20 : 0;
|
||||
if (currentOrder == null || currentOrder.Priority <= 0)
|
||||
{
|
||||
GUI.DrawString(spriteBatch, pos + textOffset + new Vector2(0, 20 + offset), $"MAIN OBJECTIVE: {currentObjective.DebugTag} ({currentObjective.Priority.FormatZeroDecimal()})", Color.White, Color.Black);
|
||||
}
|
||||
var subObjective = currentObjective.CurrentSubObjective;
|
||||
if (subObjective != null)
|
||||
{
|
||||
GUI.DrawString(spriteBatch, pos + textOffset + new Vector2(0, 40 + offset), $"SUBOBJECTIVE: {subObjective.DebugTag} ({subObjective.Priority.FormatZeroDecimal()})", Color.White, Color.Black);
|
||||
}
|
||||
var activeObjective = ObjectiveManager.GetActiveObjective();
|
||||
if (activeObjective != null)
|
||||
{
|
||||
GUI.DrawString(spriteBatch, pos + textOffset + new Vector2(0, 60 + offset), $"ACTIVE OBJECTIVE: {activeObjective.DebugTag} ({activeObjective.Priority.FormatZeroDecimal()})", Color.White, Color.Black);
|
||||
}
|
||||
stringDrawPos += new Vector2(0, 20);
|
||||
GUI.DrawString(spriteBatch, stringDrawPos, $"SUBOBJECTIVE: {subObjective.DebugTag} ({subObjective.Priority.FormatZeroDecimal()})", Color.White, Color.Black);
|
||||
}
|
||||
for (int i = 0; i < ObjectiveManager.Objectives.Count; i++)
|
||||
var activeObjective = ObjectiveManager.GetActiveObjective();
|
||||
if (activeObjective != null)
|
||||
{
|
||||
var objective = ObjectiveManager.Objectives[i];
|
||||
int offsetMultiplier;
|
||||
if (ObjectiveManager.CurrentOrder == null)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
offsetMultiplier = i - 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
offsetMultiplier = i + 1;
|
||||
}
|
||||
GUI.DrawString(spriteBatch, pos + textOffset + new Vector2(120, offsetMultiplier * 18 + 100), $"{objective.DebugTag} ({objective.Priority.FormatZeroDecimal()})", Color.White, Color.Black * 0.5f);
|
||||
stringDrawPos += new Vector2(0, 20);
|
||||
GUI.DrawString(spriteBatch, stringDrawPos, $"ACTIVE OBJECTIVE: {activeObjective.DebugTag} ({activeObjective.Priority.FormatZeroDecimal()})", Color.White, Color.Black);
|
||||
}
|
||||
}
|
||||
|
||||
Vector2 objectiveStringDrawPos = stringDrawPos + new Vector2(120, 40);
|
||||
for (int i = 0; i < ObjectiveManager.Objectives.Count; i++)
|
||||
{
|
||||
var objective = ObjectiveManager.Objectives[i];
|
||||
GUI.DrawString(spriteBatch, objectiveStringDrawPos, $"{objective.DebugTag} ({objective.Priority.FormatZeroDecimal()})", Color.White, Color.Black * 0.5f);
|
||||
objectiveStringDrawPos += new Vector2(0, 18);
|
||||
}
|
||||
|
||||
if (steeringManager is IndoorsSteeringManager pathSteering)
|
||||
{
|
||||
var path = pathSteering.CurrentPath;
|
||||
@@ -111,13 +98,21 @@ namespace Barotrauma
|
||||
new Vector2(path.CurrentNode.DrawPosition.X, -path.CurrentNode.DrawPosition.Y),
|
||||
Color.BlueViolet, 0, 3);
|
||||
|
||||
GUI.DrawString(spriteBatch, pos + textOffset + new Vector2(0, 100), "Path cost: " + path.Cost.FormatZeroDecimal(), Color.White, Color.Black * 0.5f);
|
||||
GUI.DrawString(spriteBatch, stringDrawPos + new Vector2(0, 40), "Path cost: " + path.Cost.FormatZeroDecimal(), Color.White, Color.Black * 0.5f);
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
@@ -520,7 +520,7 @@ namespace Barotrauma
|
||||
|
||||
foreach (Character c in CharacterList)
|
||||
{
|
||||
if (!CanInteractWith(c, checkVisibility: false)) continue;
|
||||
if (!CanInteractWith(c, checkVisibility: false) || (c.AnimController?.SimplePhysicsEnabled ?? true)) { continue; }
|
||||
|
||||
float dist = Vector2.DistanceSquared(mouseSimPos, c.SimPosition);
|
||||
if (dist < maxDist * maxDist && (closestCharacter == null || dist < closestDist))
|
||||
@@ -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);
|
||||
@@ -634,9 +634,9 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
partial void SetOrderProjSpecific(Order order, string orderOption)
|
||||
partial void SetOrderProjSpecific(Order order, string orderOption, int priority)
|
||||
{
|
||||
GameMain.GameSession?.CrewManager?.AddCurrentOrderIcon(this, order, orderOption);
|
||||
GameMain.GameSession?.CrewManager?.AddCurrentOrderIcon(this, order, orderOption, priority);
|
||||
}
|
||||
|
||||
public static void AddAllToGUIUpdateList()
|
||||
@@ -686,7 +686,7 @@ namespace Barotrauma
|
||||
|
||||
public virtual void DrawFront(SpriteBatch spriteBatch, Camera cam)
|
||||
{
|
||||
if (!Enabled || InvisibleTimer > 0.0f) { return; }
|
||||
if (!Enabled || InvisibleTimer > 0.0f || (AnimController?.SimplePhysicsEnabled ?? true)) { return; }
|
||||
|
||||
if (GameMain.DebugDraw)
|
||||
{
|
||||
@@ -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)
|
||||
{
|
||||
@@ -815,7 +815,7 @@ namespace Barotrauma
|
||||
iconPos.Y = -iconPos.Y;
|
||||
nameColor = iconStyle.Color;
|
||||
var icon = iconStyle.Sprites[GUIComponent.ComponentState.None].First();
|
||||
float iconScale = 30.0f / icon.Sprite.size.X / cam.Zoom;
|
||||
float iconScale = (30.0f / icon.Sprite.size.X / cam.Zoom) * GUI.Scale;
|
||||
icon.Sprite.Draw(spriteBatch, iconPos + new Vector2(-35.0f, -25.0f), iconStyle.Color * hudInfoAlpha, scale: iconScale);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Barotrauma.Items.Components;
|
||||
using Barotrauma.Extensions;
|
||||
using Barotrauma.Items.Components;
|
||||
using FarseerPhysics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
@@ -57,7 +58,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 +77,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)
|
||||
{
|
||||
@@ -130,17 +131,6 @@ namespace Barotrauma
|
||||
{
|
||||
character.Inventory.ClearSubInventories();
|
||||
}
|
||||
|
||||
for (int i = 0; i < character.Inventory.Items.Length - 1; i++)
|
||||
{
|
||||
var item = character.Inventory.Items[i];
|
||||
if (item == null || character.Inventory.SlotTypes[i] == InvSlotType.Any) continue;
|
||||
|
||||
foreach (ItemComponent ic in item.Components)
|
||||
{
|
||||
if (ic.DrawHudWhenEquipped) ic.UpdateHUD(character, deltaTime, cam);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (character.IsHumanoid && character.SelectedCharacter != null && character.SelectedCharacter.Inventory != null)
|
||||
@@ -206,22 +196,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 (character.GetCurrentOrderWithTopPriority()?.Order is Order currentOrder && DrawIcon(currentOrder))
|
||||
{
|
||||
DrawOrderIndicator(spriteBatch, cam, character, character.CurrentOrder, 1.0f);
|
||||
}
|
||||
DrawOrderIndicator(spriteBatch, cam, 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 +230,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 +243,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.None(it => it?.GetComponent<Sprayer>() != null)))
|
||||
{
|
||||
if (character.FocusedCharacter != null && character.FocusedCharacter.CanBeSelected)
|
||||
{
|
||||
@@ -281,7 +280,7 @@ namespace Barotrauma
|
||||
if (!GUI.DisableItemHighlights && !Inventory.DraggingItemToWorld)
|
||||
{
|
||||
bool shiftDown = PlayerInput.KeyDown(Keys.LeftShift) || PlayerInput.KeyDown(Keys.RightShift);
|
||||
if(shouldRecreateHudTexts || heldDownShiftWhenGotHudTexts != shiftDown)
|
||||
if (shouldRecreateHudTexts || heldDownShiftWhenGotHudTexts != shiftDown)
|
||||
{
|
||||
shouldRecreateHudTexts = true;
|
||||
heldDownShiftWhenGotHudTexts = shiftDown;
|
||||
@@ -291,8 +290,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 +306,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 +340,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 +353,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,12 +430,16 @@ 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)
|
||||
{
|
||||
var statusHUD = item?.GetComponent<StatusHUD>();
|
||||
if (statusHUD != null && statusHUD.IsActive && statusHUD.VisibleCharacters.Contains(character.FocusedCharacter))
|
||||
foreach (Item item in allItems)
|
||||
{
|
||||
return;
|
||||
var statusHUD = item?.GetComponent<StatusHUD>();
|
||||
if (statusHUD != null && statusHUD.IsActive && statusHUD.VisibleCharacters.Contains(character.FocusedCharacter))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -454,7 +456,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 +495,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 +518,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,48 +152,37 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
private void GetDisguisedSprites(IdCard idCard)
|
||||
{
|
||||
if (idCard.Item.Tags == string.Empty) return;
|
||||
|
||||
if (idCard.StoredJobPrefab == null || idCard.StoredPortrait == null)
|
||||
{
|
||||
string[] readTags = idCard.Item.Tags.Split(',');
|
||||
|
||||
if (readTags.Length == 0) return;
|
||||
|
||||
if (idCard.StoredJobPrefab == null)
|
||||
{
|
||||
string jobIdTag = readTags.First(s => s.StartsWith("jobid:"));
|
||||
string jobIdTag = readTags.FirstOrDefault(s => s.StartsWith("jobid:"));
|
||||
|
||||
if (jobIdTag != string.Empty && jobIdTag.Length > 6)
|
||||
if (jobIdTag != null && jobIdTag.Length > 6)
|
||||
{
|
||||
string jobId = jobIdTag.Substring(6);
|
||||
if (jobId != string.Empty)
|
||||
|
||||
@@ -292,7 +292,7 @@ namespace Barotrauma
|
||||
break;
|
||||
case ServerNetObject.ENTITY_EVENT:
|
||||
|
||||
int eventType = msg.ReadRangedInteger(0, 5);
|
||||
int eventType = msg.ReadRangedInteger(0, 6);
|
||||
switch (eventType)
|
||||
{
|
||||
case 0: //NetEntityEvent.Type.InventoryState
|
||||
@@ -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
|
||||
@@ -390,6 +390,19 @@ namespace Barotrauma
|
||||
byte campaignInteractionType = msg.ReadByte();
|
||||
(GameMain.GameSession?.GameMode as CampaignMode)?.AssignNPCMenuInteraction(this, (CampaignMode.InteractionType)campaignInteractionType);
|
||||
break;
|
||||
case 6: //NetEntityEvent.Type.ObjectiveManagerOrderState
|
||||
bool properData = msg.ReadBoolean();
|
||||
if (!properData) { break; }
|
||||
int orderIndex = msg.ReadRangedInteger(0, Order.PrefabList.Count);
|
||||
var orderPrefab = Order.PrefabList[orderIndex];
|
||||
string option = null;
|
||||
if (orderPrefab.HasOptions)
|
||||
{
|
||||
int optionIndex = msg.ReadRangedInteger(0, orderPrefab.Options.Length);
|
||||
option = orderPrefab.Options[optionIndex];
|
||||
}
|
||||
GameMain.GameSession.CrewManager.SetHighlightedOrderIcon(this, orderPrefab.Identifier, option);
|
||||
break;
|
||||
}
|
||||
msg.ReadPadBits();
|
||||
break;
|
||||
@@ -434,20 +447,22 @@ 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)
|
||||
{
|
||||
(GameMain.GameSession.GameMode as CampaignMode)?.AssignNPCMenuInteraction(character, character.CampaignInteractionType);
|
||||
}
|
||||
|
||||
// Check if the character has a current order
|
||||
if (inc.ReadBoolean())
|
||||
// Check if the character has current orders
|
||||
int orderCount = inc.ReadByte();
|
||||
for (int i = 0; i < orderCount; i++)
|
||||
{
|
||||
int orderPrefabIndex = inc.ReadByte();
|
||||
Entity targetEntity = FindEntityByID(inc.ReadUInt16());
|
||||
Character orderGiver = inc.ReadBoolean() ? FindEntityByID(inc.ReadUInt16()) as Character : null;
|
||||
int orderOptionIndex = inc.ReadByte();
|
||||
int orderPriority = inc.ReadByte();
|
||||
OrderTarget targetPosition = null;
|
||||
if (inc.ReadBoolean())
|
||||
{
|
||||
@@ -468,7 +483,7 @@ namespace Barotrauma
|
||||
new Order(orderPrefab, targetPosition, orderGiver: orderGiver);
|
||||
character.SetOrder(order,
|
||||
orderOptionIndex >= 0 && orderOptionIndex < orderPrefab.Options.Length ? orderPrefab.Options[orderOptionIndex] : null,
|
||||
orderGiver, speak: false);
|
||||
orderPriority, orderGiver, speak: false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -487,7 +502,7 @@ namespace Barotrauma
|
||||
character.ReadStatus(inc);
|
||||
}
|
||||
|
||||
if (character.IsHuman && character.TeamID != TeamType.FriendlyNPC && !character.IsDead)
|
||||
if (character.IsHuman && character.TeamID != CharacterTeamType.FriendlyNPC && character.TeamID != CharacterTeamType.None && !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:
|
||||
|
||||
@@ -668,12 +668,17 @@ namespace Barotrauma
|
||||
bloodParticleTimer -= deltaTime * (affliction.Strength / 10.0f);
|
||||
if (bloodParticleTimer <= 0.0f)
|
||||
{
|
||||
var emitter = Character.BloodEmitters.FirstOrDefault();
|
||||
float particleMinScale = emitter != null ? emitter.Prefab.ScaleMin : 0.5f;
|
||||
float particleMaxScale = emitter != null ? emitter.Prefab.ScaleMax : 1;
|
||||
float severity = Math.Min(affliction.Strength / affliction.Prefab.MaxStrength * Character.Params.BleedParticleMultiplier, 1);
|
||||
float bloodParticleSize = MathHelper.Lerp(particleMinScale, particleMaxScale, severity);
|
||||
bool inWater = Character.AnimController.InWater;
|
||||
float bloodParticleSize = MathHelper.Lerp(0.5f, 1.0f, affliction.Strength / 100.0f);
|
||||
if (!inWater)
|
||||
{
|
||||
bloodParticleSize *= 2.0f;
|
||||
}
|
||||
|
||||
var blood = GameMain.ParticleManager.CreateParticle(
|
||||
inWater ? Character.Params.BleedParticleWater : Character.Params.BleedParticleAir,
|
||||
targetLimb.WorldPosition, Rand.Vector(affliction.Strength), 0.0f, Character.AnimController.CurrentHull);
|
||||
@@ -682,7 +687,7 @@ namespace Barotrauma
|
||||
{
|
||||
blood.Size *= bloodParticleSize;
|
||||
}
|
||||
bloodParticleTimer = 1.0f;
|
||||
bloodParticleTimer = MathHelper.Lerp(2, 0.5f, severity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -912,7 +917,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 +1637,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 +1657,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;
|
||||
medicalItems.Add(containedItem);
|
||||
}
|
||||
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,24 +1801,27 @@ namespace Barotrauma
|
||||
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, Lights.CustomBlendStates.Multiplicative);
|
||||
|
||||
float overlayScale = Math.Min(
|
||||
drawArea.Width / (float)limbIndicatorOverlay.FrameSize.X,
|
||||
drawArea.Height / (float)limbIndicatorOverlay.FrameSize.Y);
|
||||
|
||||
int frame = 0;
|
||||
int frameCount = 17;
|
||||
if (limbIndicatorOverlayAnimState >= frameCount * 2) limbIndicatorOverlayAnimState = 0.0f;
|
||||
if (limbIndicatorOverlayAnimState < frameCount)
|
||||
if (limbIndicatorOverlay != null)
|
||||
{
|
||||
frame = (int)limbIndicatorOverlayAnimState;
|
||||
}
|
||||
else
|
||||
{
|
||||
frame = frameCount - (int)(limbIndicatorOverlayAnimState - (frameCount - 1));
|
||||
}
|
||||
float overlayScale = Math.Min(
|
||||
drawArea.Width / (float)limbIndicatorOverlay.FrameSize.X,
|
||||
drawArea.Height / (float)limbIndicatorOverlay.FrameSize.Y);
|
||||
|
||||
limbIndicatorOverlay.Draw(spriteBatch, frame, drawArea.Center.ToVector2(), Color.Gray, origin: limbIndicatorOverlay.FrameSize.ToVector2() / 2, rotate: 0.0f,
|
||||
scale: Vector2.One * overlayScale);
|
||||
int frame = 0;
|
||||
int frameCount = 17;
|
||||
if (limbIndicatorOverlayAnimState >= frameCount * 2) limbIndicatorOverlayAnimState = 0.0f;
|
||||
if (limbIndicatorOverlayAnimState < frameCount)
|
||||
{
|
||||
frame = (int)limbIndicatorOverlayAnimState;
|
||||
}
|
||||
else
|
||||
{
|
||||
frame = frameCount - (int)(limbIndicatorOverlayAnimState - (frameCount - 1));
|
||||
}
|
||||
|
||||
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,18 +426,24 @@ namespace Barotrauma
|
||||
character.Info?.CalculateHeadPosition(sprite);
|
||||
}
|
||||
|
||||
private string _texturePath;
|
||||
private string GetSpritePath(XElement element, SpriteParams spriteParams)
|
||||
{
|
||||
if (spriteParams != null)
|
||||
if (_texturePath == null)
|
||||
{
|
||||
return GetSpritePath(spriteParams.GetTexturePath());
|
||||
}
|
||||
else
|
||||
{
|
||||
string texturePath = element.GetAttributeString("texture", null);
|
||||
texturePath = string.IsNullOrWhiteSpace(texturePath) ? ragdoll.RagdollParams.Texture : texturePath;
|
||||
return GetSpritePath(texturePath);
|
||||
if (spriteParams != null)
|
||||
{
|
||||
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;
|
||||
_texturePath = GetSpritePath(texturePath);
|
||||
}
|
||||
}
|
||||
return _texturePath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -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);
|
||||
@@ -235,20 +257,23 @@ namespace Barotrauma
|
||||
|
||||
public static void DequeueMessages()
|
||||
{
|
||||
while (queuedMessages.Count > 0)
|
||||
lock (queuedMessages)
|
||||
{
|
||||
var newMsg = queuedMessages.Dequeue();
|
||||
if (listBox == null)
|
||||
while (queuedMessages.Count > 0)
|
||||
{
|
||||
//don't attempt to add to the listbox if it hasn't been created yet
|
||||
Messages.Add(newMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddMessage(newMsg);
|
||||
}
|
||||
var newMsg = queuedMessages.Dequeue();
|
||||
if (listBox == null)
|
||||
{
|
||||
//don't attempt to add to the listbox if it hasn't been created yet
|
||||
Messages.Add(newMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddMessage(newMsg);
|
||||
}
|
||||
|
||||
if (GameSettings.SaveDebugConsoleLogs) unsavedMessages.Add(newMsg);
|
||||
if (GameSettings.SaveDebugConsoleLogs) unsavedMessages.Add(newMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,7 +299,12 @@ namespace Barotrauma
|
||||
{
|
||||
var textContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.0f), listBox.Content.RectTransform), style: "InnerFrame", color: Color.White)
|
||||
{
|
||||
CanBeFocused = false
|
||||
CanBeFocused = true,
|
||||
OnSecondaryClicked = (component, data) =>
|
||||
{
|
||||
GUIContextMenu.CreateContextMenu(new ContextMenuOption("editor.copytoclipboard", true, () => { Clipboard.SetText(msg.Text); }));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
var textBlock = new GUITextBlock(new RectTransform(new Point(listBox.Content.Rect.Width - 5, 0), textContainer.RectTransform, Anchor.TopLeft) { AbsoluteOffset = new Point(2, 2) },
|
||||
msg.Text, textAlignment: Alignment.TopLeft, font: GUI.SmallFont, wrap: true)
|
||||
@@ -455,7 +485,7 @@ namespace Barotrauma
|
||||
var subInfo = new SubmarineInfo(string.Join(" ", args));
|
||||
Submarine.MainSub = Submarine.Load(subInfo, true);
|
||||
}
|
||||
GameMain.SubEditorScreen.Select();
|
||||
GameMain.SubEditorScreen.Select(enableAutoSave: Screen.Selected != GameMain.GameScreen);
|
||||
}, isCheat: true));
|
||||
|
||||
commands.Add(new Command("editparticles|particleeditor", "editparticles/particleeditor: Switch to the Particle Editor to edit particle effects.", (string[] args) =>
|
||||
@@ -487,6 +517,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;
|
||||
@@ -497,6 +545,102 @@ 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("spreadsheetexport", "Export items in format recognized by the spreadsheet importer.", (string[] args) =>
|
||||
{
|
||||
SpreadsheetExport.Export();
|
||||
}));
|
||||
|
||||
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);
|
||||
@@ -510,11 +654,19 @@ 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);
|
||||
AssignRelayToServer("spreadsheetexport", 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) => { }));
|
||||
@@ -552,14 +704,15 @@ namespace Barotrauma
|
||||
AssignOnExecute("explosion", (string[] args) =>
|
||||
{
|
||||
Vector2 explosionPos = GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition);
|
||||
float range = 500, force = 10, damage = 50, structureDamage = 10, itemDamage = 100, empStrength = 0.0f;
|
||||
float range = 500, force = 10, damage = 50, structureDamage = 10, itemDamage = 100, empStrength = 0.0f, ballastFloraStrength = 50f;
|
||||
if (args.Length > 0) float.TryParse(args[0], out range);
|
||||
if (args.Length > 1) float.TryParse(args[1], out force);
|
||||
if (args.Length > 2) float.TryParse(args[2], out damage);
|
||||
if (args.Length > 3) float.TryParse(args[3], out structureDamage);
|
||||
if (args.Length > 4) float.TryParse(args[4], out itemDamage);
|
||||
if (args.Length > 5) float.TryParse(args[5], out empStrength);
|
||||
new Explosion(range, force, damage, structureDamage, itemDamage, empStrength).Explode(explosionPos, null);
|
||||
if (args.Length > 6) float.TryParse(args[6], out ballastFloraStrength);
|
||||
new Explosion(range, force, damage, structureDamage, itemDamage, empStrength, ballastFloraStrength).Explode(explosionPos, null);
|
||||
});
|
||||
|
||||
AssignOnExecute("teleportcharacter|teleport", (string[] args) =>
|
||||
@@ -997,6 +1150,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;
|
||||
@@ -1382,6 +1546,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) =>
|
||||
{
|
||||
@@ -1416,6 +1590,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();
|
||||
@@ -1831,15 +2011,22 @@ namespace Barotrauma
|
||||
ToolBox.OpenFileWithShell(Path.GetFullPath(filePath));
|
||||
}));
|
||||
#if DEBUG
|
||||
commands.Add(new Command("playovervc", "Plays a sound over voice chat.", (args) =>
|
||||
{
|
||||
VoipCapture.Instance?.SetOverrideSound(args.Length > 0 ? args[0] : null);
|
||||
}));
|
||||
|
||||
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;
|
||||
foreach (var lobby in lobbies)
|
||||
{
|
||||
DebugConsole.NewMessage(lobby.GetData("name") + ", " + lobby.GetData("lobbyowner"));
|
||||
}
|
||||
TaskPool.Add("DebugQueryLobbies",
|
||||
SteamManager.LobbyQueryRequest(), (t) => {
|
||||
var lobbies = ((Task<List<Steamworks.Data.Lobby>>)t).Result;
|
||||
foreach (var lobby in lobbies)
|
||||
{
|
||||
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) =>
|
||||
@@ -2236,6 +2423,37 @@ namespace Barotrauma
|
||||
}
|
||||
);
|
||||
|
||||
#if DEBUG
|
||||
commands.Add(new Command("setcurrentlocationtype", "setcurrentlocationtype [location type]: Change the type of the current location.", (string[] args) =>
|
||||
{
|
||||
var character = Character.Controlled;
|
||||
if (GameMain.GameSession?.Campaign == null)
|
||||
{
|
||||
ThrowError("Campaign not active!");
|
||||
return;
|
||||
}
|
||||
if (args.Length == 0)
|
||||
{
|
||||
ThrowError("Please give the location type after the command.");
|
||||
return;
|
||||
}
|
||||
var locationType = LocationType.List.Find(lt => lt.Identifier.Equals(args[0], StringComparison.OrdinalIgnoreCase));
|
||||
if (locationType == null)
|
||||
{
|
||||
ThrowError($"Could not find the location type \"{args[0]}\".");
|
||||
return;
|
||||
}
|
||||
GameMain.GameSession.Campaign.Map.CurrentLocation.ChangeType(locationType);
|
||||
},
|
||||
() =>
|
||||
{
|
||||
return new string[][]
|
||||
{
|
||||
LocationType.List.Select(lt => lt.Identifier).ToArray()
|
||||
};
|
||||
}));
|
||||
#endif
|
||||
|
||||
commands.Add(new Command("limbscale", "Define the limbscale for the controlled character. Provide id or name if you want to target another character. Note: the changes are not saved!", (string[] args) =>
|
||||
{
|
||||
var character = Character.Controlled;
|
||||
|
||||
@@ -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,15 +43,15 @@ 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 + 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);
|
||||
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);
|
||||
|
||||
GUI.DrawString(spriteBatch, new Vector2(15, y + 65), "AvgHealth: " + (int) Math.Round(avgCrewHealth * 100), Color.Lerp(GUI.Style.Red, GUI.Style.Green, avgCrewHealth), Color.Black * 0.6f, 0, GUI.SmallFont);
|
||||
GUI.DrawString(spriteBatch, new Vector2(15, y + 80), "AvgHullIntegrity: " + (int) Math.Round(avgHullIntegrity * 100), Color.Lerp(GUI.Style.Red, GUI.Style.Green, avgHullIntegrity), Color.Black * 0.6f, 0, GUI.SmallFont);
|
||||
GUI.DrawString(spriteBatch, new Vector2(15, y + 95), "FloodingAmount: " + (int) Math.Round(floodingAmount * 100), Color.Lerp(GUI.Style.Green, GUI.Style.Red, floodingAmount), Color.Black * 0.6f, 0, GUI.SmallFont);
|
||||
GUI.DrawString(spriteBatch, new Vector2(15, y + 110), "FireAmount: " + (int) Math.Round(fireAmount * 100), Color.Lerp(GUI.Style.Green, GUI.Style.Red, fireAmount), Color.Black * 0.6f, 0, GUI.SmallFont);
|
||||
GUI.DrawString(spriteBatch, new Vector2(15, y + 125), "EnemyDanger: " + (int) Math.Round(enemyDanger * 100), Color.Lerp(GUI.Style.Green, GUI.Style.Red, enemyDanger), Color.Black * 0.6f, 0, GUI.SmallFont);
|
||||
GUI.DrawString(spriteBatch, new Vector2(15, y + 65), "AvgHealth: " + (int)Math.Round(avgCrewHealth * 100), Color.Lerp(GUI.Style.Red, GUI.Style.Green, avgCrewHealth), Color.Black * 0.6f, 0, GUI.SmallFont);
|
||||
GUI.DrawString(spriteBatch, new Vector2(15, y + 80), "AvgHullIntegrity: " + (int)Math.Round(avgHullIntegrity * 100), Color.Lerp(GUI.Style.Red, GUI.Style.Green, avgHullIntegrity), Color.Black * 0.6f, 0, GUI.SmallFont);
|
||||
GUI.DrawString(spriteBatch, new Vector2(15, y + 95), "FloodingAmount: " + (int)Math.Round(floodingAmount * 100), Color.Lerp(GUI.Style.Green, GUI.Style.Red, floodingAmount), Color.Black * 0.6f, 0, GUI.SmallFont);
|
||||
GUI.DrawString(spriteBatch, new Vector2(15, y + 110), "FireAmount: " + (int)Math.Round(fireAmount * 100), Color.Lerp(GUI.Style.Green, GUI.Style.Red, fireAmount), Color.Black * 0.6f, 0, GUI.SmallFont);
|
||||
GUI.DrawString(spriteBatch, new Vector2(15, y + 125), "EnemyDanger: " + (int)Math.Round(enemyDanger * 100), Color.Lerp(GUI.Style.Green, GUI.Style.Red, enemyDanger), Color.Black * 0.6f, 0, GUI.SmallFont);
|
||||
|
||||
#if DEBUG
|
||||
if (PlayerInput.KeyDown(Microsoft.Xna.Framework.Input.Keys.LeftAlt) &&
|
||||
@@ -86,15 +86,26 @@ 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),
|
||||
"Intensity too high for new events: " + (int) (currentIntensity * 100) + "%/" + (int) (eventThreshold * 100) + "%", Color.LightGreen * 0.8f, null, 0, GUI.SmallFont);
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
using Barotrauma.Networking;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class AbandonedOutpostMission : Mission
|
||||
{
|
||||
public override void ClientReadInitial(IReadMessage msg)
|
||||
{
|
||||
byte characterCount = msg.ReadByte();
|
||||
|
||||
for (int i = 0; i < characterCount; i++)
|
||||
{
|
||||
characters.Add(Character.ReadSpawnData(msg));
|
||||
ushort itemCount = msg.ReadUInt16();
|
||||
for (int j = 0; j < itemCount; j++)
|
||||
{
|
||||
Item.ReadSpawnData(msg);
|
||||
}
|
||||
}
|
||||
if (characters.Contains(null))
|
||||
{
|
||||
throw new System.Exception("Error in AbandonedOutpostMission.ClientReadInitial: character list contains null (mission: " + Prefab.Identifier + ")");
|
||||
}
|
||||
if (characters.Count != characterCount)
|
||||
{
|
||||
throw new System.Exception("Error in AbandonedOutpostMission.ClientReadInitial: character count does not match the server count (" + characters + " != " + characters.Count + "mission: " + Prefab.Identifier + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
|
||||
namespace Barotrauma
|
||||
namespace Barotrauma
|
||||
{
|
||||
abstract partial class MissionMode : GameMode
|
||||
{
|
||||
public override void ShowStartMessage()
|
||||
{
|
||||
if (mission == null) return;
|
||||
|
||||
new GUIMessageBox(mission.Name, mission.Description, new string[0], type: GUIMessageBox.Type.InGame, icon: mission.Prefab.Icon)
|
||||
foreach (Mission mission in missions)
|
||||
{
|
||||
IconColor = mission.Prefab.IconColor,
|
||||
UserData = "missionstartmessage"
|
||||
};
|
||||
new GUIMessageBox(mission.Name, mission.Description, new string[0], type: GUIMessageBox.Type.InGame, icon: mission.Prefab.Icon)
|
||||
{
|
||||
IconColor = mission.Prefab.IconColor,
|
||||
UserData = "missionstartmessage"
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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++)
|
||||
{
|
||||
|
||||
@@ -91,9 +91,10 @@ namespace Barotrauma
|
||||
UserData = "container"
|
||||
};
|
||||
|
||||
int panelMaxWidth = (int)(GUI.xScale * (GUI.HorizontalAspectRatio < 1.4f ? 650 : 560));
|
||||
var availableMainGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.4f, 1.0f), campaignUI.GetTabContainer(CampaignMode.InteractionType.Crew).RectTransform)
|
||||
{
|
||||
MaxSize = new Point(560, campaignUI.GetTabContainer(CampaignMode.InteractionType.Crew).Rect.Height)
|
||||
MaxSize = new Point(panelMaxWidth, campaignUI.GetTabContainer(CampaignMode.InteractionType.Crew).Rect.Height)
|
||||
})
|
||||
{
|
||||
Stretch = true,
|
||||
@@ -149,7 +150,7 @@ namespace Barotrauma
|
||||
|
||||
var pendingAndCrewMainGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.4f, 1.0f), campaignUI.GetTabContainer(CampaignMode.InteractionType.Crew).RectTransform, anchor: Anchor.TopRight)
|
||||
{
|
||||
MaxSize = new Point(560, campaignUI.GetTabContainer(CampaignMode.InteractionType.Crew).Rect.Height)
|
||||
MaxSize = new Point(panelMaxWidth, campaignUI.GetTabContainer(CampaignMode.InteractionType.Crew).Rect.Height)
|
||||
})
|
||||
{
|
||||
Stretch = true,
|
||||
@@ -177,7 +178,7 @@ namespace Barotrauma
|
||||
var pendingAndCrewGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.95f), anchor: Anchor.Center,
|
||||
parent: new GUIFrame(new RectTransform(new Vector2(1.0f, 13.25f / 14.0f), pendingAndCrewMainGroup.RectTransform)
|
||||
{
|
||||
MaxSize = new Point(560, campaignUI.GetTabContainer(CampaignMode.InteractionType.Crew).Rect.Height)
|
||||
MaxSize = new Point(panelMaxWidth, campaignUI.GetTabContainer(CampaignMode.InteractionType.Crew).Rect.Height)
|
||||
}).RectTransform));
|
||||
|
||||
float height = 0.05f;
|
||||
@@ -335,7 +336,7 @@ namespace Barotrauma
|
||||
jobColor = characterInfo.Job.Prefab.UIColor;
|
||||
}
|
||||
|
||||
GUIFrame frame = new GUIFrame(new RectTransform(new Point(listBox.Content.Rect.Width, 55), parent: listBox.Content.RectTransform), "ListBoxElement")
|
||||
GUIFrame frame = new GUIFrame(new RectTransform(new Point(listBox.Content.Rect.Width, (int)(GUI.yScale * 55)), parent: listBox.Content.RectTransform), "ListBoxElement")
|
||||
{
|
||||
UserData = new Tuple<CharacterInfo, float>(characterInfo, skill != null ? skill.Level : 0.0f)
|
||||
};
|
||||
@@ -366,7 +367,7 @@ namespace Barotrauma
|
||||
jobBlock.Text = ToolBox.LimitString(jobBlock.Text, jobBlock.Font, jobBlock.Rect.Width);
|
||||
|
||||
float width = 0.6f / 3;
|
||||
if (characterInfo.Job != null)
|
||||
if (characterInfo.Job != null && skill != null)
|
||||
{
|
||||
GUILayoutGroup skillGroup = new GUILayoutGroup(new RectTransform(new Vector2(width, 0.6f), mainGroup.RectTransform), isHorizontal: true);
|
||||
float iconWidth = (float)skillGroup.Rect.Height / skillGroup.Rect.Width;
|
||||
|
||||
@@ -287,6 +287,7 @@ namespace Barotrauma
|
||||
{
|
||||
lock (mutex)
|
||||
{
|
||||
usedIndicatorAngles.Clear();
|
||||
|
||||
if (ScreenChanged)
|
||||
{
|
||||
@@ -854,6 +855,7 @@ namespace Barotrauma
|
||||
lock (mutex)
|
||||
{
|
||||
GUIMessageBox.AddActiveToGUIUpdateList();
|
||||
GUIContextMenu.AddActiveToGUIUpdateList();
|
||||
|
||||
if (pauseMenuOpen)
|
||||
{
|
||||
@@ -920,6 +922,7 @@ namespace Barotrauma
|
||||
if ((!PlayerInput.PrimaryMouseButtonHeld() && !PlayerInput.PrimaryMouseButtonClicked()) || c == prevMouseOn)
|
||||
{
|
||||
MouseOn = c;
|
||||
var sakdjfnsjkd = c.MouseRect;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1117,15 +1120,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 +1233,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 +1258,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 +1270,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;
|
||||
float symbolScale = Math.Min(64.0f / sprite.size.X, 1.0f) * scaleMultiplier * Scale;
|
||||
|
||||
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 +1296,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 +1528,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 +1546,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 +1647,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 +2119,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 +2328,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);
|
||||
}
|
||||
}
|
||||
292
Barotrauma/BarotraumaClient/ClientSource/GUI/GUIContextMenu.cs
Normal file
292
Barotrauma/BarotraumaClient/ClientSource/GUI/GUIContextMenu.cs
Normal file
@@ -0,0 +1,292 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Barotrauma.Extensions;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
struct ContextMenuOption
|
||||
{
|
||||
public string Label;
|
||||
public Action OnSelected;
|
||||
public ContextMenuOption[]? SubOptions;
|
||||
public bool IsEnabled;
|
||||
public string Tooltip;
|
||||
|
||||
// Creates a regular context menu
|
||||
public ContextMenuOption(string label, bool isEnabled, Action onSelected)
|
||||
{
|
||||
Label = TextManager.Get(label, returnNull: true) ?? label;
|
||||
OnSelected = onSelected;
|
||||
IsEnabled = isEnabled;
|
||||
SubOptions = null;
|
||||
Tooltip = string.Empty;
|
||||
}
|
||||
|
||||
// Creates a option with a sub context menu
|
||||
public ContextMenuOption(string label, bool isEnabled, params ContextMenuOption[] options): this(label, isEnabled, () => { })
|
||||
{
|
||||
SubOptions = options;
|
||||
}
|
||||
}
|
||||
|
||||
internal class GUIContextMenu : GUIComponent
|
||||
{
|
||||
public static GUIContextMenu? CurrentContextMenu;
|
||||
|
||||
private readonly Dictionary<ContextMenuOption, GUITextBlock> Options = new Dictionary<ContextMenuOption, GUITextBlock>();
|
||||
private GUIContextMenu? SubMenu;
|
||||
public readonly GUITextBlock? HeaderLabel;
|
||||
public GUITextBlock? ParentOption;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a context menu. This constructor does not make the context menu active.
|
||||
/// Use <see cref="CreateContextMenu(Barotrauma.ContextMenuOption[])"/> to make right click context menus.
|
||||
/// </summary>
|
||||
/// <param name="position">Position at which to create the context menu</param>
|
||||
/// <param name="header">Header text</param>
|
||||
/// <param name="style">Background style</param>
|
||||
/// <param name="options">list of context menu options</param>
|
||||
public GUIContextMenu(Vector2? position, string header, string style, params ContextMenuOption[] options) : base(style, new RectTransform(Point.Zero, GUI.Canvas))
|
||||
{
|
||||
Vector2 pos = position ?? PlayerInput.MousePosition;
|
||||
ScalableFont headerFont = GUI.SubHeadingFont;
|
||||
ScalableFont font = GUI.SmallFont; // font the context menu options use
|
||||
Vector4 padding = new Vector4(4), headerPadding = new Vector4(8);
|
||||
int horizontalPadding = (int) (padding.X + padding.Z), verticalPadding = (int) (padding.Y + padding.W);
|
||||
bool hasHeader = !string.IsNullOrWhiteSpace(header);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Estimate the size of the context menu
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
Dictionary<ContextMenuOption, Vector2> optionsAndSizes = new Dictionary<ContextMenuOption, Vector2>();
|
||||
|
||||
// estimate how big the context menu needs to be
|
||||
Point estimatedSize = new Point(horizontalPadding, verticalPadding);
|
||||
|
||||
if (hasHeader)
|
||||
{
|
||||
InflateSize(ref estimatedSize, header, headerFont);
|
||||
}
|
||||
|
||||
foreach (ContextMenuOption option in options)
|
||||
{
|
||||
Vector2 optionSize = InflateSize(ref estimatedSize, option.Label, font);
|
||||
optionsAndSizes.Add(option, optionSize);
|
||||
}
|
||||
|
||||
// it's better to overestimate the size since it's going to be cropped anyways
|
||||
estimatedSize = estimatedSize.Multiply(1.2f);
|
||||
|
||||
RectTransform.NonScaledSize = estimatedSize;
|
||||
RectTransform.AbsoluteOffset = pos.ToPoint();
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Construct the GUI elements
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
GUILayoutGroup background = new GUILayoutGroup(new RectTransform(Vector2.One, RectTransform, Anchor.Center));
|
||||
|
||||
if (hasHeader)
|
||||
{
|
||||
HeaderLabel = new GUITextBlock(new RectTransform(new Vector2(1f, 0.2f), background.RectTransform), header, font: headerFont) { Padding = headerPadding };
|
||||
}
|
||||
|
||||
GUIListBox optionList = new GUIListBox(new RectTransform(new Vector2(1f, hasHeader ? 0.8f : 1f), background.RectTransform), style: null)
|
||||
{
|
||||
AutoHideScrollBar = false,
|
||||
ScrollBarVisible = false,
|
||||
Padding = hasHeader ? new Vector4(4, 0, 4, 4) : padding
|
||||
};
|
||||
|
||||
foreach (var (option, size) in optionsAndSizes)
|
||||
{
|
||||
GUITextBlock optionElement = new GUITextBlock(new RectTransform(size.ToPoint(), optionList.Content.RectTransform), option.Label, font: font)
|
||||
{
|
||||
UserData = option,
|
||||
Enabled = option.IsEnabled
|
||||
};
|
||||
Options.Add(option, optionElement);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(option.Tooltip) && optionElement.Enabled)
|
||||
{
|
||||
optionElement.ToolTip = option.Tooltip;
|
||||
}
|
||||
|
||||
if (!option.IsEnabled)
|
||||
{
|
||||
optionElement.TextColor *= 0.5f;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Positioning and cropping the context menu
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
List<GUIComponent> children = optionList.Content.Children.ToList();
|
||||
|
||||
// Resize all children to the size of their text
|
||||
foreach (GUITextBlock block in children.Where(c => c is GUITextBlock).Cast<GUITextBlock>())
|
||||
{
|
||||
block.RectTransform.NonScaledSize = new Point((int) (block.TextSize.X + (block.Padding.X + block.Padding.Z)), (int) (18 * GUI.Scale));
|
||||
}
|
||||
|
||||
int largestWidth = children.Max(c => c.Rect.Width + horizontalPadding);
|
||||
|
||||
// if the header is bigger than any of the options then overwrite
|
||||
if (HeaderLabel != null)
|
||||
{
|
||||
RectTransform headerTransform = HeaderLabel.RectTransform;
|
||||
headerTransform.MinSize = new Point((int) (HeaderLabel.TextSize.X + (headerPadding.X + headerPadding.Z)), headerTransform.NonScaledSize.Y);
|
||||
if (largestWidth < headerTransform.MinSize.X)
|
||||
{
|
||||
largestWidth = headerTransform.MinSize.X;
|
||||
}
|
||||
}
|
||||
|
||||
// resize all children to the size of the longest element
|
||||
foreach (GUIComponent c in children)
|
||||
{
|
||||
c.RectTransform.MinSize = new Point(largestWidth, c.Rect.Height);
|
||||
}
|
||||
|
||||
// the cropped size of the option list
|
||||
Point newSize = new Point(largestWidth, children.Sum(c => c.Rect.Height) + verticalPadding);
|
||||
// resize the menu itself taking into account the option menus relative Y size
|
||||
RectTransform.NonScaledSize = new Point(newSize.X, (int) (newSize.Y / optionList.RectTransform.RelativeSize.Y));
|
||||
optionList.RectTransform.NonScaledSize = newSize;
|
||||
|
||||
// move the context menu if it would go outside of screen
|
||||
if (RectTransform.Rect.Bottom > GameMain.GraphicsHeight)
|
||||
{
|
||||
Rectangle rect = RectTransform.Rect;
|
||||
RectTransform.AbsoluteOffset = new Point(rect.X, rect.Y - rect.Height);
|
||||
}
|
||||
|
||||
if (RectTransform.Rect.Right > GameMain.GraphicsWidth)
|
||||
{
|
||||
Rectangle rect = RectTransform.Rect;
|
||||
RectTransform.AbsoluteOffset = new Point(rect.X - rect.Width, rect.Y);
|
||||
}
|
||||
|
||||
background.Recalculate();
|
||||
|
||||
optionList.OnSelected = OnSelected;
|
||||
}
|
||||
|
||||
public static GUIContextMenu CreateContextMenu(params ContextMenuOption[] options) => CreateContextMenu(PlayerInput.MousePosition, string.Empty, null, options);
|
||||
|
||||
public static GUIContextMenu CreateContextMenu(Vector2? pos, string header, Color? headerColor, params ContextMenuOption[] options)
|
||||
{
|
||||
GUIContextMenu menu = new GUIContextMenu(pos,header, "GUIToolTip", options);
|
||||
if (headerColor != null)
|
||||
{
|
||||
menu.HeaderLabel?.OverrideTextColor(headerColor.Value);
|
||||
}
|
||||
CurrentContextMenu = menu;
|
||||
return menu;
|
||||
}
|
||||
|
||||
private bool OnSelected(GUIComponent _, object data)
|
||||
{
|
||||
if (data is ContextMenuOption option && option.IsEnabled)
|
||||
{
|
||||
CurrentContextMenu = null;
|
||||
option.OnSelected();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inflates a point by the size of the text
|
||||
/// </summary>
|
||||
/// <param name="size">Pint to resize</param>
|
||||
/// <param name="label">String whose size to inflate by</param>
|
||||
/// <param name="font">What font to use</param>
|
||||
/// <returns>The size of the text</returns>
|
||||
private Vector2 InflateSize(ref Point size, string label, ScalableFont font)
|
||||
{
|
||||
Vector2 textSize = font.MeasureString(label);
|
||||
size.X = Math.Max((int) Math.Ceiling(textSize.X), size.X);
|
||||
size.Y += (int) Math.Ceiling(textSize.Y);
|
||||
return textSize;
|
||||
}
|
||||
|
||||
protected override void Update(float deltaTime)
|
||||
{
|
||||
base.Update(deltaTime);
|
||||
|
||||
// keep the parent highlighted
|
||||
if (ParentOption != null)
|
||||
{
|
||||
ParentOption.State = ComponentState.Hover;
|
||||
}
|
||||
|
||||
if (SubMenu != null && !SubMenu.IsMouseOver())
|
||||
{
|
||||
SubMenu = null;
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var (option, textBlock) in Options)
|
||||
{
|
||||
// Create a new sub context menu if hovering over an option with sub options
|
||||
if (GUI.MouseOn != textBlock) { continue; }
|
||||
if (option.IsEnabled && option.SubOptions is { } subOptions && subOptions.Any())
|
||||
{
|
||||
Vector2 subMenuPos = new Vector2(textBlock.MouseRect.Right + 4, textBlock.MouseRect.Y);
|
||||
SubMenu = new GUIContextMenu(subMenuPos, "", "GUIToolTip", subOptions)
|
||||
{
|
||||
ParentOption = textBlock
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the mouse cursor is over this context menu or any of its sub menus
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private bool IsMouseOver()
|
||||
{
|
||||
Rectangle expandedRect = Rect;
|
||||
expandedRect.Inflate(20, 20);
|
||||
|
||||
bool isMouseOn = expandedRect.Contains(PlayerInput.MousePosition);
|
||||
|
||||
if (ParentOption != null)
|
||||
{
|
||||
isMouseOn |= GUI.MouseOn == ParentOption;
|
||||
}
|
||||
|
||||
// Recursively check sub context menus
|
||||
if (!isMouseOn && SubMenu != null)
|
||||
{
|
||||
isMouseOn = SubMenu.IsMouseOver();
|
||||
}
|
||||
|
||||
return isMouseOn;
|
||||
}
|
||||
|
||||
public override void AddToGUIUpdateList(bool ignoreChildren = false, int order = 0)
|
||||
{
|
||||
base.AddToGUIUpdateList(ignoreChildren, order);
|
||||
SubMenu?.AddToGUIUpdateList();
|
||||
}
|
||||
|
||||
public static void AddActiveToGUIUpdateList()
|
||||
{
|
||||
if (CurrentContextMenu != null && !CurrentContextMenu.IsMouseOver())
|
||||
{
|
||||
CurrentContextMenu = null;
|
||||
}
|
||||
|
||||
CurrentContextMenu?.AddToGUIUpdateList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -214,7 +214,22 @@ namespace Barotrauma
|
||||
public bool AutoHideScrollBar { get; set; } = true;
|
||||
private bool IsScrollBarOnDefaultSide { get; set; }
|
||||
|
||||
public bool CanDragElements { get; set; } = false;
|
||||
public bool CanDragElements
|
||||
{
|
||||
get
|
||||
{
|
||||
return canDragElements;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == false && canDragElements && draggedElement != null)
|
||||
{
|
||||
draggedElement = null;
|
||||
}
|
||||
canDragElements = value;
|
||||
}
|
||||
}
|
||||
private bool canDragElements = false;
|
||||
private GUIComponent draggedElement;
|
||||
private Rectangle draggedReferenceRectangle;
|
||||
private Point draggedReferenceOffset;
|
||||
@@ -223,9 +238,12 @@ namespace Barotrauma
|
||||
|
||||
private bool scheduledScroll = false;
|
||||
|
||||
private readonly bool isHorizontal;
|
||||
|
||||
/// <param name="isScrollBarOnDefaultSide">For horizontal listbox, default side is on the bottom. For vertical, it's on the right.</param>
|
||||
public GUIListBox(RectTransform rectT, bool isHorizontal = false, Color? color = null, string style = "", bool isScrollBarOnDefaultSide = true, bool useMouseDownToSelect = false) : base(style, rectT)
|
||||
{
|
||||
this.isHorizontal = isHorizontal;
|
||||
HoverCursor = CursorState.Hand;
|
||||
CanBeFocused = true;
|
||||
selected = new List<GUIComponent>();
|
||||
@@ -454,22 +472,42 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
draggedElement.RectTransform.AbsoluteOffset = draggedReferenceOffset + new Point(0, (int)PlayerInput.MousePosition.Y - draggedReferenceRectangle.Center.Y);
|
||||
draggedElement.RectTransform.AbsoluteOffset = isHorizontal ?
|
||||
draggedReferenceOffset + new Point((int)PlayerInput.MousePosition.X - draggedReferenceRectangle.Center.X, 0) :
|
||||
draggedReferenceOffset + new Point(0, (int)PlayerInput.MousePosition.Y - draggedReferenceRectangle.Center.Y);
|
||||
|
||||
int index = Content.RectTransform.GetChildIndex(draggedElement.RectTransform);
|
||||
int currIndex = index;
|
||||
|
||||
while (currIndex > 0 && PlayerInput.MousePosition.Y < draggedReferenceRectangle.Top)
|
||||
if (isHorizontal)
|
||||
{
|
||||
currIndex--;
|
||||
draggedReferenceRectangle.Y -= draggedReferenceRectangle.Height;
|
||||
draggedReferenceOffset.Y -= draggedReferenceRectangle.Height;
|
||||
while (currIndex > 0 && PlayerInput.MousePosition.X < draggedReferenceRectangle.Left)
|
||||
{
|
||||
currIndex--;
|
||||
draggedReferenceRectangle.X -= draggedReferenceRectangle.Width;
|
||||
draggedReferenceOffset.X -= draggedReferenceRectangle.Width;
|
||||
}
|
||||
while (currIndex < Content.CountChildren - 1 && PlayerInput.MousePosition.X > draggedReferenceRectangle.Right)
|
||||
{
|
||||
currIndex++;
|
||||
draggedReferenceRectangle.X += draggedReferenceRectangle.Width;
|
||||
draggedReferenceOffset.X += draggedReferenceRectangle.Width;
|
||||
}
|
||||
}
|
||||
while (currIndex < Content.CountChildren - 1 && PlayerInput.MousePosition.Y > draggedReferenceRectangle.Bottom)
|
||||
else
|
||||
{
|
||||
currIndex++;
|
||||
draggedReferenceRectangle.Y += draggedReferenceRectangle.Height;
|
||||
draggedReferenceOffset.Y += draggedReferenceRectangle.Height;
|
||||
while (currIndex > 0 && PlayerInput.MousePosition.Y < draggedReferenceRectangle.Top)
|
||||
{
|
||||
currIndex--;
|
||||
draggedReferenceRectangle.Y -= draggedReferenceRectangle.Height;
|
||||
draggedReferenceOffset.Y -= draggedReferenceRectangle.Height;
|
||||
}
|
||||
while (currIndex < Content.CountChildren - 1 && PlayerInput.MousePosition.Y > draggedReferenceRectangle.Bottom)
|
||||
{
|
||||
currIndex++;
|
||||
draggedReferenceRectangle.Y += draggedReferenceRectangle.Height;
|
||||
draggedReferenceOffset.Y += draggedReferenceRectangle.Height;
|
||||
}
|
||||
}
|
||||
|
||||
if (currIndex != index)
|
||||
@@ -510,10 +548,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;
|
||||
|
||||
@@ -943,9 +981,10 @@ namespace Barotrauma
|
||||
|
||||
public override void RemoveChild(GUIComponent child)
|
||||
{
|
||||
if (child == null) { return; }
|
||||
if (child == null) { return; }
|
||||
child.RectTransform.Parent = null;
|
||||
if (selected.Contains(child)) selected.Remove(child);
|
||||
if (selected.Contains(child)) { selected.Remove(child); }
|
||||
if (draggedElement == child) { draggedElement = null; }
|
||||
UpdateScrollBarSize();
|
||||
}
|
||||
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -81,10 +81,13 @@ namespace Barotrauma
|
||||
private float floatValue;
|
||||
public float FloatValue
|
||||
{
|
||||
get { return floatValue; }
|
||||
get
|
||||
{
|
||||
return floatValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (MathUtils.NearlyEqual(value, floatValue)) return;
|
||||
if (MathUtils.NearlyEqual(value, floatValue)) { return; }
|
||||
floatValue = value;
|
||||
ClampFloatValue();
|
||||
float newValue = floatValue;
|
||||
@@ -129,10 +132,13 @@ namespace Barotrauma
|
||||
private int intValue;
|
||||
public int IntValue
|
||||
{
|
||||
get { return intValue; }
|
||||
get
|
||||
{
|
||||
return intValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == intValue) return;
|
||||
if (value == intValue) { return; }
|
||||
intValue = value;
|
||||
UpdateText();
|
||||
}
|
||||
@@ -192,6 +198,29 @@ namespace Barotrauma
|
||||
};
|
||||
TextBox.CaretColor = TextBox.TextColor;
|
||||
TextBox.OnTextChanged += TextChanged;
|
||||
TextBox.OnDeselected += (sender, key) =>
|
||||
{
|
||||
if (inputType == NumberType.Int)
|
||||
{
|
||||
ClampIntValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
ClampFloatValue();
|
||||
}
|
||||
};
|
||||
TextBox.OnEnterPressed += (textBox, text) =>
|
||||
{
|
||||
if (inputType == NumberType.Int)
|
||||
{
|
||||
ClampIntValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
ClampFloatValue();
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
var buttonArea = new GUIFrame(new RectTransform(new Vector2(_relativeButtonAreaWidth, 1.0f), LayoutGroup.RectTransform, Anchor.CenterRight), style: null);
|
||||
PlusButton = new GUIButton(new RectTransform(new Vector2(1.0f, 0.5f), buttonArea.RectTransform), style: null);
|
||||
@@ -299,10 +328,12 @@ namespace Barotrauma
|
||||
if (inputType == NumberType.Int)
|
||||
{
|
||||
IntValue -= valueStep > 0 ? (int)valueStep : 1;
|
||||
ClampIntValue();
|
||||
}
|
||||
else if (maxValueFloat.HasValue && minValueFloat.HasValue)
|
||||
{
|
||||
FloatValue -= valueStep > 0 ? valueStep : Round();
|
||||
ClampFloatValue();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,10 +342,12 @@ namespace Barotrauma
|
||||
if (inputType == NumberType.Int)
|
||||
{
|
||||
IntValue += valueStep > 0 ? (int)valueStep : 1;
|
||||
ClampIntValue();
|
||||
}
|
||||
else if (inputType == NumberType.Float)
|
||||
{
|
||||
FloatValue += valueStep > 0 ? valueStep : Round();
|
||||
ClampFloatValue();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -325,7 +358,7 @@ namespace Barotrauma
|
||||
/// </summary>
|
||||
private float Round()
|
||||
{
|
||||
if (!maxValueFloat.HasValue || !minValueFloat.HasValue) return 0;
|
||||
if (!maxValueFloat.HasValue || !minValueFloat.HasValue) { return 0; }
|
||||
float onePercent = MathHelper.Lerp(minValueFloat.Value, maxValueFloat.Value, 0.01f);
|
||||
float diff = maxValueFloat.Value - minValueFloat.Value;
|
||||
int decimals = (int)MathHelper.Lerp(3, 0, MathUtils.InverseLerp(10, 1000, diff));
|
||||
@@ -337,28 +370,24 @@ namespace Barotrauma
|
||||
switch (InputType)
|
||||
{
|
||||
case NumberType.Int:
|
||||
int newIntValue = IntValue;
|
||||
if (string.IsNullOrWhiteSpace(text) || text == "-")
|
||||
{
|
||||
intValue = 0;
|
||||
}
|
||||
else if (int.TryParse(text, out newIntValue))
|
||||
else if (int.TryParse(text, out int newIntValue))
|
||||
{
|
||||
intValue = newIntValue;
|
||||
}
|
||||
ClampIntValue();
|
||||
break;
|
||||
case NumberType.Float:
|
||||
float newFloatValue = FloatValue;
|
||||
if (string.IsNullOrWhiteSpace(text) || text == "-")
|
||||
{
|
||||
floatValue = 0;
|
||||
}
|
||||
else if (float.TryParse(text, NumberStyles.Any, CultureInfo.InvariantCulture, out newFloatValue))
|
||||
else if (float.TryParse(text, NumberStyles.Any, CultureInfo.InvariantCulture, out float newFloatValue))
|
||||
{
|
||||
floatValue = newFloatValue;
|
||||
}
|
||||
ClampFloatValue();
|
||||
break;
|
||||
}
|
||||
OnValueChanged?.Invoke(this);
|
||||
|
||||
@@ -34,6 +34,8 @@ namespace Barotrauma
|
||||
|
||||
public readonly Sprite[] CursorSprite = new Sprite[7];
|
||||
|
||||
public UISprite RadiationSprite { get; private set; }
|
||||
|
||||
public UISprite UIGlow { get; private set; }
|
||||
public UISprite UIGlowCircular { get; private set; }
|
||||
|
||||
@@ -70,6 +72,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 +153,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;
|
||||
@@ -205,6 +211,9 @@ namespace Barotrauma
|
||||
case "uiglow":
|
||||
UIGlow = new UISprite(subElement);
|
||||
break;
|
||||
case "radiation":
|
||||
RadiationSprite = new UISprite(subElement);
|
||||
break;
|
||||
case "uiglowcircular":
|
||||
UIGlowCircular = new UISprite(subElement);
|
||||
break;
|
||||
@@ -344,7 +353,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 +363,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,72 @@ 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)
|
||||
{
|
||||
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 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)
|
||||
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);
|
||||
SetPriceGetters(itemFrame, true);
|
||||
}
|
||||
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 +700,73 @@ 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);
|
||||
SetPriceGetters(itemFrame, false);
|
||||
}
|
||||
SetItemFrameStatus(itemFrame, hasPermissions && itemQuantity > 0);
|
||||
if (itemQuantity < 1 && !isRequestedGood)
|
||||
{
|
||||
itemFrame.Visible = false;
|
||||
}
|
||||
if (quantity < 1) { 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);
|
||||
|
||||
@@ -604,6 +774,37 @@ namespace Barotrauma
|
||||
shoppingCrateSellList.BarScroll = prevShoppingCrateScroll;
|
||||
}
|
||||
|
||||
private void SetPriceGetters(GUIComponent itemFrame, bool buying)
|
||||
{
|
||||
if (itemFrame == null || !(itemFrame.UserData is PurchasedItem pi)) { return; }
|
||||
|
||||
if (itemFrame.FindChild("undiscountedprice", recursive: true) is GUITextBlock undiscountedPriceBlock)
|
||||
{
|
||||
if (buying)
|
||||
{
|
||||
undiscountedPriceBlock.TextGetter = () => GetCurrencyFormatted(
|
||||
CurrentLocation?.GetAdjustedItemBuyPrice(pi.ItemPrefab, considerDailySpecials: false) ?? 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
undiscountedPriceBlock.TextGetter = () => GetCurrencyFormatted(
|
||||
CurrentLocation?.GetAdjustedItemSellPrice(pi.ItemPrefab, considerRequestedGoods: false) ?? 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (itemFrame.FindChild("price", recursive: true) is GUITextBlock priceBlock)
|
||||
{
|
||||
if (buying)
|
||||
{
|
||||
priceBlock.TextGetter = () => GetCurrencyFormatted(CurrentLocation?.GetAdjustedItemBuyPrice(pi.ItemPrefab) ?? 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
priceBlock.TextGetter = () => GetCurrencyFormatted(CurrentLocation?.GetAdjustedItemSellPrice(pi.ItemPrefab) ?? 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RefreshItemsToSell()
|
||||
{
|
||||
itemsToSell.Clear();
|
||||
@@ -673,13 +874,10 @@ namespace Barotrauma
|
||||
}
|
||||
suppressBuySell = false;
|
||||
|
||||
if (priceInfo != null)
|
||||
{
|
||||
var price = listBox == shoppingCrateBuyList ?
|
||||
CurrentLocation.GetAdjustedItemBuyPrice(priceInfo) :
|
||||
CurrentLocation.GetAdjustedItemSellPrice(priceInfo);
|
||||
totalPrice += item.Quantity * price;
|
||||
}
|
||||
var price = listBox == shoppingCrateBuyList ?
|
||||
CurrentLocation.GetAdjustedItemBuyPrice(item.ItemPrefab, priceInfo: priceInfo) :
|
||||
CurrentLocation.GetAdjustedItemSellPrice(item.ItemPrefab, priceInfo: priceInfo);
|
||||
totalPrice += item.Quantity * price;
|
||||
}
|
||||
|
||||
var removedItemFrames = listBox.Content.Children.Except(existingItemFrames).ToList();
|
||||
@@ -711,32 +909,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
|
||||
{
|
||||
return CompareByElement(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
list.Content.RectTransform.SortChildren(
|
||||
(x, y) => CurrentLocation.GetAdjustedItemBuyPrice((x.GUIComponent.UserData as PurchasedItem).ItemPrefab).CompareTo(
|
||||
CurrentLocation.GetAdjustedItemBuyPrice((y.GUIComponent.UserData as PurchasedItem).ItemPrefab)));
|
||||
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 +1054,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 +1062,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 +1106,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 +1168,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 +1199,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 +1208,36 @@ 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 (locationHasDealOnItem)
|
||||
{
|
||||
priceBlock.TextGetter = () => GetCurrencyFormatted(CurrentLocation?.GetAdjustedItemSellPrice(priceInfo) ?? 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
priceBlock.TextGetter = () => GetCurrencyFormatted(CurrentLocation?.GetAdjustedItemBuyPrice(priceInfo) ?? 0);
|
||||
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"
|
||||
};
|
||||
}
|
||||
SetPriceGetters(frame, !isSellingRelatedList);
|
||||
|
||||
if (listBox == storeDealsList || listBox == storeBuyList || listBox == storeSellList)
|
||||
if (isParentOnLeftSideOfInterface)
|
||||
{
|
||||
new GUIButton(new RectTransform(new Vector2(buttonRelativeWidth, 0.9f), mainGroup.RectTransform), style: "StoreAddToCrateButton")
|
||||
{
|
||||
@@ -902,7 +1260,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 +1288,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 +1347,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 +1479,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 +1513,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 +1575,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) })
|
||||
{
|
||||
@@ -858,54 +857,60 @@ namespace Barotrauma
|
||||
|
||||
int locationInfoYOffset = locationNameText.Rect.Height + locationTypeText.Rect.Height + padding * 2;
|
||||
|
||||
GUIFrame missionDescriptionHolder;
|
||||
GUIListBox missionList;
|
||||
|
||||
if (hasPortrait)
|
||||
{
|
||||
GUIFrame missionImageHolder = new GUIFrame(new RectTransform(new Point(contentWidth, (int)(missionFrame.Rect.Height * 0.588f)), missionFrame.RectTransform, Anchor.TopCenter) { AbsoluteOffset = new Point(0, locationInfoYOffset) });
|
||||
GUIFrame portraitHolder = new GUIFrame(new RectTransform(new Point(contentWidth, (int)(missionFrame.Rect.Height * 0.588f)), missionFrame.RectTransform, Anchor.TopCenter) { AbsoluteOffset = new Point(0, locationInfoYOffset) });
|
||||
float portraitAspectRatio = portrait.SourceRect.Width / portrait.SourceRect.Height;
|
||||
GUIImage portraitImage = new GUIImage(new RectTransform(new Vector2(1.0f, 1f), missionImageHolder.RectTransform), portrait, scaleToFit: true);
|
||||
missionImageHolder.RectTransform.NonScaledSize = new Point(portraitImage.Rect.Size.X, (int)(portraitImage.Rect.Size.X / portraitAspectRatio));
|
||||
missionDescriptionHolder = new GUIFrame(new RectTransform(new Point(contentWidth, 0), missionFrame.RectTransform, Anchor.TopCenter) { AbsoluteOffset = new Point(0, missionImageHolder.RectTransform.AbsoluteOffset.Y + missionImageHolder.Rect.Height + padding) }, style: null);
|
||||
GUIImage portraitImage = new GUIImage(new RectTransform(new Vector2(1.0f, 1f), portraitHolder.RectTransform), portrait, scaleToFit: true);
|
||||
portraitHolder.RectTransform.NonScaledSize = new Point(portraitImage.Rect.Size.X, (int)(portraitImage.Rect.Size.X / portraitAspectRatio));
|
||||
|
||||
missionList = new GUIListBox(new RectTransform(new Point(contentWidth, missionFrame.Rect.Bottom - portraitHolder.Rect.Bottom - padding), missionFrame.RectTransform, Anchor.TopCenter) { AbsoluteOffset = new Point(0, portraitHolder.RectTransform.AbsoluteOffset.Y + portraitHolder.Rect.Height + padding) });
|
||||
}
|
||||
else
|
||||
{
|
||||
missionDescriptionHolder = new GUIFrame(new RectTransform(new Point(contentWidth, 0), missionFrame.RectTransform, Anchor.TopCenter) { AbsoluteOffset = new Point(0, locationInfoYOffset) }, style: null);
|
||||
}
|
||||
missionList = new GUIListBox(new RectTransform(new Point(contentWidth, missionFrame.Rect.Height - locationInfoYOffset - padding), missionFrame.RectTransform, Anchor.TopCenter) { AbsoluteOffset = new Point(0, locationInfoYOffset) });
|
||||
}
|
||||
missionList.ContentBackground.Color = Color.Transparent;
|
||||
missionList.Spacing = GUI.IntScale(15);
|
||||
|
||||
Mission mission = GameMain.GameSession?.Mission;
|
||||
if (mission != null)
|
||||
if (GameMain.GameSession?.Missions != null)
|
||||
{
|
||||
GUILayoutGroup missionTextGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.744f, 0f), missionDescriptionHolder.RectTransform, Anchor.CenterLeft) { RelativeOffset = new Vector2(0.225f, 0f) }, false, childAnchor: Anchor.TopLeft);
|
||||
|
||||
string missionNameString = ToolBox.WrapText(mission.Name, missionTextGroup.Rect.Width, GUI.LargeFont);
|
||||
string missionDescriptionString = ToolBox.WrapText(mission.Description, missionTextGroup.Rect.Width, GUI.Font);
|
||||
string rewardText = TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", mission.Reward));
|
||||
string missionRewardString = ToolBox.WrapText(TextManager.GetWithVariable("MissionReward", "[reward]", rewardText), missionTextGroup.Rect.Width, GUI.Font);
|
||||
|
||||
Vector2 missionNameSize = GUI.LargeFont.MeasureString(missionNameString);
|
||||
Vector2 missionDescriptionSize = GUI.Font.MeasureString(missionDescriptionString);
|
||||
Vector2 missionRewardSize = GUI.Font.MeasureString(missionRewardString);
|
||||
|
||||
missionDescriptionHolder.RectTransform.NonScaledSize = new Point(missionDescriptionHolder.RectTransform.NonScaledSize.X, (int)(missionNameSize.Y + missionDescriptionSize.Y + missionRewardSize.Y));
|
||||
missionTextGroup.RectTransform.NonScaledSize = new Point(missionTextGroup.RectTransform.NonScaledSize.X, missionDescriptionHolder.RectTransform.NonScaledSize.Y);
|
||||
|
||||
if (mission.Prefab.Icon != null)
|
||||
foreach (Mission mission in GameMain.GameSession.Missions)
|
||||
{
|
||||
float iconAspectRatio = mission.Prefab.Icon.SourceRect.Width / mission.Prefab.Icon.SourceRect.Height;
|
||||
int iconWidth = (int)(0.225f * missionDescriptionHolder.RectTransform.NonScaledSize.X);
|
||||
int iconHeight = Math.Max(missionTextGroup.RectTransform.NonScaledSize.Y, (int)(iconWidth * iconAspectRatio));
|
||||
Point iconSize = new Point(iconWidth, iconHeight);
|
||||
GUIFrame missionDescriptionHolder = new GUIFrame(new RectTransform(Vector2.One, missionList.Content.RectTransform), style: null);
|
||||
GUILayoutGroup missionTextGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.744f, 0f), missionDescriptionHolder.RectTransform, Anchor.CenterLeft) { RelativeOffset = new Vector2(0.225f, 0f) }, false, childAnchor: Anchor.TopLeft);
|
||||
|
||||
new GUIImage(new RectTransform(iconSize, missionDescriptionHolder.RectTransform), mission.Prefab.Icon, null, true) { Color = mission.Prefab.IconColor };
|
||||
}
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionNameString, font: GUI.LargeFont);
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionRewardString);
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionDescriptionString);
|
||||
string missionNameString = ToolBox.WrapText(mission.Name, missionTextGroup.Rect.Width, GUI.LargeFont);
|
||||
string missionDescriptionString = ToolBox.WrapText(mission.Description, missionTextGroup.Rect.Width, GUI.Font);
|
||||
string rewardText = TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", mission.Reward));
|
||||
string missionRewardString = ToolBox.WrapText(TextManager.GetWithVariable("MissionReward", "[reward]", rewardText), missionTextGroup.Rect.Width, GUI.Font);
|
||||
|
||||
Vector2 missionNameSize = GUI.LargeFont.MeasureString(missionNameString);
|
||||
Vector2 missionDescriptionSize = GUI.Font.MeasureString(missionDescriptionString);
|
||||
Vector2 missionRewardSize = GUI.Font.MeasureString(missionRewardString);
|
||||
|
||||
missionDescriptionHolder.RectTransform.NonScaledSize = new Point(missionDescriptionHolder.RectTransform.NonScaledSize.X, (int)(missionNameSize.Y + missionDescriptionSize.Y + missionRewardSize.Y));
|
||||
missionTextGroup.RectTransform.NonScaledSize = new Point(missionTextGroup.RectTransform.NonScaledSize.X, missionDescriptionHolder.RectTransform.NonScaledSize.Y);
|
||||
|
||||
if (mission.Prefab.Icon != null)
|
||||
{
|
||||
float iconAspectRatio = mission.Prefab.Icon.SourceRect.Width / mission.Prefab.Icon.SourceRect.Height;
|
||||
int iconWidth = (int)(0.225f * missionDescriptionHolder.RectTransform.NonScaledSize.X);
|
||||
int iconHeight = Math.Max(missionTextGroup.RectTransform.NonScaledSize.Y, (int)(iconWidth * iconAspectRatio));
|
||||
Point iconSize = new Point(iconWidth, iconHeight);
|
||||
|
||||
new GUIImage(new RectTransform(iconSize, missionDescriptionHolder.RectTransform), mission.Prefab.Icon, null, true) { Color = mission.Prefab.IconColor, HoverColor = mission.Prefab.IconColor };
|
||||
}
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionNameString, font: GUI.LargeFont);
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionRewardString);
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionDescriptionString);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GUILayoutGroup missionTextGroup = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0f), missionDescriptionHolder.RectTransform, Anchor.CenterLeft), false, childAnchor: Anchor.TopLeft);
|
||||
GUILayoutGroup missionTextGroup = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0f), missionList.RectTransform, Anchor.CenterLeft), false, childAnchor: Anchor.TopLeft);
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), TextManager.Get("NoMission"), font: GUI.LargeFont);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace Barotrauma
|
||||
|
||||
public Vector2 DrawPos { get; set; }
|
||||
public int size = 10;
|
||||
public float thickness = 1f;
|
||||
/// <summary>
|
||||
/// Used only for circles.
|
||||
/// </summary>
|
||||
@@ -157,7 +158,7 @@ namespace Barotrauma
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch, drawRect, secondaryColor.Value, isFilled, thickness: 2);
|
||||
}
|
||||
GUI.DrawRectangle(spriteBatch, drawRect, color, isFilled, thickness: IsSelected ? 3 : 1);
|
||||
GUI.DrawRectangle(spriteBatch, drawRect, color, isFilled, thickness: IsSelected ? (int)(thickness * 3) : (int)thickness);
|
||||
break;
|
||||
case Shape.Circle:
|
||||
if (secondaryColor.HasValue)
|
||||
@@ -182,7 +183,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (showTooltip && !string.IsNullOrEmpty(tooltip))
|
||||
{
|
||||
var offset = tooltipOffset ?? new Vector2(size, -size / 2);
|
||||
var offset = tooltipOffset ?? new Vector2(size, -size / 2f);
|
||||
GUI.DrawString(spriteBatch, DrawPos + offset, tooltip, textColor, textBackgroundColor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -557,6 +557,7 @@ namespace Barotrauma
|
||||
|
||||
GameModePreset.Init();
|
||||
|
||||
SaveUtil.DeleteDownloadedSubs();
|
||||
SubmarineInfo.RefreshSavedSubs();
|
||||
|
||||
TitleScreen.LoadState = 65.0f;
|
||||
@@ -634,6 +635,7 @@ namespace Barotrauma
|
||||
/// </summary>
|
||||
protected override void UnloadContent()
|
||||
{
|
||||
TextureLoader.CancelAll();
|
||||
CoroutineManager.StopCoroutines("Load");
|
||||
Video.Close();
|
||||
VoipCapture.Instance?.Dispose();
|
||||
@@ -682,7 +684,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
public void OnLobbyJoinRequested(Steamworks.Data.Lobby lobby, Steamworks.SteamId friendId)
|
||||
{
|
||||
{
|
||||
SteamManager.JoinLobby(lobby.Id, true);
|
||||
}
|
||||
|
||||
@@ -902,7 +904,9 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
#if !DEBUG
|
||||
if (NetworkMember == null && !WindowActive && !Paused && true && Screen.Selected != MainMenuScreen && Config.PauseOnFocusLost)
|
||||
if (NetworkMember == null && !WindowActive && !Paused && true && Config.PauseOnFocusLost &&
|
||||
Screen.Selected != MainMenuScreen && Screen.Selected != ServerListScreen && Screen.Selected != NetLobbyScreen &&
|
||||
Screen.Selected != SubEditorScreen && Screen.Selected != LevelEditorScreen)
|
||||
{
|
||||
GUI.TogglePauseMenu();
|
||||
Paused = true;
|
||||
@@ -1072,13 +1076,6 @@ namespace Barotrauma
|
||||
{
|
||||
((TutorialMode)GameSession.GameMode).Tutorial?.Stop();
|
||||
}
|
||||
|
||||
if (GameSettings.SendUserStatistics)
|
||||
{
|
||||
Mission mission = GameSession.Mission;
|
||||
GameAnalyticsManager.AddDesignEvent("QuitRound:" + (save ? "Save" : "NoSave"));
|
||||
GameAnalyticsManager.AddDesignEvent("EndRound:" + (mission == null ? "NoMission" : (mission.Completed ? "MissionCompleted" : "MissionFailed")));
|
||||
}
|
||||
}
|
||||
GUIMessageBox.CloseAll();
|
||||
MainMenuScreen.Select();
|
||||
@@ -1112,7 +1109,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,61 +39,37 @@ 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 };
|
||||
foreach (InvSlotType slot in equipmentSlots)
|
||||
return character.Inventory.FindAllItems(item =>
|
||||
{
|
||||
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 (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();
|
||||
|
||||
// Prevent selling items contained inside equipped items
|
||||
foreach (InvSlotType slot in equipmentSlots)
|
||||
bool IsInEquipmentSlot(Item item)
|
||||
{
|
||||
var index = character.Inventory.FindLimbSlot(slot);
|
||||
if (character.Inventory.Items[index] is Item item &&
|
||||
item.ContainedItems != null && item.AllowedSlots.Contains(InvSlotType.Any))
|
||||
foreach (InvSlotType slot in equipmentSlots)
|
||||
{
|
||||
RemoveContainedFromSellables(item);
|
||||
if (character.Inventory.IsInLimbSlot(item, slot)) { return true; }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -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); }
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -59,13 +59,16 @@ namespace Barotrauma
|
||||
|
||||
public override void ShowStartMessage()
|
||||
{
|
||||
if (Mission == null) return;
|
||||
|
||||
new GUIMessageBox(Mission.Name, Mission.Description, new string[0], type: GUIMessageBox.Type.InGame, icon: Mission.Prefab.Icon)
|
||||
foreach (Mission mission in Missions)
|
||||
{
|
||||
IconColor = Mission.Prefab.IconColor,
|
||||
UserData = "missionstartmessage"
|
||||
};
|
||||
new GUIMessageBox(
|
||||
mission.Prefab.IsSideObjective ? TextManager.AddPunctuation(':', TextManager.Get("sideobjective"), mission.Name) : mission.Name,
|
||||
mission.Description, new string[0], type: GUIMessageBox.Type.InGame, icon: mission.Prefab.Icon)
|
||||
{
|
||||
IconColor = mission.Prefab.IconColor,
|
||||
UserData = "missionstartmessage"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -158,7 +161,8 @@ namespace Barotrauma
|
||||
case TransitionType.ProgressToNextEmptyLocation:
|
||||
if (Level.Loaded.EndOutpost == null || !Level.Loaded.EndOutpost.DockedTo.Contains(leavingSub))
|
||||
{
|
||||
buttonText = TextManager.GetWithVariable("EnterLocation", "[locationname]", Level.Loaded.EndLocation?.Name ?? "[ERROR]");
|
||||
string textTag = availableTransition == TransitionType.ProgressToNextLocation ? "EnterLocation" : "EnterEmptyLocation";
|
||||
buttonText = TextManager.GetWithVariable(textTag, "[locationname]", Level.Loaded.EndLocation?.Name ?? "[ERROR]");
|
||||
endRoundButton.Visible = !ForceMapUI && !ShowCampaignUI;
|
||||
}
|
||||
break;
|
||||
@@ -170,7 +174,8 @@ namespace Barotrauma
|
||||
case TransitionType.ReturnToPreviousEmptyLocation:
|
||||
if (Level.Loaded.StartOutpost == null || !Level.Loaded.StartOutpost.DockedTo.Contains(leavingSub))
|
||||
{
|
||||
buttonText = TextManager.GetWithVariable("EnterLocation", "[locationname]", Level.Loaded.StartLocation?.Name ?? "[ERROR]");
|
||||
string textTag = availableTransition == TransitionType.ReturnToPreviousLocation ? "EnterLocation" : "EnterEmptyLocation";
|
||||
buttonText = TextManager.GetWithVariable(textTag, "[locationname]", Level.Loaded.StartLocation?.Name ?? "[ERROR]");
|
||||
endRoundButton.Visible = !ForceMapUI && !ShowCampaignUI;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -711,13 +711,20 @@ namespace Barotrauma
|
||||
DebugConsole.ThrowError($"Error when receiving campaign data from the server: mission prefab \"{availableMission.First}\" not found.");
|
||||
continue;
|
||||
}
|
||||
if (availableMission.Second < 0 || availableMission.Second >= campaign.Map.CurrentLocation.Connections.Count)
|
||||
if (availableMission.Second == 255)
|
||||
{
|
||||
DebugConsole.ThrowError($"Error when receiving campaign data from the server: connection index for mission \"{availableMission.First}\" out of range (index: {availableMission.Second}, current location: {campaign.Map.CurrentLocation.Name}, connections: {campaign.Map.CurrentLocation.Connections.Count}).");
|
||||
continue;
|
||||
campaign.Map.CurrentLocation.UnlockMission(missionPrefab);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (availableMission.Second < 0 || availableMission.Second >= campaign.Map.CurrentLocation.Connections.Count)
|
||||
{
|
||||
DebugConsole.ThrowError($"Error when receiving campaign data from the server: connection index for mission \"{availableMission.First}\" out of range (index: {availableMission.Second}, current location: {campaign.Map.CurrentLocation.Name}, connections: {campaign.Map.CurrentLocation.Connections.Count}).");
|
||||
continue;
|
||||
}
|
||||
LocationConnection connection = campaign.Map.CurrentLocation.Connections[availableMission.Second];
|
||||
campaign.Map.CurrentLocation.UnlockMission(missionPrefab, connection);
|
||||
}
|
||||
LocationConnection connection = campaign.Map.CurrentLocation.Connections[availableMission.Second];
|
||||
campaign.Map.CurrentLocation.UnlockMission(missionPrefab, connection);
|
||||
}
|
||||
|
||||
GameMain.NetLobbyScreen.ToggleCampaignMode(true);
|
||||
@@ -812,8 +819,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; }
|
||||
@@ -20,7 +22,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (CoroutineManager.IsCoroutineRunning("LevelTransition") || CoroutineManager.IsCoroutineRunning("SubmarineTransition") || gameOver) { return; }
|
||||
|
||||
if (PlayerInput.RightButtonClicked() ||
|
||||
if (PlayerInput.SecondaryMouseButtonClicked() ||
|
||||
PlayerInput.KeyHit(Microsoft.Xna.Framework.Input.Keys.Escape))
|
||||
{
|
||||
ShowCampaignUI = false;
|
||||
@@ -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;
|
||||
@@ -368,9 +372,6 @@ namespace Barotrauma
|
||||
SoundPlayer.OverrideMusicDuration = 18.0f;
|
||||
crewDead = false;
|
||||
|
||||
LevelData lvlData = GameMain.GameSession.LevelData;
|
||||
bool beaconActive = GameMain.GameSession.Level.CheckBeaconActive();
|
||||
|
||||
GameMain.GameSession.EndRound("", traitorResults, transitionType);
|
||||
var continueButton = GameMain.GameSession.RoundSummary?.ContinueButton;
|
||||
RoundSummary roundSummary = null;
|
||||
@@ -455,8 +456,6 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
lvlData.IsBeaconActive = beaconActive;
|
||||
|
||||
SaveUtil.SaveGame(GameMain.GameSession.SavePath);
|
||||
}
|
||||
else
|
||||
@@ -526,6 +525,8 @@ namespace Barotrauma
|
||||
if (CoroutineManager.IsCoroutineRunning("LevelTransition") || CoroutineManager.IsCoroutineRunning("SubmarineTransition") || gameOver) { return; }
|
||||
|
||||
base.Update(deltaTime);
|
||||
|
||||
Map?.Radiation.UpdateRadiation(deltaTime);
|
||||
|
||||
if (PlayerInput.SecondaryMouseButtonClicked() ||
|
||||
PlayerInput.KeyHit(Microsoft.Xna.Framework.Input.Keys.Escape))
|
||||
@@ -699,6 +700,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
|
||||
|
||||
@@ -39,6 +39,10 @@ namespace Barotrauma
|
||||
base.Start();
|
||||
|
||||
CrewManager.InitSinglePlayerRound();
|
||||
foreach (Submarine submarine in Submarine.Loaded)
|
||||
{
|
||||
submarine.NeutralizeBallast();
|
||||
}
|
||||
|
||||
if (SpawnOutpost)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
@@ -283,7 +283,7 @@ namespace Barotrauma.Tutorials
|
||||
doctor.RemoveActiveObjectiveEntity(patient1);
|
||||
TriggerTutorialSegment(3, GameMain.Config.KeyBindText(InputType.Command)); // Get the patient to medbay
|
||||
|
||||
while (patient1.CurrentOrder == null || patient1.CurrentOrder.Identifier != "follow")
|
||||
while (patient1.GetCurrentOrderWithTopPriority()?.Order?.Identifier != "follow")
|
||||
{
|
||||
// TODO: Rework order highlighting for new command UI
|
||||
// GameMain.GameSession.CrewManager.HighlightOrderButton(patient1, "follow", highlightColor, new Vector2(5, 5));
|
||||
@@ -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)
|
||||
{
|
||||
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 (ItemComponent ic in mechanic_oxygenContainer.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>();
|
||||
foreach (Item item in mechanic_oxygenContainer.Inventory.AllItems)
|
||||
{
|
||||
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,14 +420,10 @@ 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.Capacity; i++)
|
||||
{
|
||||
for (int i = 0; i < mechanic_deconstructor.InputContainer.Inventory.slots.Length; i++)
|
||||
{
|
||||
HighlightInventorySlot(mechanic_deconstructor.InputContainer.Inventory, i, highlightColor, .5f, .5f, 0f);
|
||||
}
|
||||
}
|
||||
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);
|
||||
@@ -317,7 +317,8 @@ namespace Barotrauma.Tutorials
|
||||
yield return new WaitForSeconds(2f, false);
|
||||
TriggerTutorialSegment(4, GameMain.Config.KeyBindText(InputType.Select), GameMain.Config.KeyBindText(InputType.Shoot), GameMain.Config.KeyBindText(InputType.Deselect)); // Kill hammerhead
|
||||
officer_hammerhead = SpawnMonster("hammerhead", officer_hammerheadSpawnPos);
|
||||
((EnemyAIController)officer_hammerhead.AIController).StayInsideLevel = false;
|
||||
officer_hammerhead.Params.AI.AvoidAbyss = false;
|
||||
officer_hammerhead.Params.AI.StayInAbyss = false;
|
||||
officer_hammerhead.AIController.SelectTarget(officer.AiTarget);
|
||||
SetHighlight(officer_coilgunPeriscope, true);
|
||||
float originalDistance = Vector2.Distance(officer_coilgunPeriscope.WorldPosition, officer_hammerheadSpawnPos);
|
||||
@@ -371,12 +372,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 +384,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 +397,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 +424,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);
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace Barotrauma.Tutorials
|
||||
|
||||
yield return CoroutineStatus.Running;
|
||||
|
||||
GameMain.GameSession = new GameSession(subInfo, GameModePreset.Tutorial, missionPrefab: null);
|
||||
GameMain.GameSession = new GameSession(subInfo, GameModePreset.Tutorial, missionPrefabs: null);
|
||||
(GameMain.GameSession.GameMode as TutorialMode).Tutorial = this;
|
||||
|
||||
if (generationParams != null)
|
||||
@@ -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);
|
||||
|
||||
@@ -182,7 +182,8 @@ namespace Barotrauma.Tutorials
|
||||
|
||||
protected bool HasOrder(Character character, string identifier, string option = null)
|
||||
{
|
||||
if (character.CurrentOrder?.Identifier == identifier)
|
||||
var currentOrderInfo = character.GetCurrentOrderWithTopPriority();
|
||||
if (currentOrderInfo?.Order?.Identifier == identifier)
|
||||
{
|
||||
if (option == null)
|
||||
{
|
||||
@@ -190,8 +191,7 @@ namespace Barotrauma.Tutorials
|
||||
}
|
||||
else
|
||||
{
|
||||
HumanAIController humanAI = character.AIController as HumanAIController;
|
||||
return humanAI.CurrentOrderOption == option;
|
||||
return currentOrderInfo?.OrderOption == option;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
@@ -46,6 +48,7 @@ namespace Barotrauma
|
||||
msgBox.Buttons[0].OnClicked = delegate
|
||||
{
|
||||
msgBox.Close();
|
||||
if (GameMain.Client == null) { return true; }
|
||||
SendState(ReadyStatus.Yes);
|
||||
CreateResultsMessage();
|
||||
return true;
|
||||
@@ -55,6 +58,7 @@ namespace Barotrauma
|
||||
msgBox.Buttons[1].OnClicked = delegate
|
||||
{
|
||||
msgBox.Close();
|
||||
if (GameMain.Client == null) { return true; }
|
||||
SendState(ReadyStatus.No);
|
||||
CreateResultsMessage();
|
||||
return true;
|
||||
@@ -63,6 +67,8 @@ namespace Barotrauma
|
||||
|
||||
private void CreateResultsMessage()
|
||||
{
|
||||
if (GameMain.Client == null) { return; }
|
||||
|
||||
Vector2 relativeSize = new Vector2(0.2f, 0.3f);
|
||||
Point minSize = new Point(300, 400);
|
||||
resultsBox = new GUIMessageBox(readyCheckHeader, string.Empty, new[] { closeButton }, relativeSize, minSize, type: GUIMessageBox.Type.Vote) { UserData = ResultData, Draggable = true };
|
||||
@@ -73,7 +79,7 @@ namespace Barotrauma
|
||||
|
||||
GUIListBox listBox = new GUIListBox(new RectTransform(new Vector2(1f, 0.8f), resultsBox.Content.RectTransform)) { UserData = UserListData };
|
||||
|
||||
foreach (var (id, status) in Clients)
|
||||
foreach (var (id, _) in Clients)
|
||||
{
|
||||
Client? client = GameMain.Client.ConnectedClients.FirstOrDefault(c => c.ID == id);
|
||||
GUIFrame container = new GUIFrame(new RectTransform(new Vector2(1f, 0.15f), listBox.Content.RectTransform), style: "ListBoxElement") { UserData = id };
|
||||
@@ -120,7 +126,10 @@ namespace Barotrauma
|
||||
int second = (int) Math.Ceiling(time);
|
||||
if (second < lastSecond)
|
||||
{
|
||||
SoundPlayer.PlayUISound(GUISoundType.PopupMenu);
|
||||
if (msgBox != null && !msgBox.Closed)
|
||||
{
|
||||
SoundPlayer.PlayUISound(GUISoundType.PopupMenu);
|
||||
}
|
||||
lastSecond = second;
|
||||
}
|
||||
}
|
||||
@@ -130,12 +139,20 @@ namespace Barotrauma
|
||||
ReadyCheckState state = (ReadyCheckState) inc.ReadByte();
|
||||
CrewManager? crewManager = GameMain.GameSession?.CrewManager;
|
||||
List<Client> otherClients = GameMain.Client.ConnectedClients;
|
||||
if (crewManager == null || otherClients == null) { return; }
|
||||
if (crewManager == null || otherClients == null)
|
||||
{
|
||||
if (state == ReadyCheckState.Start)
|
||||
{
|
||||
SendState(ReadyStatus.No);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case ReadyCheckState.Start:
|
||||
bool isOwn = false;
|
||||
byte authorId = 0;
|
||||
|
||||
float duration = inc.ReadSingle();
|
||||
string author = inc.ReadString();
|
||||
@@ -143,7 +160,8 @@ namespace Barotrauma
|
||||
|
||||
if (hasAuthor)
|
||||
{
|
||||
isOwn = inc.ReadByte() == GameMain.Client.ID;
|
||||
authorId = inc.ReadByte();
|
||||
isOwn = authorId == GameMain.Client.ID;
|
||||
}
|
||||
|
||||
ushort clientCount = inc.ReadUInt16();
|
||||
@@ -165,12 +183,21 @@ namespace Barotrauma
|
||||
{
|
||||
rCheck.CreateMessageBox(author);
|
||||
}
|
||||
|
||||
if (hasAuthor && rCheck.Clients.ContainsKey(authorId))
|
||||
{
|
||||
rCheck.Clients[authorId] = ReadyStatus.Yes;
|
||||
}
|
||||
break;
|
||||
case ReadyCheckState.Update:
|
||||
crewManager.ActiveReadyCheck.time = inc.ReadSingle();
|
||||
float time = inc.ReadSingle();
|
||||
ReadyStatus newState = (ReadyStatus) inc.ReadByte();
|
||||
byte targetId = inc.ReadByte();
|
||||
crewManager.ActiveReadyCheck?.UpdateState(targetId, newState);
|
||||
if (crewManager.ActiveReadyCheck != null)
|
||||
{
|
||||
crewManager.ActiveReadyCheck.time = time;
|
||||
crewManager.ActiveReadyCheck?.UpdateState(targetId, newState);
|
||||
}
|
||||
break;
|
||||
case ReadyCheckState.End:
|
||||
ushort count = inc.ReadUInt16();
|
||||
@@ -190,6 +217,9 @@ namespace Barotrauma
|
||||
|
||||
partial void EndReadyCheck()
|
||||
{
|
||||
if (IsFinished) { return; }
|
||||
IsFinished = true;
|
||||
|
||||
int readyCount = Clients.Count(pair => pair.Value == ReadyStatus.Yes);
|
||||
int totalCount = Clients.Count;
|
||||
GameMain.Client.AddChatMessage(ChatMessage.Create(string.Empty, readyCheckStatus(readyCount, totalCount), ChatMessageType.Server, null));
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Barotrauma
|
||||
private int jobColumnWidth, characterColumnWidth, statusColumnWidth;
|
||||
|
||||
private readonly SubmarineInfo sub;
|
||||
private readonly Mission selectedMission;
|
||||
private readonly List<Mission> selectedMissions;
|
||||
private readonly Location startLocation, endLocation;
|
||||
|
||||
private readonly GameMode gameMode;
|
||||
@@ -32,11 +32,11 @@ namespace Barotrauma
|
||||
|
||||
|
||||
|
||||
public RoundSummary(SubmarineInfo sub, GameMode gameMode, Mission selectedMission, Location startLocation, Location endLocation)
|
||||
public RoundSummary(SubmarineInfo sub, GameMode gameMode, IEnumerable<Mission> selectedMissions, Location startLocation, Location endLocation)
|
||||
{
|
||||
this.sub = sub;
|
||||
this.gameMode = gameMode;
|
||||
this.selectedMission = selectedMission;
|
||||
this.selectedMissions = selectedMissions.ToList();
|
||||
this.startLocation = startLocation;
|
||||
this.endLocation = endLocation;
|
||||
initialLocationReputation = startLocation?.Reputation?.Value ?? 0.0f;
|
||||
@@ -75,7 +75,7 @@ namespace Barotrauma
|
||||
|
||||
//crew panel -------------------------------------------------------------------------------
|
||||
|
||||
GUIFrame crewFrame = new GUIFrame(new RectTransform(new Vector2(0.35f, 0.55f), background.RectTransform, Anchor.TopCenter, minSize: new Point(minWidth, minHeight)));
|
||||
GUIFrame crewFrame = new GUIFrame(new RectTransform(new Vector2(0.35f, 0.45f), background.RectTransform, Anchor.TopCenter, minSize: new Point(minWidth, minHeight)));
|
||||
GUIFrame crewFrameInner = new GUIFrame(new RectTransform(new Point(crewFrame.Rect.Width - padding * 2, crewFrame.Rect.Height - padding * 2), crewFrame.RectTransform, Anchor.Center), style: "InnerFrame");
|
||||
|
||||
var crewContent = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.95f), crewFrameInner.RectTransform, Anchor.Center))
|
||||
@@ -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)
|
||||
if (gameSession.Missions.Any(m => m 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 -------------------------------------------------------------------------------
|
||||
@@ -200,7 +200,7 @@ namespace Barotrauma
|
||||
|
||||
GUIListBox reputationList = new GUIListBox(new RectTransform(Vector2.One, reputationContent.RectTransform))
|
||||
{
|
||||
Padding = new Vector4(2, 5, 0, 0)
|
||||
Padding = new Vector4(4, 10, 0, 0) * GUI.Scale
|
||||
};
|
||||
reputationList.ContentBackground.Color = Color.Transparent;
|
||||
|
||||
@@ -253,103 +253,122 @@ namespace Barotrauma
|
||||
|
||||
//mission panel -------------------------------------------------------------------------------
|
||||
|
||||
GUIFrame missionframe = new GUIFrame(new RectTransform(new Vector2(0.39f, 0.22f), background.RectTransform, Anchor.TopCenter, minSize: new Point(minWidth, minHeight / 4)));
|
||||
GUIFrame missionframeInner = new GUIFrame(new RectTransform(new Point(missionframe.Rect.Width - padding * 2, missionframe.Rect.Height - padding * 2), missionframe.RectTransform, Anchor.Center), style: "InnerFrame");
|
||||
|
||||
var missionContent = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.9f), missionframeInner.RectTransform, Anchor.Center))
|
||||
GUIFrame missionframe = new GUIFrame(new RectTransform(new Vector2(0.39f, 0.3f), background.RectTransform, Anchor.TopCenter, minSize: new Point(minWidth, minHeight / 4)));
|
||||
GUILayoutGroup missionFrameContent = new GUILayoutGroup(new RectTransform(new Point(missionframe.Rect.Width - padding * 2, missionframe.Rect.Height - padding * 2), missionframe.RectTransform, Anchor.Center))
|
||||
{
|
||||
Stretch = true,
|
||||
RelativeSpacing = 0.05f
|
||||
};
|
||||
GUIFrame missionframeInner = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.9f), missionFrameContent.RectTransform, Anchor.Center), style: "InnerFrame");
|
||||
|
||||
var missionContent = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.93f), missionframeInner.RectTransform, Anchor.Center))
|
||||
{
|
||||
RelativeSpacing = 0.05f,
|
||||
Stretch = true
|
||||
};
|
||||
|
||||
List<Mission> missionsToDisplay = new List<Mission>(selectedMissions);
|
||||
if (!selectedMissions.Any() && startLocation?.SelectedMission != null) { missionsToDisplay.Add(startLocation.SelectedMission); }
|
||||
|
||||
if (missionsToDisplay.Any())
|
||||
{
|
||||
var missionHeader = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionContent.RectTransform),
|
||||
TextManager.Get(missionsToDisplay.Count > 1 ? "Missions" : "Mission"), textAlignment: Alignment.TopLeft, font: GUI.SubHeadingFont);
|
||||
missionHeader.RectTransform.MinSize = new Point(0, (int)(missionHeader.Rect.Height * 1.2f));
|
||||
}
|
||||
|
||||
GUIListBox missionList = new GUIListBox(new RectTransform(Vector2.One, missionContent.RectTransform, Anchor.Center))
|
||||
{
|
||||
Padding = new Vector4(4, 10, 0, 0) * GUI.Scale
|
||||
};
|
||||
missionList.ContentBackground.Color = Color.Transparent;
|
||||
|
||||
ButtonArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.1f), missionFrameContent.RectTransform, Anchor.BottomCenter), isHorizontal: true, childAnchor: Anchor.BottomRight)
|
||||
{
|
||||
RelativeSpacing = 0.025f
|
||||
};
|
||||
|
||||
missionFrameContent.Recalculate();
|
||||
missionContent.Recalculate();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(endMessage))
|
||||
{
|
||||
var endText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionContent.RectTransform),
|
||||
TextManager.GetServerMessage(endMessage), wrap: true);
|
||||
var endText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionList.Content.RectTransform),
|
||||
TextManager.GetServerMessage(endMessage), wrap: true)
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
endText.RectTransform.MinSize = new Point(0, endText.Rect.Height);
|
||||
var line = new GUIFrame(new RectTransform(new Vector2(0.5f, 0.1f), missionContent.RectTransform), style: "HorizontalLine");
|
||||
var line = new GUIFrame(new RectTransform(new Vector2(0.5f, 0.1f), missionList.Content.RectTransform), style: "HorizontalLine");
|
||||
line.RectTransform.NonScaledSize = new Point(line.Rect.Width, GUI.IntScale(5.0f));
|
||||
}
|
||||
|
||||
var missionContentHorizontal = new GUILayoutGroup(new RectTransform(Vector2.One, missionContent.RectTransform), childAnchor: Anchor.TopLeft, isHorizontal: true)
|
||||
foreach (Mission displayedMission in missionsToDisplay)
|
||||
{
|
||||
RelativeSpacing = 0.025f,
|
||||
Stretch = true
|
||||
};
|
||||
var missionContentHorizontal = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.8f), missionList.Content.RectTransform), childAnchor: Anchor.CenterLeft, isHorizontal: true)
|
||||
{
|
||||
RelativeSpacing = 0.025f,
|
||||
Stretch = true
|
||||
};
|
||||
|
||||
Mission displayedMission = selectedMission ?? startLocation.SelectedMission;
|
||||
string missionMessage = "";
|
||||
GUIImage missionIcon;
|
||||
if (displayedMission != null)
|
||||
{
|
||||
missionMessage =
|
||||
displayedMission == selectedMission ?
|
||||
displayedMission.Completed ? displayedMission.SuccessMessage : displayedMission.FailureMessage :
|
||||
string missionMessage =
|
||||
selectedMissions.Contains(displayedMission) ?
|
||||
displayedMission.Completed ? displayedMission.SuccessMessage : displayedMission.FailureMessage :
|
||||
displayedMission.Description;
|
||||
missionIcon = new GUIImage(new RectTransform(new Point(missionContentHorizontal.Rect.Height), missionContentHorizontal.RectTransform), displayedMission.Prefab.Icon, scaleToFit: true)
|
||||
GUIImage missionIcon = new GUIImage(new RectTransform(new Point((int)(missionContentHorizontal.Rect.Height)), missionContentHorizontal.RectTransform), displayedMission.Prefab.Icon, scaleToFit: true)
|
||||
{
|
||||
Color = displayedMission.Prefab.IconColor
|
||||
};
|
||||
if (displayedMission == selectedMission)
|
||||
};
|
||||
missionIcon.RectTransform.MinSize = new Point((int)(missionContentHorizontal.Rect.Height * 0.9f));
|
||||
if (selectedMissions.Contains(displayedMission))
|
||||
{
|
||||
new GUIImage(new RectTransform(Vector2.One, missionIcon.RectTransform), displayedMission.Completed ? "MissionCompletedIcon" : "MissionFailedIcon", scaleToFit: true);
|
||||
new GUIImage(new RectTransform(Vector2.One, missionIcon.RectTransform), displayedMission.Completed ? "MissionCompletedIcon" : "MissionFailedIcon", scaleToFit: true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
missionIcon = new GUIImage(new RectTransform(new Point(missionContentHorizontal.Rect.Height), missionContentHorizontal.RectTransform), style: "NoMissionIcon", scaleToFit: true);
|
||||
}
|
||||
var missionTextContent = new GUILayoutGroup(new RectTransform(Vector2.One, missionContentHorizontal.RectTransform))
|
||||
{
|
||||
RelativeSpacing = 0.05f
|
||||
};
|
||||
missionContentHorizontal.Recalculate();
|
||||
missionContent.Recalculate();
|
||||
missionIcon.RectTransform.MinSize = new Point(0, missionContentHorizontal.Rect.Height);
|
||||
missionTextContent.RectTransform.MaxSize = new Point(int.MaxValue, missionIcon.Rect.Width);
|
||||
|
||||
GUITextBlock missionDescription = null;
|
||||
if (displayedMission == null)
|
||||
{
|
||||
var missionTextContent = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.8f), missionContentHorizontal.RectTransform))
|
||||
{
|
||||
RelativeSpacing = 0.05f
|
||||
};
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform),
|
||||
TextManager.Get("nomission"), font: GUI.LargeFont);
|
||||
}
|
||||
else
|
||||
{
|
||||
displayedMission.Name, font: GUI.SubHeadingFont);
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform),
|
||||
TextManager.AddPunctuation(':', TextManager.Get("Mission"), displayedMission.Name), font: GUI.SubHeadingFont);
|
||||
missionDescription = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform),
|
||||
missionMessage, wrap: true);
|
||||
if (displayedMission == selectedMission && displayedMission.Completed)
|
||||
if (selectedMissions.Contains(displayedMission) && displayedMission.Completed && displayedMission.Reward > 0)
|
||||
{
|
||||
string rewardText = TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", displayedMission.Reward));
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform),
|
||||
TextManager.GetWithVariable("MissionReward", "[reward]", rewardText));
|
||||
}
|
||||
|
||||
if (displayedMission != missionsToDisplay.Last())
|
||||
{
|
||||
var spacing = new GUIFrame(new RectTransform(new Vector2(1.0f, 1.0f), missionList.Content.RectTransform) { MaxSize = new Point(int.MaxValue, GUI.IntScale(15)) }, style: null);
|
||||
new GUIFrame(new RectTransform(new Vector2(0.8f, 1.0f), spacing.RectTransform, Anchor.Center) { RelativeOffset = new Vector2(0.1f, 0.0f) }, "HorizontalLine");
|
||||
}
|
||||
}
|
||||
|
||||
ButtonArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.1f), missionContent.RectTransform, Anchor.BottomCenter), isHorizontal: true, childAnchor: Anchor.BottomRight)
|
||||
if (!missionsToDisplay.Any())
|
||||
{
|
||||
IgnoreLayoutGroups = true,
|
||||
RelativeSpacing = 0.025f
|
||||
};
|
||||
var missionContentHorizontal = new GUILayoutGroup(new RectTransform(Vector2.One, missionList.Content.RectTransform), childAnchor: Anchor.TopLeft, isHorizontal: true)
|
||||
{
|
||||
RelativeSpacing = 0.025f,
|
||||
Stretch = true
|
||||
};
|
||||
GUIImage missionIcon = new GUIImage(new RectTransform(new Point((int)(missionContentHorizontal.Rect.Height * 0.7f)), missionContentHorizontal.RectTransform), style: "NoMissionIcon", scaleToFit: true);
|
||||
missionIcon.RectTransform.MinSize = new Point((int)(missionContentHorizontal.Rect.Height * 0.7f));
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionContentHorizontal.RectTransform),
|
||||
TextManager.Get("nomission"), font: GUI.LargeFont);
|
||||
}
|
||||
|
||||
/*missionContentHorizontal.Recalculate();
|
||||
missionContent.Recalculate();
|
||||
missionIcon.RectTransform.MinSize = new Point(0, missionContentHorizontal.Rect.Height);
|
||||
missionTextContent.RectTransform.MaxSize = new Point(int.MaxValue, missionIcon.Rect.Width);*/
|
||||
|
||||
ContinueButton = new GUIButton(new RectTransform(new Vector2(0.25f, 1.0f), ButtonArea.RectTransform), TextManager.Get("Close"));
|
||||
ButtonArea.RectTransform.NonScaledSize = new Point(ButtonArea.Rect.Width, ContinueButton.Rect.Height);
|
||||
ButtonArea.RectTransform.IsFixedSize = true;
|
||||
|
||||
missionContent.Recalculate();
|
||||
//description overlapping with the buttons -> switch to small font
|
||||
if (missionDescription != null && missionDescription.Rect.Y + missionDescription.TextSize.Y > ButtonArea.Rect.Y)
|
||||
{
|
||||
missionDescription.Font = GUI.Style.SmallFont;
|
||||
//still overlapping -> shorten the text
|
||||
if (missionDescription.Rect.Y + missionDescription.TextSize.Y > ButtonArea.Rect.Y && missionDescription.WrappedText.Contains('\n'))
|
||||
{
|
||||
missionDescription.ToolTip = missionDescription.Text;
|
||||
missionDescription.Text = missionDescription.WrappedText.Split('\n').First() + "...";
|
||||
}
|
||||
}
|
||||
missionFrameContent.Recalculate();
|
||||
|
||||
// set layout -------------------------------------------------------------------
|
||||
|
||||
@@ -396,15 +415,21 @@ namespace Barotrauma
|
||||
textTag = "RoundSummaryLeaving";
|
||||
break;
|
||||
case CampaignMode.TransitionType.ProgressToNextLocation:
|
||||
case CampaignMode.TransitionType.ProgressToNextEmptyLocation:
|
||||
locationName = endLocation?.Name;
|
||||
textTag = "RoundSummaryProgress";
|
||||
break;
|
||||
case CampaignMode.TransitionType.ProgressToNextEmptyLocation:
|
||||
locationName = endLocation?.Name;
|
||||
textTag = "RoundSummaryProgressToEmptyLocation";
|
||||
break;
|
||||
case CampaignMode.TransitionType.ReturnToPreviousLocation:
|
||||
case CampaignMode.TransitionType.ReturnToPreviousEmptyLocation:
|
||||
locationName = startLocation?.Name;
|
||||
textTag = "RoundSummaryReturn";
|
||||
break;
|
||||
case CampaignMode.TransitionType.ReturnToPreviousEmptyLocation:
|
||||
locationName = startLocation?.Name;
|
||||
textTag = "RoundSummaryReturnToEmptyLocation";
|
||||
break;
|
||||
default:
|
||||
textTag = Submarine.MainSub.AtEndPosition ? "RoundSummaryProgress" : "RoundSummaryReturn";
|
||||
break;
|
||||
@@ -456,7 +481,7 @@ namespace Barotrauma
|
||||
|
||||
GUIListBox crewList = new GUIListBox(new RectTransform(Vector2.One, parent.RectTransform))
|
||||
{
|
||||
Padding = new Vector4(2, 5, 0, 0),
|
||||
Padding = new Vector4(4, 10, 0, 0) * GUI.Scale,
|
||||
AutoHideScrollBar = false
|
||||
};
|
||||
crewList.ContentBackground.Color = Color.Transparent;
|
||||
@@ -503,7 +528,7 @@ namespace Barotrauma
|
||||
Character character = characterInfo.Character;
|
||||
if (character == null || character.IsDead)
|
||||
{
|
||||
if (character == null && characterInfo.IsNewHire)
|
||||
if (character == null && characterInfo.IsNewHire && characterInfo.CauseOfDeath == null)
|
||||
{
|
||||
statusText = TextManager.Get("CampaignCrew.NewHire");
|
||||
statusColor = GUI.Style.Blue;
|
||||
@@ -551,7 +576,7 @@ namespace Barotrauma
|
||||
string name, float reputation, float normalizedReputation, float initialReputation,
|
||||
string shortDescription, string fullDescription, Sprite icon, Sprite backgroundPortrait, Color iconColor)
|
||||
{
|
||||
var factionFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.3f), parent.RectTransform), style: null);
|
||||
var factionFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.35f), parent.RectTransform), style: null);
|
||||
|
||||
if (backgroundPortrait != null)
|
||||
{
|
||||
|
||||
@@ -65,10 +65,11 @@ namespace Barotrauma
|
||||
keyMapping[(int)InputType.Voice] = new KeyOrMouse(Keys.V);
|
||||
keyMapping[(int)InputType.LocalVoice] = new KeyOrMouse(Keys.B);
|
||||
keyMapping[(int)InputType.Command] = new KeyOrMouse(MouseButton.MiddleMouse);
|
||||
#if DEBUG
|
||||
keyMapping[(int)InputType.PreviousFireMode] = new KeyOrMouse(MouseButton.MouseWheelDown);
|
||||
keyMapping[(int)InputType.NextFireMode] = new KeyOrMouse(MouseButton.MouseWheelUp);
|
||||
#endif
|
||||
|
||||
keyMapping[(int)InputType.TakeHalfFromInventorySlot] = new KeyOrMouse(Keys.LeftShift);
|
||||
keyMapping[(int)InputType.TakeOneFromInventorySlot] = new KeyOrMouse(Keys.LeftControl);
|
||||
|
||||
if (Language == "French")
|
||||
{
|
||||
@@ -175,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))
|
||||
@@ -225,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)
|
||||
@@ -244,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;
|
||||
@@ -263,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;
|
||||
}
|
||||
|
||||
@@ -707,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"),
|
||||
@@ -727,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);
|
||||
|
||||
@@ -745,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)
|
||||
@@ -811,8 +880,7 @@ namespace Barotrauma
|
||||
ChangeSliderText(scrollBar, scroll);
|
||||
SoundVolume = scroll;
|
||||
return true;
|
||||
},
|
||||
Step = 0.05f
|
||||
}
|
||||
};
|
||||
soundScrollBar.OnMoved(soundScrollBar, soundScrollBar.BarScroll);
|
||||
|
||||
@@ -827,8 +895,7 @@ namespace Barotrauma
|
||||
ChangeSliderText(scrollBar, scroll);
|
||||
MusicVolume = scroll;
|
||||
return true;
|
||||
},
|
||||
Step = 0.05f
|
||||
}
|
||||
};
|
||||
musicScrollBar.OnMoved(musicScrollBar, musicScrollBar.BarScroll);
|
||||
|
||||
@@ -837,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) =>
|
||||
@@ -1016,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,
|
||||
@@ -1098,13 +1177,14 @@ namespace Barotrauma
|
||||
style: "GUISlider", barSize: 0.05f)
|
||||
{
|
||||
UserData = micVolumeText,
|
||||
Range = new Vector2(0,540),
|
||||
Step = 1.0f / 9.0f
|
||||
Range = new Vector2(0, ((float)VoipConfig.BUFFER_SIZE / (float)VoipConfig.FREQUENCY) * 1000.0f * 25.0f),
|
||||
Step = 1.0f / 25.0f
|
||||
};
|
||||
cutoffPreventionSlider.BarScrollValue = VoiceChatCutoffPrevention;
|
||||
cutoffPreventionSlider.OnMoved = (scrollBar, scroll) =>
|
||||
{
|
||||
VoiceChatCutoffPrevention = (int)scrollBar.BarScrollValue;
|
||||
int bufferMsLength = (int)(((float)VoipConfig.BUFFER_SIZE / (float)VoipConfig.FREQUENCY) * 1000.0f);
|
||||
VoiceChatCutoffPrevention = (int)Math.Round(scrollBar.BarScrollValue / bufferMsLength) * bufferMsLength;
|
||||
cutoffPreventionText.Text = TextManager.Get("CutoffPrevention") +
|
||||
" " + TextManager.GetWithVariable("timeformatmilliseconds", "[milliseconds]", VoiceChatCutoffPrevention.ToString());
|
||||
return true;
|
||||
@@ -1142,6 +1222,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;
|
||||
@@ -1185,7 +1266,7 @@ namespace Barotrauma
|
||||
AimAssistAmount = MathHelper.Lerp(0.0f, 5.0f, scroll);
|
||||
return true;
|
||||
},
|
||||
Step = 0.1f
|
||||
Step = 0.01f
|
||||
};
|
||||
aimAssistSlider.OnMoved(aimAssistSlider, aimAssistSlider.BarScroll);
|
||||
|
||||
@@ -1201,19 +1282,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 };
|
||||
@@ -1228,14 +1311,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 };
|
||||
@@ -1246,11 +1332,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;
|
||||
}
|
||||
|
||||
GUITextBlock.AutoScaleAndNormalize(inputNameBlocks);
|
||||
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),
|
||||
@@ -1599,7 +1694,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;
|
||||
}
|
||||
@@ -1618,7 +1713,9 @@ namespace Barotrauma
|
||||
{
|
||||
DisableRegularPackage(contentPackage);
|
||||
}
|
||||
|
||||
|
||||
ContentPackage.SortContentPackages(cp => contentPackageList.Content.GetChildIndex(contentPackageList.Content.GetChildByUserData(cp)), false, this);
|
||||
|
||||
UnsavedSettings = true;
|
||||
return true;
|
||||
}
|
||||
@@ -1709,22 +1806,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 = slots[i].FirstOrDefault()?.GetComponent<ItemContainer>();
|
||||
if (itemContainer != null)
|
||||
{
|
||||
ItemContainer itemContainer = Items[i].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));
|
||||
}
|
||||
}
|
||||
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 || !IsInLimbSlot(doubleClickedItem, InvSlotType.Any))
|
||||
{
|
||||
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);
|
||||
@@ -931,8 +948,8 @@ namespace Barotrauma
|
||||
item.Remove();
|
||||
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;
|
||||
SoundPlayer.PlayUISound(success ? GUISoundType.PickItem : GUISoundType.PickItemFail);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,12 +86,12 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
float scale = VineScale * vine.VineStep;
|
||||
|
||||
if (VineAtlas != null)
|
||||
if (VineAtlas != null && VineAtlas.Loaded)
|
||||
{
|
||||
spriteBatch.Draw(VineAtlas.Texture, pos + vine.offset, vineSprite.SourceRect, color, 0f, vineSprite.AbsoluteOrigin, scale, SpriteEffects.None, layer3);
|
||||
}
|
||||
|
||||
if (DecayAtlas != null)
|
||||
if (DecayAtlas != null && DecayAtlas.Loaded)
|
||||
{
|
||||
spriteBatch.Draw(DecayAtlas.Texture, pos, vineSprite.SourceRect, vine.HealthColor, 0f, vineSprite.AbsoluteOrigin, scale, SpriteEffects.None, layer2);
|
||||
}
|
||||
|
||||
@@ -2,9 +2,6 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
@@ -17,7 +14,11 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, bool editing, float itemDepth = -1)
|
||||
{
|
||||
if (!IsActive || picker == null || !CanBeAttached(picker) || !picker.IsKeyDown(InputType.Aim) || picker != Character.Controlled) { return; }
|
||||
if (!IsActive || picker == null || !CanBeAttached(picker) || !picker.IsKeyDown(InputType.Aim) || picker != Character.Controlled)
|
||||
{
|
||||
Drawable = false;
|
||||
return;
|
||||
}
|
||||
|
||||
Vector2 gridPos = picker.Position;
|
||||
Vector2 roundedGridPos = new Vector2(
|
||||
@@ -46,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,
|
||||
|
||||
@@ -55,13 +55,8 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (character == null || !character.IsKeyDown(InputType.Aim)) return;
|
||||
|
||||
#if DEBUG
|
||||
if (PlayerInput.KeyHit(InputType.PreviousFireMode))
|
||||
#else
|
||||
if (PlayerInput.MouseWheelDownClicked())
|
||||
#endif
|
||||
{
|
||||
|
||||
if (spraySetting > 0)
|
||||
{
|
||||
spraySetting--;
|
||||
@@ -74,11 +69,7 @@ namespace Barotrauma.Items.Components
|
||||
targetSections.Clear();
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
if (PlayerInput.KeyHit(InputType.NextFireMode))
|
||||
#else
|
||||
if (PlayerInput.MouseWheelUpClicked())
|
||||
#endif
|
||||
{
|
||||
if (spraySetting < 2)
|
||||
{
|
||||
@@ -139,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;
|
||||
@@ -248,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)
|
||||
@@ -147,6 +179,23 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
|
||||
// Expand the frame vertically if it's too small to fit the text
|
||||
if (label != null && label.RectTransform.RelativeSize.Y > 0.5f)
|
||||
{
|
||||
int newHeight = (int)(GuiFrame.Rect.Height + (2 * (label.RectTransform.RelativeSize.Y - 0.5f) * content.Rect.Height));
|
||||
if (newHeight > GuiFrame.RectTransform.MaxSize.Y)
|
||||
{
|
||||
Point newMaxSize = GuiFrame.RectTransform.MaxSize;
|
||||
newMaxSize.Y = newHeight;
|
||||
GuiFrame.RectTransform.MaxSize = newMaxSize;
|
||||
}
|
||||
GuiFrame.RectTransform.Resize(new Point(GuiFrame.Rect.Width, newHeight));
|
||||
content.RectTransform.Resize(GuiFrame.Rect.Size - GUIStyle.ItemFrameMargin);
|
||||
label.CalculateHeightFromText();
|
||||
guiCustomComponent.RectTransform.Resize(new Vector2(1.0f, Math.Max(1.0f - label.RectTransform.RelativeSize.Y, minInventoryAreaSize)));
|
||||
}
|
||||
|
||||
Inventory.RectTransform = guiCustomComponent.RectTransform;
|
||||
}
|
||||
|
||||
@@ -173,15 +222,9 @@ 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.HeldItems.Count() > 1 && character.HeldItems.All(it => it.GetComponent<ItemContainer>()?.KeepOpenWhenEquipped ?? false))
|
||||
{
|
||||
if ((character.SelectedItems[0].GetComponent<ItemContainer>()?.KeepOpenWhenEquipped ?? false) &&
|
||||
(character.SelectedItems[1].GetComponent<ItemContainer>()?.KeepOpenWhenEquipped ?? false))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -257,13 +300,11 @@ namespace Barotrauma.Items.Components
|
||||
spriteEffects |= MathUtils.NearlyEqual(ItemRotation % 180, 90.0f) ? SpriteEffects.FlipHorizontally : SpriteEffects.FlipVertically;
|
||||
}
|
||||
|
||||
bool isWiringMode = SubEditorScreen.IsWiringMode();
|
||||
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 +354,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;
|
||||
@@ -41,15 +47,22 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
textBlock = null;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
SetScrollingText();
|
||||
SetDisplayText(value);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@@ -204,11 +236,33 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
TextBlock.Text = sb.ToString();
|
||||
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;
|
||||
|
||||
@@ -21,18 +21,14 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private readonly List<Submarine> displayedSubs = new List<Submarine>();
|
||||
|
||||
private Point prevResolution;
|
||||
|
||||
partial void InitProjSpecific(XElement element)
|
||||
{
|
||||
noPowerTip = TextManager.Get("SteeringNoPowerTip");
|
||||
CreateGUI();
|
||||
}
|
||||
|
||||
protected override void OnResolutionChanged()
|
||||
{
|
||||
base.OnResolutionChanged();
|
||||
CreateHUD();
|
||||
}
|
||||
|
||||
protected override void CreateGUI()
|
||||
{
|
||||
GuiFrame.RectTransform.RelativeOffset = new Vector2(0.05f, 0.0f);
|
||||
@@ -76,15 +72,10 @@ namespace Barotrauma.Items.Components
|
||||
hullInfoFrame.AddToGUIUpdateList(order: 1);
|
||||
}
|
||||
|
||||
public override void OnMapLoaded()
|
||||
{
|
||||
base.OnMapLoaded();
|
||||
CreateHUD();
|
||||
}
|
||||
|
||||
private void CreateHUD()
|
||||
{
|
||||
submarineContainer.ClearChildren();
|
||||
prevResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
|
||||
submarineContainer?.ClearChildren();
|
||||
|
||||
if (item.Submarine == null) { return; }
|
||||
|
||||
@@ -94,19 +85,15 @@ namespace Barotrauma.Items.Components
|
||||
displayedSubs.AddRange(item.Submarine.DockedTo);
|
||||
}
|
||||
|
||||
public override void FlipX(bool relativeToSub)
|
||||
{
|
||||
CreateHUD();
|
||||
}
|
||||
|
||||
public override void UpdateHUD(Character character, float deltaTime, Camera cam)
|
||||
{
|
||||
//recreate HUD if the subs we should display have changed
|
||||
if ((item.Submarine == null && displayedSubs.Count > 0) || //item not inside a sub anymore, but display is still showing subs
|
||||
!displayedSubs.Contains(item.Submarine) || //current sub not displayer
|
||||
item.Submarine.DockedTo.Any(s => !displayedSubs.Contains(s)) || //some of the docked subs not diplayed
|
||||
!submarineContainer.Children.Any() || // We lack a GUI
|
||||
displayedSubs.Any(s => s != item.Submarine && !item.Submarine.DockedTo.Contains(s))) //displaying a sub that shouldn't be displayed
|
||||
if ((item.Submarine == null && displayedSubs.Count > 0) || //item not inside a sub anymore, but display is still showing subs
|
||||
!displayedSubs.Contains(item.Submarine) || //current sub not displayer
|
||||
prevResolution.X != GameMain.GraphicsWidth || prevResolution.Y != GameMain.GraphicsHeight || //resolution changed
|
||||
item.Submarine.DockedTo.Any(s => !displayedSubs.Contains(s)) || //some of the docked subs not diplayed
|
||||
!submarineContainer.Children.Any() || // We lack a GUI
|
||||
displayedSubs.Any(s => s != item.Submarine && !item.Submarine.DockedTo.Contains(s))) //displaying a sub that shouldn't be displayed
|
||||
{
|
||||
CreateHUD();
|
||||
}
|
||||
|
||||
@@ -215,15 +215,33 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
||||
{
|
||||
int msgStartPos = msg.BitPosition;
|
||||
|
||||
float flowPercentage = msg.ReadRangedInteger(-10, 10) * 10.0f;
|
||||
bool isActive = msg.ReadBoolean();
|
||||
bool hijacked = msg.ReadBoolean();
|
||||
float? targetLevel;
|
||||
if (msg.ReadBoolean())
|
||||
{
|
||||
targetLevel = msg.ReadSingle();
|
||||
}
|
||||
else
|
||||
{
|
||||
targetLevel = null;
|
||||
}
|
||||
|
||||
if (correctionTimer > 0.0f)
|
||||
{
|
||||
StartDelayedCorrection(type, msg.ExtractBits(5 + 1), sendingTime);
|
||||
int msgLength = msg.BitPosition - msgStartPos;
|
||||
msg.BitPosition = msgStartPos;
|
||||
StartDelayedCorrection(type, msg.ExtractBits(msgLength), sendingTime);
|
||||
return;
|
||||
}
|
||||
|
||||
FlowPercentage = msg.ReadRangedInteger(-10, 10) * 10.0f;
|
||||
IsActive = msg.ReadBoolean();
|
||||
Hijacked = msg.ReadBoolean();
|
||||
FlowPercentage = flowPercentage;
|
||||
IsActive = isActive;
|
||||
Hijacked = hijacked;
|
||||
TargetLevel = targetLevel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -502,8 +502,16 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (item.Removed) { return; }
|
||||
|
||||
Vector2 clampedOptimalTurbineOutput = optimalTurbineOutput;
|
||||
Vector2 clampedAllowedTurbineOutput = allowedTurbineOutput;
|
||||
if (clampedOptimalTurbineOutput.X > 100.0f)
|
||||
{
|
||||
clampedOptimalTurbineOutput = new Vector2(92.0f, 110.0f);
|
||||
clampedAllowedTurbineOutput = new Vector2(85.0f, 110.0f);
|
||||
}
|
||||
|
||||
DrawMeter(spriteBatch, container.Rect,
|
||||
turbineOutputMeter, TurbineOutput, new Vector2(0.0f, 100.0f), optimalTurbineOutput, allowedTurbineOutput);
|
||||
turbineOutputMeter, TurbineOutput, new Vector2(0.0f, 100.0f), clampedOptimalTurbineOutput, clampedAllowedTurbineOutput);
|
||||
}
|
||||
|
||||
public override void UpdateHUD(Character character, float deltaTime, Camera cam)
|
||||
|
||||
@@ -15,7 +15,8 @@ namespace Barotrauma.Items.Components
|
||||
public enum BlipType
|
||||
{
|
||||
Default,
|
||||
Disruption
|
||||
Disruption,
|
||||
Destructible
|
||||
}
|
||||
|
||||
private PathFinder pathFinder;
|
||||
@@ -54,7 +55,7 @@ namespace Barotrauma.Items.Components
|
||||
private Sprite sonarBlip;
|
||||
private Sprite lineSprite;
|
||||
|
||||
private readonly Dictionary<string, Sprite> targetIcons = new Dictionary<string, Sprite>();
|
||||
private readonly Dictionary<string, Tuple<Sprite, Color>> targetIcons = new Dictionary<string, Tuple<Sprite, Color>>();
|
||||
|
||||
private float displayBorderSize;
|
||||
|
||||
@@ -70,6 +71,14 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private float showDirectionalIndicatorTimer;
|
||||
|
||||
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>>();
|
||||
@@ -109,6 +118,10 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
BlipType.Disruption,
|
||||
new Color[] { Color.TransparentBlack, new Color(254, 68, 19), new Color(255, 220, 62), new Color(255, 255, 255) }
|
||||
},
|
||||
{
|
||||
BlipType.Destructible,
|
||||
new Color[] { Color.TransparentBlack, new Color(74, 113, 75) * 0.8f, new Color(151, 236, 172) * 0.8f, new Color(153, 217, 234) * 0.8f }
|
||||
}
|
||||
};
|
||||
|
||||
@@ -124,11 +137,22 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private readonly List<GUITextBlock> textBlocksToScaleAndNormalize = new List<GUITextBlock>();
|
||||
|
||||
private bool isConnectedToSteering;
|
||||
|
||||
private static string caveLabel;
|
||||
|
||||
private bool AllowUsingMineralScanner =>
|
||||
HasMineralScanner && !isConnectedToSteering;
|
||||
|
||||
partial void InitProjSpecific(XElement element)
|
||||
{
|
||||
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())
|
||||
@@ -161,7 +185,9 @@ namespace Barotrauma.Items.Components
|
||||
break;
|
||||
case "icon":
|
||||
var targetIconSprite = new Sprite(subElement);
|
||||
targetIcons.Add(subElement.GetAttributeString("identifier", ""), targetIconSprite);
|
||||
var color = subElement.GetAttributeColor("color", Color.White);
|
||||
targetIcons.Add(subElement.GetAttributeString("identifier", ""),
|
||||
new Tuple<Sprite, Color>(targetIconSprite, color));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -176,16 +202,20 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
protected override void CreateGUI()
|
||||
{
|
||||
bool isConnectedToSteering = item.GetComponent<Steering>() != null;
|
||||
Vector2 size = isConnectedToSteering ? controlBoxSize : new Vector2(controlBoxSize.X * 2.0f, controlBoxSize.Y);
|
||||
isConnectedToSteering = item.GetComponent<Steering>() != null;
|
||||
Vector2 size = isConnectedToSteering ? controlBoxSize : new Vector2(0.46f, 0.4f);
|
||||
|
||||
controlContainer = new GUIFrame(new RectTransform(size, GuiFrame.RectTransform, Anchor.BottomRight, Pivot.BottomLeft), "ItemUI");
|
||||
controlContainer = new GUIFrame(new RectTransform(size, GuiFrame.RectTransform, Anchor.BottomLeft), "ItemUI");
|
||||
if (!isConnectedToSteering && !GUI.IsFourByThree())
|
||||
{
|
||||
controlContainer.RectTransform.MaxSize = new Point((int)(380 * GUI.xScale), (int)(300 * GUI.yScale));
|
||||
}
|
||||
var paddedControlContainer = new GUIFrame(new RectTransform(controlContainer.Rect.Size - GUIStyle.ItemFrameMargin, controlContainer.RectTransform, Anchor.Center)
|
||||
{
|
||||
AbsoluteOffset = GUIStyle.ItemFrameOffset
|
||||
}, style: null);
|
||||
// Based on the height difference to the steering control box so that the elements keep the same size
|
||||
float extraHeight = 0.03f;
|
||||
float extraHeight = 0.0694f;
|
||||
var sonarModeArea = new GUIFrame(new RectTransform(new Vector2(1, 0.4f + extraHeight), paddedControlContainer.RectTransform, Anchor.TopCenter), style: null);
|
||||
SonarModeSwitch = new GUIButton(new RectTransform(new Vector2(0.2f, 1), sonarModeArea.RectTransform), string.Empty, style: "SwitchVertical")
|
||||
{
|
||||
@@ -224,6 +254,8 @@ namespace Barotrauma.Items.Components
|
||||
};
|
||||
passiveTickBox.TextBlock.OverrideTextColor(GUI.Style.TextColor);
|
||||
activeTickBox.TextBlock.OverrideTextColor(GUI.Style.TextColor);
|
||||
|
||||
textBlocksToScaleAndNormalize.Clear();
|
||||
textBlocksToScaleAndNormalize.Add(passiveTickBox.TextBlock);
|
||||
textBlocksToScaleAndNormalize.Add(activeTickBox.TextBlock);
|
||||
|
||||
@@ -249,7 +281,8 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
};
|
||||
|
||||
new GUIFrame(new RectTransform(new Vector2(0.8f, 0.01f), paddedControlContainer.RectTransform, Anchor.Center), style: "HorizontalLine");
|
||||
new GUIFrame(new RectTransform(new Vector2(0.8f, 0.01f), paddedControlContainer.RectTransform, Anchor.Center), style: "HorizontalLine")
|
||||
{ UserData = "horizontalline" };
|
||||
|
||||
var directionalModeFrame = new GUIFrame(new RectTransform(new Vector2(1, 0.45f), lowerAreaFrame.RectTransform, Anchor.BottomCenter), style: null);
|
||||
directionalModeSwitch = new GUIButton(new RectTransform(new Vector2(0.3f, 0.8f), directionalModeFrame.RectTransform, Anchor.CenterLeft), string.Empty, style: "SwitchHorizontal")
|
||||
@@ -270,6 +303,15 @@ namespace Barotrauma.Items.Components
|
||||
TextManager.Get("SonarDirectionalPing"), GUI.Style.TextColor, GUI.SubHeadingFont, Alignment.CenterLeft);
|
||||
textBlocksToScaleAndNormalize.Add(directionalModeSwitchText);
|
||||
|
||||
if (AllowUsingMineralScanner)
|
||||
{
|
||||
AddMineralScannerSwitchToGUI();
|
||||
}
|
||||
else
|
||||
{
|
||||
mineralScannerSwitch = null;
|
||||
}
|
||||
|
||||
GuiFrame.CanBeFocused = false;
|
||||
|
||||
GUITextBlock.AutoScaleAndNormalize(textBlocksToScaleAndNormalize);
|
||||
@@ -284,12 +326,17 @@ namespace Barotrauma.Items.Components
|
||||
if (isConnectedToSteering)
|
||||
{
|
||||
controlContainer.RectTransform.RelativeOffset = controlBoxOffset;
|
||||
controlContainer.RectTransform.SetPosition(Anchor.TopLeft);
|
||||
controlContainer.RectTransform.SetPosition(Anchor.TopRight);
|
||||
sonarView.RectTransform.ScaleBasis = ScaleBasis.Smallest;
|
||||
sonarView.RectTransform.SetPosition(Anchor.CenterRight);
|
||||
sonarView.RectTransform.SetPosition(Anchor.CenterLeft);
|
||||
sonarView.RectTransform.Resize(GUISizeCalculation);
|
||||
GUITextBlock.AutoScaleAndNormalize(textBlocksToScaleAndNormalize);
|
||||
}
|
||||
else if (GUI.RelativeHorizontalAspectRatio > 0.75f)
|
||||
{
|
||||
sonarView.RectTransform.RelativeOffset = new Vector2(0.13f * GUI.RelativeHorizontalAspectRatio, 0);
|
||||
sonarView.RectTransform.SetPosition(Anchor.BottomRight);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetPingDirection(Vector2 direction)
|
||||
@@ -306,20 +353,39 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
base.OnItemLoaded();
|
||||
zoomSlider.BarScroll = MathUtils.InverseLerp(MinZoom, MaxZoom, zoom);
|
||||
if (HasMineralScanner) { AddMineralScannerSwitchToGUI(); }
|
||||
if (AllowUsingMineralScanner && mineralScannerSwitch == null)
|
||||
{
|
||||
AddMineralScannerSwitchToGUI();
|
||||
GUITextBlock.AutoScaleAndNormalize(textBlocksToScaleAndNormalize);
|
||||
}
|
||||
//make the sonarView customcomponent render the steering view so it gets drawn in front of the sonar
|
||||
item.GetComponent<Steering>()?.AttachToSonarHUD(sonarView);
|
||||
}
|
||||
|
||||
private void AddMineralScannerSwitchToGUI()
|
||||
{
|
||||
// First adjust other elements of the lower area
|
||||
zoomSlider.Parent.RectTransform.RelativeSize = new Vector2(1.0f, 0.3f);
|
||||
directionalModeSwitch.Parent.RectTransform.RelativeSize = new Vector2(1.0f, 0.3f);
|
||||
// First adjust other elements to make room for the additional switch
|
||||
controlContainer.RectTransform.RelativeSize = new Vector2(
|
||||
controlContainer.RectTransform.RelativeSize.X,
|
||||
controlContainer.RectTransform.RelativeSize.Y * 1.25f);
|
||||
SonarModeSwitch.Parent.RectTransform.RelativeSize = new Vector2(
|
||||
SonarModeSwitch.Parent.RectTransform.RelativeSize.X,
|
||||
SonarModeSwitch.Parent.RectTransform.RelativeSize.Y * 0.8f);
|
||||
lowerAreaFrame.Parent.GetChildByUserData("horizontalline").RectTransform.RelativeOffset =
|
||||
new Vector2(0.0f, -0.1f);
|
||||
lowerAreaFrame.RectTransform.RelativeSize = new Vector2(
|
||||
lowerAreaFrame.RectTransform.RelativeSize.X,
|
||||
lowerAreaFrame.RectTransform.RelativeSize.Y * 1.2f);
|
||||
zoomSlider.Parent.RectTransform.RelativeSize = new Vector2(
|
||||
zoomSlider.Parent.RectTransform.RelativeSize.X,
|
||||
zoomSlider.Parent.RectTransform.RelativeSize.Y * (2.0f / 3.0f));
|
||||
directionalModeSwitch.Parent.RectTransform.RelativeSize = new Vector2(
|
||||
directionalModeSwitch.Parent.RectTransform.RelativeSize.X,
|
||||
zoomSlider.Parent.RectTransform.RelativeSize.Y);
|
||||
directionalModeSwitch.Parent.RectTransform.SetPosition(Anchor.Center);
|
||||
|
||||
// Then add the scanner switch
|
||||
var mineralScannerFrame = new GUIFrame(new RectTransform(new Vector2(1, 0.3f), lowerAreaFrame.RectTransform, Anchor.BottomCenter), style: null);
|
||||
var mineralScannerFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, zoomSlider.Parent.RectTransform.RelativeSize.Y), lowerAreaFrame.RectTransform, Anchor.BottomCenter), style: null);
|
||||
mineralScannerSwitch = new GUIButton(new RectTransform(new Vector2(0.3f, 0.8f), mineralScannerFrame.RectTransform, Anchor.CenterLeft), string.Empty, style: "SwitchHorizontal")
|
||||
{
|
||||
OnClicked = (button, data) =>
|
||||
@@ -337,7 +403,6 @@ namespace Barotrauma.Items.Components
|
||||
var mineralScannerSwitchText = new GUITextBlock(new RectTransform(new Vector2(0.7f, 1), mineralScannerFrame.RectTransform, Anchor.CenterRight),
|
||||
TextManager.Get("SonarMineralScanner"), GUI.Style.TextColor, GUI.SubHeadingFont, Alignment.CenterLeft);
|
||||
textBlocksToScaleAndNormalize.Add(mineralScannerSwitchText);
|
||||
GUITextBlock.AutoScaleAndNormalize(textBlocksToScaleAndNormalize);
|
||||
}
|
||||
|
||||
public override void UpdateHUD(Character character, float deltaTime, Camera cam)
|
||||
@@ -358,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;
|
||||
@@ -382,7 +467,7 @@ namespace Barotrauma.Items.Components
|
||||
Vector2.DistanceSquared(sonarView.Rect.Center.ToVector2(), PlayerInput.MousePosition) <
|
||||
(sonarView.Rect.Width / 2 * sonarView.Rect.Width / 2);
|
||||
|
||||
if (HasMineralScanner && Level.Loaded != null && !Level.Loaded.Generating)
|
||||
if (AllowUsingMineralScanner && Level.Loaded != null && !Level.Loaded.Generating)
|
||||
{
|
||||
if (MineralClusters == null)
|
||||
{
|
||||
@@ -417,26 +502,42 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (Level.Loaded != null)
|
||||
{
|
||||
nearbyObjectUpdateTimer -= deltaTime;
|
||||
if (nearbyObjectUpdateTimer <= 0.0f)
|
||||
{
|
||||
nearbyObjects.Clear();
|
||||
foreach (var nearbyObject in Level.Loaded.LevelObjectManager.GetAllObjects(transducerCenter, range * zoom))
|
||||
{
|
||||
if (!nearbyObject.VisibleOnSonar) { continue; }
|
||||
float objectRange = range + nearbyObject.SonarRadius;
|
||||
if (Vector2.DistanceSquared(transducerCenter, nearbyObject.WorldPosition) < objectRange * objectRange)
|
||||
{
|
||||
nearbyObjects.Add(nearbyObject);
|
||||
}
|
||||
}
|
||||
nearbyObjectUpdateTimer = NearbyObjectUpdateInterval;
|
||||
}
|
||||
|
||||
List<LevelTrigger> ballastFloraSpores = new List<LevelTrigger>();
|
||||
Dictionary<LevelTrigger, Vector2> levelTriggerFlows = new Dictionary<LevelTrigger, Vector2>();
|
||||
for (var pingIndex = 0; pingIndex < activePingsCount; ++pingIndex)
|
||||
{
|
||||
var activePing = activePings[pingIndex];
|
||||
LevelObjectManager objManager = Level.Loaded.LevelObjectManager;
|
||||
float pingRange = range * activePing.State / zoom;
|
||||
foreach (LevelObject levelObject in objManager.GetAllObjects(transducerCenter, pingRange))
|
||||
foreach (LevelObject levelObject in nearbyObjects)
|
||||
{
|
||||
if (levelObject.Triggers == null) { continue; }
|
||||
//gather all nearby triggers that are causing the water to flow into the dictionary
|
||||
foreach (LevelTrigger trigger in levelObject.Triggers)
|
||||
{
|
||||
Vector2 flow = trigger.GetWaterFlowVelocity();
|
||||
//ignore ones that are barely doing anything (flow^2 < 1)
|
||||
if (flow.LengthSquared() > 1.0f && !levelTriggerFlows.ContainsKey(trigger))
|
||||
//ignore ones that are barely doing anything (flow^2 <= 1)
|
||||
if (flow.LengthSquared() >= 1.0f && !levelTriggerFlows.ContainsKey(trigger))
|
||||
{
|
||||
levelTriggerFlows.Add(trigger, flow);
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(trigger.InfectIdentifier) && Vector2.DistanceSquared(transducerCenter, trigger.WorldPosition) < pingRange / 2 * pingRange / 2)
|
||||
if (!string.IsNullOrWhiteSpace(trigger.InfectIdentifier) &&
|
||||
Vector2.DistanceSquared(transducerCenter, trigger.WorldPosition) < pingRange / 2 * pingRange / 2)
|
||||
{
|
||||
ballastFloraSpores.Add(trigger);
|
||||
}
|
||||
@@ -727,8 +828,8 @@ namespace Barotrauma.Items.Components
|
||||
float directionalPingVisibility = useDirectionalPing && currentMode == Mode.Active ? 1.0f : showDirectionalIndicatorTimer;
|
||||
if (directionalPingVisibility > 0.0f)
|
||||
{
|
||||
Vector2 sector1 = MathUtils.RotatePointAroundTarget(pingDirection * DisplayRadius, Vector2.Zero, DirectionalPingSector * 0.5f);
|
||||
Vector2 sector2 = MathUtils.RotatePointAroundTarget(pingDirection * DisplayRadius, Vector2.Zero, -DirectionalPingSector * 0.5f);
|
||||
Vector2 sector1 = MathUtils.RotatePointAroundTarget(pingDirection * DisplayRadius, Vector2.Zero, MathHelper.ToRadians(DirectionalPingSector * 0.5f));
|
||||
Vector2 sector2 = MathUtils.RotatePointAroundTarget(pingDirection * DisplayRadius, Vector2.Zero, MathHelper.ToRadians(-DirectionalPingSector * 0.5f));
|
||||
DrawLine(spriteBatch, Vector2.Zero, sector1, Color.LightCyan * 0.2f * directionalPingVisibility, width: 3);
|
||||
DrawLine(spriteBatch, Vector2.Zero, sector2, Color.LightCyan * 0.2f * directionalPingVisibility, width: 3);
|
||||
}
|
||||
@@ -761,7 +862,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
DrawMarker(spriteBatch,
|
||||
Level.Loaded.StartLocation.Name,
|
||||
"outpost",
|
||||
Level.Loaded.StartOutpost != null ? "outpost" : "location",
|
||||
Level.Loaded.StartLocation.Name,
|
||||
Level.Loaded.StartPosition, transducerCenter,
|
||||
displayScale, center, DisplayRadius);
|
||||
@@ -771,16 +872,28 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
DrawMarker(spriteBatch,
|
||||
Level.Loaded.EndLocation.Name,
|
||||
"outpost",
|
||||
Level.Loaded.EndOutpost != null ? "outpost" : "location",
|
||||
Level.Loaded.EndLocation.Name,
|
||||
Level.Loaded.EndPosition, transducerCenter,
|
||||
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)
|
||||
{
|
||||
@@ -793,10 +906,8 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
if (GameMain.GameSession.Mission != null)
|
||||
foreach (Mission mission in GameMain.GameSession.Missions)
|
||||
{
|
||||
var mission = GameMain.GameSession.Mission;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(mission.SonarLabel))
|
||||
{
|
||||
foreach (Vector2 sonarPosition in mission.SonarPositions)
|
||||
@@ -811,18 +922,17 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
if (HasMineralScanner && useMineralScanner && CurrentMode == Mode.Active && MineralClusters != null)
|
||||
if (AllowUsingMineralScanner && useMineralScanner && CurrentMode == Mode.Active && MineralClusters != null)
|
||||
{
|
||||
var maxMineralScanRangeSquared = Range * Range;
|
||||
foreach (var t in MineralClusters)
|
||||
{
|
||||
var unobtainedMinerals = t.Item2.Where(i => i != null && i.GetRootInventoryOwner() == i);
|
||||
if (unobtainedMinerals.None()) { continue; }
|
||||
if (Vector2.DistanceSquared(transducerCenter, t.Item1) > maxMineralScanRangeSquared) { continue; }
|
||||
if (!CheckResourceMarkerVisibility(t.Item1, transducerCenter)) { continue; }
|
||||
var i = unobtainedMinerals.FirstOrDefault();
|
||||
if (i == null) { continue; }
|
||||
DrawMarker(spriteBatch,
|
||||
i.Name, null, i,
|
||||
i.Name, "mineral", i,
|
||||
t.Item1, transducerCenter,
|
||||
displayScale, center, DisplayRadius * 0.95f,
|
||||
onlyShowTextOnMouseOver: true);
|
||||
@@ -832,16 +942,11 @@ 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,
|
||||
sub.Info.DisplayName,
|
||||
|
||||
DrawMarker(spriteBatch,
|
||||
sub.Info.DisplayName,
|
||||
sub.Info.HasTag(SubmarineTag.Shuttle) ? "shuttle" : "submarine",
|
||||
sub,
|
||||
sub.WorldPosition, transducerCenter,
|
||||
@@ -861,10 +966,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);
|
||||
|
||||
@@ -948,8 +1051,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;
|
||||
}
|
||||
@@ -1075,8 +1178,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
for (var pingIndex = 0; pingIndex < activePingsCount; ++pingIndex)
|
||||
{
|
||||
var activePing = activePings[pingIndex];
|
||||
foreach (LevelObject levelObject in Level.Loaded.LevelObjectManager.GetAllObjects(pingSource, range * activePing.State))
|
||||
foreach (LevelObject levelObject in nearbyObjects)
|
||||
{
|
||||
if (levelObject.ActivePrefab?.SonarDisruption <= 0.0f) { continue; }
|
||||
|
||||
@@ -1157,19 +1259,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++)
|
||||
@@ -1209,9 +1302,9 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
foreach (Voronoi2.GraphEdge edge in cell.Edges)
|
||||
{
|
||||
if (!edge.IsSolid) continue;
|
||||
if (!edge.IsSolid) { continue; }
|
||||
float cellDot = Vector2.Dot(cell.Center - pingSource, (edge.Center + cell.Translation) - cell.Center);
|
||||
if (cellDot > 0) continue;
|
||||
if (cellDot > 0) { continue; }
|
||||
|
||||
float facingDot = Vector2.Dot(
|
||||
Vector2.Normalize(edge.Point1 - edge.Point2),
|
||||
@@ -1222,7 +1315,8 @@ namespace Barotrauma.Items.Components
|
||||
edge.Point2 + cell.Translation,
|
||||
pingSource, transducerPos,
|
||||
pingRadius, prevPingRadius,
|
||||
350.0f, 3.0f * (Math.Abs(facingDot) + 1.0f), range, pingStrength, passive);
|
||||
350.0f, 3.0f * (Math.Abs(facingDot) + 1.0f), range, pingStrength, passive,
|
||||
blipType : cell.IsDestructible ? BlipType.Destructible : BlipType.Default);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1311,7 +1405,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
private void CreateBlipsForLine(Vector2 point1, Vector2 point2, Vector2 pingSource, Vector2 transducerPos, float pingRadius, float prevPingRadius,
|
||||
float lineStep, float zStep, float range, float pingStrength, bool passive)
|
||||
float lineStep, float zStep, float range, float pingStrength, bool passive, BlipType blipType = BlipType.Default)
|
||||
{
|
||||
lineStep /= zoom;
|
||||
zStep /= zoom;
|
||||
@@ -1327,13 +1421,13 @@ namespace Barotrauma.Items.Components
|
||||
//ignore if outside the display
|
||||
Vector2 transducerDiff = point - transducerPos;
|
||||
Vector2 transducerDisplayDiff = transducerDiff * displayScale;
|
||||
if (transducerDisplayDiff.LengthSquared() > DisplayRadius * DisplayRadius) continue;
|
||||
if (transducerDisplayDiff.LengthSquared() > DisplayRadius * DisplayRadius) { continue; }
|
||||
|
||||
//ignore if the point is not within the ping
|
||||
Vector2 pointDiff = point - pingSource;
|
||||
Vector2 displayPointDiff = pointDiff * displayScale;
|
||||
float displayPointDistSqr = displayPointDiff.LengthSquared();
|
||||
if (displayPointDistSqr < prevPingRadius * prevPingRadius || displayPointDistSqr > pingRadius * pingRadius) continue;
|
||||
if (displayPointDistSqr < prevPingRadius * prevPingRadius || displayPointDistSqr > pingRadius * pingRadius) { continue; }
|
||||
|
||||
//ignore if direction is disrupted
|
||||
float transducerDist = transducerDiff.Length();
|
||||
@@ -1348,7 +1442,7 @@ namespace Barotrauma.Items.Components
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (disrupted) continue;
|
||||
if (disrupted) { continue; }
|
||||
|
||||
float displayPointDist = (float)Math.Sqrt(displayPointDistSqr);
|
||||
float alpha = pingStrength * Rand.Range(1.5f, 2.0f);
|
||||
@@ -1360,8 +1454,8 @@ namespace Barotrauma.Items.Components
|
||||
int minDist = (int)(200 / zoom);
|
||||
sonarBlips.RemoveAll(b => b.FadeTimer < fadeTimer && Math.Abs(pos.X - b.Position.X) < minDist && Math.Abs(pos.Y - b.Position.Y) < minDist);
|
||||
|
||||
var blip = new SonarBlip(pos, fadeTimer, 1.0f + ((displayPointDist + z) / DisplayRadius));
|
||||
if (!passive && !CheckBlipVisibility(blip, transducerPos)) continue;
|
||||
var blip = new SonarBlip(pos, fadeTimer, 1.0f + ((displayPointDist + z) / DisplayRadius), blipType);
|
||||
if (!passive && !CheckBlipVisibility(blip, transducerPos)) { continue; }
|
||||
|
||||
sonarBlips.Add(blip);
|
||||
zStep += 0.5f / zoom;
|
||||
@@ -1375,7 +1469,7 @@ namespace Barotrauma.Items.Components
|
||||
alpha -= 0.1f;
|
||||
}
|
||||
|
||||
if (alpha < 0) break;
|
||||
if (alpha < 0) { break; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1404,6 +1498,30 @@ namespace Barotrauma.Items.Components
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Based largely on existing CheckBlipVisibility() code
|
||||
/// </summary>
|
||||
private bool CheckResourceMarkerVisibility(Vector2 resourcePos, Vector2 transducerPos)
|
||||
{
|
||||
var distSquared = Vector2.DistanceSquared(transducerPos, resourcePos);
|
||||
if (distSquared > Range * Range)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (currentPingIndex != -1 && activePings[currentPingIndex].IsDirectional)
|
||||
{
|
||||
var pos = (resourcePos - transducerPos) * displayScale * zoom;
|
||||
pos.Y = -pos.Y;
|
||||
var length = pos.Length();
|
||||
var dir = pos / length;
|
||||
if (Vector2.Dot(activePings[currentPingIndex].Direction, dir) < DirectionalPingDotProduct)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void DrawBlip(SpriteBatch spriteBatch, SonarBlip blip, Vector2 transducerPos, Vector2 center, float strength, float blipScale)
|
||||
{
|
||||
strength = MathHelper.Clamp(strength, 0.0f, 1.0f);
|
||||
@@ -1524,13 +1642,14 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(iconIdentifier) || !targetIcons.ContainsKey(iconIdentifier))
|
||||
if (iconIdentifier == null || !targetIcons.ContainsKey(iconIdentifier))
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle((int)markerPos.X - 3, (int)markerPos.Y - 3, 6, 6), markerColor, thickness: 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
targetIcons[iconIdentifier].Draw(spriteBatch, markerPos);
|
||||
var iconInfo = targetIcons[iconIdentifier];
|
||||
iconInfo.Item1.Draw(spriteBatch, markerPos, iconInfo.Item2);
|
||||
}
|
||||
|
||||
if (alpha <= 0.0f) { return; }
|
||||
@@ -1561,9 +1680,9 @@ namespace Barotrauma.Items.Components
|
||||
screenBackground?.Remove();
|
||||
lineSprite?.Remove();
|
||||
|
||||
foreach (Sprite sprite in targetIcons.Values)
|
||||
foreach (var t in targetIcons.Values)
|
||||
{
|
||||
sprite.Remove();
|
||||
t.Item1.Remove();
|
||||
}
|
||||
targetIcons.Clear();
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private GUIComponent steerArea;
|
||||
|
||||
private GUITextBlock pressureWarningText;
|
||||
private GUITextBlock pressureWarningText, iceSpireWarningText;
|
||||
|
||||
private GUITextBlock tipContainer;
|
||||
|
||||
@@ -112,7 +112,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
protected override void CreateGUI()
|
||||
{
|
||||
controlContainer = new GUIFrame(new RectTransform(new Vector2(Sonar.controlBoxSize.X, 1 - Sonar.controlBoxSize.Y * 2), GuiFrame.RectTransform, Anchor.CenterLeft), "ItemUI");
|
||||
controlContainer = new GUIFrame(new RectTransform(new Vector2(Sonar.controlBoxSize.X, 1 - Sonar.controlBoxSize.Y * 2), GuiFrame.RectTransform, Anchor.CenterRight), "ItemUI");
|
||||
var paddedControlContainer = new GUIFrame(new RectTransform(controlContainer.Rect.Size - GUIStyle.ItemFrameMargin, controlContainer.RectTransform, Anchor.Center)
|
||||
{
|
||||
AbsoluteOffset = GUIStyle.ItemFrameOffset
|
||||
@@ -265,7 +265,7 @@ namespace Barotrauma.Items.Components
|
||||
levelStartSelected ? Destination.LevelStart : Destination.LevelEnd);
|
||||
|
||||
// Status ->
|
||||
statusContainer = new GUIFrame(new RectTransform(Sonar.controlBoxSize, GuiFrame.RectTransform, Anchor.BottomLeft)
|
||||
statusContainer = new GUIFrame(new RectTransform(Sonar.controlBoxSize, GuiFrame.RectTransform, Anchor.BottomRight)
|
||||
{
|
||||
RelativeOffset = Sonar.controlBoxOffset
|
||||
}, "ItemUI");
|
||||
@@ -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;
|
||||
@@ -339,9 +340,9 @@ namespace Barotrauma.Items.Components
|
||||
//docking interface ----------------------------------------------------
|
||||
float dockingButtonSize = 1.1f;
|
||||
float elementScale = 0.6f;
|
||||
dockingContainer = new GUIFrame(new RectTransform(Sonar.controlBoxSize, GuiFrame.RectTransform, Anchor.BottomLeft, scaleBasis: ScaleBasis.Smallest)
|
||||
dockingContainer = new GUIFrame(new RectTransform(Sonar.controlBoxSize, GuiFrame.RectTransform, Anchor.BottomRight, scaleBasis: ScaleBasis.Smallest)
|
||||
{
|
||||
RelativeOffset = new Vector2(Sonar.controlBoxOffset.X + 0.05f, Sonar.controlBoxOffset.Y)
|
||||
RelativeOffset = new Vector2(Sonar.controlBoxOffset.X + 0.05f, -0.05f)
|
||||
}, style: null);
|
||||
|
||||
dockText = TextManager.Get("label.navterminaldock", fallBackTag: "captain.dock");
|
||||
@@ -436,12 +437,17 @@ namespace Barotrauma.Items.Components
|
||||
};
|
||||
|
||||
// Sonar area
|
||||
steerArea = new GUICustomComponent(new RectTransform(Sonar.GUISizeCalculation, GuiFrame.RectTransform, Anchor.CenterRight, scaleBasis: ScaleBasis.Smallest),
|
||||
steerArea = new GUICustomComponent(new RectTransform(Sonar.GUISizeCalculation, GuiFrame.RectTransform, Anchor.CenterLeft, scaleBasis: ScaleBasis.Smallest),
|
||||
(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;
|
||||
|
||||
@@ -66,7 +66,11 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
foreach (ParticleEmitter particleEmitter in particleEmitters)
|
||||
{
|
||||
float particleAngle = item.body.Rotation + MathHelper.ToRadians(BarrelRotation) + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi);
|
||||
float particleAngle = MathHelper.ToRadians(BarrelRotation);
|
||||
if (item.body != null)
|
||||
{
|
||||
particleAngle += item.body.Rotation + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi);
|
||||
}
|
||||
particleEmitter.Emit(
|
||||
deltaTime, ConvertUnits.ToDisplayUnits(raystart),
|
||||
item.CurrentHull, particleAngle, particleEmitter.Prefab.CopyEntityAngle ? -particleAngle : 0);
|
||||
@@ -109,25 +113,28 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
partial void FixItemProjSpecific(Character user, float deltaTime, Item targetItem)
|
||||
partial void FixItemProjSpecific(Character user, float deltaTime, Item targetItem, bool showProgressBar)
|
||||
{
|
||||
float progressBarState = targetItem.ConditionPercentage / 100.0f;
|
||||
if (!MathUtils.NearlyEqual(progressBarState, prevProgressBarState) || prevProgressBarTarget != targetItem)
|
||||
if (showProgressBar)
|
||||
{
|
||||
var door = targetItem.GetComponent<Door>();
|
||||
if (door == null || door.Stuck <= 0)
|
||||
float progressBarState = targetItem.ConditionPercentage / 100.0f;
|
||||
if (!MathUtils.NearlyEqual(progressBarState, prevProgressBarState) || prevProgressBarTarget != targetItem)
|
||||
{
|
||||
Vector2 progressBarPos = targetItem.DrawPosition;
|
||||
var progressBar = user.UpdateHUDProgressBar(
|
||||
targetItem,
|
||||
progressBarPos,
|
||||
progressBarState,
|
||||
GUI.Style.Red, GUI.Style.Green,
|
||||
progressBarState < prevProgressBarState ? "progressbar.cutting" : "");
|
||||
if (progressBar != null) { progressBar.Size = new Vector2(60.0f, 20.0f); }
|
||||
var door = targetItem.GetComponent<Door>();
|
||||
if (door == null || door.Stuck <= 0)
|
||||
{
|
||||
Vector2 progressBarPos = targetItem.DrawPosition;
|
||||
var progressBar = user?.UpdateHUDProgressBar(
|
||||
targetItem,
|
||||
progressBarPos,
|
||||
progressBarState,
|
||||
GUI.Style.Red, GUI.Style.Green,
|
||||
progressBarState < prevProgressBarState ? "progressbar.cutting" : "");
|
||||
if (progressBar != null) { progressBar.Size = new Vector2(60.0f, 20.0f); }
|
||||
}
|
||||
prevProgressBarState = progressBarState;
|
||||
prevProgressBarTarget = targetItem;
|
||||
}
|
||||
prevProgressBarState = progressBarState;
|
||||
prevProgressBarTarget = targetItem;
|
||||
}
|
||||
|
||||
Vector2 particlePos = ConvertUnits.ToDisplayUnits(pickedPosition);
|
||||
|
||||
@@ -48,18 +48,14 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
Wire equippedWire = null;
|
||||
|
||||
bool allowRewiring = GameMain.NetworkMember?.ServerSettings == null || GameMain.NetworkMember.ServerSettings.AllowRewiring;
|
||||
bool allowRewiring = GameMain.NetworkMember?.ServerSettings == null || GameMain.NetworkMember.ServerSettings.AllowRewiring || panel.AlwaysAllowRewiring;
|
||||
if (allowRewiring && (!panel.Locked || Screen.Selected == GameMain.SubEditorScreen))
|
||||
{
|
||||
//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; }
|
||||
@@ -380,7 +381,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
ConnectionPanel.HighlightedWire = wire;
|
||||
|
||||
bool allowRewiring = GameMain.NetworkMember?.ServerSettings == null || GameMain.NetworkMember.ServerSettings.AllowRewiring;
|
||||
bool allowRewiring = GameMain.NetworkMember?.ServerSettings == null || GameMain.NetworkMember.ServerSettings.AllowRewiring || panel.AlwaysAllowRewiring;
|
||||
if (allowRewiring && (!wire.Locked && !panel.Locked || Screen.Selected == GameMain.SubEditorScreen))
|
||||
{
|
||||
//start dragging the wire
|
||||
|
||||
@@ -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,41 +36,70 @@ 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)
|
||||
{
|
||||
RelativeSpacing = 0.02f,
|
||||
UserData = ciElement
|
||||
};
|
||||
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")
|
||||
var layoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, elementSize), uiElementContainer.RectTransform), isHorizontal: true)
|
||||
{
|
||||
OverflowClip = true,
|
||||
RelativeSpacing = 0.02f,
|
||||
UserData = ciElement
|
||||
};
|
||||
//reset size restrictions set by the Style to make sure the elements can fit the interface
|
||||
textBox.RectTransform.MinSize = textBox.Frame.RectTransform.MinSize = new Point(0, 0);
|
||||
textBox.RectTransform.MaxSize = textBox.Frame.RectTransform.MaxSize = new Point(int.MaxValue, int.MaxValue);
|
||||
textBox.OnDeselected += (tb, key) =>
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), layoutGroup.RectTransform),
|
||||
TextManager.Get(ciElement.Label, returnNull: true) ?? ciElement.Label);
|
||||
if (!ciElement.IsIntegerInput)
|
||||
{
|
||||
if (GameMain.Client == null)
|
||||
var textBox = new GUITextBox(new RectTransform(new Vector2(0.5f, 1.0f), layoutGroup.RectTransform), ciElement.Signal, style: "GUITextBoxNoIcon")
|
||||
{
|
||||
TextChanged(tb.UserData as CustomInterfaceElement, textBox.Text);
|
||||
}
|
||||
else
|
||||
OverflowClip = true,
|
||||
UserData = ciElement
|
||||
};
|
||||
//reset size restrictions set by the Style to make sure the elements can fit the interface
|
||||
textBox.RectTransform.MinSize = textBox.Frame.RectTransform.MinSize = new Point(0, 0);
|
||||
textBox.RectTransform.MaxSize = textBox.Frame.RectTransform.MaxSize = new Point(int.MaxValue, int.MaxValue);
|
||||
textBox.OnDeselected += (tb, key) =>
|
||||
{
|
||||
item.CreateClientEvent(this);
|
||||
}
|
||||
};
|
||||
if (GameMain.Client == null)
|
||||
{
|
||||
TextChanged(tb.UserData as CustomInterfaceElement, textBox.Text);
|
||||
}
|
||||
else
|
||||
{
|
||||
item.CreateClientEvent(this);
|
||||
}
|
||||
};
|
||||
|
||||
textBox.OnEnterPressed += (tb, text) =>
|
||||
textBox.OnEnterPressed += (tb, text) =>
|
||||
{
|
||||
tb.Deselect();
|
||||
return true;
|
||||
};
|
||||
uiElements.Add(textBox);
|
||||
}
|
||||
else
|
||||
{
|
||||
tb.Deselect();
|
||||
return true;
|
||||
};
|
||||
uiElements.Add(textBox);
|
||||
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)
|
||||
{
|
||||
@@ -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,36 +231,29 @@ 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)
|
||||
{
|
||||
if (e.SerializableProperties.ContainsKey(customInterfaceElementList[i].PropertyName))
|
||||
{
|
||||
textBox.Text = e.SerializableProperties[customInterfaceElementList[i].PropertyName].GetValue(e) as string;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string CreateLabelText(int elementIndex)
|
||||
{
|
||||
return string.IsNullOrWhiteSpace(customInterfaceElementList[elementIndex].Label) ?
|
||||
TextManager.GetWithVariable("connection.signaloutx", "[num]", (elementIndex + 1).ToString()) :
|
||||
customInterfaceElementList[elementIndex].Label;
|
||||
}
|
||||
|
||||
uiElementContainer.Recalculate();
|
||||
var textBlocks = new List<GUITextBlock>();
|
||||
foreach (GUIComponent element in uiElementContainer.Children)
|
||||
@@ -258,14 +279,40 @@ 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)
|
||||
{
|
||||
msg.Write(((GUITextBox)uiElements[i]).Text);
|
||||
if (!customInterfaceElementList[i].IsIntegerInput)
|
||||
{
|
||||
msg.Write(((GUITextBox)uiElements[i]).Text);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.Write(((GUINumberInput)uiElements[i]).IntValue.ToString());
|
||||
}
|
||||
}
|
||||
else if (customInterfaceElementList[i].ContinuousSignal)
|
||||
{
|
||||
@@ -282,9 +329,17 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
for (int i = 0; i < customInterfaceElementList.Count; i++)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(customInterfaceElementList[i].PropertyName))
|
||||
if (customInterfaceElementList[i].HasPropertyName)
|
||||
{
|
||||
TextChanged(customInterfaceElementList[i], msg.ReadString());
|
||||
if (!customInterfaceElementList[i].IsIntegerInput)
|
||||
{
|
||||
TextChanged(customInterfaceElementList[i], msg.ReadString());
|
||||
}
|
||||
else
|
||||
{
|
||||
int.TryParse(msg.ReadString(), out int value);
|
||||
ValueChanged(customInterfaceElementList[i], value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -300,6 +355,8 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UpdateSignalsProjSpecific();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,9 +117,9 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (defaultWireSprite == null)
|
||||
{
|
||||
defaultWireSprite = new Sprite("Content/Items/wireHorizontal.png", new Vector2(0.5f, 0.5f))
|
||||
defaultWireSprite = new Sprite("Content/Items/Electricity/signalcomp.png", new Rectangle(970, 47, 14, 16), new Vector2(0.5f, 0.5f))
|
||||
{
|
||||
Depth = 0.85f
|
||||
Depth = 0.855f
|
||||
};
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ namespace Barotrauma.Items.Components
|
||||
drawOffset = sub.DrawPosition + sub.HiddenSubPosition;
|
||||
}
|
||||
|
||||
float depth = item.IsSelected ? 0.0f : SubEditorScreen.IsWiringMode() ? 0.02f : wireSprite.Depth + ((item.ID % 100) * 0.00001f);
|
||||
float depth = item.IsSelected ? 0.0f : SubEditorScreen.IsWiringMode() ? 0.02f : wireSprite.Depth + (item.ID % 100) * 0.000001f;// item.GetDrawDepth(wireSprite.Depth, wireSprite);
|
||||
|
||||
if (item.IsHighlighted)
|
||||
{
|
||||
@@ -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,
|
||||
@@ -286,10 +289,8 @@ namespace Barotrauma.Items.Components
|
||||
public static void UpdateEditing(List<Wire> wires)
|
||||
{
|
||||
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,20 +148,20 @@ namespace Barotrauma.Items.Components
|
||||
List<string> texts = new List<string>();
|
||||
List<Color> textColors = new List<Color>();
|
||||
|
||||
if (target.Info != null)
|
||||
{
|
||||
texts.Add(target.Name);
|
||||
textColors.Add(GUI.Style.TextColor);
|
||||
}
|
||||
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);
|
||||
texts.Add(
|
||||
target.CauseOfDeath.Affliction?.CauseOfDeathDescription ??
|
||||
TextManager.AddPunctuation(':', TextManager.Get("CauseOfDeath"), TextManager.Get("CauseOfDeath." + target.CauseOfDeath.Type.ToString())));
|
||||
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
|
||||
{
|
||||
@@ -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,7 +196,7 @@ namespace Barotrauma.Items.Components
|
||||
texts.Add(TextManager.Get("Stunned"));
|
||||
textColors.Add(GUI.Style.Orange);
|
||||
}
|
||||
|
||||
|
||||
int oxygenTextIndex = MathHelper.Clamp((int)Math.Floor((1.0f - (target.Oxygen / 100.0f)) * OxygenTexts.Length), 0, OxygenTexts.Length - 1);
|
||||
texts.Add(OxygenTexts[oxygenTextIndex]);
|
||||
textColors.Add(Color.Lerp(GUI.Style.Red, GUI.Style.Green, target.Oxygen / 100.0f));
|
||||
@@ -210,7 +225,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
foreach (AfflictionPrefab affliction in combinedAfflictionStrengths.Keys)
|
||||
{
|
||||
texts.Add(TextManager.AddPunctuation(':', affliction.Name, ((int)combinedAfflictionStrengths[affliction]).ToString() + " %"));
|
||||
texts.Add(TextManager.AddPunctuation(':', affliction.Name, Math.Max(((int)combinedAfflictionStrengths[affliction]), 1).ToString() + " %"));
|
||||
textColors.Add(Color.Lerp(GUI.Style.Orange, GUI.Style.Red, combinedAfflictionStrengths[affliction] / affliction.MaxStrength));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
@@ -247,7 +247,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, bool editing = false, float itemDepth = -1)
|
||||
{
|
||||
if (!MathUtils.NearlyEqual(item.Rotation, prevBaseRotation))
|
||||
if (!MathUtils.NearlyEqual(item.Rotation, prevBaseRotation) || !MathUtils.NearlyEqual(item.Scale, prevScale))
|
||||
{
|
||||
UpdateTransformedBarrelPos();
|
||||
}
|
||||
@@ -290,9 +290,10 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
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);
|
||||
|
||||
const float coneRadius = 300.0f;
|
||||
@@ -300,7 +301,11 @@ namespace Barotrauma.Items.Components
|
||||
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);
|
||||
}
|
||||
@@ -309,12 +314,15 @@ namespace Barotrauma.Items.Components
|
||||
spriteBatch.DrawSector(drawPos, circleRadius, radians, (int)Math.Abs(90 * radians), GUI.Style.Green, offset: minRotation, thickness: lineThickness);
|
||||
}
|
||||
|
||||
Widget minRotationWidget = GetWidget("minrotation", spriteBatch, size: 10, initMethod: (widget) =>
|
||||
int baseWidgetScale = GUI.IntScale(16);
|
||||
int widgetSize = (int) (Math.Max(baseWidgetScale, baseWidgetScale / Screen.Selected.Cam.Zoom));
|
||||
float widgetThickness = Math.Max(1f, lineThickness);
|
||||
Widget minRotationWidget = GetWidget("minrotation", spriteBatch, size: widgetSize, thickness: widgetThickness, initMethod: (widget) =>
|
||||
{
|
||||
widget.Selected += () =>
|
||||
{
|
||||
oldRotation = RotationLimits;
|
||||
};
|
||||
{
|
||||
oldRotation = RotationLimits;
|
||||
};
|
||||
widget.MouseDown += () =>
|
||||
{
|
||||
widget.color = GUI.Style.Green;
|
||||
@@ -324,6 +332,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
widget.color = Color.Yellow;
|
||||
item.CreateEditingHUD();
|
||||
RotationLimits = RotationLimits;
|
||||
if (SubEditorScreen.IsSubEditor())
|
||||
{
|
||||
SubEditorScreen.StoreCommand(new PropertyCommand(this, "RotationLimits", RotationLimits, oldRotation));
|
||||
@@ -332,13 +341,7 @@ namespace Barotrauma.Items.Components
|
||||
widget.MouseHeld += (deltaTime) =>
|
||||
{
|
||||
minRotation = GetRotationAngle(GetDrawPos());
|
||||
if (minRotation > maxRotation)
|
||||
{
|
||||
float temp = minRotation;
|
||||
minRotation = maxRotation;
|
||||
maxRotation = temp;
|
||||
}
|
||||
RotationLimits = RotationLimits;
|
||||
UpdateBarrel();
|
||||
MapEntity.DisableSelect = true;
|
||||
};
|
||||
widget.PreUpdate += (deltaTime) =>
|
||||
@@ -359,7 +362,7 @@ namespace Barotrauma.Items.Components
|
||||
};
|
||||
});
|
||||
|
||||
Widget maxRotationWidget = GetWidget("maxrotation", spriteBatch, size: 10, initMethod: (widget) =>
|
||||
Widget maxRotationWidget = GetWidget("maxrotation", spriteBatch, size: widgetSize, thickness: widgetThickness, initMethod: (widget) =>
|
||||
{
|
||||
widget.Selected += () =>
|
||||
{
|
||||
@@ -368,12 +371,13 @@ namespace Barotrauma.Items.Components
|
||||
widget.MouseDown += () =>
|
||||
{
|
||||
widget.color = GUI.Style.Green;
|
||||
prevAngle = minRotation;
|
||||
prevAngle = maxRotation;
|
||||
};
|
||||
widget.Deselected += () =>
|
||||
{
|
||||
widget.color = Color.Yellow;
|
||||
item.CreateEditingHUD();
|
||||
RotationLimits = RotationLimits;
|
||||
if (SubEditorScreen.IsSubEditor())
|
||||
{
|
||||
SubEditorScreen.StoreCommand(new PropertyCommand(this, "RotationLimits", RotationLimits, oldRotation));
|
||||
@@ -382,13 +386,7 @@ namespace Barotrauma.Items.Components
|
||||
widget.MouseHeld += (deltaTime) =>
|
||||
{
|
||||
maxRotation = GetRotationAngle(GetDrawPos());
|
||||
if (minRotation > maxRotation)
|
||||
{
|
||||
float temp = minRotation;
|
||||
minRotation = maxRotation;
|
||||
maxRotation = temp;
|
||||
}
|
||||
RotationLimits = RotationLimits;
|
||||
UpdateBarrel();
|
||||
MapEntity.DisableSelect = true;
|
||||
};
|
||||
widget.PreUpdate += (deltaTime) =>
|
||||
@@ -418,22 +416,32 @@ namespace Barotrauma.Items.Components
|
||||
drawPos.Y = -drawPos.Y;
|
||||
return drawPos;
|
||||
}
|
||||
|
||||
void UpdateBarrel()
|
||||
{
|
||||
rotation = (minRotation + maxRotation) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
private Widget GetWidget(string id, SpriteBatch spriteBatch, int size = 5, Action<Widget> initMethod = null)
|
||||
private Widget GetWidget(string id, SpriteBatch spriteBatch, int size = 5, float thickness = 1f, Action<Widget> initMethod = null)
|
||||
{
|
||||
Vector2 offset = new Vector2(size / 2 + 5, -10);
|
||||
if (!widgets.TryGetValue(id, out Widget widget))
|
||||
{
|
||||
widget = new Widget(id, size, Widget.Shape.Rectangle)
|
||||
{
|
||||
color = Color.Yellow,
|
||||
tooltipOffset = new Vector2(size / 2 + 5, -10),
|
||||
tooltipOffset = offset,
|
||||
inputAreaMargin = 20,
|
||||
RequireMouseOn = false
|
||||
};
|
||||
widgets.Add(id, widget);
|
||||
initMethod?.Invoke(widget);
|
||||
}
|
||||
|
||||
widget.size = size;
|
||||
widget.tooltipOffset = offset;
|
||||
widget.thickness = thickness;
|
||||
return widget;
|
||||
}
|
||||
|
||||
@@ -488,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 =
|
||||
@@ -536,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)
|
||||
|
||||
@@ -165,7 +165,14 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (isLocked)
|
||||
{
|
||||
Lock(isNetworkMessage: true, forcePosition: true);
|
||||
if (DockingTarget.joint != null)
|
||||
{
|
||||
DockingTarget.Lock(isNetworkMessage: true, forcePosition: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Lock(isNetworkMessage: true, forcePosition: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
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>();
|
||||
|
||||
@@ -85,7 +87,7 @@ namespace Barotrauma
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!GameMain.SubEditorScreen.ShowThalamus && prefab.Category.HasFlag(MapEntityCategory.Thalamus))
|
||||
if (GameMain.SubEditorScreen.IsSubcategoryHidden(prefab.Subcategory))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -93,18 +95,20 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public float GetDrawDepth()
|
||||
{
|
||||
return GetDrawDepth(SpriteDepth, Sprite);
|
||||
}
|
||||
|
||||
public Color GetSpriteColor()
|
||||
{
|
||||
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;
|
||||
break;
|
||||
}
|
||||
color = item.ContainerColor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return color;
|
||||
@@ -115,13 +119,10 @@ 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;
|
||||
break;
|
||||
}
|
||||
color = item.ContainerColor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return color;
|
||||
@@ -130,6 +131,7 @@ namespace Barotrauma
|
||||
partial void SetActiveSpriteProjSpecific()
|
||||
{
|
||||
activeSprite = prefab.sprite;
|
||||
activeContainedSprite = null;
|
||||
Holdable holdable = GetComponent<Holdable>();
|
||||
if (holdable != null && holdable.Attached)
|
||||
{
|
||||
@@ -137,7 +139,9 @@ namespace Barotrauma
|
||||
{
|
||||
if (containedSprite.UseWhenAttached)
|
||||
{
|
||||
activeSprite = containedSprite.Sprite;
|
||||
activeContainedSprite = containedSprite;
|
||||
activeSprite = containedSprite.Sprite;
|
||||
UpdateSpriteStates(0.0f);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -149,7 +153,9 @@ namespace Barotrauma
|
||||
{
|
||||
if (containedSprite.MatchesContainer(Container))
|
||||
{
|
||||
activeContainedSprite = containedSprite;
|
||||
activeSprite = containedSprite.Sprite;
|
||||
UpdateSpriteStates(0.0f);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -182,6 +188,7 @@ namespace Barotrauma
|
||||
decorativeSprite.Sprite.EnsureLazyLoaded();
|
||||
spriteAnimState.Add(decorativeSprite, new DecorativeSprite.State());
|
||||
}
|
||||
SetActiveSprite();
|
||||
UpdateSpriteStates(0.0f);
|
||||
}
|
||||
|
||||
@@ -235,12 +242,20 @@ 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);
|
||||
|
||||
bool isWiringMode = editing && SubEditorScreen.IsWiringMode() && !isWire && parentInventory == null;
|
||||
bool isWiringMode = editing && SubEditorScreen.TransparentWiringMode && SubEditorScreen.IsWiringMode() && !isWire && parentInventory == null;
|
||||
bool renderTransparent = isWiringMode && GetComponent<ConnectionPanel>() == null;
|
||||
if (renderTransparent) { color *= 0.15f; }
|
||||
|
||||
@@ -300,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,
|
||||
@@ -323,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);
|
||||
@@ -331,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));
|
||||
}
|
||||
}
|
||||
@@ -348,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)
|
||||
@@ -360,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)
|
||||
@@ -379,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);
|
||||
@@ -388,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));
|
||||
}
|
||||
}
|
||||
@@ -400,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));
|
||||
}
|
||||
|
||||
@@ -500,12 +515,39 @@ namespace Barotrauma
|
||||
|
||||
public void UpdateSpriteStates(float deltaTime)
|
||||
{
|
||||
DecorativeSprite.UpdateSpriteStates(Prefab.DecorativeSpriteGroups, spriteAnimState, ID, deltaTime, ConditionalMatches);
|
||||
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);
|
||||
|
||||
var upgradeSprites = GetUpgradeSprites(upgrade);
|
||||
foreach (var decorativeSprite in upgradeSprites)
|
||||
{
|
||||
var spriteState = spriteAnimState[decorativeSprite];
|
||||
@@ -1030,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; }
|
||||
@@ -1254,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;
|
||||
@@ -1262,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 ||
|
||||
@@ -1485,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; }
|
||||
@@ -1516,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);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.Items.Components;
|
||||
using Barotrauma.Networking;
|
||||
using Barotrauma.Particles;
|
||||
using Barotrauma.Sounds;
|
||||
using FarseerPhysics;
|
||||
using FarseerPhysics.Dynamics;
|
||||
using Microsoft.Xna.Framework;
|
||||
@@ -33,12 +35,19 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
[Serialize(defaultValue: 0f, isSaveable: false)]
|
||||
public float MaxVelocity { get; set; }
|
||||
|
||||
[Serialize(defaultValue: "255,255,255,255", isSaveable: false)]
|
||||
public Color ColorMultiplier { get; set; }
|
||||
|
||||
private float RandRotation() => Rand.Range(MinRotation, MaxRotation);
|
||||
private float RandVelocity() => Rand.Range(MinVelocity, MaxVelocity);
|
||||
|
||||
public void Emit(Vector2 pos)
|
||||
{
|
||||
GameMain.ParticleManager.CreateParticle(Identifier, pos, RandRotation(), RandVelocity());
|
||||
Particle particle = GameMain.ParticleManager.CreateParticle(Identifier, pos, RandRotation(), RandVelocity());
|
||||
if (particle != null)
|
||||
{
|
||||
particle.ColorMultiplier = ColorMultiplier.ToVector4();
|
||||
}
|
||||
}
|
||||
|
||||
public DamageParticle(XElement element)
|
||||
@@ -54,6 +63,9 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
public readonly List<Sprite> LeafSprites = new List<Sprite>(), DamagedLeafSprites = new List<Sprite>();
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -97,6 +109,9 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
case "damageparticle":
|
||||
DamageParticles.Add(new DamageParticle(subElement));
|
||||
break;
|
||||
case "deathparticle":
|
||||
DeathParticles.Add(new DamageParticle(subElement));
|
||||
break;
|
||||
case "targets":
|
||||
LoadTargets(subElement);
|
||||
break;
|
||||
@@ -112,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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,11 +144,22 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly Color DarkColor = new Color(25, 25, 25);
|
||||
private void CreateDeathParticle(BallastFloraBranch branch)
|
||||
{
|
||||
Vector2 pos = GetWorldPosition() + branch.Position;
|
||||
int amount = (int)Math.Clamp(branch.MaxHealth / 10f, 1, 10);
|
||||
for (int i = 0; i < amount; i++)
|
||||
{
|
||||
foreach (DamageParticle particle in DeathParticles)
|
||||
{
|
||||
particle.Emit(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
const float zStep = 0.00001f;
|
||||
const float zStep = 0.000001f;
|
||||
float leafDepth = zStep;
|
||||
float flowerDepth = zStep;
|
||||
|
||||
@@ -217,12 +243,12 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
|
||||
if (HasBrokenThrough)
|
||||
{
|
||||
if (branchAtlas != null)
|
||||
if (branchAtlas != null && branchAtlas.Loaded)
|
||||
{
|
||||
spriteBatch.Draw(branchAtlas.Texture, pos + branch.offset, branchSprite.SourceRect, branchColor, 0f, branchSprite.AbsoluteOrigin, BaseBranchScale * branch.VineStep, SpriteEffects.None, layer2);
|
||||
}
|
||||
|
||||
if (decayAtlas != null && isDamaged)
|
||||
if (decayAtlas != null && isDamaged && decayAtlas.Loaded)
|
||||
{
|
||||
spriteBatch.Draw(decayAtlas.Texture, pos + branch.offset, branchSprite.SourceRect, branch.HealthColor, 0f, branchSprite.AbsoluteOrigin, BaseBranchScale * branch.VineStep, SpriteEffects.None, layer2 - zStep);
|
||||
}
|
||||
@@ -242,6 +268,10 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
DamagedFlowerSprites[variant].Draw(spriteBatch, pos, branch.HealthColor, flowerSprite.Origin, scale: flowerScale, rotate: branch.FlowerConfig.Rotation, depth: layer1 - flowerDepth - zStep);
|
||||
}
|
||||
flowerDepth -= zStep;
|
||||
if (flowerDepth > 0.01f)
|
||||
{
|
||||
flowerDepth = zStep;
|
||||
}
|
||||
}
|
||||
|
||||
if (branch.LeafConfig.Variant >= 0 && HasBrokenThrough)
|
||||
@@ -254,6 +284,10 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
DamagedLeafSprites[variant].Draw(spriteBatch, pos, branch.HealthColor, leafSprite.Origin, scale: BaseLeafScale * branch.LeafConfig.Scale * branch.FlowerStep, rotate: branch.LeafConfig.Rotation, depth: layer3 + leafDepth - zStep);
|
||||
}
|
||||
leafDepth += zStep;
|
||||
if (leafDepth > 0.01f)
|
||||
{
|
||||
flowerDepth = zStep;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -264,25 +298,42 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
switch (header)
|
||||
{
|
||||
case NetworkHeader.Infect:
|
||||
int infectBranch = -1;
|
||||
ushort itemId = msg.ReadUInt16();
|
||||
bool infect = msg.ReadBoolean();
|
||||
if (Entity.FindEntityByID(itemId) is Item item)
|
||||
if (infect)
|
||||
{
|
||||
infectBranch = msg.ReadInt32();
|
||||
}
|
||||
|
||||
Entity? entity = Entity.FindEntityByID(itemId);
|
||||
if (entity is Item item)
|
||||
{
|
||||
if (infect)
|
||||
{
|
||||
ClaimTarget(item, null);
|
||||
ClaimTarget(item, Branches.FirstOrDefault(b => b.ID == infectBranch));
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveClaim(itemId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.AddWarning($"Received Infect.{infect} Network Header with invalid item ID: {itemId}, which belongs to {entity?.ToString() ?? "null!"}");
|
||||
}
|
||||
break;
|
||||
case NetworkHeader.BranchCreate:
|
||||
int parentId = msg.ReadInt32();
|
||||
BallastFloraBranch branch = ReadBranch(msg);
|
||||
BallastFloraBranch? parent = Branches.FirstOrDefault(b => b.ID == parentId);
|
||||
|
||||
UpdateConnections(branch, Branches.FirstOrDefault(b => b.ID == parentId));
|
||||
if (parent == null)
|
||||
{
|
||||
DebugConsole.AddWarning($"Received BranchCreate with an invalid parent ID: {parentId}, Maximum ID is {Branches.Max(b => b.ID)}");
|
||||
}
|
||||
|
||||
UpdateConnections(branch, parent);
|
||||
Branches.Add(branch);
|
||||
OnBranchGrowthSuccess(branch);
|
||||
break;
|
||||
@@ -290,7 +341,15 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
|
||||
int removedBranchId = msg.ReadInt32();
|
||||
BallastFloraBranch removedBranch = Branches.FirstOrDefault(b => b.ID == removedBranchId);
|
||||
if (removedBranch != null) { RemoveBranch(removedBranch); }
|
||||
if (removedBranch != null)
|
||||
{
|
||||
RemoveBranch(removedBranch);
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.AddWarning($"Received BranchRemove for a branch that doesn't exist. ID: {removedBranchId}, Maximum ID is {Branches.Max(b => b.ID)}");
|
||||
}
|
||||
|
||||
break;
|
||||
case NetworkHeader.BranchDamage:
|
||||
|
||||
@@ -303,6 +362,10 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
CreateDamageParticle(damagedBranch, damage);
|
||||
damagedBranch.Health = health;
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.AddWarning($"Received BranchDamage for a branch that doesn't exist. ID: {damageBranchId}, Maximum ID is {Branches.Max(b => b.ID)}");
|
||||
}
|
||||
break;
|
||||
case NetworkHeader.Kill:
|
||||
Kill();
|
||||
@@ -326,6 +389,7 @@ namespace Barotrauma.MapCreatures.Behavior
|
||||
return new BallastFloraBranch(this, pos, (VineTileType)type, FoliageConfig.Deserialize(flowerConfig), FoliageConfig.Deserialize(leafConfig))
|
||||
{
|
||||
ID = id,
|
||||
MaxHealth = maxHealth,
|
||||
Sides = (TileSide) sides
|
||||
};
|
||||
}
|
||||
|
||||
@@ -22,47 +22,47 @@ namespace Barotrauma
|
||||
var underwaterExplosion = GameMain.ParticleManager.CreateParticle("underwaterexplosion", worldPosition, Vector2.Zero, 0.0f, hull);
|
||||
if (underwaterExplosion != null)
|
||||
{
|
||||
underwaterExplosion.Size *= MathHelper.Clamp(attack.Range / 150.0f, 0.5f, 10.0f);
|
||||
underwaterExplosion.Size *= MathHelper.Clamp(Attack.Range / 150.0f, 0.5f, 10.0f);
|
||||
underwaterExplosion.StartDelay = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < attack.Range * 0.1f; i++)
|
||||
for (int i = 0; i < Attack.Range * 0.1f; i++)
|
||||
{
|
||||
if (!underwater)
|
||||
{
|
||||
float particleSpeed = Rand.Range(0.0f, 1.0f);
|
||||
particleSpeed = particleSpeed * particleSpeed * attack.Range;
|
||||
particleSpeed = particleSpeed * particleSpeed * Attack.Range;
|
||||
|
||||
if (flames)
|
||||
{
|
||||
float particleScale = MathHelper.Clamp(attack.Range * 0.0025f, 0.5f, 2.0f);
|
||||
float particleScale = MathHelper.Clamp(Attack.Range * 0.0025f, 0.5f, 2.0f);
|
||||
var flameParticle = GameMain.ParticleManager.CreateParticle("explosionfire",
|
||||
ClampParticlePos(worldPosition + Rand.Vector((float)System.Math.Sqrt(Rand.Range(0.0f, attack.Range))), hull),
|
||||
ClampParticlePos(worldPosition + Rand.Vector((float)System.Math.Sqrt(Rand.Range(0.0f, Attack.Range))), hull),
|
||||
Rand.Vector(Rand.Range(0.0f, particleSpeed)), 0.0f, hull);
|
||||
if (flameParticle != null) flameParticle.Size *= particleScale;
|
||||
}
|
||||
if (smoke)
|
||||
{
|
||||
GameMain.ParticleManager.CreateParticle(Rand.Range(0.0f, 1.0f) < 0.5f ? "explosionsmoke" : "smoke",
|
||||
ClampParticlePos(worldPosition + Rand.Vector((float)System.Math.Sqrt(Rand.Range(0.0f, attack.Range))), hull),
|
||||
ClampParticlePos(worldPosition + Rand.Vector((float)System.Math.Sqrt(Rand.Range(0.0f, Attack.Range))), hull),
|
||||
Rand.Vector(Rand.Range(0.0f, particleSpeed)), 0.0f, hull);
|
||||
}
|
||||
}
|
||||
else if (underwaterBubble)
|
||||
{
|
||||
Vector2 bubblePos = Rand.Vector(Rand.Range(0.0f, attack.Range * 0.5f));
|
||||
Vector2 bubblePos = Rand.Vector(Rand.Range(0.0f, Attack.Range * 0.5f));
|
||||
|
||||
GameMain.ParticleManager.CreateParticle("risingbubbles", worldPosition + bubblePos,
|
||||
Vector2.Zero, 0.0f, hull);
|
||||
|
||||
if (i < attack.Range * 0.02f)
|
||||
if (i < Attack.Range * 0.02f)
|
||||
{
|
||||
var underwaterExplosion = GameMain.ParticleManager.CreateParticle("underwaterexplosion", worldPosition + bubblePos,
|
||||
Vector2.Zero, 0.0f, hull);
|
||||
if (underwaterExplosion != null)
|
||||
{
|
||||
underwaterExplosion.Size *= MathHelper.Clamp(attack.Range / 300.0f, 0.5f, 2.0f) * Rand.Range(0.8f, 1.2f);
|
||||
underwaterExplosion.Size *= MathHelper.Clamp(Attack.Range / 300.0f, 0.5f, 2.0f) * Rand.Range(0.8f, 1.2f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace Barotrauma
|
||||
|
||||
if (flash)
|
||||
{
|
||||
float displayRange = flashRange.HasValue ? flashRange.Value : attack.Range;
|
||||
float displayRange = flashRange.HasValue ? flashRange.Value : Attack.Range;
|
||||
if (displayRange < 0.1f) { return; }
|
||||
var light = new LightSource(worldPosition, displayRange, Color.LightYellow, null);
|
||||
CoroutineManager.StartCoroutine(DimLight(light));
|
||||
|
||||
@@ -336,6 +336,7 @@ namespace Barotrauma
|
||||
|
||||
public void DrawSectionColors(SpriteBatch spriteBatch)
|
||||
{
|
||||
if (BackgroundSections == null || BackgroundSections.Count == 0) { return; }
|
||||
Vector2 drawOffset = Submarine == null ? Vector2.Zero : Submarine.DrawPosition;
|
||||
Point sectionSize = BackgroundSections[0].Rect.Size;
|
||||
Vector2 drawPos = drawOffset + new Vector2(rect.Location.X + sectionSize.X / 2, rect.Location.Y - sectionSize.Y / 2);
|
||||
|
||||
@@ -31,11 +31,20 @@ namespace Barotrauma
|
||||
List<VertexPositionTexture> vertices = new List<VertexPositionTexture>();
|
||||
foreach (VoronoiCell cell in cells)
|
||||
{
|
||||
Vector2 minVert = cell.Edges[0].Point1;
|
||||
Vector2 maxVert = cell.Edges[0].Point1;
|
||||
float circumference = 0.0f;
|
||||
foreach (GraphEdge edge in cell.Edges)
|
||||
{
|
||||
circumference += Vector2.Distance(edge.Point1, edge.Point2);
|
||||
minVert = new Vector2(
|
||||
Math.Min(minVert.X, edge.Point1.X),
|
||||
Math.Min(minVert.Y, edge.Point1.Y));
|
||||
maxVert = new Vector2(
|
||||
Math.Max(maxVert.X, edge.Point1.X),
|
||||
Math.Max(maxVert.Y, edge.Point1.Y));
|
||||
}
|
||||
Vector2 center = (minVert + maxVert) / 2;
|
||||
foreach (GraphEdge edge in cell.Edges)
|
||||
{
|
||||
if (!edge.IsSolid) { continue; }
|
||||
@@ -130,8 +139,8 @@ namespace Barotrauma
|
||||
break;
|
||||
}
|
||||
|
||||
float point1UV = MathUtils.WrapAngleTwoPi(MathUtils.VectorToAngle(edge.Point1 - cell.Center));
|
||||
float point2UV = MathUtils.WrapAngleTwoPi(MathUtils.VectorToAngle(edge.Point2 - cell.Center));
|
||||
float point1UV = MathUtils.WrapAngleTwoPi(MathUtils.VectorToAngle(edge.Point1 - center));
|
||||
float point2UV = MathUtils.WrapAngleTwoPi(MathUtils.VectorToAngle(edge.Point2 - center));
|
||||
//handle wrapping around 0/360
|
||||
if (point1UV - point2UV > MathHelper.Pi)
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -3,9 +3,11 @@ using Barotrauma.Networking;
|
||||
using Barotrauma.Particles;
|
||||
using Barotrauma.Sounds;
|
||||
using Barotrauma.SpriteDeformations;
|
||||
using FarseerPhysics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
@@ -72,6 +74,18 @@ namespace Barotrauma
|
||||
private set;
|
||||
}
|
||||
|
||||
public bool VisibleOnSonar
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public float SonarRadius
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
partial void InitProjSpecific()
|
||||
{
|
||||
Sprite?.EnsureLazyLoaded();
|
||||
@@ -135,6 +149,13 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VisibleOnSonar = Prefab.SonarDisruption > 0.0f || Prefab.OverrideProperties.Any(p => p != null && p.SonarDisruption > 0.0f) ||
|
||||
(Triggers != null && Triggers.Any(t => !MathUtils.NearlyEqual(t.Force, Vector2.Zero) && t.ForceMode != LevelTrigger.TriggerForceMode.LimitVelocity || !string.IsNullOrWhiteSpace(t.InfectIdentifier)));
|
||||
if (VisibleOnSonar && Triggers.Any())
|
||||
{
|
||||
SonarRadius = Triggers.Select(t => t.ColliderRadius * 1.5f).Max();
|
||||
}
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
@@ -220,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)
|
||||
{
|
||||
@@ -294,7 +302,7 @@ namespace Barotrauma
|
||||
{
|
||||
GUI.DrawLine(spriteBatch, new Vector2(edge.Point1.X + cell.Translation.X, -(edge.Point1.Y + cell.Translation.Y)),
|
||||
new Vector2(edge.Point2.X + cell.Translation.X, -(edge.Point2.Y + cell.Translation.Y)), edge.NextToCave ? Color.Red : (cell.Body == null ? Color.Cyan * 0.5f : (edge.IsSolid ? Color.White : Color.Gray)),
|
||||
width: edge.NextToCave ? 8 :1);
|
||||
width: edge.NextToCave ? 8 : 1);
|
||||
}
|
||||
|
||||
foreach (Vector2 point in cell.BodyVertices)
|
||||
@@ -314,6 +322,11 @@ namespace Barotrauma
|
||||
}
|
||||
}*/
|
||||
|
||||
foreach (var abyssIsland in level.AbyssIslands)
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch, new Vector2(abyssIsland.Area.X, -abyssIsland.Area.Y - abyssIsland.Area.Height), abyssIsland.Area.Size.ToVector2(), Color.Cyan, thickness: 5);
|
||||
}
|
||||
|
||||
foreach (var ruin in level.Ruins)
|
||||
{
|
||||
ruin.DebugDraw(spriteBatch);
|
||||
@@ -395,20 +408,20 @@ namespace Barotrauma
|
||||
graphicsDevice.SetVertexBuffer(wall.WallBuffer);
|
||||
graphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, (int)Math.Floor(wall.WallBuffer.VertexCount / 3.0f));
|
||||
|
||||
if (destructibleWall.Damage > 0.0f)
|
||||
{
|
||||
wallCenterEffect.Texture = level.GenerationParams.WallSpriteDestroyed.Texture;
|
||||
wallCenterEffect.Alpha = MathHelper.Lerp(0.2f, 1.0f, destructibleWall.Damage / destructibleWall.MaxHealth) * wall.Alpha;
|
||||
wallCenterEffect.CurrentTechnique.Passes[0].Apply();
|
||||
graphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, (int)Math.Floor(wall.WallEdgeBuffer.VertexCount / 3.0f));
|
||||
}
|
||||
|
||||
wallEdgeEffect.Texture = level.GenerationParams.DestructibleWallEdgeSprite?.Texture ?? level.GenerationParams.WallEdgeSprite.Texture;
|
||||
wallEdgeEffect.World = wall.GetTransform() * transformMatrix;
|
||||
wallEdgeEffect.Alpha = wall.Alpha;
|
||||
wallEdgeEffect.CurrentTechnique.Passes[0].Apply();
|
||||
graphicsDevice.SetVertexBuffer(wall.WallEdgeBuffer);
|
||||
graphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, (int)Math.Floor(wall.WallEdgeBuffer.VertexCount / 3.0f));
|
||||
|
||||
if (destructibleWall.Damage <= 0.0f) { continue; }
|
||||
wallEdgeEffect.Texture = level.GenerationParams.WallSpriteDestroyed.Texture;
|
||||
wallEdgeEffect.Alpha = MathHelper.Lerp(0.2f, 1.0f, destructibleWall.Damage / destructibleWall.MaxHealth) * wall.Alpha;
|
||||
wallEdgeEffect.World = wall.GetTransform() * transformMatrix;
|
||||
wallEdgeEffect.CurrentTechnique.Passes[0].Apply();
|
||||
graphicsDevice.SetVertexBuffer(wall.WallEdgeBuffer);
|
||||
graphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, (int)Math.Floor(wall.WallEdgeBuffer.VertexCount / 3.0f));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -132,7 +132,7 @@ namespace Barotrauma.Lights
|
||||
|
||||
public void AddLight(LightSource light)
|
||||
{
|
||||
if (!lights.Contains(light)) lights.Add(light);
|
||||
if (!lights.Contains(light)) { lights.Add(light); }
|
||||
}
|
||||
|
||||
public void RemoveLight(LightSource light)
|
||||
@@ -153,7 +153,7 @@ namespace Barotrauma.Lights
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
foreach (LightSource light in lights)
|
||||
foreach (LightSource light in activeLights)
|
||||
{
|
||||
if (!light.Enabled) { continue; }
|
||||
light.Update(deltaTime);
|
||||
@@ -183,7 +183,7 @@ namespace Barotrauma.Lights
|
||||
foreach (LightSource light in lights)
|
||||
{
|
||||
if (!light.Enabled) { continue; }
|
||||
if ((light.Color.A < 1 || light.Range < 1.0f || light.CurrentBrightness <= 0.0f) && !light.LightSourceParams.OverrideLightSpriteAlpha.HasValue) { continue; }
|
||||
if ((light.Color.A < 1 || light.Range < 1.0f) && !light.LightSourceParams.OverrideLightSpriteAlpha.HasValue) { continue; }
|
||||
if (light.ParentBody != null)
|
||||
{
|
||||
light.Position = light.ParentBody.DrawPosition;
|
||||
@@ -212,7 +212,7 @@ namespace Barotrauma.Lights
|
||||
spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.NonPremultiplied, transformMatrix: spriteBatchTransform);
|
||||
foreach (LightSource light in activeLights)
|
||||
{
|
||||
if (light.IsBackground) { continue; }
|
||||
if (light.IsBackground || light.CurrentBrightness <= 0.0f) { continue; }
|
||||
//draw limb lights at this point, because they were skipped over previously to prevent them from being obstructed
|
||||
if (light.ParentBody?.UserData is Limb limb && !limb.Hide) { light.DrawSprite(spriteBatch, cam); }
|
||||
}
|
||||
@@ -227,7 +227,7 @@ namespace Barotrauma.Lights
|
||||
Level.Loaded?.BackgroundCreatureManager?.DrawLights(spriteBatch, cam);
|
||||
foreach (LightSource light in activeLights)
|
||||
{
|
||||
if (!light.IsBackground) { continue; }
|
||||
if (!light.IsBackground || light.CurrentBrightness <= 0.0f) { continue; }
|
||||
light.DrawSprite(spriteBatch, cam);
|
||||
light.DrawLightVolume(spriteBatch, lightEffect, transform);
|
||||
}
|
||||
@@ -272,7 +272,7 @@ namespace Barotrauma.Lights
|
||||
foreach (LightSource light in activeLights)
|
||||
{
|
||||
//don't draw limb lights at this point, they need to be drawn after lights have been obstructed by characters
|
||||
if (light.IsBackground || light.ParentBody?.UserData is Limb) { continue; }
|
||||
if (light.IsBackground || light.ParentBody?.UserData is Limb || light.CurrentBrightness <= 0.0f) { continue; }
|
||||
light.DrawSprite(spriteBatch, cam);
|
||||
}
|
||||
spriteBatch.End();
|
||||
@@ -337,7 +337,7 @@ namespace Barotrauma.Lights
|
||||
|
||||
foreach (LightSource light in activeLights)
|
||||
{
|
||||
if (light.IsBackground) { continue; }
|
||||
if (light.IsBackground || light.CurrentBrightness <= 0.0f) { continue; }
|
||||
light.DrawLightVolume(spriteBatch, lightEffect, transform);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -470,37 +470,29 @@ namespace Barotrauma.Lights
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
float brightness = 1.0f;
|
||||
if (lightSourceParams.BlinkFrequency > 0.0f)
|
||||
{
|
||||
blinkTimer = (blinkTimer + deltaTime * lightSourceParams.BlinkFrequency) % 1.0f;
|
||||
if (blinkTimer > 0.5f)
|
||||
{
|
||||
CurrentBrightness = 0.0f;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (lightSourceParams.PulseFrequency > 0.0f)
|
||||
if (lightSourceParams.PulseFrequency > 0.0f && lightSourceParams.PulseAmount > 0.0f)
|
||||
{
|
||||
pulseState = (pulseState + deltaTime * lightSourceParams.PulseFrequency) % 1.0f;
|
||||
//oscillate between 0-1
|
||||
brightness *= 1.0f - (float)(Math.Sin(pulseState * MathHelper.TwoPi) + 1.0f) / 2.0f * lightSourceParams.PulseAmount;
|
||||
}
|
||||
|
||||
if (blinkTimer > 0.5f)
|
||||
if (lightSourceParams.Flicker > 0.0f)
|
||||
{
|
||||
CurrentBrightness = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
float flicker = 0.0f;
|
||||
float pulse = 0.0f;
|
||||
if (lightSourceParams.Flicker > 0.0f)
|
||||
{
|
||||
flickerState += deltaTime * lightSourceParams.FlickerSpeed;
|
||||
flickerState %= 255;
|
||||
flicker = PerlinNoise.GetPerlin(flickerState, flickerState * 0.5f) * lightSourceParams.Flicker;
|
||||
}
|
||||
if (lightSourceParams.PulseFrequency > 0.0f && lightSourceParams.PulseAmount > 0.0f)
|
||||
{
|
||||
//oscillate between 0-1
|
||||
pulse = (float)(Math.Sin(pulseState * MathHelper.TwoPi) + 1.0f) / 2.0f * lightSourceParams.PulseAmount;
|
||||
}
|
||||
CurrentBrightness = (1.0f - flicker) * (1.0f - pulse);
|
||||
flickerState += deltaTime * lightSourceParams.FlickerSpeed;
|
||||
flickerState %= 255;
|
||||
brightness *= 1.0f - PerlinNoise.GetPerlin(flickerState, flickerState * 0.5f) * lightSourceParams.Flicker;
|
||||
}
|
||||
CurrentBrightness = brightness;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -63,6 +63,8 @@ namespace Barotrauma
|
||||
private Sprite[,] mapTiles;
|
||||
private bool[,] tileDiscovered;
|
||||
|
||||
private float connectionHighlightState;
|
||||
|
||||
private Pair<Rectangle, string> connectionTooltip;
|
||||
|
||||
#if DEBUG
|
||||
@@ -120,7 +122,6 @@ namespace Barotrauma
|
||||
DrawOffset = -CurrentLocation.MapPosition;
|
||||
}
|
||||
|
||||
|
||||
Vector2 tileSize = generationParams.MapTiles.Values.First().First().size * generationParams.MapTileScale;
|
||||
int tilesX = (int)Math.Ceiling(Width / tileSize.X);
|
||||
int tilesY = (int)Math.Ceiling(Height / tileSize.Y);
|
||||
@@ -222,7 +223,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())
|
||||
{
|
||||
@@ -267,15 +268,37 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
currLocationIndicatorPos = Vector2.Lerp(currLocationIndicatorPos, CurrentDisplayLocation.MapPosition, deltaTime);
|
||||
Vector2 currentPosition = CurrentDisplayLocation.MapPosition;
|
||||
if (Level.Loaded?.Type == LevelData.LevelType.LocationConnection && Level.Loaded.StartLocation != null && Level.Loaded.EndLocation != null)
|
||||
{
|
||||
Vector2 startPos = CurrentDisplayLocation == Level.Loaded.StartLocation ? Level.Loaded.StartLocation.MapPosition : Level.Loaded.EndLocation.MapPosition;
|
||||
int moveDir = CurrentDisplayLocation == Level.Loaded.StartLocation ? 1 : -1;
|
||||
|
||||
Vector2 diff = Level.Loaded.EndLocation.MapPosition - Level.Loaded.StartLocation.MapPosition;
|
||||
currentPosition = startPos +
|
||||
Vector2.Normalize(diff) * Math.Min(100, diff.Length() * 0.2f) * moveDir;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentPosition += Vector2.UnitY * 35;
|
||||
}
|
||||
|
||||
currLocationIndicatorPos = Vector2.Lerp(currLocationIndicatorPos, currentPosition, deltaTime);
|
||||
#if DEBUG
|
||||
if (GameMain.DebugDraw)
|
||||
{
|
||||
if (editor == null) CreateEditor();
|
||||
editor.AddToGUIUpdateList(order: 1);
|
||||
}
|
||||
|
||||
if (PlayerInput.KeyHit(Keys.Space))
|
||||
{
|
||||
Radiation?.OnStep();
|
||||
}
|
||||
#endif
|
||||
|
||||
Radiation?.MapUpdate(deltaTime);
|
||||
|
||||
if (mapAnimQueue.Count > 0)
|
||||
{
|
||||
hudVisibility = Math.Max(hudVisibility - deltaTime, 0.0f);
|
||||
@@ -324,6 +347,15 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
if (SelectedConnection != null)
|
||||
{
|
||||
connectionHighlightState = Math.Min(connectionHighlightState + deltaTime, 1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
connectionHighlightState = 0.0f;
|
||||
}
|
||||
|
||||
if (GUI.KeyboardDispatcher.Subscriber == null)
|
||||
{
|
||||
float moveSpeed = 1000.0f;
|
||||
@@ -336,7 +368,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
targetZoom = MathHelper.Clamp(targetZoom, generationParams.MinZoom, generationParams.MaxZoom);
|
||||
zoom = MathHelper.Lerp(zoom, targetZoom, 0.1f);
|
||||
zoom = MathHelper.Lerp(zoom, targetZoom * GUI.Scale, 0.1f);
|
||||
|
||||
if (GUI.MouseOn == mapContainer)
|
||||
{
|
||||
@@ -351,6 +383,7 @@ namespace Barotrauma
|
||||
//clients aren't allowed to select the location without a permission
|
||||
if ((GameMain.GameSession?.GameMode as CampaignMode)?.AllowedToManageCampaign() ?? false)
|
||||
{
|
||||
connectionHighlightState = 0.0f;
|
||||
SelectedConnection = connection;
|
||||
SelectedLocation = HighlightedLocation;
|
||||
|
||||
@@ -383,12 +416,13 @@ namespace Barotrauma
|
||||
Level.Loaded.DebugSetEndLocation(null);
|
||||
|
||||
CurrentLocation.Discovered = true;
|
||||
CurrentLocation.CreateStore();
|
||||
OnLocationChanged?.Invoke(prevLocation, CurrentLocation);
|
||||
SelectLocation(-1);
|
||||
if (GameMain.Client == null)
|
||||
{
|
||||
CurrentLocation.CreateStore();
|
||||
ProgressWorld();
|
||||
Radiation.OnStep(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -483,6 +517,8 @@ namespace Barotrauma
|
||||
float rawNoiseScale = 1.0f + PerlinNoise.GetPerlin((int)(Timing.TotalTime * 1 - 1), (int)(Timing.TotalTime * 1 - 1));
|
||||
cameraNoiseStrength = PerlinNoise.GetPerlin((int)(Timing.TotalTime * 1 - 1), (int)(Timing.TotalTime * 1 - 1));
|
||||
|
||||
Radiation.Draw(spriteBatch, rect, zoom);
|
||||
|
||||
noiseOverlay.DrawTiled(spriteBatch, rect.Location.ToVector2(), rect.Size.ToVector2(),
|
||||
startOffset: new Vector2(Rand.Range(0.0f, noiseOverlay.SourceRect.Width), Rand.Range(0.0f, noiseOverlay.SourceRect.Height)),
|
||||
color : Color.White * cameraNoiseStrength * 0.1f,
|
||||
@@ -519,22 +555,6 @@ namespace Barotrauma
|
||||
|
||||
if (!rect.Intersects(drawRect)) { continue; }
|
||||
|
||||
if (location == CurrentDisplayLocation )
|
||||
{
|
||||
generationParams.CurrentLocationIndicator.Draw(spriteBatch,
|
||||
rectCenter + (currLocationIndicatorPos + viewOffset) * zoom,
|
||||
generationParams.IndicatorColor,
|
||||
generationParams.CurrentLocationIndicator.Origin, 0, Vector2.One * (generationParams.LocationIconSize / generationParams.CurrentLocationIndicator.size.X) * 1.7f * zoom);
|
||||
}
|
||||
|
||||
if (location == SelectedLocation)
|
||||
{
|
||||
generationParams.SelectedLocationIndicator.Draw(spriteBatch,
|
||||
rectCenter + (location.MapPosition + viewOffset) * zoom,
|
||||
generationParams.IndicatorColor,
|
||||
generationParams.SelectedLocationIndicator.Origin, 0, Vector2.One * (generationParams.LocationIconSize / generationParams.SelectedLocationIndicator.size.X) * 1.7f * zoom);
|
||||
}
|
||||
|
||||
Color color = location.Type.SpriteColor;
|
||||
if (!location.Discovered) { color = Color.White; }
|
||||
if (location.Connections.Find(c => c.Locations.Contains(CurrentDisplayLocation)) == null)
|
||||
@@ -542,6 +562,12 @@ namespace Barotrauma
|
||||
color *= 0.5f;
|
||||
}
|
||||
|
||||
// TODO proper visualization of this
|
||||
if (location.Type.HasOutpost && !location.HasOutpost())
|
||||
{
|
||||
color = GUI.Style.Red;
|
||||
}
|
||||
|
||||
float iconScale = location == CurrentDisplayLocation ? 1.2f : 1.0f;
|
||||
if (location == HighlightedLocation)
|
||||
{
|
||||
@@ -550,7 +576,35 @@ 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 == CurrentDisplayLocation)
|
||||
{
|
||||
if (SelectedLocation != null)
|
||||
{
|
||||
Vector2 dir = Vector2.Normalize(SelectedLocation.MapPosition - currLocationIndicatorPos);
|
||||
GUI.Arrow.Draw(spriteBatch,
|
||||
rectCenter + (currLocationIndicatorPos + viewOffset) * zoom + dir * generationParams.LocationIconSize * 0.6f * zoom,
|
||||
generationParams.IndicatorColor,
|
||||
GUI.Arrow.Origin,
|
||||
rotate: MathUtils.VectorToAngle(dir) + MathHelper.PiOver2,
|
||||
new Vector2(0.5f, 1.0f) * zoom);
|
||||
}
|
||||
generationParams.CurrentLocationIndicator.Draw(spriteBatch,
|
||||
rectCenter + (currLocationIndicatorPos + viewOffset) * zoom,
|
||||
generationParams.IndicatorColor,
|
||||
generationParams.CurrentLocationIndicator.Origin, 0, Vector2.One * (generationParams.LocationIconSize / generationParams.CurrentLocationIndicator.size.X) * 0.8f * zoom);
|
||||
|
||||
}
|
||||
|
||||
if (location == SelectedLocation)
|
||||
{
|
||||
generationParams.SelectedLocationIndicator.Draw(spriteBatch,
|
||||
rectCenter + (location.MapPosition + viewOffset) * zoom,
|
||||
generationParams.IndicatorColor,
|
||||
generationParams.SelectedLocationIndicator.Origin, 0, Vector2.One * (generationParams.LocationIconSize / generationParams.SelectedLocationIndicator.size.X) * 1.7f * zoom);
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -576,7 +630,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
if (GameMain.DebugDraw && location == HighlightedLocation && (!location.Discovered || !location.Type.HasOutpost))
|
||||
if (GameMain.DebugDraw && location == HighlightedLocation && (!location.Discovered || !location.HasOutpost()))
|
||||
{
|
||||
if (location.Reputation != null)
|
||||
{
|
||||
@@ -608,9 +662,9 @@ namespace Barotrauma
|
||||
Vector2 pos = rectCenter + (HighlightedLocation.MapPosition + viewOffset) * zoom;
|
||||
pos.X += 50 * zoom;
|
||||
Vector2 nameSize = GUI.LargeFont.MeasureString(HighlightedLocation.Name);
|
||||
Vector2 typeSize = GUI.Font.MeasureString(HighlightedLocation.Type.Name);
|
||||
Vector2 typeSize = string.IsNullOrEmpty(HighlightedLocation.Type.Name) ? Vector2.Zero : 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)
|
||||
@@ -674,19 +728,22 @@ namespace Barotrauma
|
||||
|
||||
int width = (int)(generationParams.LocationConnectionWidth * zoom);
|
||||
|
||||
//current level
|
||||
if (Level.Loaded?.LevelData == connection.LevelData)
|
||||
{
|
||||
connectionColor = generationParams.HighlightedConnectionColor;
|
||||
width = (int)(width * 1.5f);
|
||||
}
|
||||
//selected connection
|
||||
if (SelectedLocation != CurrentDisplayLocation &&
|
||||
(connection.Locations.Contains(SelectedLocation) && connection.Locations.Contains(CurrentDisplayLocation)))
|
||||
connection.Locations.Contains(SelectedLocation) && connection.Locations.Contains(CurrentDisplayLocation))
|
||||
{
|
||||
connectionColor = generationParams.HighlightedConnectionColor;
|
||||
width *= 2;
|
||||
}
|
||||
//highlighted connection
|
||||
else if (HighlightedLocation != CurrentDisplayLocation &&
|
||||
(connection.Locations.Contains(HighlightedLocation) && connection.Locations.Contains(CurrentDisplayLocation)))
|
||||
connection.Locations.Contains(HighlightedLocation) && connection.Locations.Contains(CurrentDisplayLocation))
|
||||
{
|
||||
connectionColor = generationParams.HighlightedConnectionColor;
|
||||
width *= 2;
|
||||
@@ -741,47 +798,90 @@ namespace Barotrauma
|
||||
}
|
||||
float dist = Vector2.Distance(start, end);
|
||||
var connectionSprite = connection.Passed ? generationParams.PassedConnectionSprite : generationParams.ConnectionSprite;
|
||||
|
||||
Color segmentColor = connectionColor;
|
||||
int segmentWidth = width;
|
||||
if (connection == SelectedConnection)
|
||||
{
|
||||
float t = (i - startIndex) / (float)(endIndex - startIndex - 1);
|
||||
if (CurrentDisplayLocation == connection.Locations[1]) { t = 1.0f - t; }
|
||||
if (t > connectionHighlightState)
|
||||
{
|
||||
segmentWidth /= 2;
|
||||
segmentColor = connection.Passed ? generationParams.ConnectionColor : generationParams.UnvisitedConnectionColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
spriteBatch.Draw(connectionSprite.Texture,
|
||||
new Rectangle((int)start.X, (int)start.Y, (int)(dist - 1 * zoom), width),
|
||||
connectionSprite.SourceRect, connectionColor * a, MathUtils.VectorToAngle(end - start),
|
||||
new Rectangle((int)start.X, (int)start.Y, (int)(dist - 1 * zoom), segmentWidth),
|
||||
connectionSprite.SourceRect, segmentColor * a,
|
||||
MathUtils.VectorToAngle(end - start),
|
||||
new Vector2(0, connectionSprite.size.Y / 2), SpriteEffects.None, 0.01f);
|
||||
}
|
||||
|
||||
int iconCount = 0, iconIndex = 0;
|
||||
if (connectionStart.HasValue && connectionEnd.HasValue)
|
||||
{
|
||||
GUIComponentStyle crushDepthWarningIconStyle = null;
|
||||
{
|
||||
if (connection.LevelData.HasBeaconStation) { iconCount++; }
|
||||
if (connection.LevelData.HasHuntingGrounds) { iconCount++; }
|
||||
string tooltip = null;
|
||||
if (connection.LevelData.InitialDepth * Physics.DisplayToRealWorldRatio > connection.LevelData.RealWorldCrushDepth)
|
||||
var subCrushDepth = Submarine.MainSub?.RealWorldCrushDepth ?? Level.DefaultRealWorldCrushDepth;
|
||||
if (GameMain.GameSession?.Campaign?.UpgradeManager != null)
|
||||
{
|
||||
crushDepthWarningIconStyle = GUI.Style.GetComponentStyle("CrushDepthWarningHighIcon");
|
||||
var hullUpgradePrefab = UpgradePrefab.Find("increasewallhealth");
|
||||
if (hullUpgradePrefab != null)
|
||||
{
|
||||
int pendingLevel = GameMain.GameSession.Campaign.UpgradeManager.GetUpgradeLevel(hullUpgradePrefab, hullUpgradePrefab.UpgradeCategories.First());
|
||||
int currentLevel = GameMain.GameSession.Campaign.UpgradeManager.GetRealUpgradeLevel(hullUpgradePrefab, hullUpgradePrefab.UpgradeCategories.First());
|
||||
if (pendingLevel > currentLevel)
|
||||
{
|
||||
string updateValueStr = hullUpgradePrefab.SourceElement?.Element("Structure")?.GetAttributeString("crushdepth", null);
|
||||
if (!string.IsNullOrEmpty(updateValueStr))
|
||||
{
|
||||
subCrushDepth = PropertyReference.CalculateUpgrade(subCrushDepth, pendingLevel - currentLevel, updateValueStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string crushDepthWarningIconStyle = null;
|
||||
if (connection.LevelData.InitialDepth * Physics.DisplayToRealWorldRatio > subCrushDepth)
|
||||
{
|
||||
iconCount++;
|
||||
crushDepthWarningIconStyle = "CrushDepthWarningHighIcon";
|
||||
tooltip = "crushdepthwarninghigh";
|
||||
}
|
||||
else if ((connection.LevelData.InitialDepth + connection.LevelData.Size.Y) * Physics.DisplayToRealWorldRatio > connection.LevelData.RealWorldCrushDepth)
|
||||
else if ((connection.LevelData.InitialDepth + connection.LevelData.Size.Y) * Physics.DisplayToRealWorldRatio > subCrushDepth)
|
||||
{
|
||||
crushDepthWarningIconStyle = GUI.Style.GetComponentStyle("CrushDepthWarningLowIcon");
|
||||
iconCount++;
|
||||
crushDepthWarningIconStyle = "CrushDepthWarningLowIcon";
|
||||
tooltip = "crushdepthwarninglow";
|
||||
}
|
||||
|
||||
if (connection.LevelData.HasBeaconStation)
|
||||
{
|
||||
var beaconStationIconStyle = connection.LevelData.IsBeaconActive ? "BeaconStationActive" : "BeaconStationInactive";
|
||||
DrawIcon(beaconStationIconStyle, (int)(28 * zoom), TextManager.Get(connection.LevelData.IsBeaconActive ? "BeaconStationActiveTooltip" : "BeaconStationInactiveTooltip"));
|
||||
}
|
||||
|
||||
if (connection.LevelData.HasHuntingGrounds)
|
||||
{
|
||||
DrawIcon("HuntingGrounds", (int)(28 * zoom), TextManager.Get("HuntingGroundsTooltip"));
|
||||
}
|
||||
|
||||
if (crushDepthWarningIconStyle != null)
|
||||
{
|
||||
Vector2 iconPos = (connectionStart.Value + connectionEnd.Value) / 2;
|
||||
float iconSize = 32.0f * GUI.Scale;
|
||||
bool mouseOn = HighlightedLocation == null && Vector2.DistanceSquared(iconPos, PlayerInput.MousePosition) < iconSize * iconSize;
|
||||
Sprite crushDepthWarningIcon = crushDepthWarningIconStyle.GetDefaultSprite();
|
||||
crushDepthWarningIcon.Draw(spriteBatch, iconPos,
|
||||
mouseOn ? crushDepthWarningIconStyle.HoverColor : crushDepthWarningIconStyle.Color,
|
||||
scale: iconSize / crushDepthWarningIcon.size.X);
|
||||
if (mouseOn)
|
||||
{
|
||||
connectionTooltip = new Pair<Rectangle, string>(
|
||||
new Rectangle(iconPos.ToPoint(), new Point((int)iconSize)),
|
||||
TextManager.Get(tooltip)
|
||||
DrawIcon(crushDepthWarningIconStyle, (int)(32 * zoom),
|
||||
TextManager.Get(tooltip)
|
||||
.Replace("[initialdepth]", ((int)(connection.LevelData.InitialDepth * Physics.DisplayToRealWorldRatio)).ToString())
|
||||
.Replace("[submarinecrushdepth]", ((int)(Submarine.MainSub?.RealWorldCrushDepth ?? Level.DefaultRealWorldCrushDepth)).ToString()));
|
||||
}
|
||||
.Replace("[submarinecrushdepth]", ((int)subCrushDepth).ToString()));
|
||||
}
|
||||
}
|
||||
|
||||
if (GameMain.DebugDraw && zoom > 1.0f && generationParams.ShowLevelTypeNames)
|
||||
if (GameMain.DebugDraw && zoom > (1.0f * GUI.Scale) && generationParams.ShowLevelTypeNames)
|
||||
{
|
||||
Vector2 center = rectCenter + (connection.CenterPos + viewOffset) * zoom;
|
||||
if (viewArea.Contains(center) && connection.Biome != null)
|
||||
@@ -789,6 +889,25 @@ namespace Barotrauma
|
||||
GUI.DrawString(spriteBatch, center, connection.Biome.Identifier + " (" + connection.Difficulty + ")", Color.White);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawIcon(string iconStyle, int iconSize, string tooltip)
|
||||
{
|
||||
Vector2 iconPos = (connectionStart.Value + connectionEnd.Value) / 2;
|
||||
Vector2 iconDiff = Vector2.Normalize(connectionEnd.Value - connectionStart.Value) * iconSize;
|
||||
|
||||
iconPos += (iconDiff * -(iconCount - 1) / 2.0f) + iconDiff * iconIndex;
|
||||
|
||||
var style = GUI.Style.GetComponentStyle(iconStyle);
|
||||
bool mouseOn = HighlightedLocation == null && Vector2.DistanceSquared(iconPos, PlayerInput.MousePosition) < iconSize * iconSize;
|
||||
Sprite iconSprite = style.GetDefaultSprite();
|
||||
iconSprite.Draw(spriteBatch, iconPos, (mouseOn ? style.HoverColor : style.Color) * 0.7f,
|
||||
scale: iconSize / iconSprite.size.X);
|
||||
if (mouseOn)
|
||||
{
|
||||
connectionTooltip = new Pair<Rectangle, string>(new Rectangle(iconPos.ToPoint(), new Point(iconSize)), tooltip);
|
||||
}
|
||||
iconIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
private float hudVisibility;
|
||||
@@ -819,8 +938,9 @@ namespace Barotrauma
|
||||
return;
|
||||
}
|
||||
|
||||
if (anim.StartZoom == null) { anim.StartZoom = MathUtils.InverseLerp(generationParams.MinZoom, generationParams.MaxZoom, zoom); }
|
||||
if (anim.EndZoom == null) { anim.EndZoom = MathUtils.InverseLerp(generationParams.MinZoom, generationParams.MaxZoom, zoom); }
|
||||
float unscaledZoom = zoom / GUI.Scale;
|
||||
if (anim.StartZoom == null) { anim.StartZoom = MathUtils.InverseLerp(generationParams.MinZoom, generationParams.MaxZoom, unscaledZoom); }
|
||||
if (anim.EndZoom == null) { anim.EndZoom = MathUtils.InverseLerp(generationParams.MinZoom, generationParams.MaxZoom, unscaledZoom); }
|
||||
|
||||
anim.StartPos = (anim.StartLocation == null) ? -DrawOffset : anim.StartLocation.MapPosition;
|
||||
|
||||
@@ -833,7 +953,8 @@ namespace Barotrauma
|
||||
|
||||
zoom =
|
||||
MathHelper.Lerp(generationParams.MinZoom, generationParams.MaxZoom,
|
||||
MathHelper.SmoothStep(anim.StartZoom.Value, anim.EndZoom.Value, t));
|
||||
MathHelper.SmoothStep(anim.StartZoom.Value, anim.EndZoom.Value, t))
|
||||
* GUI.Scale;
|
||||
|
||||
if (anim.Timer >= anim.Duration)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
#nullable enable
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
internal partial class Radiation
|
||||
{
|
||||
public void Draw(SpriteBatch spriteBatch, Rectangle container, float zoom)
|
||||
{
|
||||
if (!Enabled) { return; }
|
||||
|
||||
UISprite uiSprite = GUI.Style.RadiationSprite;
|
||||
var (offsetX, offsetY) = Map.DrawOffset * zoom;
|
||||
var (centerX, centerY) = container.Center.ToVector2();
|
||||
var (halfSizeX, halfSizeY) = new Vector2(container.Width / 2f, container.Height / 2f) * zoom;
|
||||
float viewBottom = centerY + Map.Height * zoom;
|
||||
Vector2 topLeft = new Vector2(centerX + offsetX - halfSizeX, centerY + offsetY - halfSizeY);
|
||||
Vector2 size = new Vector2((Amount - increasedAmount) * zoom + halfSizeX, viewBottom - topLeft.Y);
|
||||
if (size.X < 0) { return; }
|
||||
|
||||
uiSprite.Sprite.DrawTiled(spriteBatch, topLeft, size, GUI.Style.Red * 0.33f, Vector2.Zero, textureScale: new Vector2(zoom));
|
||||
|
||||
if (container.Contains(PlayerInput.MousePosition) && PlayerInput.MousePosition.X < topLeft.X + size.X)
|
||||
{
|
||||
// TODO tooltip?
|
||||
}
|
||||
}
|
||||
|
||||
public void MapUpdate(float deltaTime)
|
||||
{
|
||||
if (increasedAmount > 0)
|
||||
{
|
||||
increasedAmount -= (lastIncrease / Params.AnimationSpeed) * deltaTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -114,6 +114,18 @@ namespace Barotrauma
|
||||
public MapEntity ReplacedBy;
|
||||
|
||||
public virtual void Draw(SpriteBatch spriteBatch, bool editing, bool back = true) { }
|
||||
|
||||
/// <summary>
|
||||
/// A method that modifies the draw depth to prevent z-fighting between entities with the same sprite depth
|
||||
/// </summary>
|
||||
public float GetDrawDepth(float baseDepth, Sprite sprite)
|
||||
{
|
||||
float depth = baseDepth
|
||||
//take texture into account to get entities with (roughly) the same base depth and texture to render consecutively to minimize texture swaps
|
||||
+ (sprite?.Texture?.SortingKey ?? 0) % 100 * 0.00001f
|
||||
+ ID % 100 * 0.000001f;
|
||||
return Math.Min(depth, 1.0f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the selection logic in submarine editor
|
||||
@@ -202,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))
|
||||
{
|
||||
@@ -267,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
|
||||
@@ -464,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
|
||||
@@ -479,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;
|
||||
@@ -499,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,7 +45,10 @@ namespace Barotrauma
|
||||
{
|
||||
CreateInstance(newRect);
|
||||
placePosition = Vector2.Zero;
|
||||
selected = null;
|
||||
if (!PlayerInput.IsShiftDown())
|
||||
{
|
||||
selected = null;
|
||||
}
|
||||
}
|
||||
|
||||
newRect.Y = -newRect.Y;
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace Barotrauma
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!GameMain.SubEditorScreen.ShowThalamus && prefab.Category.HasFlag(MapEntityCategory.Thalamus))
|
||||
if (GameMain.SubEditorScreen.IsSubcategoryHidden(prefab.Subcategory))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -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,11 +221,14 @@ namespace Barotrauma
|
||||
Draw(spriteBatch, editing, false, damageEffect);
|
||||
}
|
||||
|
||||
private float GetRealDepth()
|
||||
{
|
||||
return SpriteDepthOverrideIsSet ? SpriteOverrideDepth : prefab.sprite.Depth;
|
||||
}
|
||||
|
||||
public float GetDrawDepth()
|
||||
{
|
||||
float depth = SpriteDepthOverrideIsSet ? SpriteOverrideDepth : prefab.sprite.Depth;
|
||||
depth -= (ID % 255) * 0.000001f;
|
||||
return depth;
|
||||
return GetDrawDepth(GetRealDepth(), prefab.sprite);
|
||||
}
|
||||
|
||||
private void Draw(SpriteBatch spriteBatch, bool editing, bool back = true, Effect damageEffect = null)
|
||||
@@ -254,7 +258,7 @@ namespace Barotrauma
|
||||
thickness: Math.Max(1, (int)(2 / Screen.Selected.Cam.Zoom)));
|
||||
}
|
||||
|
||||
bool isWiringMode = editing && SubEditorScreen.IsWiringMode();
|
||||
bool isWiringMode = editing && SubEditorScreen.TransparentWiringMode && SubEditorScreen.IsWiringMode();
|
||||
|
||||
if (isWiringMode) { color *= 0.15f; }
|
||||
|
||||
@@ -263,8 +267,8 @@ namespace Barotrauma
|
||||
float depth = GetDrawDepth();
|
||||
|
||||
Vector2 textureOffset = this.textureOffset;
|
||||
if (FlippedX) textureOffset.X = -textureOffset.X;
|
||||
if (FlippedY) textureOffset.Y = -textureOffset.Y;
|
||||
if (FlippedX) { textureOffset.X = -textureOffset.X; }
|
||||
if (FlippedY) { textureOffset.Y = -textureOffset.Y; }
|
||||
|
||||
if (back && damageEffect == null && !isWiringMode)
|
||||
{
|
||||
@@ -304,7 +308,7 @@ namespace Barotrauma
|
||||
color: Prefab.BackgroundSpriteColor,
|
||||
textureScale: TextureScale * Scale,
|
||||
startOffset: backGroundOffset,
|
||||
depth: Math.Max(Prefab.BackgroundSprite.Depth + (ID % 255) * 0.000001f, depth + 0.000001f));
|
||||
depth: Math.Max(GetDrawDepth(Prefab.BackgroundSprite.Depth, Prefab.BackgroundSprite), depth + 0.000001f));
|
||||
|
||||
if (UseDropShadow)
|
||||
{
|
||||
@@ -322,13 +326,14 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
if (back == depth > 0.5f)
|
||||
if (back == GetRealDepth() > 0.5f)
|
||||
{
|
||||
SpriteEffects oldEffects = prefab.sprite.effects;
|
||||
prefab.sprite.effects ^= SpriteEffects;
|
||||
|
||||
for (int i = 0; i < Sections.Length; i++)
|
||||
{
|
||||
Rectangle drawSection = Sections[i].rect;
|
||||
if (damageEffect != null)
|
||||
{
|
||||
float newCutoff = MathHelper.Lerp(0.0f, 0.65f, Sections[i].damage / MaxHealth);
|
||||
@@ -345,21 +350,30 @@ namespace Barotrauma
|
||||
Submarine.DamageEffectColor = color;
|
||||
}
|
||||
}
|
||||
if (!HasDamage && i == 0)
|
||||
{
|
||||
drawSection = new Rectangle(
|
||||
drawSection.X,
|
||||
drawSection.Y,
|
||||
Sections[Sections.Length -1 ].rect.Right - drawSection.X,
|
||||
drawSection.Y - (Sections[Sections.Length - 1].rect.Y - Sections[Sections.Length - 1].rect.Height));
|
||||
i = Sections.Length;
|
||||
}
|
||||
|
||||
Vector2 sectionOffset = new Vector2(
|
||||
Math.Abs(rect.Location.X - Sections[i].rect.Location.X),
|
||||
Math.Abs(rect.Location.Y - Sections[i].rect.Location.Y));
|
||||
Math.Abs(rect.Location.X - drawSection.Location.X),
|
||||
Math.Abs(rect.Location.Y - drawSection.Location.Y));
|
||||
|
||||
if (FlippedX && IsHorizontal) sectionOffset.X = Sections[i].rect.Right - rect.Right;
|
||||
if (FlippedY && !IsHorizontal) sectionOffset.Y = (rect.Y - rect.Height) - (Sections[i].rect.Y - Sections[i].rect.Height);
|
||||
if (FlippedX && IsHorizontal) { sectionOffset.X = drawSection.Right - rect.Right; }
|
||||
if (FlippedY && !IsHorizontal) { sectionOffset.Y = (rect.Y - rect.Height) - (drawSection.Y - drawSection.Height); }
|
||||
|
||||
sectionOffset.X += MathUtils.PositiveModulo((int)-textureOffset.X, prefab.sprite.SourceRect.Width);
|
||||
sectionOffset.Y += MathUtils.PositiveModulo((int)-textureOffset.Y, prefab.sprite.SourceRect.Height);
|
||||
|
||||
prefab.sprite.DrawTiled(
|
||||
spriteBatch,
|
||||
new Vector2(Sections[i].rect.X + drawOffset.X, -(Sections[i].rect.Y + drawOffset.Y)),
|
||||
new Vector2(Sections[i].rect.Width, Sections[i].rect.Height),
|
||||
new Vector2(drawSection.X + drawOffset.X, -(drawSection.Y + drawOffset.Y)),
|
||||
new Vector2(drawSection.Width, drawSection.Height),
|
||||
color: color,
|
||||
startOffset: sectionOffset,
|
||||
depth: depth,
|
||||
@@ -369,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;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user