v0.10.5.1
This commit is contained in:
@@ -68,29 +68,52 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (Window.Height > 0 && Window.Width > 0)
|
||||
{
|
||||
rect.Height = -(int)(Window.Y * item.Scale);
|
||||
|
||||
rect.Y += (int)(doorRect.Height * openState);
|
||||
rect.Height = Math.Max(rect.Height - (rect.Y - doorRect.Y), 0);
|
||||
rect.Y = Math.Min(doorRect.Y, rect.Y);
|
||||
|
||||
if (convexHull2 != null)
|
||||
if (IsHorizontal)
|
||||
{
|
||||
Rectangle rect2 = doorRect;
|
||||
rect2.Y += (int)(Window.Y * item.Scale - Window.Height * item.Scale);
|
||||
|
||||
rect2.Y += (int)(doorRect.Height * openState);
|
||||
rect2.Y = Math.Min(doorRect.Y, rect2.Y);
|
||||
rect2.Height = rect2.Y - (doorRect.Y - (int)(doorRect.Height * (1.0f - openState)));
|
||||
|
||||
if (rect2.Height == 0)
|
||||
rect.Width = (int)(Window.X * item.Scale);
|
||||
rect.X -= (int)(doorRect.Width * openState);
|
||||
rect.Width = Math.Max(rect.Width - (doorRect.X - rect.X), 0);
|
||||
rect.X = Math.Max(doorRect.X, rect.X);
|
||||
if (convexHull2 != null)
|
||||
{
|
||||
convexHull2.Enabled = false;
|
||||
Rectangle rect2 = doorRect;
|
||||
rect2.X += (int)(Window.Right * item.Scale);
|
||||
rect2.X -= (int)(doorRect.Width * openState);
|
||||
rect2.X = Math.Max(doorRect.X, rect2.X);
|
||||
rect2.Width = doorRect.Right - (int)(doorRect.Width * openState) - rect2.X;
|
||||
if (rect2.Width == 0)
|
||||
{
|
||||
convexHull2.Enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
convexHull2.Enabled = true;
|
||||
convexHull2.SetVertices(GetConvexHullCorners(rect2));
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
rect.Height = -(int)(Window.Y * item.Scale);
|
||||
rect.Y += (int)(doorRect.Height * openState);
|
||||
rect.Height = Math.Max(rect.Height - (rect.Y - doorRect.Y), 0);
|
||||
rect.Y = Math.Min(doorRect.Y, rect.Y);
|
||||
if (convexHull2 != null)
|
||||
{
|
||||
convexHull2.Enabled = true;
|
||||
convexHull2.SetVertices(GetConvexHullCorners(rect2));
|
||||
Rectangle rect2 = doorRect;
|
||||
rect2.Y += (int)(Window.Y * item.Scale - Window.Height * item.Scale);
|
||||
rect2.Y += (int)(doorRect.Height * openState);
|
||||
rect2.Y = Math.Min(doorRect.Y, rect2.Y);
|
||||
rect2.Height = rect2.Y - (doorRect.Y - (int)(doorRect.Height * (1.0f - openState)));
|
||||
if (rect2.Height == 0)
|
||||
{
|
||||
convexHull2.Enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
convexHull2.Enabled = true;
|
||||
convexHull2.SetVertices(GetConvexHullCorners(rect2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -251,8 +274,9 @@ namespace Barotrauma.Items.Components
|
||||
bool open = msg.ReadBoolean();
|
||||
bool broken = msg.ReadBoolean();
|
||||
bool forcedOpen = msg.ReadBoolean();
|
||||
bool isStuck = msg.ReadBoolean();
|
||||
SetState(open, isNetworkMessage: true, sendNetworkMessage: false, forcedOpen: forcedOpen);
|
||||
Stuck = msg.ReadRangedSingle(0.0f, 100.0f, 8);
|
||||
stuck = msg.ReadRangedSingle(0.0f, 100.0f, 8);
|
||||
UInt16 lastUserID = msg.ReadUInt16();
|
||||
Character user = lastUserID == 0 ? null : Entity.FindEntityByID(lastUserID) as Character;
|
||||
if (user != lastUser)
|
||||
@@ -260,7 +284,7 @@ namespace Barotrauma.Items.Components
|
||||
lastUser = user;
|
||||
toggleCooldownTimer = ToggleCoolDown;
|
||||
}
|
||||
|
||||
this.isStuck = isStuck;
|
||||
if (isStuck) { OpenState = 0.0f; }
|
||||
IsBroken = broken;
|
||||
PredictedState = null;
|
||||
|
||||
@@ -0,0 +1,360 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.Networking;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
internal partial class VineTile
|
||||
{
|
||||
public void Draw(SpriteBatch spriteBatch, Vector2 position, float depth, float leafDepth)
|
||||
{
|
||||
Vector2 pos = position + Position;
|
||||
pos.Y = -pos.Y;
|
||||
|
||||
VineSprite vineSprite = Parent.VineSprites[Type];
|
||||
Color color = Parent.Decayed ? Parent.DeadTint : Parent.VineTint;
|
||||
|
||||
float layer1 = depth + 0.01f, // flowers
|
||||
layer2 = depth + 0.02f, // decay atlas
|
||||
layer3 = depth + 0.03f; // branches and leaves
|
||||
|
||||
float scale = Parent.VineScale * VineStep;
|
||||
|
||||
if (Parent.VineAtlas != null)
|
||||
{
|
||||
spriteBatch.Draw(Parent.VineAtlas.Texture, pos + offset, vineSprite.SourceRect, color, 0f, vineSprite.AbsoluteOrigin, scale, SpriteEffects.None, layer3);
|
||||
}
|
||||
|
||||
if (Parent.DecayAtlas != null)
|
||||
{
|
||||
spriteBatch.Draw(Parent.DecayAtlas.Texture, pos, vineSprite.SourceRect, HealthColor, 0f, vineSprite.AbsoluteOrigin, scale, SpriteEffects.None, layer2);
|
||||
}
|
||||
|
||||
if (FlowerConfig.Variant >= 0 && !Parent.Decayed)
|
||||
{
|
||||
Sprite flowerSprite = Parent.FlowerSprites[FlowerConfig.Variant];
|
||||
flowerSprite.Draw(spriteBatch, pos, Parent.FlowerTint, flowerSprite.Origin, scale: Parent.BaseFlowerScale * FlowerConfig.Scale * FlowerStep, rotate: FlowerConfig.Rotation, depth: layer1);
|
||||
}
|
||||
|
||||
if (LeafConfig.Variant >= 0)
|
||||
{
|
||||
Sprite leafSprite = Parent.LeafSprites[LeafConfig.Variant];
|
||||
leafSprite.Draw(spriteBatch, pos, Parent.Decayed ? Parent.DeadTint : Parent.LeafTint, leafSprite.Origin, scale: Parent.BaseLeafScale * LeafConfig.Scale * FlowerStep, rotate: LeafConfig.Rotation, depth: layer3 + leafDepth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class VineSprite
|
||||
{
|
||||
[Serialize("0,0,0,0", false)]
|
||||
public Rectangle SourceRect { get; private set; }
|
||||
|
||||
[Serialize("0.5,0.5", false)]
|
||||
public Vector2 Origin { get; private set; }
|
||||
|
||||
public Vector2 AbsoluteOrigin;
|
||||
|
||||
public VineSprite(XElement element)
|
||||
{
|
||||
SerializableProperty.DeserializeProperties(this, element);
|
||||
AbsoluteOrigin = new Vector2(SourceRect.Width * Origin.X, SourceRect.Height * Origin.Y);
|
||||
}
|
||||
}
|
||||
|
||||
internal partial class Growable
|
||||
{
|
||||
public readonly Dictionary<VineTileType, VineSprite> VineSprites = new Dictionary<VineTileType, VineSprite>();
|
||||
public readonly List<Sprite> FlowerSprites = new List<Sprite>();
|
||||
public readonly List<Sprite> LeafSprites = new List<Sprite>();
|
||||
|
||||
public Sprite? VineAtlas, DecayAtlas;
|
||||
|
||||
protected override void RemoveComponentSpecific()
|
||||
{
|
||||
VineAtlas?.Remove();
|
||||
DecayAtlas?.Remove();
|
||||
|
||||
foreach (Sprite sprite in FlowerSprites)
|
||||
{
|
||||
sprite.Remove();
|
||||
}
|
||||
|
||||
foreach (Sprite sprite in LeafSprites)
|
||||
{
|
||||
sprite.Remove();
|
||||
}
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, Planter planter, Vector2 offset, float depth)
|
||||
{
|
||||
const float zStep = 0.0001f;
|
||||
float leafDepth = 0f;
|
||||
|
||||
foreach (VineTile vine in Vines)
|
||||
{
|
||||
leafDepth += zStep;
|
||||
vine.Draw(spriteBatch, planter.Item.DrawPosition + offset, depth, leafDepth);
|
||||
}
|
||||
|
||||
if (GameMain.DebugDraw)
|
||||
{
|
||||
foreach (Rectangle rect in FailedRectangles)
|
||||
{
|
||||
Rectangle wRect = rect;
|
||||
wRect.Y = -wRect.Y;
|
||||
wRect.Y -= wRect.Height;
|
||||
GUI.DrawRectangle(spriteBatch, wRect, Color.Red);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
partial void LoadVines(XElement element)
|
||||
{
|
||||
string? vineAtlasPath = element.GetAttributeString("vineatlas", null);
|
||||
string? decayAtlasPath = element.GetAttributeString("decayatlas", null);
|
||||
|
||||
if (vineAtlasPath != null)
|
||||
{
|
||||
VineAtlas = new Sprite(vineAtlasPath, Rectangle.Empty);
|
||||
}
|
||||
|
||||
if (decayAtlasPath != null)
|
||||
{
|
||||
DecayAtlas = new Sprite(decayAtlasPath, Rectangle.Empty);
|
||||
}
|
||||
|
||||
foreach (XElement subElement in element.Elements())
|
||||
{
|
||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||
{
|
||||
case "vinesprite":
|
||||
var tileType = subElement.GetAttributeString("type", null);
|
||||
VineTileType type = Enum.Parse<VineTileType>(tileType);
|
||||
VineSprites.Add(type, new VineSprite(subElement));
|
||||
break;
|
||||
case "flowersprite":
|
||||
FlowerSprites.Add(new Sprite(subElement));
|
||||
break;
|
||||
case "leafsprite":
|
||||
LeafSprites.Add(new Sprite(subElement));
|
||||
break;
|
||||
}
|
||||
|
||||
flowerVariants = FlowerSprites.Count;
|
||||
leafVariants = LeafSprites.Count;
|
||||
}
|
||||
|
||||
foreach (VineTileType type in Enum.GetValues(typeof(VineTileType)))
|
||||
{
|
||||
if (!VineSprites.ContainsKey(type))
|
||||
{
|
||||
DebugConsole.ThrowError($"Vine sprite missing from {item.prefab.Identifier}: {type}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private readonly object mutex = new object();
|
||||
|
||||
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
||||
{
|
||||
Health = msg.ReadRangedSingle(0, MaxHealth, 8);
|
||||
int startOffset = msg.ReadRangedInteger(-1, MaximumVines);
|
||||
if (startOffset > -1)
|
||||
{
|
||||
int vineCount = msg.ReadRangedInteger(0, VineChunkSize);
|
||||
List<VineTile> tiles = new List<VineTile>();
|
||||
for (int i = 0; i < vineCount; i++)
|
||||
{
|
||||
VineTileType vineType = (VineTileType) msg.ReadRangedInteger(0b0000, 0b1111);
|
||||
int flowerConfig = msg.ReadRangedInteger(0, 0xFFF);
|
||||
int leafConfig = msg.ReadRangedInteger(0, 0xFFF);
|
||||
sbyte posX = (sbyte) msg.ReadByte(), posY = (sbyte) msg.ReadByte();
|
||||
Vector2 pos = new Vector2(posX * VineTile.Size, posY * VineTile.Size);
|
||||
|
||||
tiles.Add(new VineTile(this, pos, vineType, FoliageConfig.Deserialize(flowerConfig), FoliageConfig.Deserialize(leafConfig)));
|
||||
}
|
||||
|
||||
// is this even needed??
|
||||
lock (mutex)
|
||||
{
|
||||
for (var i = 0; i < vineCount; i++)
|
||||
{
|
||||
int index = i + startOffset;
|
||||
if (index >= Vines.Count)
|
||||
{
|
||||
Vines.Add(tiles[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
VineTile oldVine = Vines[index];
|
||||
VineTile newVine = tiles[i];
|
||||
newVine.GrowthStep = oldVine.GrowthStep;
|
||||
Vines[index] = newVine;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UpdateBranchHealth();
|
||||
ResetPlanterSize();
|
||||
}
|
||||
|
||||
private void ResetPlanterSize()
|
||||
{
|
||||
if (item.ParentInventory is ItemInventory itemInventory && itemInventory.Owner is Item parentItem)
|
||||
{
|
||||
if (parentItem.GetComponent<Planter>() is { } planter)
|
||||
{
|
||||
planter.Item.ResetCachedVisibleSize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
private int seed;
|
||||
|
||||
// Huge bowl of spaghetti
|
||||
public void CreateDebugHUD(Planter planter, PlantSlot slot)
|
||||
{
|
||||
Vector2 relativeSize = new Vector2(0.3f, 0.6f);
|
||||
GUIMessageBox msgBox = new GUIMessageBox(item.Name, "", new[] { TextManager.Get("applysettingsbutton") }, relativeSize);
|
||||
|
||||
GUILayoutGroup content = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.85f), msgBox.Content.RectTransform)) { Stretch = true };
|
||||
GUINumberInput seedInput = CreateIntEntry("Random Seed", seed, content.RectTransform);
|
||||
GUINumberInput vineTileSizeInput = CreateIntEntry("Vine Tile Size (Global)", VineTile.Size, content.RectTransform);
|
||||
GUINumberInput[] leafScaleRangeInput = CreateMinMaxEntry("Leaf Scale Range (Global)", new []{ MinLeafScale, MaxLeafScale }, 1.5f, content.RectTransform);
|
||||
GUINumberInput[] flowerScaleRangeInput = CreateMinMaxEntry("Flower Scale Range (Global)", new []{ MinFlowerScale, MaxFlowerScale }, 1.5f, content.RectTransform);
|
||||
GUINumberInput vineCountInput = CreateIntEntry("Vine Count", MaximumVines, content.RectTransform);
|
||||
GUINumberInput vineScaleInput = CreateFloatEntry("Vine Scale", VineScale, content.RectTransform);
|
||||
GUINumberInput flowerInput = CreateIntEntry("Flower Quantity", FlowerQuantity, content.RectTransform);
|
||||
GUINumberInput flowerScaleInput = CreateFloatEntry("Flower Scale", BaseFlowerScale, content.RectTransform);
|
||||
GUINumberInput leafScaleInput = CreateFloatEntry("Leaf Scale", BaseLeafScale, content.RectTransform);
|
||||
GUINumberInput leafProbabilityInput = CreateFloatEntry("Leaf Probability", LeafProbability, content.RectTransform);
|
||||
GUINumberInput[] leafTintInputs = CreateMinMaxEntry("Leaf Tint", new []{ LeafTint.R / 255f, LeafTint.G / 255f, LeafTint.B / 255f }, 1.0f, content.RectTransform);
|
||||
GUINumberInput[] flowerTintInputs = CreateMinMaxEntry("Flower Tint", new []{ FlowerTint.R / 255f, FlowerTint.G / 255f, FlowerTint.B / 255f }, 1.0f, content.RectTransform);
|
||||
GUINumberInput[] vineTintInputs = CreateMinMaxEntry("Branch Tint", new []{ VineTint.R / 255f, VineTint.G / 255f, VineTint.B / 255f }, 1.0f, content.RectTransform);
|
||||
|
||||
// Apply
|
||||
msgBox.Buttons[0].OnClicked = (button, o) =>
|
||||
{
|
||||
seed = seedInput.IntValue;
|
||||
MaximumVines = vineCountInput.IntValue;
|
||||
FlowerQuantity = flowerInput.IntValue;
|
||||
BaseFlowerScale = flowerScaleInput.FloatValue;
|
||||
VineScale = vineScaleInput.FloatValue;
|
||||
BaseLeafScale = leafScaleInput.FloatValue;
|
||||
LeafProbability = leafProbabilityInput.FloatValue;
|
||||
VineTile.Size = vineTileSizeInput.IntValue;
|
||||
|
||||
MinFlowerScale = flowerScaleRangeInput[0].FloatValue;
|
||||
MaxFlowerScale = flowerScaleRangeInput[1].FloatValue;
|
||||
MinLeafScale = leafScaleRangeInput[0].FloatValue;
|
||||
MaxLeafScale = leafScaleRangeInput[1].FloatValue;
|
||||
|
||||
LeafTint = new Color(leafTintInputs[0].FloatValue, leafTintInputs[1].FloatValue, leafTintInputs[2].FloatValue);
|
||||
FlowerTint = new Color(flowerTintInputs[0].FloatValue, flowerTintInputs[1].FloatValue, flowerTintInputs[2].FloatValue);
|
||||
VineTint = new Color(vineTintInputs[0].FloatValue, vineTintInputs[1].FloatValue, vineTintInputs[2].FloatValue);
|
||||
|
||||
if (FlowerQuantity >= MaximumVines - 1)
|
||||
{
|
||||
vineCountInput.Flash(Color.Red);
|
||||
flowerInput.Flash(Color.Red);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (MinFlowerScale > MaxFlowerScale)
|
||||
{
|
||||
foreach (GUINumberInput input in flowerScaleRangeInput)
|
||||
{
|
||||
input.Flash(Color.Red);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (MinLeafScale > MaxLeafScale)
|
||||
{
|
||||
foreach (GUINumberInput input in leafScaleRangeInput)
|
||||
{
|
||||
input.Flash(Color.Red);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
msgBox.Close();
|
||||
|
||||
Random random = new Random(seed);
|
||||
Random flowerRandom = new Random(seed);
|
||||
Vines.Clear();
|
||||
GenerateFlowerTiles(flowerRandom);
|
||||
GenerateStem();
|
||||
|
||||
Decayed = false;
|
||||
FullyGrown = false;
|
||||
while (MaximumVines > Vines.Count)
|
||||
{
|
||||
if (!CanGrowMore())
|
||||
{
|
||||
Decayed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
TryGenerateBranches(planter, slot, random, flowerRandom);
|
||||
}
|
||||
|
||||
if (!Decayed)
|
||||
{
|
||||
FullyGrown = true;
|
||||
}
|
||||
|
||||
foreach (VineTile vineTile in Vines)
|
||||
{
|
||||
vineTile.GrowthStep = 2.0f;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
private static GUINumberInput CreateIntEntry(string label, int defaultValue, RectTransform parent)
|
||||
{
|
||||
GUILayoutGroup layout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.08f), parent), isHorizontal: true);
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), layout.RectTransform), label);
|
||||
GUINumberInput input = new GUINumberInput(new RectTransform(new Vector2(0.5f, 1f), layout.RectTransform), GUINumberInput.NumberType.Int) { IntValue = defaultValue };
|
||||
return input;
|
||||
}
|
||||
|
||||
private static GUINumberInput CreateFloatEntry(string label, float defaultValue, RectTransform parent)
|
||||
{
|
||||
GUILayoutGroup layout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.08f), parent), isHorizontal: true);
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), layout.RectTransform), label);
|
||||
GUINumberInput input = new GUINumberInput(new RectTransform(new Vector2(0.5f, 1f), layout.RectTransform), GUINumberInput.NumberType.Float) { FloatValue = defaultValue, DecimalsToDisplay = 2 };
|
||||
return input;
|
||||
}
|
||||
|
||||
private static GUINumberInput[] CreateMinMaxEntry(string label, float[] values, float max, RectTransform parent, float min = 0f)
|
||||
{
|
||||
GUILayoutGroup layout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.08f), parent), isHorizontal: true);
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), layout.RectTransform), label);
|
||||
GUINumberInput[] inputs = new GUINumberInput[values.Length];
|
||||
for (var i = 0; i < values.Length; i++)
|
||||
{
|
||||
float value = values[i];
|
||||
GUINumberInput input = new GUINumberInput(new RectTransform(new Vector2(0.5f / values.Length, 1f), layout.RectTransform), GUINumberInput.NumberType.Float)
|
||||
{
|
||||
FloatValue = value, DecimalsToDisplay = 2,
|
||||
MinValueFloat = min,
|
||||
MaxValueFloat = max
|
||||
};
|
||||
inputs[i] = input;
|
||||
}
|
||||
|
||||
return inputs;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -12,11 +12,11 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class RangedWeapon : ItemComponent
|
||||
{
|
||||
private Sprite crosshairSprite, crosshairPointerSprite;
|
||||
protected Sprite crosshairSprite, crosshairPointerSprite;
|
||||
|
||||
private Vector2 crosshairPos, crosshairPointerPos;
|
||||
protected Vector2 crosshairPos, crosshairPointerPos;
|
||||
|
||||
private float currentCrossHairScale, currentCrossHairPointerScale;
|
||||
protected float currentCrossHairScale, currentCrossHairPointerScale;
|
||||
|
||||
private readonly List<ParticleEmitter> particleEmitters = new List<ParticleEmitter>();
|
||||
|
||||
@@ -86,7 +86,6 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
|
||||
{
|
||||
if (crosshairSprite == null) { return; }
|
||||
if (character == null || !character.IsKeyDown(InputType.Aim)) { return; }
|
||||
|
||||
//camera focused on some other item/device, don't draw the crosshair
|
||||
|
||||
@@ -0,0 +1,338 @@
|
||||
using Barotrauma.Networking;
|
||||
using Barotrauma.Particles;
|
||||
using FarseerPhysics;
|
||||
using FarseerPhysics.Dynamics;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
|
||||
partial class Sprayer : RangedWeapon, IDrawableComponent
|
||||
{
|
||||
#if DEBUG
|
||||
private Vector2 debugRayStartPos, debugRayEndPos;
|
||||
#endif
|
||||
|
||||
public Vector2 DrawSize
|
||||
{
|
||||
get { return Vector2.Zero; }
|
||||
}
|
||||
|
||||
private readonly List<ParticleEmitter> particleEmitters = new List<ParticleEmitter>();
|
||||
private Hull targetHull;
|
||||
|
||||
private Vector2 rayStartWorldPosition;
|
||||
|
||||
private Color color;
|
||||
|
||||
partial void InitProjSpecific(XElement element)
|
||||
{
|
||||
currentCrossHairPointerScale = element.GetAttributeFloat("crosshairscale", 0.1f);
|
||||
|
||||
foreach (XElement subElement in element.Elements())
|
||||
{
|
||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||
{
|
||||
case "particleemitter":
|
||||
particleEmitters.Add(new ParticleEmitter(subElement));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private readonly List<BackgroundSection> targetSections = new List<BackgroundSection>();
|
||||
|
||||
// 0 = 1x1, 1 = 2x2, 2 = 3x3
|
||||
private int spraySetting = 0;
|
||||
private readonly Point[] sprayArray = new Point[8];
|
||||
|
||||
public override void UpdateHUD(Character character, float deltaTime, Camera cam)
|
||||
{
|
||||
if (character == null || !character.IsKeyDown(InputType.Aim)) return;
|
||||
|
||||
#if DEBUG
|
||||
if (PlayerInput.KeyHit(InputType.PreviousFireMode))
|
||||
#else
|
||||
if (PlayerInput.MouseWheelDownClicked())
|
||||
#endif
|
||||
{
|
||||
|
||||
if (spraySetting > 0)
|
||||
{
|
||||
spraySetting--;
|
||||
}
|
||||
else
|
||||
{
|
||||
spraySetting = 2;
|
||||
}
|
||||
|
||||
targetSections.Clear();
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
if (PlayerInput.KeyHit(InputType.NextFireMode))
|
||||
#else
|
||||
if (PlayerInput.MouseWheelUpClicked())
|
||||
#endif
|
||||
{
|
||||
if (spraySetting < 2)
|
||||
{
|
||||
spraySetting++;
|
||||
}
|
||||
else
|
||||
{
|
||||
spraySetting = 0;
|
||||
}
|
||||
|
||||
targetSections.Clear();
|
||||
}
|
||||
|
||||
crosshairPointerPos = PlayerInput.MousePosition;
|
||||
|
||||
Vector2 rayStart;
|
||||
Vector2 sourcePos = character?.AnimController == null ? item.SimPosition : character.AnimController.AimSourceSimPos;
|
||||
Vector2 barrelPos = item.SimPosition + TransformedBarrelPos;
|
||||
//make sure there's no obstacles between the base of the item (or the shoulder of the character) and the end of the barrel
|
||||
if (Submarine.PickBody(sourcePos, barrelPos, collisionCategory: Physics.CollisionItem | Physics.CollisionItemBlocking | Physics.CollisionWall) == null)
|
||||
{
|
||||
//no obstacles -> we start the raycast at the end of the barrel
|
||||
rayStart = ConvertUnits.ToSimUnits(item.WorldPosition) + TransformedBarrelPos;
|
||||
}
|
||||
else
|
||||
{
|
||||
targetHull = null;
|
||||
targetSections.Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
Vector2 pos = character.CursorWorldPosition;
|
||||
Vector2 rayEnd = ConvertUnits.ToSimUnits(pos);
|
||||
rayStartWorldPosition = ConvertUnits.ToDisplayUnits(rayStart);
|
||||
|
||||
if (Vector2.Distance(rayStartWorldPosition, pos) > Range)
|
||||
{
|
||||
targetHull = null;
|
||||
targetSections.Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
debugRayStartPos = ConvertUnits.ToDisplayUnits(rayStart);
|
||||
debugRayEndPos = ConvertUnits.ToDisplayUnits(rayEnd);
|
||||
#endif
|
||||
|
||||
Submarine parentSub = character.Submarine ?? item.Submarine;
|
||||
if (parentSub != null)
|
||||
{
|
||||
rayStart -= parentSub.SimPosition;
|
||||
rayEnd -= parentSub.SimPosition;
|
||||
}
|
||||
|
||||
var obstacles = Submarine.PickBodies(rayStart, rayEnd, collisionCategory: Physics.CollisionItem | Physics.CollisionItemBlocking | Physics.CollisionWall);
|
||||
foreach (var body in obstacles)
|
||||
{
|
||||
if (body.UserData is Item item)
|
||||
{
|
||||
var door = item.GetComponent<Door>();
|
||||
if (door != null && door.IsOpen || door.IsBroken) continue;
|
||||
}
|
||||
|
||||
targetHull = null;
|
||||
targetSections.Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
targetHull = Hull.GetCleanTarget(pos);
|
||||
if (targetHull == null)
|
||||
{
|
||||
targetSections.Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
BackgroundSection mousedOverSection = targetHull.GetBackgroundSection(pos);
|
||||
|
||||
if (mousedOverSection == null)
|
||||
{
|
||||
targetSections.Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
// No need to refresh
|
||||
if (targetSections.Count > 0 && mousedOverSection == targetSections[0])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
targetSections.Clear();
|
||||
|
||||
targetSections.Add(mousedOverSection);
|
||||
int mousedOverIndex = mousedOverSection.Index;
|
||||
|
||||
// Start with 2x2
|
||||
if (spraySetting > 0)
|
||||
{
|
||||
sprayArray[0].X = mousedOverIndex + 1;
|
||||
sprayArray[0].Y = mousedOverSection.RowIndex;
|
||||
|
||||
sprayArray[1].X = mousedOverIndex + targetHull.xBackgroundMax;
|
||||
sprayArray[1].Y = mousedOverSection.RowIndex + 1;
|
||||
|
||||
sprayArray[2].X = sprayArray[1].X + 1;
|
||||
sprayArray[2].Y = sprayArray[1].Y;
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (targetHull.DoesSectionMatch(sprayArray[i].X, sprayArray[i].Y))
|
||||
{
|
||||
targetSections.Add(targetHull.BackgroundSections[sprayArray[i].X]);
|
||||
}
|
||||
}
|
||||
|
||||
// Add more if it's 3x3
|
||||
if (spraySetting == 2)
|
||||
{
|
||||
sprayArray[3].X = mousedOverIndex - 1;
|
||||
sprayArray[3].Y = mousedOverSection.RowIndex;
|
||||
|
||||
sprayArray[4].X = sprayArray[1].X - 1;
|
||||
sprayArray[4].Y = sprayArray[1].Y;
|
||||
|
||||
sprayArray[5].X = sprayArray[3].X - targetHull.xBackgroundMax;
|
||||
sprayArray[5].Y = sprayArray[3].Y - 1;
|
||||
|
||||
sprayArray[6].X = sprayArray[5].X + 1;
|
||||
sprayArray[6].Y = sprayArray[5].Y;
|
||||
|
||||
sprayArray[7].X = sprayArray[6].X + 1;
|
||||
sprayArray[7].Y = sprayArray[6].Y;
|
||||
|
||||
for (int i = 3; i < sprayArray.Length; i++)
|
||||
{
|
||||
if (targetHull.DoesSectionMatch(sprayArray[i].X, sprayArray[i].Y))
|
||||
{
|
||||
targetSections.Add(targetHull.BackgroundSections[sprayArray[i].X]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
|
||||
{
|
||||
if (character == null || !character.IsKeyDown(InputType.Aim)) { return; }
|
||||
GUI.HideCursor = targetSections.Count > 0;
|
||||
}
|
||||
|
||||
public override bool Use(float deltaTime, Character character = null)
|
||||
{
|
||||
if (character == null) { return false; }
|
||||
if (character == Character.Controlled)
|
||||
{
|
||||
if (targetSections.Count == 0) { return false; }
|
||||
Spray(deltaTime);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//allow remote players to use the sprayer, but don't actually color the walls (we'll receive the data from the server)
|
||||
return character.IsRemotePlayer;
|
||||
}
|
||||
}
|
||||
|
||||
public void Spray(float deltaTime)
|
||||
{
|
||||
if (targetSections.Count == 0) { return; }
|
||||
|
||||
Item liquidItem = liquidContainer?.Inventory.Items[0];
|
||||
if (liquidItem == null) { return; }
|
||||
|
||||
bool isCleaning = false;
|
||||
liquidColors.TryGetValue(liquidItem.prefab.Identifier, out color);
|
||||
|
||||
// Ethanol or other cleaning solvent
|
||||
if (color.A == 0) { isCleaning = true; }
|
||||
|
||||
float sizeAdjustedSprayStrength = SprayStrength / targetSections.Count;
|
||||
|
||||
if (!isCleaning)
|
||||
{
|
||||
for (int i = 0; i < targetSections.Count; i++)
|
||||
{
|
||||
targetHull.SetSectionColorOrStrength(targetSections[i], color, sizeAdjustedSprayStrength * deltaTime, true, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < targetSections.Count; i++)
|
||||
{
|
||||
targetHull.CleanSection(targetSections[i], -sizeAdjustedSprayStrength * deltaTime, true);
|
||||
}
|
||||
}
|
||||
|
||||
Vector2 particleStartPos = item.WorldPosition + ConvertUnits.ToDisplayUnits(TransformedBarrelPos);
|
||||
Vector2 particleEndPos = Vector2.Zero;
|
||||
for (int i = 0; i < targetSections.Count; i++)
|
||||
{
|
||||
particleEndPos += new Vector2(targetSections[i].Rect.Center.X, targetSections[i].Rect.Y - targetSections[i].Rect.Height / 2) + targetHull.Rect.Location.ToVector2();
|
||||
}
|
||||
particleEndPos /= targetSections.Count;
|
||||
if (targetHull?.Submarine != null)
|
||||
{
|
||||
particleEndPos += targetHull.Submarine.Position;
|
||||
}
|
||||
float dist = Vector2.Distance(particleStartPos, particleEndPos);
|
||||
|
||||
foreach (ParticleEmitter particleEmitter in particleEmitters)
|
||||
{
|
||||
float particleAngle = item.body.Rotation + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi);
|
||||
float particleRange = particleEmitter.Prefab.VelocityMax * particleEmitter.Prefab.ParticlePrefab.LifeTime;
|
||||
particleEmitter.Emit(
|
||||
deltaTime, particleStartPos,
|
||||
item.CurrentHull, particleAngle, particleEmitter.Prefab.CopyEntityAngle ? -particleAngle : 0, velocityMultiplier: dist / particleRange * 1.5f,
|
||||
colorMultiplier: new Color(color.R, color.G, color.B, (byte)255));
|
||||
}
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, bool editing, float itemDepth = -1)
|
||||
{
|
||||
#if DEBUG
|
||||
if (GameMain.DebugDraw && Character.Controlled != null && Character.Controlled.IsKeyDown(InputType.Aim))
|
||||
{
|
||||
GUI.DrawLine(spriteBatch,
|
||||
new Vector2(debugRayStartPos.X, -debugRayStartPos.Y),
|
||||
new Vector2(debugRayEndPos.X, -debugRayEndPos.Y),
|
||||
Color.Yellow);
|
||||
}
|
||||
#endif
|
||||
if (Character.Controlled == null || !Character.Controlled.HasEquippedItem(item) || !Character.Controlled.IsKeyDown(InputType.Aim) || targetHull == null || targetSections.Count == 0) return;
|
||||
|
||||
Vector2 drawOffset = targetHull.Submarine == null ? Vector2.Zero : targetHull.Submarine.DrawPosition;
|
||||
Point sectionSize = targetSections[0].Rect.Size;
|
||||
Rectangle drawPositionRect = new Rectangle((int)(drawOffset.X + targetHull.Rect.X), (int)(drawOffset.Y + targetHull.Rect.Y), sectionSize.X, sectionSize.Y);
|
||||
|
||||
if (crosshairSprite == null && crosshairPointerSprite == null)
|
||||
{
|
||||
for (int i = 0; i < targetSections.Count; i++)
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch, new Vector2(drawPositionRect.X + targetSections[i].Rect.X, -(drawPositionRect.Y + targetSections[i].Rect.Y)), new Vector2(sectionSize.X, sectionSize.Y), Color.White, false, 0.0f, 1);
|
||||
}
|
||||
}
|
||||
else if (targetSections.Count > 0)
|
||||
{
|
||||
Vector2 drawPos = Vector2.Zero;
|
||||
for (int i = 0; i < targetSections.Count; i++)
|
||||
{
|
||||
drawPos += new Vector2(drawPositionRect.X + targetSections[i].Rect.X + sectionSize.X / 2, -(drawPositionRect.Y + targetSections[i].Rect.Y - sectionSize.Y / 2));
|
||||
}
|
||||
drawPos /= targetSections.Count;
|
||||
crosshairSprite?.Draw(spriteBatch, drawPos, scale: sectionSize.X * 3 / crosshairSprite.size.X);
|
||||
crosshairPointerSprite?.Draw(spriteBatch, drawPos, scale: sectionSize.X * (spraySetting + 1) / crosshairPointerSprite.size.X);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -256,6 +256,7 @@ namespace Barotrauma.Items.Components
|
||||
loopingSoundChannel = loopingSound.RoundSound.Sound.Play(
|
||||
new Vector3(item.WorldPosition, 0.0f),
|
||||
0.01f,
|
||||
loopingSound.RoundSound.GetRandomFrequencyMultiplier(),
|
||||
SoundPlayer.ShouldMuffleSound(Character.Controlled, item.WorldPosition, loopingSound.Range, Character.Controlled?.CurrentHull));
|
||||
loopingSoundChannel.Looping = true;
|
||||
//TODO: tweak
|
||||
@@ -326,7 +327,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, item.CurrentHull);
|
||||
var channel = SoundPlayer.PlaySound(itemSound.RoundSound.Sound, position, volume, itemSound.Range, itemSound.RoundSound.GetRandomFrequencyMultiplier(), item.CurrentHull);
|
||||
if (channel != null) { playingOneshotSoundChannels.Add(channel); }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,6 +172,8 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
Vector2 transformedItemPos = ItemPos * item.Scale;
|
||||
Vector2 transformedItemInterval = ItemInterval * item.Scale;
|
||||
Vector2 transformedItemIntervalHorizontal = new Vector2(transformedItemInterval.X, 0.0f);
|
||||
Vector2 transformedItemIntervalVertical = new Vector2(0.0f, transformedItemInterval.Y);
|
||||
|
||||
if (item.body == null)
|
||||
{
|
||||
@@ -180,15 +182,26 @@ namespace Barotrauma.Items.Components
|
||||
transformedItemPos.X = -transformedItemPos.X;
|
||||
transformedItemPos.X += item.Rect.Width;
|
||||
transformedItemInterval.X = -transformedItemInterval.X;
|
||||
transformedItemIntervalHorizontal.X = -transformedItemIntervalHorizontal.X;
|
||||
}
|
||||
if (item.FlippedY)
|
||||
{
|
||||
transformedItemPos.Y = -transformedItemPos.Y;
|
||||
transformedItemPos.Y -= item.Rect.Height;
|
||||
transformedItemInterval.Y = -transformedItemInterval.Y;
|
||||
transformedItemIntervalVertical.Y = -transformedItemIntervalVertical.Y;
|
||||
}
|
||||
transformedItemPos += new Vector2(item.Rect.X, item.Rect.Y);
|
||||
if (item.Submarine != null) { transformedItemPos += item.Submarine.DrawPosition; }
|
||||
|
||||
if (Math.Abs(item.Rotation) > 0.01f)
|
||||
{
|
||||
Matrix transform = Matrix.CreateRotationZ(MathHelper.ToRadians(-item.Rotation));
|
||||
transformedItemPos = Vector2.Transform(transformedItemPos - item.DrawPosition, transform) + item.DrawPosition;
|
||||
transformedItemInterval = Vector2.Transform(transformedItemInterval, transform);
|
||||
transformedItemIntervalHorizontal = Vector2.Transform(transformedItemIntervalHorizontal, transform);
|
||||
transformedItemIntervalVertical = Vector2.Transform(transformedItemIntervalVertical, transform);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -197,9 +210,12 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
transformedItemPos.X = -transformedItemPos.X;
|
||||
transformedItemInterval.X = -transformedItemInterval.X;
|
||||
transformedItemIntervalHorizontal.X = -transformedItemIntervalHorizontal.X;
|
||||
}
|
||||
|
||||
transformedItemPos = Vector2.Transform(transformedItemPos, transform);
|
||||
transformedItemInterval = Vector2.Transform(transformedItemInterval, transform);
|
||||
transformedItemIntervalHorizontal = Vector2.Transform(transformedItemIntervalHorizontal, transform);
|
||||
|
||||
transformedItemPos += item.DrawPosition;
|
||||
}
|
||||
@@ -207,8 +223,14 @@ namespace Barotrauma.Items.Components
|
||||
Vector2 currentItemPos = transformedItemPos;
|
||||
|
||||
SpriteEffects spriteEffects = SpriteEffects.None;
|
||||
if ((item.body != null && item.body.Dir == -1) || item.FlippedX) { spriteEffects |= SpriteEffects.FlipHorizontally; }
|
||||
if (item.FlippedY) { spriteEffects |= SpriteEffects.FlipVertically; }
|
||||
if ((item.body != null && item.body.Dir == -1) || item.FlippedX)
|
||||
{
|
||||
spriteEffects |= MathUtils.NearlyEqual(ItemRotation % 180, 90.0f) ? SpriteEffects.FlipVertically : SpriteEffects.FlipHorizontally;
|
||||
}
|
||||
if (item.FlippedY)
|
||||
{
|
||||
spriteEffects |= MathUtils.NearlyEqual(ItemRotation % 180, 90.0f) ? SpriteEffects.FlipHorizontally : SpriteEffects.FlipVertically;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
foreach (Item containedItem in Inventory.Items)
|
||||
@@ -233,7 +255,7 @@ namespace Barotrauma.Items.Components
|
||||
new Vector2(currentItemPos.X, -currentItemPos.Y),
|
||||
containedItem.GetSpriteColor(),
|
||||
origin,
|
||||
-(containedItem.body == null ? 0.0f : containedItem.body.DrawRotation),
|
||||
-(containedItem.body == null ? 0.0f : containedItem.body.DrawRotation + MathHelper.ToRadians(-item.Rotation)),
|
||||
containedItem.Scale,
|
||||
spriteEffects,
|
||||
depth: containedSpriteDepth);
|
||||
@@ -248,11 +270,11 @@ namespace Barotrauma.Items.Components
|
||||
if (Math.Abs(ItemInterval.X) > 0.001f && Math.Abs(ItemInterval.Y) > 0.001f)
|
||||
{
|
||||
//interval set on both axes -> use a grid layout
|
||||
currentItemPos.X += transformedItemInterval.X;
|
||||
currentItemPos += transformedItemIntervalHorizontal;
|
||||
if (i % ItemsPerRow == 0)
|
||||
{
|
||||
currentItemPos.X = transformedItemPos.X;
|
||||
currentItemPos.Y += transformedItemInterval.Y;
|
||||
currentItemPos = transformedItemPos;
|
||||
currentItemPos += transformedItemIntervalVertical * (i / ItemsPerRow);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -264,6 +286,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public override void UpdateHUD(Character character, float deltaTime, Camera cam)
|
||||
{
|
||||
if (item.NonInteractable) { return; }
|
||||
if (Inventory.RectTransform != null)
|
||||
{
|
||||
guiCustomComponent.RectTransform.Parent = Inventory.RectTransform;
|
||||
@@ -272,7 +295,7 @@ namespace Barotrauma.Items.Components
|
||||
//if the item is in the character's inventory, no need to update the item's inventory
|
||||
//because the player can see it by hovering the cursor over the item
|
||||
guiCustomComponent.Visible = item.ParentInventory?.Owner != character && DrawInventory;
|
||||
if (!guiCustomComponent.Visible) return;
|
||||
if (!guiCustomComponent.Visible) { return; }
|
||||
|
||||
Inventory.Update(deltaTime, cam);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Barotrauma.Networking;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Text;
|
||||
@@ -225,5 +226,10 @@ namespace Barotrauma.Items.Components
|
||||
textBlock.TextOffset = drawPos - textBlock.Rect.Location.ToVector2() + new Vector2(scrollAmount + scrollPadding, 0.0f);
|
||||
textBlock.DrawManually(spriteBatch);
|
||||
}
|
||||
|
||||
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
||||
{
|
||||
Text = msg.ReadString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,8 +49,8 @@ namespace Barotrauma.Items.Components
|
||||
if (light.LightSprite != null && (item.body == null || item.body.Enabled) && lightBrightness > 0.0f && IsOn)
|
||||
{
|
||||
Vector2 origin = light.LightSprite.Origin;
|
||||
if (light.LightSpriteEffect == SpriteEffects.FlipHorizontally) { origin.X = light.LightSprite.SourceRect.Width - origin.X; }
|
||||
if (light.LightSpriteEffect == SpriteEffects.FlipVertically) { origin.Y = light.LightSprite.SourceRect.Height - origin.Y; }
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,9 @@ namespace Barotrauma.Items.Components
|
||||
RelativeOffset = new Vector2(0.05f, 0)
|
||||
}, TextManager.Get("PumpAutoControl", fallBackTag: "ReactorAutoControl"), font: GUI.SubHeadingFont, style: "IndicatorLightYellow")
|
||||
{
|
||||
CanBeFocused = false
|
||||
Selected = false,
|
||||
Enabled = false,
|
||||
ToolTip = TextManager.Get("AutoControlTip")
|
||||
};
|
||||
powerIndicator.TextBlock.Wrap = autoControlIndicator.TextBlock.Wrap = true;
|
||||
powerIndicator.TextBlock.OverrideTextColor(GUI.Style.TextColor);
|
||||
@@ -75,6 +77,7 @@ namespace Barotrauma.Items.Components
|
||||
if (Math.Abs(newTargetForce - targetForce) < 0.01) { return false; }
|
||||
|
||||
targetForce = newTargetForce;
|
||||
User = Character.Controlled;
|
||||
|
||||
if (GameMain.Client != null)
|
||||
{
|
||||
@@ -145,7 +148,7 @@ namespace Barotrauma.Items.Components
|
||||
propellerSprite.Draw(spriteBatch, (int)Math.Floor(spriteIndex), drawPos, Color.White, propellerSprite.Origin, 0.0f, Vector2.One);
|
||||
}
|
||||
|
||||
if (editing)
|
||||
if (editing && !GUI.DisableHUD)
|
||||
{
|
||||
Vector2 drawPos = item.DrawPosition;
|
||||
drawPos += PropellerPos;
|
||||
@@ -164,11 +167,16 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (correctionTimer > 0.0f)
|
||||
{
|
||||
StartDelayedCorrection(type, msg.ExtractBits(5), sendingTime);
|
||||
StartDelayedCorrection(type, msg.ExtractBits(5 + 16), sendingTime);
|
||||
return;
|
||||
}
|
||||
|
||||
targetForce = msg.ReadRangedInteger(-10, 10) * 10.0f;
|
||||
UInt16 userID = msg.ReadUInt16();
|
||||
if (userID != Entity.NullEntityID)
|
||||
{
|
||||
User = Entity.FindEntityByID(userID) as Character;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ namespace Barotrauma.Items.Components
|
||||
OnSelected = (component, userdata) =>
|
||||
{
|
||||
selectedItem = userdata as FabricationRecipe;
|
||||
if (selectedItem != null) SelectItem(Character.Controlled, selectedItem);
|
||||
if (selectedItem != null) { SelectItem(Character.Controlled, selectedItem); }
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -292,7 +292,7 @@ namespace Barotrauma.Items.Components
|
||||
foreach (Item item in inputContainer.Inventory.Items)
|
||||
{
|
||||
if (item == null) { continue; }
|
||||
missingItems.Remove(missingItems.FirstOrDefault(mi => mi.ItemPrefab == item.prefab));
|
||||
missingItems.Remove(missingItems.FirstOrDefault(mi => mi.ItemPrefabs.Contains(item.prefab)));
|
||||
}
|
||||
|
||||
var availableIngredients = GetAvailableIngredients();
|
||||
@@ -328,12 +328,12 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (slotIndex >= inputContainer.Capacity) { break; }
|
||||
|
||||
var itemIcon = requiredItem.ItemPrefab.InventoryIcon ?? requiredItem.ItemPrefab.sprite;
|
||||
var itemIcon = requiredItem.ItemPrefabs.First().InventoryIcon ?? requiredItem.ItemPrefabs.First().sprite;
|
||||
Rectangle slotRect = inputContainer.Inventory.slots[slotIndex].Rect;
|
||||
itemIcon.Draw(
|
||||
spriteBatch,
|
||||
slotRect.Center.ToVector2(),
|
||||
color: requiredItem.ItemPrefab.InventoryIconColor * 0.3f,
|
||||
color: requiredItem.ItemPrefabs.First().InventoryIconColor * 0.3f,
|
||||
scale: Math.Min(slotRect.Width / itemIcon.size.X, slotRect.Height / itemIcon.size.Y));
|
||||
|
||||
if (requiredItem.UseCondition && requiredItem.MinCondition < 1.0f)
|
||||
@@ -346,14 +346,16 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (slotRect.Contains(PlayerInput.MousePosition))
|
||||
{
|
||||
string toolTipText = requiredItem.ItemPrefab.Name;
|
||||
var suitableIngredients = requiredItem.ItemPrefabs.Select(ip => ip.Name);
|
||||
string toolTipText = string.Join(", ", suitableIngredients.Count() > 3 ? suitableIngredients.SkipLast(suitableIngredients.Count() - 3) : suitableIngredients);
|
||||
if (suitableIngredients.Count() > 3) { toolTipText += "..."; }
|
||||
if (requiredItem.UseCondition && requiredItem.MinCondition < 1.0f)
|
||||
{
|
||||
toolTipText += " " + (int)Math.Round(requiredItem.MinCondition * 100) + "%";
|
||||
}
|
||||
if (!string.IsNullOrEmpty(requiredItem.ItemPrefab.Description))
|
||||
if (!string.IsNullOrEmpty(requiredItem.ItemPrefabs.First().Description))
|
||||
{
|
||||
toolTipText += '\n' + requiredItem.ItemPrefab.Description;
|
||||
toolTipText += '\n' + requiredItem.ItemPrefabs.First().Description;
|
||||
}
|
||||
tooltip = new Pair<Rectangle, string>(slotRect, toolTipText);
|
||||
}
|
||||
@@ -378,10 +380,11 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (fabricatedItem != null)
|
||||
{
|
||||
float clampedProgressState = Math.Clamp(progressState, 0f, 1f);
|
||||
GUI.DrawRectangle(spriteBatch,
|
||||
new Rectangle(
|
||||
slotRect.X, slotRect.Y + (int)(slotRect.Height * (1.0f - progressState)),
|
||||
slotRect.Width, (int)(slotRect.Height * progressState)),
|
||||
slotRect.X, slotRect.Y + (int)(slotRect.Height * (1.0f - clampedProgressState)),
|
||||
slotRect.Width, (int)(slotRect.Height * clampedProgressState)),
|
||||
GUI.Style.Green * 0.5f, isFilled: true);
|
||||
}
|
||||
|
||||
@@ -429,8 +432,10 @@ namespace Barotrauma.Items.Components
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool SelectItem(Character user, FabricationRecipe selectedItem)
|
||||
private bool SelectItem(Character user, FabricationRecipe selectedItem, float? overrideRequiredTime = null)
|
||||
{
|
||||
this.selectedItem = selectedItem;
|
||||
|
||||
selectedItemFrame.ClearChildren();
|
||||
selectedItemReqsFrame.ClearChildren();
|
||||
|
||||
@@ -496,7 +501,8 @@ namespace Barotrauma.Items.Components
|
||||
float degreeOfSuccess = user == null ? 0.0f : FabricationDegreeOfSuccess(user, selectedItem.RequiredSkills);
|
||||
if (degreeOfSuccess > 0.5f) { degreeOfSuccess = 1.0f; }
|
||||
|
||||
float requiredTime = user == null ? selectedItem.RequiredTime : GetRequiredTime(selectedItem, user);
|
||||
float requiredTime = overrideRequiredTime ??
|
||||
(user == null ? selectedItem.RequiredTime : GetRequiredTime(selectedItem, user));
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedReqFrame.RectTransform),
|
||||
TextManager.Get("FabricatorRequiredTime") , textColor: ToolBox.GradientLerp(degreeOfSuccess, GUI.Style.Red, Color.Yellow, GUI.Style.Green), font: GUI.SubHeadingFont)
|
||||
@@ -605,7 +611,7 @@ namespace Barotrauma.Items.Components
|
||||
State = newState;
|
||||
timeUntilReady = newTimeUntilReady;
|
||||
|
||||
if (newState == FabricatorState.Stopped || itemIndex == -1 || user == null)
|
||||
if (newState == FabricatorState.Stopped || itemIndex == -1)
|
||||
{
|
||||
CancelFabricating();
|
||||
}
|
||||
|
||||
@@ -81,7 +81,9 @@ namespace Barotrauma.Items.Components
|
||||
autoControlIndicator = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.25f), rightArea.RectTransform, Anchor.TopLeft),
|
||||
TextManager.Get("PumpAutoControl", fallBackTag: "ReactorAutoControl"), font: GUI.SubHeadingFont, style: "IndicatorLightYellow")
|
||||
{
|
||||
CanBeFocused = false
|
||||
Selected = false,
|
||||
Enabled = false,
|
||||
ToolTip = TextManager.Get("AutoControlTip")
|
||||
};
|
||||
autoControlIndicator.TextBlock.AutoScaleHorizontal = true;
|
||||
autoControlIndicator.TextBlock.OverrideTextColor(GUI.Style.TextColor);
|
||||
|
||||
@@ -131,17 +131,23 @@ namespace Barotrauma.Items.Components
|
||||
criticalHeatWarning = new GUITickBox(new RectTransform(new Vector2(0.33f, 1.0f), topLeftArea.RectTransform) { MaxSize = maxIndicatorSize },
|
||||
TextManager.Get("ReactorWarningCriticalTemp"), font: GUI.SubHeadingFont, style: "IndicatorLightRed")
|
||||
{
|
||||
CanBeFocused = false
|
||||
Selected = false,
|
||||
Enabled = false,
|
||||
ToolTip = TextManager.Get("ReactorHeatTip")
|
||||
};
|
||||
lowTemperatureWarning = new GUITickBox(new RectTransform(new Vector2(0.33f, 1.0f), topLeftArea.RectTransform) { MaxSize = maxIndicatorSize },
|
||||
TextManager.Get("ReactorWarningCriticalLowTemp"), font: GUI.SubHeadingFont, style: "IndicatorLightRed")
|
||||
{
|
||||
CanBeFocused = false
|
||||
Selected = false,
|
||||
Enabled = false,
|
||||
ToolTip = TextManager.Get("ReactorTempTip")
|
||||
};
|
||||
criticalOutputWarning = new GUITickBox(new RectTransform(new Vector2(0.33f, 1.0f), topLeftArea.RectTransform) { MaxSize = maxIndicatorSize },
|
||||
TextManager.Get("ReactorWarningCriticalOutput"), font: GUI.SubHeadingFont, style: "IndicatorLightRed")
|
||||
{
|
||||
CanBeFocused = false
|
||||
Selected = false,
|
||||
Enabled = false,
|
||||
ToolTip = TextManager.Get("ReactorOutputTip")
|
||||
};
|
||||
List<GUITickBox> indicatorLights = new List<GUITickBox>() { criticalHeatWarning, lowTemperatureWarning, criticalOutputWarning };
|
||||
indicatorLights.ForEach(l => l.TextBlock.OverrideTextColor(GUI.Style.TextColor));
|
||||
|
||||
@@ -6,7 +6,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.Extensions;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
@@ -20,7 +19,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private PathFinder pathFinder;
|
||||
|
||||
private bool dynamicDockingIndicator = true;
|
||||
private readonly bool dynamicDockingIndicator = true;
|
||||
|
||||
private bool unsentChanges;
|
||||
private float networkUpdateTimer;
|
||||
@@ -378,7 +377,6 @@ namespace Barotrauma.Items.Components
|
||||
float edgeDist = Rand.Range(0.0f, 1.0f);
|
||||
Vector2 blipPos = trigger.WorldPosition + Rand.Vector(trigger.ColliderRadius * edgeDist);
|
||||
Vector2 blipVel = flow;
|
||||
if (trigger.ForceFalloff) flow *= (1.0f - edgeDist);
|
||||
|
||||
//go through other triggers in range and add the flows of the ones that the blip is inside
|
||||
foreach (KeyValuePair<LevelTrigger, Vector2> triggerFlow2 in levelTriggerFlows)
|
||||
@@ -387,7 +385,7 @@ namespace Barotrauma.Items.Components
|
||||
if (trigger2 != trigger && Vector2.DistanceSquared(blipPos, trigger2.WorldPosition) < trigger2.ColliderRadius * trigger2.ColliderRadius)
|
||||
{
|
||||
Vector2 trigger2flow = triggerFlow2.Value;
|
||||
if (trigger2.ForceFalloff) trigger2flow *= (1.0f - Vector2.Distance(blipPos, trigger2.WorldPosition) / trigger2.ColliderRadius);
|
||||
if (trigger2.ForceFalloff) trigger2flow *= 1.0f - Vector2.Distance(blipPos, trigger2.WorldPosition) / trigger2.ColliderRadius;
|
||||
blipVel += trigger2flow;
|
||||
}
|
||||
}
|
||||
@@ -507,7 +505,7 @@ namespace Barotrauma.Items.Components
|
||||
float passivePingRadius = (float)(Timing.TotalTime % 1.0f);
|
||||
if (passivePingRadius > 0.0f)
|
||||
{
|
||||
disruptedDirections.Clear();
|
||||
if (activePingsCount == 0) { disruptedDirections.Clear(); }
|
||||
foreach (AITarget t in AITarget.List)
|
||||
{
|
||||
if (t.Entity is Character c && c.Params.HideInSonar) { continue; }
|
||||
@@ -581,14 +579,14 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
if (currentMode == Mode.Active && currentPingIndex != -1)
|
||||
if (currentPingIndex != -1)
|
||||
{
|
||||
var activePing = activePings[currentPingIndex];
|
||||
if (activePing.IsDirectional && directionalPingCircle != null)
|
||||
{
|
||||
directionalPingCircle.Draw(spriteBatch, center, Color.White * (1.0f - activePing.State),
|
||||
rotate: MathUtils.VectorToAngle(activePing.Direction),
|
||||
scale: (DisplayRadius / directionalPingCircle.size.X) * activePing.State);
|
||||
rotate: MathUtils.VectorToAngle(activePing.Direction),
|
||||
scale: DisplayRadius / directionalPingCircle.size.X * activePing.State);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -611,13 +609,13 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (sonarBlips.Count > 0)
|
||||
{
|
||||
zoomSqrt = (float)Math.Sqrt(zoom);
|
||||
float blipScale = 0.08f * (float)Math.Sqrt(zoom) * (rect.Width / 700.0f);
|
||||
spriteBatch.End();
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive);
|
||||
|
||||
foreach (SonarBlip sonarBlip in sonarBlips)
|
||||
{
|
||||
DrawBlip(spriteBatch, sonarBlip, transducerCenter, center, sonarBlip.FadeTimer / 2.0f * signalStrength);
|
||||
DrawBlip(spriteBatch, sonarBlip, transducerCenter, center, sonarBlip.FadeTimer / 2.0f * signalStrength, blipScale);
|
||||
}
|
||||
|
||||
spriteBatch.End();
|
||||
@@ -1297,7 +1295,7 @@ namespace Barotrauma.Items.Components
|
||||
return true;
|
||||
}
|
||||
|
||||
private void DrawBlip(SpriteBatch spriteBatch, SonarBlip blip, Vector2 transducerPos, Vector2 center, float strength)
|
||||
private void DrawBlip(SpriteBatch spriteBatch, SonarBlip blip, Vector2 transducerPos, Vector2 center, float strength, float blipScale)
|
||||
{
|
||||
strength = MathHelper.Clamp(strength, 0.0f, 1.0f);
|
||||
|
||||
@@ -1306,8 +1304,8 @@ namespace Barotrauma.Items.Components
|
||||
Vector2 pos = (blip.Position - transducerPos) * displayScale * zoom;
|
||||
pos.Y = -pos.Y;
|
||||
|
||||
if (Rand.Range(0.5f, 2.0f) < distort) pos.X = -pos.X;
|
||||
if (Rand.Range(0.5f, 2.0f) < distort) pos.Y = -pos.Y;
|
||||
if (Rand.Range(0.5f, 2.0f) < distort) { pos.X = -pos.X; }
|
||||
if (Rand.Range(0.5f, 2.0f) < distort) { pos.Y = -pos.Y; }
|
||||
|
||||
float posDistSqr = pos.LengthSquared();
|
||||
if (posDistSqr > DisplayRadius * DisplayRadius)
|
||||
@@ -1324,15 +1322,15 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
Vector2 dir = pos / (float)Math.Sqrt(posDistSqr);
|
||||
Vector2 normal = new Vector2(dir.Y, -dir.X);
|
||||
float scale = (strength + 3.0f) * blip.Scale * zoomSqrt;
|
||||
float scale = (strength + 3.0f) * blip.Scale * blipScale;
|
||||
Color color = ToolBox.GradientLerp(strength, blipColorGradient[blip.BlipType]);
|
||||
|
||||
sonarBlip.Draw(spriteBatch, center + pos, color, sonarBlip.Origin, blip.Rotation ?? MathUtils.VectorToAngle(pos),
|
||||
blip.Size * scale * 0.04f, SpriteEffects.None, 0);
|
||||
blip.Size * scale * 0.5f, SpriteEffects.None, 0);
|
||||
|
||||
pos += Rand.Range(0.0f, 1.0f) * dir + Rand.Range(-scale, scale) * normal;
|
||||
|
||||
sonarBlip.Draw(spriteBatch, center + pos, color * 0.5f, sonarBlip.Origin, 0, scale * 0.08f, SpriteEffects.None, 0);
|
||||
sonarBlip.Draw(spriteBatch, center + pos, color * 0.5f, sonarBlip.Origin, 0, scale, SpriteEffects.None, 0);
|
||||
}
|
||||
|
||||
private void DrawMarker(SpriteBatch spriteBatch, string label, string iconIdentifier, object targetIdentifier, Vector2 worldPosition, Vector2 transducerPosition, float scale, Vector2 center, float radius)
|
||||
|
||||
@@ -22,6 +22,7 @@ namespace Barotrauma.Items.Components
|
||||
LevelEnd,
|
||||
LevelStart
|
||||
};
|
||||
|
||||
private GUITickBox maintainPosTickBox, levelEndTickBox, levelStartTickBox;
|
||||
|
||||
private GUIComponent statusContainer, dockingContainer, controlContainer;
|
||||
@@ -349,20 +350,34 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
OnClicked = (btn, userdata) =>
|
||||
{
|
||||
|
||||
if (GameMain.GameSession?.Campaign != null)
|
||||
if (GameMain.GameSession?.Campaign is CampaignMode campaign)
|
||||
{
|
||||
if (Level.IsLoadedOutpost &&
|
||||
DockingSources.Any(d => d.Docked && (d.DockingTarget?.Item.Submarine?.Info?.IsOutpost ?? false)))
|
||||
{
|
||||
GameMain.GameSession.Campaign.CampaignUI.SelectTab(CampaignMode.InteractionType.Map);
|
||||
GameMain.GameSession.Campaign.ShowCampaignUI = true;
|
||||
// Undocking from an outpost
|
||||
campaign.CampaignUI.SelectTab(CampaignMode.InteractionType.Map);
|
||||
campaign.ShowCampaignUI = true;
|
||||
return false;
|
||||
}
|
||||
else if (!Level.IsLoadedOutpost && DockingModeEnabled && ActiveDockingSource != null &&
|
||||
!ActiveDockingSource.Docked && (DockingTarget?.Item?.Submarine?.Info.IsOutpost ?? false))
|
||||
!ActiveDockingSource.Docked && DockingTarget?.Item?.Submarine == Level.Loaded.StartOutpost && (DockingTarget?.Item?.Submarine?.Info.IsOutpost ?? false))
|
||||
{
|
||||
enterOutpostPrompt = new GUIMessageBox("", TextManager.GetWithVariable("campaignenteroutpostprompt", "[locationname]", DockingTarget.Item.Submarine.Info.Name), new string[] { TextManager.Get("yes"), TextManager.Get("no") });
|
||||
// Docking to an outpost
|
||||
var subsToLeaveBehind = campaign.GetSubsToLeaveBehind(Item.Submarine);
|
||||
if (subsToLeaveBehind.Any())
|
||||
{
|
||||
enterOutpostPrompt = new GUIMessageBox(
|
||||
TextManager.GetWithVariable("enterlocation", "[locationname]", DockingTarget.Item.Submarine.Info.Name),
|
||||
TextManager.Get(subsToLeaveBehind.Count == 1 ? "LeaveSubBehind" : "LeaveSubsBehind"),
|
||||
new string[] { TextManager.Get("yes"), TextManager.Get("no") });
|
||||
}
|
||||
else
|
||||
{
|
||||
enterOutpostPrompt = new GUIMessageBox("",
|
||||
TextManager.GetWithVariable("campaignenteroutpostprompt", "[locationname]", DockingTarget.Item.Submarine.Info.Name),
|
||||
new string[] { TextManager.Get("yes"), TextManager.Get("no") });
|
||||
}
|
||||
enterOutpostPrompt.Buttons[0].OnClicked += (btn, userdata) =>
|
||||
{
|
||||
SendDockingSignal();
|
||||
@@ -780,10 +795,16 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
checkConnectedPortsTimer = CheckConnectedPortsInterval;
|
||||
}
|
||||
else
|
||||
{
|
||||
checkConnectedPortsTimer -= deltaTime;
|
||||
}
|
||||
|
||||
float closestDist = DockingAssistThreshold * DockingAssistThreshold;
|
||||
DockingModeEnabled = false;
|
||||
|
||||
|
||||
if (connectedPorts.None()) { return; }
|
||||
|
||||
float closestDist = DockingAssistThreshold * DockingAssistThreshold;
|
||||
foreach (DockingPort sourcePort in connectedPorts)
|
||||
{
|
||||
if (sourcePort.Docked || sourcePort.Item.Submarine == null) { continue; }
|
||||
@@ -795,15 +816,14 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (targetPort.Docked || targetPort.Item.Submarine == null) { continue; }
|
||||
if (targetPort.Item.Submarine == controlledSub || targetPort.IsHorizontal != sourcePort.IsHorizontal) { continue; }
|
||||
if (targetPort.Item.Submarine.DockedTo?.Contains(sourcePort.Item.Submarine) ?? false) { continue; }
|
||||
if (Level.Loaded != null && targetPort.Item.Submarine.WorldPosition.Y > Level.Loaded.Size.Y) { continue; }
|
||||
|
||||
int targetDir = targetPort.GetDir();
|
||||
|
||||
if (sourceDir == targetDir) { continue; }
|
||||
if (sourceDir == targetPort.GetDir()) { continue; }
|
||||
|
||||
float dist = Vector2.DistanceSquared(sourcePort.Item.WorldPosition, targetPort.Item.WorldPosition);
|
||||
if (dist < closestDist)
|
||||
{
|
||||
closestDist = dist;
|
||||
DockingModeEnabled = true;
|
||||
ActiveDockingSource = sourcePort;
|
||||
DockingTarget = targetPort;
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
internal partial class Planter
|
||||
{
|
||||
public Vector2 DrawSize => CalculateSize();
|
||||
|
||||
private Vector2 CalculateSize()
|
||||
{
|
||||
if (GrowableSeeds.All(s => s == null)) { return Vector2.Zero; }
|
||||
|
||||
Point pos = item.DrawPosition.ToPoint();
|
||||
Rectangle rect = new Rectangle(pos, Point.Zero);
|
||||
|
||||
for (int i = 0; i < GrowableSeeds.Length; i++)
|
||||
{
|
||||
Growable seed = GrowableSeeds[i];
|
||||
PlantSlot slot = PlantSlots.ContainsKey(i) ? PlantSlots[i] : NullSlot;
|
||||
if (seed == null) { continue; }
|
||||
|
||||
foreach (VineTile vine in seed.Vines)
|
||||
{
|
||||
Rectangle worldRect = vine.Rect;
|
||||
worldRect.Location += slot.Offset.ToPoint();
|
||||
worldRect.Location += pos;
|
||||
rect = Rectangle.Union(rect, worldRect);
|
||||
}
|
||||
}
|
||||
|
||||
Vector2 result = new Vector2(MaxDistance(pos.X, rect.Left, rect.Right) * 2, MaxDistance(pos.Y, rect.Top, rect.Bottom) * 2);
|
||||
return result;
|
||||
|
||||
static float MaxDistance(float origin, float x, float y)
|
||||
{
|
||||
return Math.Max(Math.Abs(origin - x), Math.Abs(origin - y));
|
||||
}
|
||||
}
|
||||
|
||||
private LightComponent lightComponent;
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, bool editing, float itemDepth = -1)
|
||||
{
|
||||
for (var i = 0; i < GrowableSeeds.Length; i++)
|
||||
{
|
||||
Growable growable = GrowableSeeds[i];
|
||||
PlantSlot slot = PlantSlots.ContainsKey(i) ? PlantSlots[i] : NullSlot;
|
||||
growable?.Draw(spriteBatch, this, slot.Offset, itemDepth);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@ namespace Barotrauma.Items.Components
|
||||
private List<Pair<RelatedItem, ParticleEmitter>> particleEmitterHitItem = new List<Pair<RelatedItem, ParticleEmitter>>();
|
||||
|
||||
private float prevProgressBarState;
|
||||
private Item prevProgressBarTarget = null;
|
||||
|
||||
partial void InitProjSpecific(XElement element)
|
||||
{
|
||||
@@ -65,7 +66,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
foreach (ParticleEmitter particleEmitter in particleEmitters)
|
||||
{
|
||||
float particleAngle = item.body.Rotation + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi);
|
||||
float particleAngle = item.body.Rotation + MathHelper.ToRadians(BarrelRotation) + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi);
|
||||
particleEmitter.Emit(
|
||||
deltaTime, ConvertUnits.ToDisplayUnits(raystart),
|
||||
item.CurrentHull, particleAngle, particleEmitter.Prefab.CopyEntityAngle ? -particleAngle : 0);
|
||||
@@ -92,7 +93,7 @@ namespace Barotrauma.Items.Components
|
||||
if (targetStructure.Submarine != null) particlePos += targetStructure.Submarine.DrawPosition;
|
||||
foreach (var emitter in particleEmitterHitStructure)
|
||||
{
|
||||
float particleAngle = item.body.Rotation + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi);
|
||||
float particleAngle = item.body.Rotation + MathHelper.ToRadians(BarrelRotation) + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi);
|
||||
emitter.Emit(deltaTime, particlePos, item.CurrentHull, particleAngle + MathHelper.Pi, -particleAngle + MathHelper.Pi);
|
||||
}
|
||||
}
|
||||
@@ -103,7 +104,7 @@ namespace Barotrauma.Items.Components
|
||||
if (targetCharacter.Submarine != null) particlePos += targetCharacter.Submarine.DrawPosition;
|
||||
foreach (var emitter in particleEmitterHitCharacter)
|
||||
{
|
||||
float particleAngle = item.body.Rotation + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi);
|
||||
float particleAngle = item.body.Rotation + MathHelper.ToRadians(BarrelRotation) + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi);
|
||||
emitter.Emit(deltaTime, particlePos, item.CurrentHull, particleAngle + MathHelper.Pi, -particleAngle + MathHelper.Pi);
|
||||
}
|
||||
}
|
||||
@@ -111,7 +112,7 @@ namespace Barotrauma.Items.Components
|
||||
partial void FixItemProjSpecific(Character user, float deltaTime, Item targetItem)
|
||||
{
|
||||
float progressBarState = targetItem.ConditionPercentage / 100.0f;
|
||||
if (!MathUtils.NearlyEqual(progressBarState, prevProgressBarState))
|
||||
if (!MathUtils.NearlyEqual(progressBarState, prevProgressBarState) || prevProgressBarTarget != targetItem)
|
||||
{
|
||||
var door = targetItem.GetComponent<Door>();
|
||||
if (door == null || door.Stuck <= 0)
|
||||
@@ -121,18 +122,20 @@ namespace Barotrauma.Items.Components
|
||||
targetItem,
|
||||
progressBarPos,
|
||||
progressBarState,
|
||||
GUI.Style.Red, GUI.Style.Green);
|
||||
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;
|
||||
}
|
||||
|
||||
Vector2 particlePos = ConvertUnits.ToDisplayUnits(pickedPosition);
|
||||
if (targetItem.Submarine != null) particlePos += targetItem.Submarine.DrawPosition;
|
||||
foreach (var emitter in particleEmitterHitItem)
|
||||
{
|
||||
if (!emitter.First.MatchesItem(targetItem)) continue;
|
||||
float particleAngle = item.body.Rotation + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi);
|
||||
if (!emitter.First.MatchesItem(targetItem)) { continue; }
|
||||
float particleAngle = item.body.Rotation + MathHelper.ToRadians(BarrelRotation) + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi);
|
||||
emitter.Second.Emit(deltaTime, particlePos, item.CurrentHull, particleAngle + MathHelper.Pi, -particleAngle + MathHelper.Pi);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,6 +192,7 @@ namespace Barotrauma.Items.Components
|
||||
foreach (Wire wire in panel.DisconnectedWires)
|
||||
{
|
||||
if (wire == DraggingConnected && mouseInRect) { continue; }
|
||||
if (wire.HiddenInGame && Screen.Selected == GameMain.GameScreen) { continue; }
|
||||
|
||||
Connection recipient = wire.OtherConnection(null);
|
||||
string label = recipient == null ? "" : recipient.item.Name + $" ({recipient.DisplayName})";
|
||||
@@ -238,6 +239,7 @@ namespace Barotrauma.Items.Components
|
||||
for (int i = 0; i < MaxLinked; 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; }
|
||||
|
||||
Connection recipient = wires[i].OtherConnection(this);
|
||||
string label = recipient == null ? "" : recipient.item.Name + $" ({recipient.DisplayName})";
|
||||
@@ -289,7 +291,7 @@ namespace Barotrauma.Items.Components
|
||||
flashColor * (float)Math.Sin(FlashTimer % flashCycleDuration / flashCycleDuration * MathHelper.Pi * 0.8f), scale: connectorSpriteScale);
|
||||
}
|
||||
|
||||
if (Wires.Any(w => w != null && w != DraggingConnected && !w.Hidden))
|
||||
if (Wires.Any(w => w != null && w != DraggingConnected && !w.Hidden && (!w.HiddenInGame || Screen.Selected != GameMain.GameScreen)))
|
||||
{
|
||||
int screwIndex = (int)Math.Floor(position.Y / 30.0f) % screwSprites.Count;
|
||||
screwSprites[screwIndex].Draw(spriteBatch, position, scale: connectorSpriteScale);
|
||||
@@ -325,7 +327,7 @@ namespace Barotrauma.Items.Components
|
||||
canDrag &&
|
||||
((PlayerInput.MousePosition.X > Math.Min(start.X, end.X) &&
|
||||
PlayerInput.MousePosition.X < Math.Max(start.X, end.X) &&
|
||||
MathUtils.LineToPointDistance(start, end, PlayerInput.MousePosition) < 6) ||
|
||||
MathUtils.LineToPointDistanceSquared(start, end, PlayerInput.MousePosition) < 36) ||
|
||||
Vector2.Distance(end, PlayerInput.MousePosition) < 20.0f ||
|
||||
new Rectangle((start.X < end.X) ? textX - 100 : textX, (int)start.Y - 5, 100, 14).Contains(PlayerInput.MousePosition));
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
using Barotrauma.Networking;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class MemoryComponent : ItemComponent
|
||||
{
|
||||
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
||||
{
|
||||
Value = msg.ReadString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -165,6 +165,12 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!string.IsNullOrEmpty(target.customInteractHUDText) && target.AllowCustomInteract)
|
||||
{
|
||||
texts.Add(target.customInteractHUDText);
|
||||
textColors.Add(GUI.Style.Green);
|
||||
}
|
||||
|
||||
if (target.IsUnconscious)
|
||||
{
|
||||
texts.Add(TextManager.Get("Unconscious"));
|
||||
|
||||
@@ -17,6 +17,17 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private GUIProgressBar powerIndicator;
|
||||
|
||||
public int UIElementHeight
|
||||
{
|
||||
get
|
||||
{
|
||||
int height = 0;
|
||||
if (ShowChargeIndicator) { height += powerIndicator.Rect.Height; }
|
||||
if (ShowProjectileIndicator) { height += (int)(Inventory.SlotSpriteSmall.size.Y * Inventory.UIScale) + 5; }
|
||||
return height;
|
||||
}
|
||||
}
|
||||
|
||||
private float recoilTimer;
|
||||
|
||||
private float RetractionTime => Math.Max(Reload * RetractionDurationMultiplier, RecoilTime);
|
||||
@@ -235,12 +246,11 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, bool editing = false, float itemDepth = -1)
|
||||
{
|
||||
Vector2 drawPos = new Vector2(item.Rect.X + transformedBarrelPos.X, item.Rect.Y - transformedBarrelPos.Y);
|
||||
if (item.Submarine != null)
|
||||
if (!MathUtils.NearlyEqual(item.Rotation, prevBaseRotation))
|
||||
{
|
||||
drawPos += item.Submarine.DrawPosition;
|
||||
UpdateTransformedBarrelPos();
|
||||
}
|
||||
drawPos.Y = -drawPos.Y;
|
||||
Vector2 drawPos = GetDrawPos();
|
||||
|
||||
float recoilOffset = 0.0f;
|
||||
if (Math.Abs(RecoilDistance) > 0.0f && recoilTimer > 0.0f)
|
||||
@@ -275,7 +285,7 @@ namespace Barotrauma.Items.Components
|
||||
rotation + MathHelper.PiOver2, item.Scale,
|
||||
SpriteEffects.None, item.SpriteDepth + (barrelSprite.Depth - item.Sprite.Depth));
|
||||
|
||||
if (!editing) { return; }
|
||||
if (!editing || GUI.DisableHUD) { return; }
|
||||
|
||||
float widgetRadius = 60.0f;
|
||||
|
||||
@@ -310,7 +320,7 @@ namespace Barotrauma.Items.Components
|
||||
};
|
||||
widget.MouseHeld += (deltaTime) =>
|
||||
{
|
||||
minRotation = GetRotationAngle(drawPos);
|
||||
minRotation = GetRotationAngle(GetDrawPos());
|
||||
if (minRotation > maxRotation)
|
||||
{
|
||||
float temp = minRotation;
|
||||
@@ -332,7 +342,7 @@ namespace Barotrauma.Items.Components
|
||||
widget.PreDraw += (sprtBtch, deltaTime) =>
|
||||
{
|
||||
widget.tooltip = "Min: " + (int)MathHelper.ToDegrees(minRotation);
|
||||
widget.DrawPos = drawPos + new Vector2((float)Math.Cos(minRotation), (float)Math.Sin(minRotation)) * widgetRadius;
|
||||
widget.DrawPos = GetDrawPos() + new Vector2((float)Math.Cos(minRotation), (float)Math.Sin(minRotation)) * widgetRadius;
|
||||
widget.Update(deltaTime);
|
||||
};
|
||||
});
|
||||
@@ -351,7 +361,7 @@ namespace Barotrauma.Items.Components
|
||||
};
|
||||
widget.MouseHeld += (deltaTime) =>
|
||||
{
|
||||
maxRotation = GetRotationAngle(drawPos);
|
||||
maxRotation = GetRotationAngle(GetDrawPos());
|
||||
if (minRotation > maxRotation)
|
||||
{
|
||||
float temp = minRotation;
|
||||
@@ -373,12 +383,20 @@ namespace Barotrauma.Items.Components
|
||||
widget.PreDraw += (sprtBtch, deltaTime) =>
|
||||
{
|
||||
widget.tooltip = "Max: " + (int)MathHelper.ToDegrees(maxRotation);
|
||||
widget.DrawPos = drawPos + new Vector2((float)Math.Cos(maxRotation), (float)Math.Sin(maxRotation)) * widgetRadius;
|
||||
widget.DrawPos = GetDrawPos() + new Vector2((float)Math.Cos(maxRotation), (float)Math.Sin(maxRotation)) * widgetRadius;
|
||||
widget.Update(deltaTime);
|
||||
};
|
||||
});
|
||||
minRotationWidget.Draw(spriteBatch, (float)Timing.Step);
|
||||
maxRotationWidget.Draw(spriteBatch, (float)Timing.Step);
|
||||
|
||||
Vector2 GetDrawPos()
|
||||
{
|
||||
Vector2 drawPos = new Vector2(item.Rect.X + transformedBarrelPos.X, item.Rect.Y - transformedBarrelPos.Y);
|
||||
if (item.Submarine != null) { drawPos += item.Submarine.DrawPosition; }
|
||||
drawPos.Y = -drawPos.Y;
|
||||
return drawPos;
|
||||
}
|
||||
}
|
||||
|
||||
private Widget GetWidget(string id, SpriteBatch spriteBatch, int size = 5, Action<Widget> initMethod = null)
|
||||
|
||||
Reference in New Issue
Block a user