(f0d812055) v0.9.9.0
This commit is contained in:
@@ -52,10 +52,14 @@ namespace Barotrauma.Items.Components
|
||||
get { return sounds.Count > 0; }
|
||||
}
|
||||
|
||||
private bool[] hasSoundsOfType;
|
||||
private Dictionary<ActionType, List<ItemSound>> sounds;
|
||||
private readonly bool[] hasSoundsOfType;
|
||||
private readonly Dictionary<ActionType, List<ItemSound>> sounds;
|
||||
private Dictionary<ActionType, SoundSelectionMode> soundSelectionModes;
|
||||
|
||||
protected float correctionTimer;
|
||||
|
||||
public float IsActiveTimer;
|
||||
|
||||
public GUILayoutSettings DefaultLayout { get; protected set; }
|
||||
public GUILayoutSettings AlternativeLayout { get; protected set; }
|
||||
|
||||
@@ -230,20 +234,23 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (loopingSound != null)
|
||||
{
|
||||
float targetGain = 0.0f;
|
||||
if (Vector3.DistanceSquared(GameMain.SoundManager.ListenerPosition, new Vector3(item.WorldPosition, 0.0f)) > loopingSound.Range * loopingSound.Range ||
|
||||
(targetGain = GetSoundVolume(loopingSound)) <= 0.0001f)
|
||||
(GetSoundVolume(loopingSound)) <= 0.0001f)
|
||||
{
|
||||
if (loopingSoundChannel != null)
|
||||
{
|
||||
loopingSoundChannel.FadeOutAndDispose(); loopingSoundChannel = null;
|
||||
loopingSoundChannel.FadeOutAndDispose();
|
||||
loopingSoundChannel = null;
|
||||
loopingSound = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (loopingSoundChannel != null && loopingSoundChannel.Sound != loopingSound.RoundSound.Sound)
|
||||
{
|
||||
loopingSoundChannel.FadeOutAndDispose(); loopingSoundChannel = null;
|
||||
loopingSoundChannel.FadeOutAndDispose();
|
||||
loopingSoundChannel = null;
|
||||
loopingSound = null;
|
||||
}
|
||||
if (loopingSoundChannel == null || !loopingSoundChannel.IsPlaying)
|
||||
{
|
||||
@@ -258,8 +265,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
ItemSound itemSound = null;
|
||||
|
||||
var matchingSounds = sounds[type];
|
||||
if (loopingSoundChannel == null || !loopingSoundChannel.IsPlaying)
|
||||
{
|
||||
@@ -277,7 +283,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
foreach (ItemSound sound in matchingSounds)
|
||||
{
|
||||
PlaySound(sound, item.WorldPosition, user);
|
||||
PlaySound(sound, item.WorldPosition);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -286,13 +292,12 @@ namespace Barotrauma.Items.Components
|
||||
index = Rand.Int(matchingSounds.Count);
|
||||
}
|
||||
|
||||
itemSound = matchingSounds[index];
|
||||
PlaySound(matchingSounds[index], item.WorldPosition, user);
|
||||
PlaySound(matchingSounds[index], item.WorldPosition);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void PlaySound(ItemSound itemSound, Vector2 position, Character user = null)
|
||||
private void PlaySound(ItemSound itemSound, Vector2 position)
|
||||
{
|
||||
if (Vector2.DistanceSquared(new Vector2(GameMain.SoundManager.ListenerPosition.X, GameMain.SoundManager.ListenerPosition.Y), position) > itemSound.Range * itemSound.Range)
|
||||
{
|
||||
@@ -301,8 +306,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (itemSound.Loop)
|
||||
{
|
||||
loopingSound = itemSound;
|
||||
if (loopingSoundChannel != null && loopingSoundChannel.Sound != loopingSound.RoundSound.Sound)
|
||||
if (loopingSoundChannel != null && loopingSoundChannel.Sound != itemSound.RoundSound.Sound)
|
||||
{
|
||||
loopingSoundChannel.FadeOutAndDispose(); loopingSoundChannel = null;
|
||||
}
|
||||
@@ -310,6 +314,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
float volume = GetSoundVolume(itemSound);
|
||||
if (volume <= 0.0001f) { return; }
|
||||
loopingSound = itemSound;
|
||||
loopingSoundChannel = loopingSound.RoundSound.Sound.Play(
|
||||
new Vector3(position.X, position.Y, 0.0f),
|
||||
0.01f,
|
||||
|
||||
@@ -3,11 +3,17 @@ using Barotrauma.Lights;
|
||||
using Barotrauma.Networking;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class LightComponent : Powered, IServerSerializable, IDrawableComponent
|
||||
{
|
||||
private bool? lastReceivedState;
|
||||
|
||||
private CoroutineHandle resetPredictionCoroutine;
|
||||
private float resetPredictionTimer;
|
||||
|
||||
public Vector2 DrawSize
|
||||
{
|
||||
get { return new Vector2(light.Range * 2, light.Range * 2); }
|
||||
@@ -32,6 +38,12 @@ 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)
|
||||
@@ -49,9 +61,36 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
partial void OnStateChanged()
|
||||
{
|
||||
if (GameMain.Client == null || !lastReceivedState.HasValue) { return; }
|
||||
//reset to last known server state after the state hasn't changed in 1.0 seconds client-side
|
||||
resetPredictionTimer = 1.0f;
|
||||
if (resetPredictionCoroutine == null || !CoroutineManager.IsCoroutineRunning(resetPredictionCoroutine))
|
||||
{
|
||||
resetPredictionCoroutine = CoroutineManager.StartCoroutine(ResetPredictionAfterDelay());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reset client-side prediction of the light's state to the last known state sent by the server after resetPredictionTimer runs out
|
||||
/// </summary>
|
||||
private IEnumerable<object> ResetPredictionAfterDelay()
|
||||
{
|
||||
while (resetPredictionTimer > 0.0f)
|
||||
{
|
||||
resetPredictionTimer -= CoroutineManager.DeltaTime;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
if (lastReceivedState.HasValue) { IsActive = lastReceivedState.Value; }
|
||||
resetPredictionCoroutine = null;
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
|
||||
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
||||
{
|
||||
IsOn = msg.ReadBoolean();
|
||||
IsActive = msg.ReadBoolean();
|
||||
lastReceivedState = IsActive;
|
||||
}
|
||||
|
||||
protected override void RemoveComponentSpecific()
|
||||
|
||||
@@ -140,11 +140,11 @@ namespace Barotrauma.Items.Components
|
||||
var inputArea = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 1f), bottomFrame.RectTransform, Anchor.BottomCenter), isHorizontal: true, childAnchor: Anchor.BottomLeft);
|
||||
|
||||
// === INPUT SLOTS === //
|
||||
inputInventoryHolder = new GUIFrame(new RectTransform(new Vector2(0.8f, 1f), inputArea.RectTransform), style: null);
|
||||
inputInventoryHolder = new GUIFrame(new RectTransform(new Vector2(0.7f, 1f), inputArea.RectTransform), style: null);
|
||||
new GUICustomComponent(new RectTransform(Vector2.One, inputInventoryHolder.RectTransform), DrawInputOverLay) { CanBeFocused = false };
|
||||
|
||||
// === ACTIVATE BUTTON === //
|
||||
var buttonFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.2f, 0.8f), inputArea.RectTransform), childAnchor: Anchor.CenterRight);
|
||||
var buttonFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.3f, 0.8f), inputArea.RectTransform), childAnchor: Anchor.CenterRight);
|
||||
activateButton = new GUIButton(new RectTransform(new Vector2(1f, 0.6f), buttonFrame.RectTransform),
|
||||
TextManager.Get("FabricatorCreate"), style: "DeviceButton")
|
||||
{
|
||||
@@ -356,6 +356,8 @@ namespace Barotrauma.Items.Components
|
||||
private void DrawOutputOverLay(SpriteBatch spriteBatch, GUICustomComponent overlayComponent)
|
||||
{
|
||||
overlayComponent.RectTransform.SetAsLastChild();
|
||||
|
||||
if (outputContainer.Inventory.Items.First() != null) { return; }
|
||||
|
||||
FabricationRecipe targetItem = fabricatedItem ?? selectedItem;
|
||||
if (targetItem != null)
|
||||
|
||||
@@ -91,6 +91,7 @@ namespace Barotrauma.Items.Components
|
||||
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
|
||||
{
|
||||
CreateHUD();
|
||||
@@ -116,21 +117,23 @@ namespace Barotrauma.Items.Components
|
||||
private void DrawHUDFront(SpriteBatch spriteBatch, GUICustomComponent container)
|
||||
{
|
||||
if (Voltage < MinVoltage)
|
||||
{
|
||||
{
|
||||
Vector2 textSize = GUI.Font.MeasureString(noPowerTip);
|
||||
Vector2 textPos = GuiFrame.Rect.Center.ToVector2();
|
||||
|
||||
GUI.DrawString(spriteBatch, textPos - textSize / 2, noPowerTip,
|
||||
GUI.Style.Orange * (float)Math.Abs(Math.Sin(Timing.TotalTime)), Color.Black * 0.8f, font: GUI.SubHeadingFont);
|
||||
GUI.Style.Orange * (float)Math.Abs(Math.Sin(Timing.TotalTime)), Color.Black * 0.8f, font: GUI.SubHeadingFont);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!submarineContainer.Children.Any()) { return; }
|
||||
|
||||
foreach (GUIComponent child in submarineContainer.Children.First().Children)
|
||||
{
|
||||
if (child.UserData is Hull hull)
|
||||
{
|
||||
if (hull.Submarine == null || !hull.Submarine.IsOutpost) { continue; }
|
||||
string text = TextManager.GetWithVariable("MiniMapOutpostDockingInfo", "[outpost]", hull.Submarine.Name);
|
||||
if (hull.Submarine == null || !hull.Submarine.Info.IsOutpost) { continue; }
|
||||
string text = TextManager.GetWithVariable("MiniMapOutpostDockingInfo", "[outpost]", hull.Submarine.Info.Name);
|
||||
Vector2 textSize = GUI.Font.MeasureString(text);
|
||||
Vector2 textPos = child.Center;
|
||||
if (textPos.X + textSize.X / 2 > submarineContainer.Rect.Right)
|
||||
@@ -151,7 +154,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
foreach (Hull hull in Hull.hullList)
|
||||
{
|
||||
var hullFrame = submarineContainer.Children.First().FindChild(hull);
|
||||
var hullFrame = submarineContainer.Children.FirstOrDefault()?.FindChild(hull);
|
||||
if (hullFrame == null) { continue; }
|
||||
|
||||
if (GUI.MouseOn == hullFrame || hullFrame.IsParentOf(GUI.MouseOn))
|
||||
@@ -175,7 +178,7 @@ namespace Barotrauma.Items.Components
|
||||
foreach (Hull hull in Hull.hullList)
|
||||
{
|
||||
if (hull.Submarine == null) continue;
|
||||
var hullFrame = submarineContainer.Children.First().FindChild(hull);
|
||||
var hullFrame = submarineContainer.Children.FirstOrDefault()?.FindChild(hull);
|
||||
if (hullFrame == null) continue;
|
||||
|
||||
hullDatas.TryGetValue(hull, out HullData hullData);
|
||||
|
||||
@@ -99,6 +99,10 @@ namespace Barotrauma.Items.Components
|
||||
Step = 0.05f,
|
||||
OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
|
||||
{
|
||||
if (pumpSpeedLockTimer <= 0.0f)
|
||||
{
|
||||
targetLevel = null;
|
||||
}
|
||||
float newValue = barScroll * 200.0f - 100.0f;
|
||||
if (Math.Abs(newValue - FlowPercentage) < 0.1f) { return false; }
|
||||
|
||||
|
||||
@@ -192,9 +192,10 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
RelativeOffset = new Vector2(0, fissionMeter.RectTransform.RelativeOffset.Y + meterSize.Y)
|
||||
},
|
||||
style: "DeviceSlider", barSize: 0.1f)
|
||||
style: "DeviceSlider", barSize: 0.15f)
|
||||
{
|
||||
Enabled = false,
|
||||
Step = 1.0f / 255,
|
||||
OnMoved = (GUIScrollBar bar, float scrollAmount) =>
|
||||
{
|
||||
LastUser = Character.Controlled;
|
||||
@@ -209,9 +210,10 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
RelativeOffset = new Vector2(0, turbineMeter.RectTransform.RelativeOffset.Y + meterSize.Y)
|
||||
},
|
||||
style: "DeviceSlider", barSize: 0.1f, isHorizontal: true)
|
||||
style: "DeviceSlider", barSize: 0.15f, isHorizontal: true)
|
||||
{
|
||||
Enabled = false,
|
||||
Step = 1.0f / 255,
|
||||
OnMoved = (GUIScrollBar bar, float scrollAmount) =>
|
||||
{
|
||||
LastUser = Character.Controlled;
|
||||
@@ -715,8 +717,14 @@ namespace Barotrauma.Items.Components
|
||||
targetTurbineOutput = msg.ReadRangedSingle(0.0f, 100.0f, 8);
|
||||
degreeOfSuccess = msg.ReadRangedSingle(0.0f, 1.0f, 8);
|
||||
|
||||
FissionRateScrollBar.BarScroll = targetFissionRate / 100.0f;
|
||||
TurbineOutputScrollBar.BarScroll = targetTurbineOutput / 100.0f;
|
||||
if (Math.Abs(FissionRateScrollBar.BarScroll - targetFissionRate / 100.0f) > 0.01f)
|
||||
{
|
||||
FissionRateScrollBar.BarScroll = targetFissionRate / 100.0f;
|
||||
}
|
||||
if (Math.Abs(TurbineOutputScrollBar.BarScroll - targetTurbineOutput / 100.0f) > 0.01f)
|
||||
{
|
||||
TurbineOutputScrollBar.BarScroll = targetTurbineOutput / 100.0f;
|
||||
}
|
||||
|
||||
IsActive = true;
|
||||
}
|
||||
|
||||
@@ -490,6 +490,7 @@ namespace Barotrauma.Items.Components
|
||||
disruptedDirections.Clear();
|
||||
foreach (AITarget t in AITarget.List)
|
||||
{
|
||||
if (t.Entity is Character c && c.Params.HideInSonar) { continue; }
|
||||
if (t.SoundRange <= 0.0f || float.IsNaN(t.SoundRange) || float.IsInfinity(t.SoundRange)) { continue; }
|
||||
|
||||
float distSqr = Vector2.DistanceSquared(t.WorldPosition, transducerCenter);
|
||||
@@ -647,6 +648,8 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (GameMain.GameSession == null) { return; }
|
||||
|
||||
if (Level.Loaded == null) { return; }
|
||||
|
||||
DrawMarker(spriteBatch,
|
||||
GameMain.GameSession.StartLocation.Name,
|
||||
"outpost",
|
||||
@@ -699,8 +702,8 @@ namespace Barotrauma.Items.Components
|
||||
if (sub.WorldPosition.Y > Level.Loaded.Size.Y) { continue; }
|
||||
|
||||
DrawMarker(spriteBatch,
|
||||
sub.Name,
|
||||
sub.HasTag(SubmarineTag.Shuttle) ? "shuttle" : "submarine",
|
||||
sub.Info.DisplayName,
|
||||
sub.Info.HasTag(SubmarineTag.Shuttle) ? "shuttle" : "submarine",
|
||||
sub.WorldPosition - transducerCenter,
|
||||
displayScale, center, DisplayRadius * 0.95f);
|
||||
}
|
||||
@@ -799,8 +802,11 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (Level.Loaded != null && dockingPort.Item.Submarine.WorldPosition.Y > Level.Loaded.Size.Y) { continue; }
|
||||
|
||||
if (dockingPort.Item.Submarine == null) { continue; }
|
||||
if (dockingPort.Item.Submarine.Info.IsWreck) { continue; }
|
||||
|
||||
//don't show the docking ports of the opposing team on the sonar
|
||||
if (item.Submarine != null && dockingPort.Item.Submarine != null)
|
||||
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))
|
||||
@@ -1125,6 +1131,7 @@ namespace Barotrauma.Items.Components
|
||||
foreach (Character c in Character.CharacterList)
|
||||
{
|
||||
if (c.AnimController.CurrentHull != null || !c.Enabled) { continue; }
|
||||
if (c.Params.HideInSonar) { continue; }
|
||||
if (DetectSubmarineWalls && c.AnimController.CurrentHull == null && item.CurrentHull != null) { continue; }
|
||||
|
||||
if (c.AnimController.SimplePhysicsEnabled)
|
||||
|
||||
@@ -46,6 +46,8 @@ namespace Barotrauma.Items.Components
|
||||
private float checkConnectedPortsTimer;
|
||||
private const float CheckConnectedPortsInterval = 1.0f;
|
||||
|
||||
public DockingPort ActiveDockingSource, DockingTarget;
|
||||
|
||||
private Vector2 keyboardInput = Vector2.Zero;
|
||||
private float inputCumulation;
|
||||
|
||||
@@ -665,7 +667,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (Vector2.DistanceSquared(PlayerInput.MousePosition, steerArea.Rect.Center.ToVector2()) < steerRadius * steerRadius)
|
||||
{
|
||||
if (PlayerInput.PrimaryMouseButtonHeld() && !CrewManager.IsCommandInterfaceOpen && !GameSession.IsInfoFrameOpen)
|
||||
if (PlayerInput.PrimaryMouseButtonHeld() && !CrewManager.IsCommandInterfaceOpen && !GameSession.IsTabMenuOpen)
|
||||
{
|
||||
Vector2 displaySubPos = (-sonar.DisplayOffset * sonar.Zoom) / sonar.Range * sonar.DisplayRadius * sonar.Zoom;
|
||||
displaySubPos.Y = -displaySubPos.Y;
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
using Barotrauma.Networking;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class Projectile : ItemComponent
|
||||
{
|
||||
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
||||
{
|
||||
bool isStuck = msg.ReadBoolean();
|
||||
if (isStuck)
|
||||
{
|
||||
ushort submarineID = msg.ReadUInt16();
|
||||
ushort hullID = msg.ReadUInt16();
|
||||
Vector2 simPosition = new Vector2(
|
||||
msg.ReadSingle(),
|
||||
msg.ReadSingle());
|
||||
Vector2 axis = new Vector2(
|
||||
msg.ReadSingle(),
|
||||
msg.ReadSingle());
|
||||
UInt16 entityID = msg.ReadUInt16();
|
||||
|
||||
Entity entity = Entity.FindEntityByID(entityID);
|
||||
Submarine submarine = Entity.FindEntityByID(submarineID) as Submarine;
|
||||
Hull hull = Entity.FindEntityByID(hullID) as Hull;
|
||||
item.Submarine = submarine;
|
||||
item.CurrentHull = hull;
|
||||
item.body.SetTransform(simPosition, item.body.Rotation);
|
||||
if (entity is Character character)
|
||||
{
|
||||
byte limbIndex = msg.ReadByte();
|
||||
if (limbIndex >= character.AnimController.Limbs.Length)
|
||||
{
|
||||
DebugConsole.ThrowError($"Failed to read a projectile update from the server. Limb index out of bounds ({limbIndex}, character: {character.ToString()})");
|
||||
return;
|
||||
}
|
||||
if (character.Removed) { return; }
|
||||
var limb = character.AnimController.Limbs[limbIndex];
|
||||
StickToTarget(limb.body.FarseerBody, axis);
|
||||
}
|
||||
else if (entity is Structure structure)
|
||||
{
|
||||
byte bodyIndex = msg.ReadByte();
|
||||
if (bodyIndex == 255) { bodyIndex = 0; }
|
||||
if (bodyIndex >= structure.Bodies.Count)
|
||||
{
|
||||
DebugConsole.ThrowError($"Failed to read a projectile update from the server. Structure body index out of bounds ({bodyIndex}, structure: {structure.ToString()})");
|
||||
return;
|
||||
}
|
||||
var body = structure.Bodies[bodyIndex];
|
||||
StickToTarget(body, axis);
|
||||
}
|
||||
else if (entity is Item item)
|
||||
{
|
||||
if (item.Removed) { return; }
|
||||
StickToTarget(item.body.FarseerBody, axis);
|
||||
}
|
||||
else if (entity is Submarine sub)
|
||||
{
|
||||
StickToTarget(sub.PhysicsBody.FarseerBody, axis);
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.ThrowError($"Failed to read a projectile update from the server. Invalid stick target ({entity?.ToString() ?? "null"}, {entityID})");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Unstick();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -117,9 +117,18 @@ namespace Barotrauma.Items.Components
|
||||
case "emitter":
|
||||
case "particleemitter":
|
||||
particleEmitters.Add(new ParticleEmitter(subElement));
|
||||
particleEmitterConditionRanges.Add(new Vector2(
|
||||
subElement.GetAttributeFloat("mincondition", 0.0f),
|
||||
subElement.GetAttributeFloat("maxcondition", 100.0f)));
|
||||
float minCondition = subElement.GetAttributeFloat("mincondition", 0.0f);
|
||||
float maxCondition = subElement.GetAttributeFloat("maxcondition", 100.0f);
|
||||
|
||||
if (maxCondition < minCondition)
|
||||
{
|
||||
DebugConsole.ThrowError("Invalid damage particle configuration in the Repairable component of " + item.Name + ". MaxCondition needs to be larger than MinCondition.");
|
||||
float temp = maxCondition;
|
||||
maxCondition = minCondition;
|
||||
minCondition = temp;
|
||||
}
|
||||
particleEmitterConditionRanges.Add(new Vector2(minCondition, maxCondition));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -236,15 +245,7 @@ namespace Barotrauma.Items.Components
|
||||
DeteriorateAlways = msg.ReadBoolean();
|
||||
ushort currentFixerID = msg.ReadUInt16();
|
||||
currentFixerAction = (FixActions)msg.ReadRangedInteger(0, 2);
|
||||
|
||||
if (currentFixerID == 0)
|
||||
{
|
||||
CurrentFixer = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentFixer = Entity.FindEntityByID(currentFixerID) as Character;
|
||||
}
|
||||
CurrentFixer = currentFixerID != 0 ? Entity.FindEntityByID(currentFixerID) as Character : null;
|
||||
}
|
||||
|
||||
public void ClientWrite(IWriteMessage msg, object[] extraData = null)
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
using Barotrauma.Networking;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
partial class Rope : ItemComponent, IDrawableComponent
|
||||
{
|
||||
private Sprite sprite, startSprite, endSprite;
|
||||
|
||||
[Serialize(5, false)]
|
||||
public int SpriteWidth
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize("255,255,255,255", false)]
|
||||
public Color SpriteColor
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(false, false)]
|
||||
public bool Tile
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public Vector2 DrawSize
|
||||
{
|
||||
get
|
||||
{
|
||||
if (target == null || source == null) { return Vector2.Zero; }
|
||||
return new Vector2(
|
||||
Math.Abs(target.DrawPosition.X - source.DrawPosition.X),
|
||||
Math.Abs(target.DrawPosition.Y - source.DrawPosition.Y)) * 1.5f;
|
||||
}
|
||||
}
|
||||
|
||||
partial void InitProjSpecific(XElement element)
|
||||
{
|
||||
foreach (XElement subElement in element.Elements())
|
||||
{
|
||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||
{
|
||||
case "sprite":
|
||||
sprite = new Sprite(subElement);
|
||||
break;
|
||||
case "startsprite":
|
||||
startSprite = new Sprite(subElement);
|
||||
break;
|
||||
case "endsprite":
|
||||
endSprite = new Sprite(subElement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, bool editing, float itemDepth = -1)
|
||||
{
|
||||
if (target == null) { return; }
|
||||
|
||||
Vector2 startPos = new Vector2(source.DrawPosition.X, -source.DrawPosition.Y);
|
||||
var turret = source?.GetComponent<Turret>();
|
||||
if (turret != null)
|
||||
{
|
||||
startPos = new Vector2(source.WorldRect.X + turret.TransformedBarrelPos.X, -(source.WorldRect.Y - turret.TransformedBarrelPos.Y));
|
||||
if (turret.BarrelSprite != null)
|
||||
{
|
||||
startPos += new Vector2((float)Math.Cos(turret.Rotation), (float)Math.Sin(turret.Rotation)) * turret.BarrelSprite.size.Y * turret.BarrelSprite.RelativeOrigin.Y * item.Scale * 0.9f;
|
||||
}
|
||||
}
|
||||
Vector2 endPos = new Vector2(target.DrawPosition.X, -target.DrawPosition.Y);
|
||||
|
||||
if (Snapped)
|
||||
{
|
||||
float snapState = 1.0f - snapTimer / SnapAnimDuration;
|
||||
Vector2 diff = target.DrawPosition - source.DrawPosition;
|
||||
diff.Y = -diff.Y;
|
||||
|
||||
int width = (int)(SpriteWidth * snapState);
|
||||
if (width > 0.0f)
|
||||
{
|
||||
DrawRope(spriteBatch, endPos - diff * snapState * 0.5f, endPos, width);
|
||||
DrawRope(spriteBatch, startPos, startPos + diff * snapState * 0.5f, width);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawRope(spriteBatch, startPos, endPos, SpriteWidth);
|
||||
}
|
||||
|
||||
if (startSprite != null || endSprite != null)
|
||||
{
|
||||
Vector2 dir = endPos - startPos;
|
||||
float angle = (float)Math.Atan2(dir.Y, dir.X);
|
||||
if (startSprite != null)
|
||||
{
|
||||
float depth = Math.Min(item.GetDrawDepth() + (startSprite.Depth - item.Sprite.Depth), 0.999f);
|
||||
startSprite?.Draw(spriteBatch, startPos, SpriteColor, angle, depth: depth);
|
||||
}
|
||||
if (endSprite != null)
|
||||
{
|
||||
float depth = Math.Min(item.GetDrawDepth() + (endSprite.Depth - item.Sprite.Depth), 0.999f);
|
||||
endSprite?.Draw(spriteBatch, endPos, SpriteColor, angle, depth: depth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawRope(SpriteBatch spriteBatch, Vector2 startPos, Vector2 endPos, int width)
|
||||
{
|
||||
float depth = sprite == null ?
|
||||
item.Sprite.Depth + 0.001f :
|
||||
Math.Min(item.GetDrawDepth() + (sprite.Depth - item.Sprite.Depth), 0.999f);
|
||||
|
||||
if (sprite?.Texture == null)
|
||||
{
|
||||
GUI.DrawLine(spriteBatch,
|
||||
startPos,
|
||||
endPos,
|
||||
SpriteColor, depth: depth, width: width);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Tile)
|
||||
{
|
||||
float length = Vector2.Distance(startPos, endPos);
|
||||
Vector2 dir = (endPos - startPos) / length;
|
||||
float x;
|
||||
for (x = 0.0f; x <= length - sprite.size.X; x += sprite.size.X)
|
||||
{
|
||||
GUI.DrawLine(spriteBatch, sprite,
|
||||
startPos + dir * (x - 5.0f),
|
||||
startPos + dir * (x + sprite.size.X),
|
||||
SpriteColor, depth: depth, width: width);
|
||||
}
|
||||
float leftOver = length - x;
|
||||
if (leftOver > 0.0f)
|
||||
{
|
||||
GUI.DrawLine(spriteBatch, sprite,
|
||||
startPos + dir * (x - 5.0f),
|
||||
endPos,
|
||||
SpriteColor, depth: depth, width: width);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.DrawLine(spriteBatch, sprite,
|
||||
startPos,
|
||||
endPos,
|
||||
SpriteColor, depth: depth, width: width);
|
||||
}
|
||||
}
|
||||
|
||||
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
||||
{
|
||||
snapped = msg.ReadBoolean();
|
||||
}
|
||||
|
||||
protected override void RemoveComponentSpecific()
|
||||
{
|
||||
sprite?.Remove(); sprite = null;
|
||||
startSprite?.Remove(); startSprite = null;
|
||||
endSprite?.Remove(); endSprite = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
+77
-11
@@ -45,13 +45,48 @@ namespace Barotrauma.Items.Components
|
||||
float elementSize = Math.Min(1.0f / visibleElements.Count(), 1);
|
||||
foreach (CustomInterfaceElement ciElement in visibleElements)
|
||||
{
|
||||
if (ciElement.ContinuousSignal)
|
||||
if (!string.IsNullOrEmpty(ciElement.PropertyName))
|
||||
{
|
||||
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")
|
||||
{
|
||||
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) =>
|
||||
{
|
||||
if (GameMain.Client == null)
|
||||
{
|
||||
TextChanged(tb.UserData as CustomInterfaceElement, textBox.Text);
|
||||
}
|
||||
else
|
||||
{
|
||||
item.CreateClientEvent(this);
|
||||
}
|
||||
};
|
||||
|
||||
textBox.OnEnterPressed += (tb, text) =>
|
||||
{
|
||||
tb.Deselect();
|
||||
return true;
|
||||
};
|
||||
uiElements.Add(textBox);
|
||||
}
|
||||
else if (ciElement.ContinuousSignal)
|
||||
{
|
||||
var tickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, elementSize), uiElementContainer.RectTransform)
|
||||
{
|
||||
MaxSize = ElementMaxSize
|
||||
},
|
||||
TextManager.Get(ciElement.Label, returnNull: true) ?? ciElement.Label)
|
||||
}, TextManager.Get(ciElement.Label, returnNull: true) ?? ciElement.Label)
|
||||
{
|
||||
UserData = ciElement
|
||||
};
|
||||
@@ -148,7 +183,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() || (element.Connection != null && element.Connection.Wires.Any(w => w != null));
|
||||
bool visible = Screen.Selected == GameMain.SubEditorScreen || element.StatusEffects.Any() || !string.IsNullOrEmpty(element.PropertyName) || (element.Connection != null && element.Connection.Wires.Any(w => w != null));
|
||||
if (visible) { visibleElementCount++; }
|
||||
if (uiElement.Visible != visible)
|
||||
{
|
||||
@@ -188,6 +223,22 @@ namespace Barotrauma.Items.Components
|
||||
customInterfaceElementList[i].Label;
|
||||
tickBox.TextBlock.Wrap = tickBox.Text.Contains(' ');
|
||||
}
|
||||
if (uiElements[i] is GUITextBox textBox)
|
||||
{
|
||||
var textBlock = textBox.Parent.GetChild<GUITextBlock>();
|
||||
textBlock.Text = string.IsNullOrWhiteSpace(customInterfaceElementList[i].Label) ?
|
||||
TextManager.GetWithVariable("connection.signaloutx", "[num]", (i + 1).ToString()) :
|
||||
customInterfaceElementList[i].Label;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uiElementContainer.Recalculate();
|
||||
@@ -206,6 +257,10 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
textBlocks.Add(tickBox.TextBlock);
|
||||
}
|
||||
else if (element is GUILayoutGroup)
|
||||
{
|
||||
textBlocks.Add(element.GetChild<GUITextBlock>());
|
||||
}
|
||||
}
|
||||
uiElementContainer.Recalculate();
|
||||
GUITextBlock.AutoScaleAndNormalize(textBlocks);
|
||||
@@ -216,7 +271,11 @@ namespace Barotrauma.Items.Components
|
||||
//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 (customInterfaceElementList[i].ContinuousSignal)
|
||||
if (!string.IsNullOrEmpty(customInterfaceElementList[i].PropertyName))
|
||||
{
|
||||
msg.Write(((GUITextBox)uiElements[i]).Text);
|
||||
}
|
||||
else if (customInterfaceElementList[i].ContinuousSignal)
|
||||
{
|
||||
msg.Write(((GUITickBox)uiElements[i]).Selected);
|
||||
}
|
||||
@@ -231,15 +290,22 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
for (int i = 0; i < customInterfaceElementList.Count; i++)
|
||||
{
|
||||
bool elementState = msg.ReadBoolean();
|
||||
if (customInterfaceElementList[i].ContinuousSignal)
|
||||
if (!string.IsNullOrEmpty(customInterfaceElementList[i].PropertyName))
|
||||
{
|
||||
((GUITickBox)uiElements[i]).Selected = elementState;
|
||||
TickBoxToggled(customInterfaceElementList[i], elementState);
|
||||
TextChanged(customInterfaceElementList[i], msg.ReadString());
|
||||
}
|
||||
else if (elementState)
|
||||
else
|
||||
{
|
||||
ButtonClicked(customInterfaceElementList[i]);
|
||||
bool elementState = msg.ReadBoolean();
|
||||
if (customInterfaceElementList[i].ContinuousSignal)
|
||||
{
|
||||
((GUITickBox)uiElements[i]).Selected = elementState;
|
||||
TickBoxToggled(customInterfaceElementList[i], elementState);
|
||||
}
|
||||
else if (elementState)
|
||||
{
|
||||
ButtonClicked(customInterfaceElementList[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,15 +56,6 @@ namespace Barotrauma.Items.Components
|
||||
};
|
||||
}
|
||||
|
||||
public override void OnItemLoaded()
|
||||
{
|
||||
base.OnItemLoaded();
|
||||
if (!string.IsNullOrEmpty(DisplayedWelcomeMessage))
|
||||
{
|
||||
ShowOnDisplay(DisplayedWelcomeMessage);
|
||||
}
|
||||
}
|
||||
|
||||
private void SendOutput(string input)
|
||||
{
|
||||
if (input.Length > MaxMessageLength)
|
||||
@@ -123,6 +114,11 @@ namespace Barotrauma.Items.Components
|
||||
public override void AddToGUIUpdateList()
|
||||
{
|
||||
base.AddToGUIUpdateList();
|
||||
if (!string.IsNullOrEmpty(DisplayedWelcomeMessage))
|
||||
{
|
||||
ShowOnDisplay(DisplayedWelcomeMessage);
|
||||
DisplayedWelcomeMessage = "";
|
||||
}
|
||||
if (shouldSelectInputBox)
|
||||
{
|
||||
inputBox.Select();
|
||||
|
||||
@@ -17,14 +17,60 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
partial class WireSection
|
||||
{
|
||||
public VertexPositionColorTexture[] vertices;
|
||||
public VertexPositionColorTexture[] shiftedVertices;
|
||||
|
||||
private float cachedWidth = 0f;
|
||||
|
||||
private void RecalculateVertices(Wire wire, float width)
|
||||
{
|
||||
if (MathUtils.NearlyEqual(cachedWidth, width)) { return; }
|
||||
cachedWidth = width;
|
||||
|
||||
vertices = new VertexPositionColorTexture[4];
|
||||
|
||||
Vector2 expandDir = start-end;
|
||||
expandDir.Normalize();
|
||||
float temp = expandDir.X;
|
||||
expandDir.X = -expandDir.Y;
|
||||
expandDir.Y = -temp;
|
||||
|
||||
Rectangle srcRect = wire.wireSprite.SourceRect;
|
||||
|
||||
expandDir *= width * srcRect.Height * 0.5f;
|
||||
|
||||
Vector2 rectLocation = srcRect.Location.ToVector2();
|
||||
Vector2 rectSize = srcRect.Size.ToVector2();
|
||||
Vector2 textureSize = new Vector2(wire.wireSprite.Texture.Width, wire.wireSprite.Texture.Height);
|
||||
|
||||
Vector2 topLeftUv = rectLocation / textureSize;
|
||||
Vector2 bottomRightUv = (rectLocation + rectSize) / textureSize;
|
||||
|
||||
Vector2 invStart = new Vector2(start.X, -start.Y);
|
||||
Vector2 invEnd = new Vector2(end.X, -end.Y);
|
||||
|
||||
vertices[0] = new VertexPositionColorTexture(new Vector3(invStart + expandDir, 0f), Color.White, topLeftUv);
|
||||
vertices[2] = new VertexPositionColorTexture(new Vector3(invEnd + expandDir, 0f), Color.White, new Vector2(bottomRightUv.X, topLeftUv.Y));
|
||||
vertices[1] = new VertexPositionColorTexture(new Vector3(invStart - expandDir, 0f), Color.White, new Vector2(topLeftUv.X, bottomRightUv.Y));
|
||||
vertices[3] = new VertexPositionColorTexture(new Vector3(invEnd - expandDir, 0f), Color.White, bottomRightUv);
|
||||
|
||||
shiftedVertices = (VertexPositionColorTexture[])vertices.Clone();
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, Wire wire, Color color, Vector2 offset, float depth, float width = 0.3f)
|
||||
{
|
||||
if (width <= 0f) { return; }
|
||||
RecalculateVertices(wire, width);
|
||||
|
||||
for (int i=0;i<vertices.Length;i++)
|
||||
{
|
||||
shiftedVertices[i].Color = color;
|
||||
shiftedVertices[i].Position = vertices[i].Position;
|
||||
shiftedVertices[i].Position.X += offset.X;
|
||||
shiftedVertices[i].Position.Y -= offset.Y;
|
||||
}
|
||||
spriteBatch.Draw(wire.wireSprite.Texture,
|
||||
new Vector2(start.X + offset.X, -(start.Y + offset.Y)), null, color,
|
||||
-angle,
|
||||
new Vector2(0.0f, wire.wireSprite.size.Y / 2.0f),
|
||||
new Vector2(length / wire.wireSprite.Texture.Width, width),
|
||||
SpriteEffects.None,
|
||||
shiftedVertices,
|
||||
depth);
|
||||
}
|
||||
|
||||
@@ -34,10 +80,10 @@ namespace Barotrauma.Items.Components
|
||||
end.Y = -end.Y;
|
||||
|
||||
spriteBatch.Draw(wire.wireSprite.Texture,
|
||||
start, null, color,
|
||||
start, wire.wireSprite.SourceRect, color,
|
||||
MathUtils.VectorToAngle(end - start),
|
||||
new Vector2(0.0f, wire.wireSprite.size.Y / 2.0f),
|
||||
new Vector2((Vector2.Distance(start, end)) / wire.wireSprite.Texture.Width, width),
|
||||
new Vector2((Vector2.Distance(start, end)) / wire.wireSprite.size.X, width),
|
||||
SpriteEffects.None,
|
||||
depth);
|
||||
}
|
||||
@@ -50,6 +96,13 @@ namespace Barotrauma.Items.Components
|
||||
private static int? selectedNodeIndex;
|
||||
private static int? highlightedNodeIndex;
|
||||
|
||||
[Serialize(0.3f, false)]
|
||||
public float Width
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public Vector2 DrawSize
|
||||
{
|
||||
get { return sectionExtents; }
|
||||
@@ -72,7 +125,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
foreach (XElement subElement in element.Elements())
|
||||
{
|
||||
if (subElement.Name.ToString().ToLowerInvariant() == "wiresprite")
|
||||
if (subElement.Name.ToString().Equals("wiresprite", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
overrideSprite = new Sprite(subElement);
|
||||
break;
|
||||
@@ -103,26 +156,26 @@ namespace Barotrauma.Items.Components
|
||||
drawOffset = sub.DrawPosition + sub.HiddenSubPosition;
|
||||
}
|
||||
|
||||
float depth = item.IsSelected ? 0.0f : wireSprite.Depth + ((item.ID % 100) * 0.00001f);
|
||||
float depth = item.IsSelected ? 0.0f : Screen.Selected is SubEditorScreen editor && editor.WiringMode ? 0.00002f : wireSprite.Depth + ((item.ID % 100) * 0.00001f);
|
||||
|
||||
if (item.IsHighlighted)
|
||||
{
|
||||
foreach (WireSection section in sections)
|
||||
{
|
||||
section.Draw(spriteBatch, this, Screen.Selected == GameMain.GameScreen ? higlightColor : editorHighlightColor, drawOffset, depth + 0.00001f, 0.7f);
|
||||
section.Draw(spriteBatch, this, Screen.Selected == GameMain.GameScreen ? higlightColor : editorHighlightColor, drawOffset, depth + 0.00001f, Width * 2.0f);
|
||||
}
|
||||
}
|
||||
else if (item.IsSelected)
|
||||
{
|
||||
foreach (WireSection section in sections)
|
||||
{
|
||||
section.Draw(spriteBatch, this, editorSelectedColor, drawOffset, depth + 0.00001f, 0.7f);
|
||||
section.Draw(spriteBatch, this, editorSelectedColor, drawOffset, depth + 0.00001f, Width * 2.0f);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (WireSection section in sections)
|
||||
{
|
||||
section.Draw(spriteBatch, this, item.Color, drawOffset, depth, 0.3f);
|
||||
section.Draw(spriteBatch, this, item.Color, drawOffset, depth, Width);
|
||||
}
|
||||
|
||||
if (nodes.Count > 0)
|
||||
@@ -167,13 +220,13 @@ namespace Barotrauma.Items.Components
|
||||
spriteBatch, this,
|
||||
new Vector2(nodes[nodes.Count - 1].X, nodes[nodes.Count - 1].Y) + drawOffset,
|
||||
new Vector2(newNodePos.X, newNodePos.Y) + drawOffset,
|
||||
item.Color, 0.0f, 0.3f);
|
||||
item.Color, 0.0f, Width);
|
||||
|
||||
WireSection.Draw(
|
||||
spriteBatch, this,
|
||||
new Vector2(newNodePos.X, newNodePos.Y) + drawOffset,
|
||||
item.DrawPosition,
|
||||
item.Color, itemDepth, 0.3f);
|
||||
item.Color, itemDepth, Width);
|
||||
|
||||
GUI.DrawRectangle(spriteBatch, new Vector2(newNodePos.X + drawOffset.X, -(newNodePos.Y + drawOffset.Y)) - Vector2.One * 3, Vector2.One * 6, item.Color);
|
||||
}
|
||||
@@ -183,7 +236,7 @@ namespace Barotrauma.Items.Components
|
||||
spriteBatch, this,
|
||||
new Vector2(nodes[nodes.Count - 1].X, nodes[nodes.Count - 1].Y) + drawOffset,
|
||||
item.DrawPosition,
|
||||
item.Color, 0.0f, 0.3f);
|
||||
item.Color, 0.0f, Width);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -235,7 +288,7 @@ namespace Barotrauma.Items.Components
|
||||
Wire equippedWire =
|
||||
Character.Controlled?.SelectedItems[0]?.GetComponent<Wire>() ??
|
||||
Character.Controlled?.SelectedItems[1]?.GetComponent<Wire>();
|
||||
if (equippedWire != null)
|
||||
if (equippedWire != null && GUI.MouseOn == null)
|
||||
{
|
||||
if (PlayerInput.PrimaryMouseButtonClicked() && Character.Controlled.SelectedConstruction == null)
|
||||
{
|
||||
@@ -404,6 +457,20 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsMouseOn()
|
||||
{
|
||||
if (GUI.MouseOn == null)
|
||||
{
|
||||
Vector2 mousePos = GameMain.SubEditorScreen.Cam.ScreenToWorld(PlayerInput.MousePosition);
|
||||
if (item.Submarine != null) { mousePos -= (item.Submarine.Position + item.Submarine.HiddenSubPosition); }
|
||||
|
||||
if (GetClosestNodeIndex(mousePos, 10, out _) > -1) { return true; }
|
||||
if (GetClosestSectionIndex(mousePos, 10, out _) > -1) { return true; }
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
||||
{
|
||||
int eventIndex = msg.ReadRangedInteger(0, (int)Math.Ceiling(MaxNodeCount / (float)MaxNodesPerNetworkEvent));
|
||||
|
||||
@@ -19,6 +19,8 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private float recoilTimer;
|
||||
|
||||
private float RetractionTime => Math.Max(Reload * RetractionDurationMultiplier, RecoilTime);
|
||||
|
||||
private RoundSound startMoveSound, endMoveSound, moveSound;
|
||||
|
||||
private SoundChannel moveSoundChannel;
|
||||
@@ -83,6 +85,11 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
public Sprite BarrelSprite
|
||||
{
|
||||
get { return barrelSprite; }
|
||||
}
|
||||
|
||||
partial void InitProjSpecific(XElement element)
|
||||
{
|
||||
foreach (XElement subElement in element.Elements())
|
||||
@@ -126,7 +133,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
partial void LaunchProjSpecific()
|
||||
{
|
||||
recoilTimer = Math.Max(Reload, 0.1f);
|
||||
recoilTimer = RetractionTime;
|
||||
PlaySound(ActionType.OnUse);
|
||||
Vector2 particlePos = new Vector2(item.WorldRect.X + transformedBarrelPos.X, item.WorldRect.Y - transformedBarrelPos.Y);
|
||||
foreach (ParticleEmitter emitter in particleEmitters)
|
||||
@@ -135,6 +142,12 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateBroken(float deltaTime, Camera cam)
|
||||
{
|
||||
base.UpdateBroken(deltaTime, cam);
|
||||
recoilTimer -= deltaTime;
|
||||
}
|
||||
|
||||
partial void UpdateProjSpecific(float deltaTime)
|
||||
{
|
||||
recoilTimer -= deltaTime;
|
||||
@@ -223,21 +236,30 @@ 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) drawPos += item.Submarine.DrawPosition;
|
||||
if (item.Submarine != null)
|
||||
{
|
||||
drawPos += item.Submarine.DrawPosition;
|
||||
}
|
||||
drawPos.Y = -drawPos.Y;
|
||||
|
||||
float recoilOffset = 0.0f;
|
||||
if (RecoilDistance > 0.0f && recoilTimer > 0.0f)
|
||||
if (Math.Abs(RecoilDistance) > 0.0f && recoilTimer > 0.0f)
|
||||
{
|
||||
//move the barrel backwards 0.1 seconds after launching
|
||||
if (recoilTimer >= Math.Max(Reload, 0.1f) - 0.1f)
|
||||
float diff = RetractionTime - RecoilTime;
|
||||
if (recoilTimer >= diff)
|
||||
{
|
||||
recoilOffset = RecoilDistance * (1.0f - (recoilTimer - (Math.Max(Reload, 0.1f) - 0.1f)) / 0.1f);
|
||||
//move the barrel backwards 0.1 seconds (defined by RecoilTime) after launching
|
||||
recoilOffset = RecoilDistance * (1.0f - (recoilTimer - diff) / RecoilTime);
|
||||
}
|
||||
else if (recoilTimer <= diff - RetractionDelay)
|
||||
{
|
||||
//move back to normal position while reloading
|
||||
float t = diff - RetractionDelay;
|
||||
recoilOffset = RecoilDistance * recoilTimer / t;
|
||||
}
|
||||
//move back to normal position while reloading
|
||||
else
|
||||
{
|
||||
recoilOffset = RecoilDistance * recoilTimer / (Math.Max(Reload, 0.1f) - 0.1f);
|
||||
recoilOffset = RecoilDistance;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -369,13 +391,26 @@ namespace Barotrauma.Items.Components
|
||||
tooltipOffset = new Vector2(size / 2 + 5, -10),
|
||||
inputAreaMargin = 20,
|
||||
RequireMouseOn = false
|
||||
};
|
||||
};
|
||||
widgets.Add(id, widget);
|
||||
initMethod?.Invoke(widget);
|
||||
}
|
||||
return widget;
|
||||
}
|
||||
|
||||
private void GetAvailablePower(out float availableCharge, out float availableCapacity)
|
||||
{
|
||||
var batteries = item.GetConnectedComponents<PowerContainer>();
|
||||
|
||||
availableCharge = 0.0f;
|
||||
availableCapacity = 0.0f;
|
||||
foreach (PowerContainer battery in batteries)
|
||||
{
|
||||
availableCharge += battery.Charge;
|
||||
availableCapacity += battery.Capacity;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns correct angle between -2PI and +2PI
|
||||
/// </summary>
|
||||
@@ -488,17 +523,31 @@ namespace Barotrauma.Items.Components
|
||||
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
||||
{
|
||||
UInt16 projectileID = msg.ReadUInt16();
|
||||
//projectile removed, do nothing
|
||||
if (projectileID == 0) return;
|
||||
float newTargetRotation = msg.ReadRangedSingle(minRotation, maxRotation, 16);
|
||||
|
||||
Item projectile = Entity.FindEntityByID(projectileID) as Item;
|
||||
if (projectile == null)
|
||||
if (Character.Controlled == null || user != Character.Controlled)
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to launch a projectile - item with the ID \"" + projectileID + " not found");
|
||||
return;
|
||||
targetRotation = newTargetRotation;
|
||||
}
|
||||
|
||||
//projectile removed, do nothing
|
||||
if (projectileID == 0) { return; }
|
||||
|
||||
//ID ushort.MaxValue = launched without a projectile
|
||||
if (projectileID == ushort.MaxValue)
|
||||
{
|
||||
Launch(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(Entity.FindEntityByID(projectileID) is Item projectile))
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to launch a projectile - item with the ID \"" + projectileID + " not found");
|
||||
return;
|
||||
}
|
||||
Launch(projectile, launchRotation: newTargetRotation);
|
||||
}
|
||||
|
||||
Launch(projectile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user