v0.10.6.2
This commit is contained in:
@@ -110,5 +110,7 @@ namespace Barotrauma
|
||||
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
|
||||
static partial void PlayTinnitusProjSpecific(float volume) => SoundPlayer.PlaySound("tinnitus", volume: volume);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,11 +11,18 @@ namespace Barotrauma
|
||||
|
||||
partial void UpdateProjSpecific(float growModifier)
|
||||
{
|
||||
EmitParticles(size, WorldPosition, hull, growModifier, OnChangeHull);
|
||||
if (this is DummyFireSource)
|
||||
{
|
||||
EmitParticles(size, WorldPosition, hull, growModifier, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitParticles(size, WorldPosition, hull, growModifier, OnChangeHull);
|
||||
}
|
||||
|
||||
lightSource.Color = new Color(1.0f, 0.45f, 0.3f) * Rand.Range(0.8f, 1.0f);
|
||||
if (Math.Abs((lightSource.Range * 0.2f) - Math.Max(size.X, size.Y)) > 1.0f) lightSource.Range = Math.Max(size.X, size.Y) * 5.0f;
|
||||
if (Vector2.DistanceSquared(lightSource.Position, position) > 5.0f) lightSource.Position = position + Vector2.UnitY * 30.0f;
|
||||
if (Math.Abs((lightSource.Range * 0.2f) - Math.Max(size.X, size.Y)) > 1.0f) { lightSource.Range = Math.Max(size.X, size.Y) * 5.0f; }
|
||||
if (Vector2.DistanceSquared(lightSource.Position, position) > 5.0f) { lightSource.Position = position + Vector2.UnitY * 30.0f; }
|
||||
}
|
||||
|
||||
public static void EmitParticles(Vector2 size, Vector2 worldPosition, Hull hull, float growModifier, Particle.OnChangeHullHandler onChangeHull = null)
|
||||
@@ -32,6 +39,8 @@ namespace Barotrauma
|
||||
(particlePos.X - (worldPosition.X + size.X / 2.0f)),
|
||||
(float)Math.Sqrt(size.X) * Rand.Range(0.0f, 15.0f) * growModifier);
|
||||
|
||||
particleVel.X = MathHelper.Clamp(particleVel.X, -200.0f, 200.0f);
|
||||
|
||||
var particle = GameMain.ParticleManager.CreateParticle("flame",
|
||||
particlePos, particleVel, 0.0f, hull);
|
||||
|
||||
|
||||
@@ -10,11 +10,30 @@ namespace Barotrauma
|
||||
{
|
||||
partial class Hull : MapEntity, ISerializableEntity, IServerSerializable, IClientSerializable
|
||||
{
|
||||
private class RemoteDecal
|
||||
{
|
||||
public readonly UInt32 DecalId;
|
||||
public readonly int SpriteIndex;
|
||||
public Vector2 NormalizedPos;
|
||||
public readonly float Scale;
|
||||
|
||||
public RemoteDecal(UInt32 decalId, int spriteIndex, Vector2 normalizedPos, float scale)
|
||||
{
|
||||
DecalId = decalId;
|
||||
SpriteIndex = spriteIndex;
|
||||
NormalizedPos = normalizedPos;
|
||||
Scale = scale;
|
||||
}
|
||||
}
|
||||
|
||||
private float serverUpdateDelay;
|
||||
private float remoteWaterVolume, remoteOxygenPercentage;
|
||||
private List<Vector3> remoteFireSources;
|
||||
private readonly List<BackgroundSection> remoteBackgroundSections = new List<BackgroundSection>();
|
||||
private readonly List<RemoteDecal> remoteDecals = new List<RemoteDecal>();
|
||||
|
||||
private readonly HashSet<Decal> pendingDecalUpdates = new HashSet<Decal>();
|
||||
|
||||
private double lastAmbientLightEditTime;
|
||||
|
||||
public override bool SelectableInEditor
|
||||
@@ -94,20 +113,21 @@ namespace Barotrauma
|
||||
{
|
||||
if (entity == this || !entity.IsHighlighted) { continue; }
|
||||
if (!entity.IsMouseOn(position)) { continue; }
|
||||
if (entity.linkedTo != null && entity.linkedTo.Contains(this))
|
||||
if (entity.linkedTo == null || !entity.Linkable) { continue; }
|
||||
if (entity.linkedTo.Contains(this) || linkedTo.Contains(entity) || rClick)
|
||||
{
|
||||
if (entity == this || !entity.IsHighlighted) continue;
|
||||
if (!entity.IsMouseOn(position)) continue;
|
||||
if (entity.Linkable && entity.linkedTo != null && !entity.linkedTo.Contains(this))
|
||||
if (entity == this || !entity.IsHighlighted) { continue; }
|
||||
if (!entity.IsMouseOn(position)) { continue; }
|
||||
if (entity.linkedTo.Contains(this))
|
||||
{
|
||||
entity.linkedTo.Add(this);
|
||||
linkedTo.Add(entity);
|
||||
entity.linkedTo.Remove(this);
|
||||
linkedTo.Remove(entity);
|
||||
}
|
||||
}
|
||||
else if (entity.Linkable && entity.linkedTo != null)
|
||||
else
|
||||
{
|
||||
entity.linkedTo.Add(this);
|
||||
linkedTo.Add(entity);
|
||||
if (!entity.linkedTo.Contains(this)) { entity.linkedTo.Add(this); }
|
||||
if (!linkedTo.Contains(this)) { linkedTo.Add(entity); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -125,10 +145,14 @@ namespace Barotrauma
|
||||
networkUpdateTimer += deltaTime;
|
||||
if (networkUpdateTimer > 0.2f)
|
||||
{
|
||||
if (!pendingSectionUpdates.Any())
|
||||
if (!pendingSectionUpdates.Any() && !pendingDecalUpdates.Any())
|
||||
{
|
||||
GameMain.NetworkMember?.CreateEntityEvent(this);
|
||||
}
|
||||
foreach (Decal decal in pendingDecalUpdates)
|
||||
{
|
||||
GameMain.NetworkMember?.CreateEntityEvent(this, new object[] { decal });
|
||||
}
|
||||
foreach (int pendingSectionUpdate in pendingSectionUpdates)
|
||||
{
|
||||
GameMain.NetworkMember?.CreateEntityEvent(this, new object[] { pendingSectionUpdate });
|
||||
@@ -261,6 +285,13 @@ namespace Barotrauma
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle(fireSourceRect.X - (int)fs.DamageRange, fireSourceRect.Y, fireSourceRect.Width + (int)fs.DamageRange * 2, fireSourceRect.Height), GUI.Style.Orange, false, 0, 5);
|
||||
//GUI.DrawRectangle(spriteBatch, new Rectangle((int)fs.LastExtinguishPos.X, (int)-fs.LastExtinguishPos.Y, 5,5), Color.Yellow, true);
|
||||
}
|
||||
foreach (FireSource fs in FakeFireSources)
|
||||
{
|
||||
Rectangle fireSourceRect = new Rectangle((int)fs.WorldPosition.X, -(int)fs.WorldPosition.Y, (int)fs.Size.X, (int)fs.Size.Y);
|
||||
GUI.DrawRectangle(spriteBatch, fireSourceRect, GUI.Style.Red, false, 0, 5);
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle(fireSourceRect.X - (int)fs.DamageRange, fireSourceRect.Y, fireSourceRect.Width + (int)fs.DamageRange * 2, fireSourceRect.Height), GUI.Style.Orange, false, 0, 5);
|
||||
//GUI.DrawRectangle(spriteBatch, new Rectangle((int)fs.LastExtinguishPos.X, (int)-fs.LastExtinguishPos.Y, 5,5), Color.Yellow, true);
|
||||
}
|
||||
|
||||
|
||||
/*GUI.DrawLine(spriteBatch, new Vector2(drawRect.X, -WorldSurface), new Vector2(drawRect.Right, -WorldSurface), Color.Cyan * 0.5f);
|
||||
@@ -530,9 +561,9 @@ namespace Barotrauma
|
||||
|
||||
public void ClientWrite(IWriteMessage msg, object[] extraData = null)
|
||||
{
|
||||
msg.Write(extraData != null);
|
||||
if (extraData == null)
|
||||
{
|
||||
msg.WriteRangedInteger(0, 0, 2);
|
||||
msg.WriteRangedSingle(MathHelper.Clamp(waterVolume / Volume, 0.0f, 1.5f), 0.0f, 1.5f, 8);
|
||||
|
||||
msg.Write(FireSources.Count > 0);
|
||||
@@ -552,8 +583,16 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (extraData[0] is Decal decal)
|
||||
{
|
||||
msg.WriteRangedInteger(1, 0, 2);
|
||||
int decalIndex = decals.IndexOf(decal);
|
||||
msg.Write((byte)(decalIndex < 0 ? 255 : decalIndex));
|
||||
msg.WriteRangedSingle(decal.BaseAlpha, 0.0f, 1.0f, 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.WriteRangedInteger(2, 0, 2);
|
||||
int sectorToUpdate = (int)extraData[0];
|
||||
int start = sectorToUpdate * BackgroundSectionsPerNetworkEvent;
|
||||
int end = Math.Min((sectorToUpdate + 1) * BackgroundSectionsPerNetworkEvent, BackgroundSections.Count - 1);
|
||||
@@ -598,11 +637,6 @@ namespace Barotrauma
|
||||
{
|
||||
float colorStrength = message.ReadRangedSingle(0.0f, 1.0f, 8);
|
||||
Color color = new Color(message.ReadUInt32());
|
||||
float prevColorStrength = BackgroundSections[i].ColorStrength;
|
||||
BackgroundSections[i].SetColorStrength(colorStrength);
|
||||
BackgroundSections[i].SetColor(color);
|
||||
paintAmount = Math.Max(0, paintAmount + (BackgroundSections[i].ColorStrength - prevColorStrength) / BackgroundSections.Count);
|
||||
|
||||
var remoteBackgroundSection = remoteBackgroundSections.Find(s => s.Index == i);
|
||||
if (remoteBackgroundSection != null)
|
||||
{
|
||||
@@ -619,16 +653,16 @@ namespace Barotrauma
|
||||
else
|
||||
{
|
||||
int decalCount = message.ReadRangedInteger(0, MaxDecalsPerHull);
|
||||
decals.Clear();
|
||||
if (decalCount == 0) { decals.Clear(); }
|
||||
remoteDecals.Clear();
|
||||
for (int i = 0; i < decalCount; i++)
|
||||
{
|
||||
UInt32 decalId = message.ReadUInt32();
|
||||
int spriteIndex = message.ReadByte();
|
||||
float normalizedXPos = message.ReadRangedSingle(0.0f, 1.0f, 8);
|
||||
float normalizedYPos = message.ReadRangedSingle(0.0f, 1.0f, 8);
|
||||
float decalPosX = MathHelper.Lerp(rect.X, rect.Right, normalizedXPos);
|
||||
float decalPosY = MathHelper.Lerp(rect.Y - rect.Height, rect.Y, normalizedYPos);
|
||||
float decalScale = message.ReadRangedSingle(0.0f, 2.0f, 12);
|
||||
AddDecal(decalId, new Vector2(decalPosX, decalPosY), decalScale, isNetworkEvent: true);
|
||||
remoteDecals.Add(new RemoteDecal(decalId, spriteIndex, new Vector2(normalizedXPos, normalizedYPos), decalScale));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -642,11 +676,30 @@ namespace Barotrauma
|
||||
{
|
||||
foreach (BackgroundSection remoteBackgroundSection in remoteBackgroundSections)
|
||||
{
|
||||
float prevColorStrength = BackgroundSections[remoteBackgroundSection.Index].ColorStrength;
|
||||
BackgroundSections[remoteBackgroundSection.Index].SetColor(remoteBackgroundSection.Color);
|
||||
BackgroundSections[remoteBackgroundSection.Index].SetColorStrength(remoteBackgroundSection.ColorStrength);
|
||||
paintAmount = Math.Max(0, paintAmount + (BackgroundSections[remoteBackgroundSection.Index].ColorStrength - prevColorStrength) / BackgroundSections.Count);
|
||||
}
|
||||
remoteBackgroundSections.Clear();
|
||||
|
||||
if (remoteDecals.Any())
|
||||
{
|
||||
decals.Clear();
|
||||
foreach (RemoteDecal remoteDecal in remoteDecals)
|
||||
{
|
||||
float decalPosX = MathHelper.Lerp(rect.X, rect.Right, remoteDecal.NormalizedPos.X);
|
||||
float decalPosY = MathHelper.Lerp(rect.Y - rect.Height, rect.Y, remoteDecal.NormalizedPos.Y);
|
||||
if (Submarine != null)
|
||||
{
|
||||
decalPosX += Submarine.Position.X;
|
||||
decalPosY += Submarine.Position.Y;
|
||||
}
|
||||
AddDecal(remoteDecal.DecalId, new Vector2(decalPosX, decalPosY), remoteDecal.Scale, isNetworkEvent: true, spriteIndex: remoteDecal.SpriteIndex);
|
||||
}
|
||||
remoteDecals.Clear();
|
||||
}
|
||||
|
||||
if (remoteFireSources == null) { return; }
|
||||
|
||||
WaterVolume = remoteWaterVolume;
|
||||
|
||||
@@ -219,7 +219,7 @@ namespace Barotrauma.Lights
|
||||
{
|
||||
if (!light.IsBackground) { continue; }
|
||||
light.DrawSprite(spriteBatch, cam);
|
||||
if (light.Color.A > 0 && light.Range > 0.0f) { light.DrawLightVolume(spriteBatch, lightEffect, transform); }
|
||||
light.DrawLightVolume(spriteBatch, lightEffect, transform);
|
||||
}
|
||||
GameMain.ParticleManager.Draw(spriteBatch, true, null, Particles.ParticleBlendState.Additive);
|
||||
spriteBatch.End();
|
||||
@@ -328,7 +328,7 @@ namespace Barotrauma.Lights
|
||||
foreach (LightSource light in activeLights)
|
||||
{
|
||||
if (light.IsBackground) { continue; }
|
||||
if (light.Color.A > 0 && light.Range > 0.0f) { light.DrawLightVolume(spriteBatch, lightEffect, transform); }
|
||||
light.DrawLightVolume(spriteBatch, lightEffect, transform);
|
||||
}
|
||||
|
||||
lightEffect.World = transform;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Barotrauma.Extensions;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
@@ -6,6 +7,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
|
||||
|
||||
namespace Barotrauma.Lights
|
||||
{
|
||||
class LightSourceParams : ISerializableEntity
|
||||
@@ -42,6 +44,12 @@ namespace Barotrauma.Lights
|
||||
}
|
||||
}
|
||||
|
||||
[Serialize(1f, true), Editable(minValue: 0.01f, maxValue: 100f, ValueStep = 0.1f, DecimalCount = 2)]
|
||||
public float Scale { get; set; }
|
||||
|
||||
[Serialize("0, 0", true), Editable(ValueStep = 1, DecimalCount = 1, MinValueFloat = -1000f, MaxValueFloat = 1000f)]
|
||||
public Vector2 Offset { get; set; }
|
||||
|
||||
public float TextureRange
|
||||
{
|
||||
get;
|
||||
@@ -239,11 +247,13 @@ namespace Barotrauma.Lights
|
||||
}
|
||||
}
|
||||
|
||||
private Vector2 _spriteScale = Vector2.One;
|
||||
|
||||
public Vector2 SpriteScale
|
||||
{
|
||||
get;
|
||||
set;
|
||||
} = Vector2.One;
|
||||
get { return _spriteScale * lightSourceParams.Scale; }
|
||||
set { _spriteScale = value; }
|
||||
}
|
||||
|
||||
public float? OverrideLightSpriteAlpha
|
||||
{
|
||||
@@ -278,7 +288,9 @@ namespace Barotrauma.Lights
|
||||
{
|
||||
get { return lightSourceParams.LightSprite; }
|
||||
}
|
||||
|
||||
|
||||
private Vector2 OverrideLightTextureOrigin => OverrideLightTexture.Origin + LightSourceParams.Offset;
|
||||
|
||||
public Color Color
|
||||
{
|
||||
get { return lightSourceParams.Color; }
|
||||
@@ -331,16 +343,42 @@ namespace Barotrauma.Lights
|
||||
|
||||
public bool Enabled = true;
|
||||
|
||||
public LightSource (XElement element)
|
||||
private ISerializableEntity conditionalTarget;
|
||||
private readonly PropertyConditional.Comparison comparison;
|
||||
private readonly List<PropertyConditional> conditionals = new List<PropertyConditional>();
|
||||
|
||||
public LightSource (XElement element, ISerializableEntity conditionalTarget = null)
|
||||
: this(Vector2.Zero, 100.0f, Color.White, null)
|
||||
{
|
||||
lightSourceParams = new LightSourceParams(element);
|
||||
CastShadows = element.GetAttributeBool("castshadows", true);
|
||||
string comparison = element.GetAttributeString("comparison", null);
|
||||
if (comparison != null)
|
||||
{
|
||||
Enum.TryParse(comparison, ignoreCase: true, out this.comparison);
|
||||
}
|
||||
|
||||
if (lightSourceParams.DeformableLightSpriteElement != null)
|
||||
{
|
||||
DeformableLightSprite = new DeformableSprite(lightSourceParams.DeformableLightSpriteElement, invert: true);
|
||||
}
|
||||
|
||||
this.conditionalTarget = conditionalTarget;
|
||||
foreach (XElement subElement in element.Elements())
|
||||
{
|
||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||
{
|
||||
case "conditional":
|
||||
foreach (XAttribute attribute in subElement.Attributes())
|
||||
{
|
||||
if (PropertyConditional.IsValid(attribute))
|
||||
{
|
||||
conditionals.Add(new PropertyConditional(attribute));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public LightSource(LightSourceParams lightSourceParams)
|
||||
@@ -363,7 +401,8 @@ namespace Barotrauma.Lights
|
||||
CastShadows = true;
|
||||
texture = LightTexture;
|
||||
diffToSub = new Dictionary<Submarine, Vector2>();
|
||||
if (addLight) GameMain.LightManager.AddLight(this);
|
||||
if (addLight) { GameMain.LightManager.AddLight(this); }
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -493,7 +532,7 @@ namespace Barotrauma.Lights
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (Range < 1.0f || Color.A < 0.01f) return null;
|
||||
if (Range < 1.0f || Color.A < 1) { return null; }
|
||||
|
||||
Vector2 drawPos = position;
|
||||
if (ParentSub != null) drawPos += ParentSub.DrawPosition;
|
||||
@@ -535,7 +574,7 @@ namespace Barotrauma.Lights
|
||||
|
||||
var overrideTextureDims = new Vector2(OverrideLightTexture.SourceRect.Width, OverrideLightTexture.SourceRect.Height);
|
||||
|
||||
Vector2 origin = OverrideLightTexture.Origin;
|
||||
Vector2 origin = OverrideLightTextureOrigin;
|
||||
|
||||
origin /= Math.Max(overrideTextureDims.X, overrideTextureDims.Y);
|
||||
origin -= Vector2.One * 0.5f;
|
||||
@@ -844,7 +883,7 @@ namespace Barotrauma.Lights
|
||||
{
|
||||
overrideTextureDims = new Vector2(OverrideLightTexture.SourceRect.Width, OverrideLightTexture.SourceRect.Height);
|
||||
|
||||
Vector2 origin = OverrideLightTexture.Origin;
|
||||
Vector2 origin = OverrideLightTextureOrigin;
|
||||
if (LightSpriteEffect == SpriteEffects.FlipHorizontally) { origin.X = OverrideLightTexture.SourceRect.Width - origin.X; }
|
||||
if (LightSpriteEffect == SpriteEffects.FlipVertically) { origin.Y = OverrideLightTexture.SourceRect.Height - origin.Y; }
|
||||
uvOffset = (origin / overrideTextureDims) - new Vector2(0.5f, 0.5f);
|
||||
@@ -1031,7 +1070,7 @@ namespace Barotrauma.Lights
|
||||
{
|
||||
var overrideTextureDims = new Vector2(OverrideLightTexture.SourceRect.Width, OverrideLightTexture.SourceRect.Height);
|
||||
|
||||
Vector2 origin = OverrideLightTexture.Origin;
|
||||
Vector2 origin = OverrideLightTextureOrigin;
|
||||
|
||||
origin /= Math.Max(overrideTextureDims.X, overrideTextureDims.Y);
|
||||
origin *= TextureRange;
|
||||
@@ -1059,13 +1098,12 @@ namespace Barotrauma.Lights
|
||||
|
||||
if (DeformableLightSprite != null)
|
||||
{
|
||||
Vector2 origin = DeformableLightSprite.Origin;
|
||||
Vector2 origin = DeformableLightSprite.Origin + LightSourceParams.Offset;
|
||||
Vector2 drawPos = position;
|
||||
if (ParentSub != null)
|
||||
{
|
||||
drawPos += ParentSub.DrawPosition;
|
||||
}
|
||||
|
||||
if (LightSpriteEffect == SpriteEffects.FlipHorizontally)
|
||||
{
|
||||
origin.X = DeformableLightSprite.Sprite.SourceRect.Width - origin.X;
|
||||
@@ -1084,7 +1122,7 @@ namespace Barotrauma.Lights
|
||||
|
||||
if (LightSprite != null)
|
||||
{
|
||||
Vector2 origin = LightSprite.Origin;
|
||||
Vector2 origin = LightSprite.Origin + LightSourceParams.Offset;
|
||||
if ((LightSpriteEffect & SpriteEffects.FlipHorizontally) == SpriteEffects.FlipHorizontally)
|
||||
{
|
||||
origin.X = LightSprite.SourceRect.Width - origin.X;
|
||||
@@ -1128,12 +1166,27 @@ namespace Barotrauma.Lights
|
||||
GUI.DrawLine(spriteBatch, drawPos - Vector2.One * Range, drawPos + Vector2.One * Range, Color);
|
||||
GUI.DrawLine(spriteBatch, drawPos - new Vector2(1.0f, -1.0f) * Range, drawPos + new Vector2(1.0f, -1.0f) * Range, Color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void CheckConditionals()
|
||||
{
|
||||
if (conditionals.None()) { return; }
|
||||
if (conditionalTarget == null) { return; }
|
||||
if (comparison == PropertyConditional.Comparison.And)
|
||||
{
|
||||
Enabled = conditionals.All(c => c.Matches(conditionalTarget));
|
||||
}
|
||||
else
|
||||
{
|
||||
Enabled = conditionals.Any(c => c.Matches(conditionalTarget));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void DrawLightVolume(SpriteBatch spriteBatch, BasicEffect lightEffect, Matrix transform)
|
||||
{
|
||||
if (Range < 1.0f || Color.A < 1) { return; }
|
||||
|
||||
if (CastShadows)
|
||||
{
|
||||
CheckHullsInRange();
|
||||
@@ -1158,7 +1211,6 @@ namespace Barotrauma.Lights
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (NeedsRecalculation)
|
||||
{
|
||||
var verts = FindRaycastHits();
|
||||
@@ -1168,7 +1220,6 @@ namespace Barotrauma.Lights
|
||||
NeedsRecalculation = false;
|
||||
}
|
||||
|
||||
|
||||
Vector2 offset = ParentSub == null ? Vector2.Zero : ParentSub.DrawPosition;
|
||||
lightEffect.World =
|
||||
Matrix.CreateTranslation(-new Vector3(position, 0.0f)) *
|
||||
|
||||
@@ -27,6 +27,9 @@ namespace Barotrauma
|
||||
|
||||
private static bool resizing;
|
||||
private int resizeDirX, resizeDirY;
|
||||
private Rectangle? prevRect;
|
||||
|
||||
public static bool SelectionChanged;
|
||||
|
||||
//which entities have been selected for editing
|
||||
private static List<MapEntity> selectedList = new List<MapEntity>();
|
||||
@@ -105,6 +108,11 @@ namespace Barotrauma
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used for undo/redo to determine what this item has been replaced with
|
||||
/// </summary>
|
||||
public MapEntity ReplacedBy;
|
||||
|
||||
public virtual void Draw(SpriteBatch spriteBatch, bool editing, bool back = true) { }
|
||||
|
||||
/// <summary>
|
||||
@@ -147,13 +155,13 @@ namespace Barotrauma
|
||||
}
|
||||
if (GUI.KeyboardDispatcher.Subscriber == null)
|
||||
{
|
||||
if (PlayerInput.KeyDown(Keys.Delete))
|
||||
if (PlayerInput.KeyHit(Keys.Delete))
|
||||
{
|
||||
selectedList.ForEach(e =>
|
||||
if (selectedList.Any())
|
||||
{
|
||||
//orphaned wires may already have been removed
|
||||
if (!e.Removed) { e.Remove(); }
|
||||
});
|
||||
SubEditorScreen.StoreCommand(new AddOrDeleteCommand(selectedList, true));
|
||||
}
|
||||
selectedList.ForEach(e => { if (!e.Removed) { e.Remove(); } });
|
||||
selectedList.Clear();
|
||||
}
|
||||
|
||||
@@ -217,30 +225,6 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (PlayerInput.KeyHit(Keys.Z))
|
||||
{
|
||||
SetPreviousRects(e => e.rectMemento.Undo());
|
||||
}
|
||||
else if (PlayerInput.KeyHit(Keys.R))
|
||||
{
|
||||
SetPreviousRects(e => e.rectMemento.Redo());
|
||||
}
|
||||
|
||||
void SetPreviousRects(Func<MapEntity, Rectangle> memoryMethod)
|
||||
{
|
||||
foreach (var e in SelectedList)
|
||||
{
|
||||
if (e.rectMemento != null)
|
||||
{
|
||||
Point diff = memoryMethod(e).Location - e.Rect.Location;
|
||||
// We have to call the move method, because there's a lot more than just storing the rect (in some cases)
|
||||
// We also have to reassign the rect, because the move method does not set the width and height. They might have changed too.
|
||||
// The Rect property is virtual and it's overridden for structs. Setting the rect via the property should automatically recreate the sections for resizable structures.
|
||||
e.Move(diff.ToVector2());
|
||||
e.Rect = e.rectMemento.Current;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,35 +327,38 @@ namespace Barotrauma
|
||||
//clone
|
||||
if (PlayerInput.IsCtrlDown())
|
||||
{
|
||||
var clones = Clone(selectedList);
|
||||
var clones = Clone(selectedList).Where(c => c != null).ToList();
|
||||
selectedList = clones;
|
||||
SubEditorScreen.StoreCommand(new AddOrDeleteCommand(clones, false));
|
||||
selectedList.ForEach(c => c.Move(moveAmount));
|
||||
}
|
||||
else // move
|
||||
{
|
||||
var oldRects = selectedList.Select(e => e.Rect).ToList();
|
||||
List<MapEntity> deposited = new List<MapEntity>();
|
||||
foreach (MapEntity e in selectedList)
|
||||
{
|
||||
if (e.rectMemento == null)
|
||||
{
|
||||
e.rectMemento = new Memento<Rectangle>();
|
||||
e.rectMemento.Store(e.Rect);
|
||||
}
|
||||
e.Move(moveAmount);
|
||||
|
||||
if (isShiftDown && e is Item item && targetContainer != null)
|
||||
{
|
||||
if (targetContainer.OwnInventory.TryPutItem(item, Character.Controlled))
|
||||
{
|
||||
GUI.PlayUISound(GUISoundType.DropItem);
|
||||
SoundPlayer.PlayUISound(GUISoundType.DropItem);
|
||||
deposited.Add(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.PlayUISound(GUISoundType.PickItemFail);
|
||||
SoundPlayer.PlayUISound(GUISoundType.PickItemFail);
|
||||
}
|
||||
}
|
||||
e.rectMemento.Store(e.Rect);
|
||||
}
|
||||
|
||||
SubEditorScreen.StoreCommand(new TransformCommand(new List<MapEntity>(selectedList),selectedList.Select(entity => entity.Rect).ToList(), oldRects, false));
|
||||
if (deposited.Any() && deposited.Any(entity => entity is Item))
|
||||
{
|
||||
var depositedItems = deposited.Where(entity => entity is Item).Cast<Item>().ToList();
|
||||
SubEditorScreen.StoreCommand(new InventoryPlaceCommand(targetContainer.OwnInventory, depositedItems, false));
|
||||
}
|
||||
|
||||
deposited.ForEach(entity => { selectedList.Remove(entity); });
|
||||
@@ -492,6 +479,11 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public MapEntity GetReplacementOrThis()
|
||||
{
|
||||
return ReplacedBy?.GetReplacementOrThis() ?? this;
|
||||
}
|
||||
|
||||
public static Item GetPotentialContainer(Vector2 position, List<MapEntity> entities = null)
|
||||
{
|
||||
Item targetContainer = null;
|
||||
@@ -904,13 +896,12 @@ namespace Barotrauma
|
||||
public static void Cut(List<MapEntity> entities)
|
||||
{
|
||||
if (entities.Count == 0) { return; }
|
||||
|
||||
|
||||
SubEditorScreen.StoreCommand(new AddOrDeleteCommand(new List<MapEntity>(entities), true));
|
||||
|
||||
CopyEntities(entities);
|
||||
|
||||
entities.ForEach(e =>
|
||||
{
|
||||
e.Remove();
|
||||
});
|
||||
|
||||
entities.ForEach(e => { if (!e.Removed) { e.Remove(); } });
|
||||
entities.Clear();
|
||||
}
|
||||
|
||||
@@ -922,6 +913,7 @@ namespace Barotrauma
|
||||
Clone(copiedList);
|
||||
|
||||
var clones = mapEntityList.Except(prevEntities).ToList();
|
||||
SubEditorScreen.StoreCommand(new AddOrDeleteCommand(clones, false));
|
||||
var nonWireClones = clones.Where(c => !(c is Item item) || item.GetComponent<Wire>() == null);
|
||||
if (!nonWireClones.Any()) { nonWireClones = clones; }
|
||||
|
||||
@@ -1031,12 +1023,11 @@ namespace Barotrauma
|
||||
|
||||
if (resizing)
|
||||
{
|
||||
if (rectMemento == null)
|
||||
if (prevRect == null)
|
||||
{
|
||||
rectMemento = new Memento<Rectangle>();
|
||||
rectMemento.Store(Rect);
|
||||
prevRect = new Rectangle(Rect.Location, Rect.Size);
|
||||
}
|
||||
|
||||
|
||||
Vector2 placePosition = new Vector2(rect.X, rect.Y);
|
||||
Vector2 placeSize = new Vector2(rect.Width, rect.Height);
|
||||
|
||||
@@ -1079,9 +1070,15 @@ namespace Barotrauma
|
||||
|
||||
if (!PlayerInput.PrimaryMouseButtonHeld())
|
||||
{
|
||||
rectMemento.Store(Rect);
|
||||
resizing = false;
|
||||
Resized?.Invoke(rect);
|
||||
if (prevRect != null)
|
||||
{
|
||||
var newData = new List<Rectangle> { Rect };
|
||||
var oldData = new List<Rectangle> { prevRect.Value };
|
||||
SubEditorScreen.StoreCommand(new TransformCommand(new List<MapEntity> { this }, newData, oldData, true));
|
||||
}
|
||||
prevRect = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ namespace Barotrauma
|
||||
int heightScaled = (int)(20 * GUI.Scale);
|
||||
editingHUD = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.25f), GUI.Canvas, Anchor.CenterRight) { MinSize = new Point(400, 0) }) { UserData = this };
|
||||
GUIListBox listBox = new GUIListBox(new RectTransform(new Vector2(0.95f, 0.8f), editingHUD.RectTransform, Anchor.Center), style: null);
|
||||
var editor = new SerializableEntityEditor(listBox.Content.RectTransform, this, inGame, showName: true, titleFont: GUI.LargeFont);
|
||||
var editor = new SerializableEntityEditor(listBox.Content.RectTransform, this, inGame, showName: true, titleFont: GUI.LargeFont) { UserData = this };
|
||||
|
||||
if (Submarine.MainSub?.Info?.Type == SubmarineType.OutpostModule)
|
||||
{
|
||||
|
||||
@@ -56,11 +56,12 @@ namespace Barotrauma
|
||||
if (PlayerInput.PrimaryMouseButtonReleased())
|
||||
{
|
||||
newRect.Location -= MathUtils.ToPoint(Submarine.MainSub.Position);
|
||||
new Structure(newRect, this, Submarine.MainSub)
|
||||
var structure = new Structure(newRect, this, Submarine.MainSub)
|
||||
{
|
||||
Submarine = Submarine.MainSub
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
SubEditorScreen.StoreCommand(new AddOrDeleteCommand(new List<MapEntity> { structure }, false));
|
||||
selected = null;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ namespace Barotrauma
|
||||
{
|
||||
string errorMsg = "Error when loading round sound (" + element + ") - file path not set";
|
||||
DebugConsole.ThrowError(errorMsg);
|
||||
GameAnalyticsManager.AddErrorEventOnce("Submarine.LoadRoundSound:FilePathEmpty" + element.ToString(), GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg + "\n" + Environment.StackTrace);
|
||||
GameAnalyticsManager.AddErrorEventOnce("Submarine.LoadRoundSound:FilePathEmpty" + element.ToString(), GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg + "\n" + Environment.StackTrace.CleanupStackTrace());
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
existingSound = roundSounds.Find(s => s.Filename == filename && s.Stream == stream)?.Sound;
|
||||
existingSound = roundSounds.Find(s => s.Filename == filename && s.Stream == stream && !s.Sound.Disposed)?.Sound;
|
||||
}
|
||||
|
||||
if (existingSound == null)
|
||||
@@ -121,7 +121,7 @@ namespace Barotrauma
|
||||
{
|
||||
string errorMsg = "Failed to load sound file \"" + filename + "\".";
|
||||
DebugConsole.ThrowError(errorMsg, e);
|
||||
GameAnalyticsManager.AddErrorEventOnce("Submarine.LoadRoundSound:FileNotFound" + filename, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg + "\n" + Environment.StackTrace);
|
||||
GameAnalyticsManager.AddErrorEventOnce("Submarine.LoadRoundSound:FileNotFound" + filename, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg + "\n" + Environment.StackTrace.CleanupStackTrace());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -132,6 +132,26 @@ namespace Barotrauma
|
||||
return newSound;
|
||||
}
|
||||
|
||||
public static void ReloadRoundSound(RoundSound roundSound)
|
||||
{
|
||||
Sound existingSound = roundSounds?.Find(s => s.Filename == roundSound.Filename && s.Stream == roundSound.Stream && !s.Sound.Disposed)?.Sound;
|
||||
if (existingSound == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
existingSound = GameMain.SoundManager.LoadSound(roundSound.Filename, roundSound.Stream);
|
||||
}
|
||||
catch (System.IO.FileNotFoundException e)
|
||||
{
|
||||
string errorMsg = "Failed to load sound file \"" + roundSound.Filename + "\".";
|
||||
DebugConsole.ThrowError(errorMsg, e);
|
||||
GameAnalyticsManager.AddErrorEventOnce("Submarine.LoadRoundSound:FileNotFound" + roundSound.Filename, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg + "\n" + Environment.StackTrace.CleanupStackTrace());
|
||||
return;
|
||||
}
|
||||
}
|
||||
roundSound.Sound = existingSound;
|
||||
}
|
||||
|
||||
private static void RemoveRoundSound(RoundSound roundSound)
|
||||
{
|
||||
roundSound.Sound?.Dispose();
|
||||
@@ -438,10 +458,15 @@ namespace Barotrauma
|
||||
public void CheckForErrors()
|
||||
{
|
||||
List<string> errorMsgs = new List<string>();
|
||||
List<SubEditorScreen.WarningType> warnings = new List<SubEditorScreen.WarningType>();
|
||||
|
||||
if (!Hull.hullList.Any())
|
||||
{
|
||||
errorMsgs.Add(TextManager.Get("NoHullsWarning"));
|
||||
if (!IsWarningSuppressed(SubEditorScreen.WarningType.NoWaypoints))
|
||||
{
|
||||
errorMsgs.Add(TextManager.Get("NoHullsWarning"));
|
||||
warnings.Add(SubEditorScreen.WarningType.NoHulls);
|
||||
}
|
||||
}
|
||||
|
||||
if (Info.Type != SubmarineType.OutpostModule ||
|
||||
@@ -449,7 +474,11 @@ namespace Barotrauma
|
||||
{
|
||||
if (!WayPoint.WayPointList.Any(wp => wp.ShouldBeSaved && wp.SpawnType == SpawnType.Path))
|
||||
{
|
||||
errorMsgs.Add(TextManager.Get("NoWaypointsWarning"));
|
||||
if (!IsWarningSuppressed(SubEditorScreen.WarningType.NoWaypoints))
|
||||
{
|
||||
errorMsgs.Add(TextManager.Get("NoWaypointsWarning"));
|
||||
warnings.Add(SubEditorScreen.WarningType.NoWaypoints);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -460,22 +489,38 @@ namespace Barotrauma
|
||||
if (item.GetComponent<Items.Components.Vent>() == null) { continue; }
|
||||
if (!item.linkedTo.Any())
|
||||
{
|
||||
errorMsgs.Add(TextManager.Get("DisconnectedVentsWarning"));
|
||||
if (!IsWarningSuppressed(SubEditorScreen.WarningType.DisconnectedVents))
|
||||
{
|
||||
errorMsgs.Add(TextManager.Get("DisconnectedVentsWarning"));
|
||||
warnings.Add(SubEditorScreen.WarningType.DisconnectedVents);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!WayPoint.WayPointList.Any(wp => wp.ShouldBeSaved && wp.SpawnType == SpawnType.Human))
|
||||
{
|
||||
errorMsgs.Add(TextManager.Get("NoHumanSpawnpointWarning"));
|
||||
if (!IsWarningSuppressed(SubEditorScreen.WarningType.NoHumanSpawnpoints))
|
||||
{
|
||||
errorMsgs.Add(TextManager.Get("NoHumanSpawnpointWarning"));
|
||||
warnings.Add(SubEditorScreen.WarningType.NoHumanSpawnpoints);
|
||||
}
|
||||
}
|
||||
if (WayPoint.WayPointList.Find(wp => wp.SpawnType == SpawnType.Cargo) == null)
|
||||
{
|
||||
errorMsgs.Add(TextManager.Get("NoCargoSpawnpointWarning"));
|
||||
if (!IsWarningSuppressed(SubEditorScreen.WarningType.NoCargoSpawnpoints))
|
||||
{
|
||||
errorMsgs.Add(TextManager.Get("NoCargoSpawnpointWarning"));
|
||||
warnings.Add(SubEditorScreen.WarningType.NoCargoSpawnpoints);
|
||||
}
|
||||
}
|
||||
if (!Item.ItemList.Any(it => it.GetComponent<Items.Components.Pump>() != null && it.HasTag("ballast")))
|
||||
{
|
||||
errorMsgs.Add(TextManager.Get("NoBallastTagsWarning"));
|
||||
if (!IsWarningSuppressed(SubEditorScreen.WarningType.NoBallastTag))
|
||||
{
|
||||
errorMsgs.Add(TextManager.Get("NoBallastTagsWarning"));
|
||||
warnings.Add(SubEditorScreen.WarningType.NoBallastTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Info.Type == SubmarineType.OutpostModule)
|
||||
@@ -503,7 +548,11 @@ namespace Barotrauma
|
||||
|
||||
if (Gap.GapList.Any(g => g.linkedTo.Count == 0))
|
||||
{
|
||||
errorMsgs.Add(TextManager.Get("NonLinkedGapsWarning"));
|
||||
if (!IsWarningSuppressed(SubEditorScreen.WarningType.NonLinkedGaps))
|
||||
{
|
||||
errorMsgs.Add(TextManager.Get("NonLinkedGapsWarning"));
|
||||
warnings.Add(SubEditorScreen.WarningType.NonLinkedGaps);
|
||||
}
|
||||
}
|
||||
|
||||
int disabledItemLightCount = 0;
|
||||
@@ -515,12 +564,35 @@ namespace Barotrauma
|
||||
int count = GameMain.LightManager.Lights.Count(l => l.CastShadows) - disabledItemLightCount;
|
||||
if (count > 45)
|
||||
{
|
||||
errorMsgs.Add(TextManager.Get("subeditor.shadowcastinglightswarning"));
|
||||
if (!IsWarningSuppressed(SubEditorScreen.WarningType.TooManyLights))
|
||||
{
|
||||
errorMsgs.Add(TextManager.Get("subeditor.shadowcastinglightswarning"));
|
||||
warnings.Add(SubEditorScreen.WarningType.TooManyLights);
|
||||
}
|
||||
}
|
||||
|
||||
if (errorMsgs.Any())
|
||||
{
|
||||
new GUIMessageBox(TextManager.Get("Warning"), string.Join("\n\n", errorMsgs), new Vector2(0.25f, 0.0f), new Point(400, 200));
|
||||
GUIMessageBox msgBox = new GUIMessageBox(TextManager.Get("Warning"), string.Join("\n\n", errorMsgs), new Vector2(0.25f, 0.0f), new Point(400, 200));
|
||||
if (warnings.Any())
|
||||
{
|
||||
Point size = msgBox.RectTransform.NonScaledSize;
|
||||
GUITickBox suppress = new GUITickBox(new RectTransform(new Vector2(1f, 0.33f), msgBox.Content.RectTransform), TextManager.Get("editor.suppresswarnings"));
|
||||
msgBox.RectTransform.NonScaledSize = new Point(size.X, size.Y + suppress.RectTransform.NonScaledSize.Y);
|
||||
|
||||
msgBox.Buttons[0].OnClicked += (button, obj) =>
|
||||
{
|
||||
if (suppress.Selected)
|
||||
{
|
||||
foreach (SubEditorScreen.WarningType warning in warnings.Where(warning => !SubEditorScreen.SuppressedWarnings.Contains(warning)))
|
||||
{
|
||||
SubEditorScreen.SuppressedWarnings.Add(warning);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
foreach (MapEntity e in MapEntity.mapEntityList)
|
||||
@@ -556,6 +628,11 @@ namespace Barotrauma
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool IsWarningSuppressed(SubEditorScreen.WarningType type)
|
||||
{
|
||||
return SubEditorScreen.SuppressedWarnings.Contains(type);
|
||||
}
|
||||
}
|
||||
|
||||
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
||||
|
||||
Reference in New Issue
Block a user