Release v0.15.12.0
This commit is contained in:
@@ -8,6 +8,8 @@ namespace Barotrauma
|
||||
{
|
||||
partial void ExplodeProjSpecific(Vector2 worldPosition, Hull hull)
|
||||
{
|
||||
if (GameMain.Client?.MidRoundSyncing ?? false) { return; }
|
||||
|
||||
if (shockwave)
|
||||
{
|
||||
GameMain.ParticleManager.CreateParticle("shockwave", worldPosition,
|
||||
|
||||
@@ -676,7 +676,7 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
remoteBackgroundSections.Add(new BackgroundSection(new Rectangle(0, 0, 1, 1), i, colorStrength, color, 0));
|
||||
remoteBackgroundSections.Add(new BackgroundSection(new Rectangle(0, 0, 1, 1), (ushort)i, colorStrength, color, 0));
|
||||
}
|
||||
}
|
||||
paintAmount = BackgroundSections.Sum(s => s.ColorStrength);
|
||||
|
||||
@@ -7,14 +7,9 @@ namespace Barotrauma.RuinGeneration
|
||||
{
|
||||
public void DebugDraw(SpriteBatch spriteBatch)
|
||||
{
|
||||
foreach (RuinShape shape in allShapes)
|
||||
{
|
||||
GUI.DrawString(spriteBatch, new Vector2(shape.Center.X, -shape.Center.Y - 50), shape.DistanceFromEntrance.ToString(), Color.White, Color.Black * 0.5f, font: GUI.LargeFont);
|
||||
}
|
||||
foreach (Line line in walls)
|
||||
{
|
||||
GUI.DrawLine(spriteBatch, new Vector2(line.A.X, -line.A.Y), new Vector2(line.B.X, -line.B.Y), GUI.Style.Red, 0.0f, 10);
|
||||
}
|
||||
Rectangle drawRect = Area;
|
||||
drawRect.Y = -drawRect.Y - Area.Height;
|
||||
GUI.DrawRectangle(spriteBatch, drawRect, Color.Cyan, false, 0, 6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -846,16 +846,15 @@ namespace Barotrauma.Lights
|
||||
if (chList.Submarine == null)
|
||||
{
|
||||
list.AddRange(chList.List.FindAll(ch => MathUtils.CircleIntersectsRectangle(lightPos, range, ch.BoundingBox)));
|
||||
|
||||
}
|
||||
//light is outside, convexhull inside a sub
|
||||
else
|
||||
{
|
||||
Rectangle subBorders = chList.Submarine.Borders;
|
||||
subBorders.Y -= chList.Submarine.Borders.Height;
|
||||
if (!MathUtils.CircleIntersectsRectangle(lightPos - chList.Submarine.WorldPosition, range, subBorders)) continue;
|
||||
if (!MathUtils.CircleIntersectsRectangle(lightPos - chList.Submarine.WorldPosition, range, subBorders)) { continue; }
|
||||
|
||||
lightPos -= (chList.Submarine.WorldPosition - chList.Submarine.HiddenSubPosition);
|
||||
lightPos -= chList.Submarine.WorldPosition - chList.Submarine.HiddenSubPosition;
|
||||
|
||||
list.AddRange(chList.List.FindAll(ch => MathUtils.CircleIntersectsRectangle(lightPos, range, ch.BoundingBox)));
|
||||
}
|
||||
@@ -865,14 +864,6 @@ namespace Barotrauma.Lights
|
||||
//light is inside, convexhull outside
|
||||
if (chList.Submarine == null)
|
||||
{
|
||||
lightPos += (ParentSub.WorldPosition - ParentSub.HiddenSubPosition);
|
||||
HashSet<RuinGeneration.Ruin> visibleRuins = new HashSet<RuinGeneration.Ruin>();
|
||||
foreach (RuinGeneration.Ruin ruin in Level.Loaded.Ruins)
|
||||
{
|
||||
if (!MathUtils.CircleIntersectsRectangle(lightPos, range, ruin.Area)) { continue; }
|
||||
visibleRuins.Add(ruin);
|
||||
}
|
||||
list.AddRange(chList.List.FindAll(ch => ch.ParentEntity?.ParentRuin != null && visibleRuins.Contains(ch.ParentEntity.ParentRuin)));
|
||||
continue;
|
||||
}
|
||||
//light and convexhull are both inside the same sub
|
||||
|
||||
@@ -126,8 +126,8 @@ namespace Barotrauma.Lights
|
||||
}
|
||||
|
||||
LosTexture?.Dispose();
|
||||
LosTexture = new RenderTarget2D(graphics,
|
||||
(int)(GameMain.GraphicsWidth * GameMain.Config.LightMapScale),
|
||||
LosTexture = new RenderTarget2D(graphics,
|
||||
(int)(GameMain.GraphicsWidth * GameMain.Config.LightMapScale),
|
||||
(int)(GameMain.GraphicsHeight * GameMain.Config.LightMapScale), false, SurfaceFormat.Color, DepthFormat.None);
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ namespace Barotrauma.Lights
|
||||
activeLights.Clear();
|
||||
foreach (LightSource light in lights)
|
||||
{
|
||||
if (!light.Enabled) { continue; }
|
||||
if (!light.Enabled) { continue; }
|
||||
if ((light.Color.A < 1 || light.Range < 1.0f) && !light.LightSourceParams.OverrideLightSpriteAlpha.HasValue) { continue; }
|
||||
if (light.ParentBody != null)
|
||||
{
|
||||
@@ -197,7 +197,9 @@ namespace Barotrauma.Lights
|
||||
float spriteRange = Math.Max(
|
||||
light.LightSprite.size.X * light.SpriteScale.X * (0.5f + Math.Abs(light.LightSprite.RelativeOrigin.X - 0.5f)),
|
||||
light.LightSprite.size.Y * light.SpriteScale.Y * (0.5f + Math.Abs(light.LightSprite.RelativeOrigin.Y - 0.5f)));
|
||||
range = Math.Max(spriteRange, range);
|
||||
|
||||
float targetSize = Math.Max(light.LightTextureTargetSize.X, light.LightTextureTargetSize.Y);
|
||||
range = Math.Max(Math.Max(spriteRange, targetSize), range);
|
||||
}
|
||||
if (!MathUtils.CircleIntersectsRectangle(light.WorldPosition, range, viewRect)) { continue; }
|
||||
activeLights.Add(light);
|
||||
@@ -238,16 +240,16 @@ namespace Barotrauma.Lights
|
||||
//draw a black rectangle on hulls to hide background lights behind subs
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
|
||||
if (backgroundObstructor != null)
|
||||
/*if (backgroundObstructor != null)
|
||||
{
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied);
|
||||
spriteBatch.Draw(backgroundObstructor, new Rectangle(0, 0,
|
||||
(int)(GameMain.GraphicsWidth * currLightMapScale), (int)(GameMain.GraphicsHeight * currLightMapScale)), Color.Black);
|
||||
spriteBatch.End();
|
||||
}
|
||||
}*/
|
||||
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque, transformMatrix: spriteBatchTransform);
|
||||
Dictionary<Hull, Rectangle> visibleHulls = GetVisibleHulls(cam);
|
||||
Dictionary<Hull, Rectangle> visibleHulls = GetVisibleHulls(cam);
|
||||
foreach (KeyValuePair<Hull, Rectangle> hull in visibleHulls)
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch,
|
||||
@@ -258,18 +260,18 @@ namespace Barotrauma.Lights
|
||||
spriteBatch.End();
|
||||
|
||||
SolidColorEffect.CurrentTechnique = SolidColorEffect.Techniques["SolidColor"];
|
||||
SolidColorEffect.Parameters["color"].SetValue(AmbientLight.ToVector4());
|
||||
SolidColorEffect.Parameters["color"].SetValue(AmbientLight.Opaque().ToVector4());
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, transformMatrix: spriteBatchTransform, effect: SolidColorEffect);
|
||||
Submarine.DrawDamageable(spriteBatch, null);
|
||||
spriteBatch.End();
|
||||
|
||||
graphics.BlendState = BlendState.Additive;
|
||||
|
||||
|
||||
|
||||
//draw the focused item and character to highlight them,
|
||||
//and light sprites (done before drawing the actual light volumes so we can make characters obstruct the highlights and sprites)
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive, transformMatrix: spriteBatchTransform);
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive, transformMatrix: spriteBatchTransform);
|
||||
foreach (LightSource light in activeLights)
|
||||
{
|
||||
//don't draw limb lights at this point, they need to be drawn after lights have been obstructed by characters
|
||||
@@ -294,8 +296,8 @@ namespace Barotrauma.Lights
|
||||
{
|
||||
if (character.CurrentHull == null || !character.Enabled || !character.IsVisible) { continue; }
|
||||
if (Character.Controlled?.FocusedCharacter == character) { continue; }
|
||||
Color lightColor = character.CurrentHull.AmbientLight == Color.TransparentBlack ?
|
||||
Color.Black :
|
||||
Color lightColor = character.CurrentHull.AmbientLight == Color.TransparentBlack ?
|
||||
Color.Black :
|
||||
character.CurrentHull.AmbientLight.Multiply(character.CurrentHull.AmbientLight.A / 255.0f).Opaque();
|
||||
foreach (Limb limb in character.AnimController.Limbs)
|
||||
{
|
||||
@@ -304,7 +306,7 @@ namespace Barotrauma.Lights
|
||||
}
|
||||
}
|
||||
spriteBatch.End();
|
||||
|
||||
|
||||
DeformableSprite.Effect.CurrentTechnique = DeformableSprite.Effect.Techniques["DeformShaderSolidVertexColor"];
|
||||
DeformableSprite.Effect.CurrentTechnique.Passes[0].Apply();
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, transformMatrix: spriteBatchTransform);
|
||||
@@ -312,8 +314,8 @@ namespace Barotrauma.Lights
|
||||
{
|
||||
if (character.CurrentHull == null || !character.Enabled || !character.IsVisible) { continue; }
|
||||
if (Character.Controlled?.FocusedCharacter == character) { continue; }
|
||||
Color lightColor = character.CurrentHull.AmbientLight == Color.TransparentBlack ?
|
||||
Color.Black :
|
||||
Color lightColor = character.CurrentHull.AmbientLight == Color.TransparentBlack ?
|
||||
Color.Black :
|
||||
character.CurrentHull.AmbientLight.Multiply(character.CurrentHull.AmbientLight.A / 255.0f).Opaque();
|
||||
foreach (Limb limb in character.AnimController.Limbs)
|
||||
{
|
||||
@@ -343,9 +345,9 @@ namespace Barotrauma.Lights
|
||||
}
|
||||
|
||||
lightEffect.World = transform;
|
||||
|
||||
|
||||
GameMain.ParticleManager.Draw(spriteBatch, false, null, Particles.ParticleBlendState.Additive);
|
||||
|
||||
|
||||
if (Character.Controlled != null)
|
||||
{
|
||||
DrawHalo(Character.Controlled);
|
||||
@@ -412,7 +414,7 @@ namespace Barotrauma.Lights
|
||||
}
|
||||
}
|
||||
if (highlightedEntities.Count == 0) { return false; }
|
||||
|
||||
|
||||
//draw characters in light blue first
|
||||
graphics.SetRenderTarget(HighlightMap);
|
||||
SolidColorEffect.CurrentTechnique = SolidColorEffect.Techniques["SolidColor"];
|
||||
@@ -484,9 +486,9 @@ namespace Barotrauma.Lights
|
||||
|
||||
//raster pattern on top of everything
|
||||
spriteBatch.Begin(blendState: BlendState.NonPremultiplied, samplerState: SamplerState.LinearWrap);
|
||||
spriteBatch.Draw(highlightRaster,
|
||||
new Rectangle(0, 0, HighlightMap.Width, HighlightMap.Height),
|
||||
new Rectangle(0, 0, (int)(HighlightMap.Width / currLightMapScale * 0.5f), (int)(HighlightMap.Height / currLightMapScale * 0.5f)),
|
||||
spriteBatch.Draw(highlightRaster,
|
||||
new Rectangle(0, 0, HighlightMap.Width, HighlightMap.Height),
|
||||
new Rectangle(0, 0, (int)(HighlightMap.Width / currLightMapScale * 0.5f), (int)(HighlightMap.Height / currLightMapScale * 0.5f)),
|
||||
Color.White * 0.5f);
|
||||
spriteBatch.End();
|
||||
|
||||
@@ -542,7 +544,7 @@ namespace Barotrauma.Lights
|
||||
{
|
||||
graphics.Clear(Color.White);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------
|
||||
|
||||
@@ -595,9 +597,9 @@ namespace Barotrauma.Lights
|
||||
}
|
||||
}
|
||||
}
|
||||
graphics.SetRenderTarget(null);
|
||||
graphics.SetRenderTarget(null);
|
||||
}
|
||||
|
||||
|
||||
public void ClearLights()
|
||||
{
|
||||
lights.Clear();
|
||||
|
||||
@@ -104,13 +104,13 @@ namespace Barotrauma.Lights
|
||||
blinkFrequency = MathHelper.Clamp(value, 0.0f, 60.0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public float TextureRange
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
|
||||
public Sprite OverrideLightTexture
|
||||
{
|
||||
get;
|
||||
@@ -137,7 +137,7 @@ namespace Barotrauma.Lights
|
||||
public LightSourceParams(XElement element)
|
||||
{
|
||||
Deserialize(element);
|
||||
|
||||
|
||||
foreach (XElement subElement in element.Elements())
|
||||
{
|
||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||
@@ -206,9 +206,9 @@ namespace Barotrauma.Lights
|
||||
private short[] indices;
|
||||
|
||||
private List<ConvexHullList> hullsInRange;
|
||||
|
||||
|
||||
public Texture2D texture;
|
||||
|
||||
|
||||
public SpriteEffects LightSpriteEffect;
|
||||
|
||||
public Submarine ParentSub;
|
||||
@@ -224,7 +224,7 @@ namespace Barotrauma.Lights
|
||||
private float prevCalculatedRange;
|
||||
private Vector2 prevCalculatedPosition;
|
||||
|
||||
//do we need to recheck which convex hulls are within range
|
||||
//do we need to recheck which convex hulls are within range
|
||||
//(e.g. position or range of the lightsource has changed)
|
||||
public bool NeedsHullCheck = true;
|
||||
//do we need to recalculate the vertices of the light volume
|
||||
@@ -278,7 +278,7 @@ namespace Barotrauma.Lights
|
||||
translateVertices = position - prevCalculatedPosition;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
NeedsHullCheck = true;
|
||||
NeedsRecalculation = true;
|
||||
}
|
||||
@@ -360,7 +360,7 @@ namespace Barotrauma.Lights
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
|
||||
public float Range
|
||||
{
|
||||
get { return lightSourceParams.Range; }
|
||||
@@ -369,13 +369,29 @@ namespace Barotrauma.Lights
|
||||
|
||||
lightSourceParams.Range = value;
|
||||
if (Math.Abs(prevCalculatedRange - lightSourceParams.Range) < 10.0f) return;
|
||||
|
||||
|
||||
NeedsHullCheck = true;
|
||||
NeedsRecalculation = true;
|
||||
prevCalculatedRange = lightSourceParams.Range;
|
||||
}
|
||||
}
|
||||
|
||||
private Vector2 lightTextureTargetSize;
|
||||
|
||||
public Vector2 LightTextureTargetSize
|
||||
{
|
||||
get => lightTextureTargetSize;
|
||||
set
|
||||
{
|
||||
NeedsRecalculation = true;
|
||||
NeedsHullCheck = true;
|
||||
lightTextureTargetSize = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 LightTextureOffset { get; set; }
|
||||
public Vector2 LightTextureScale { get; set; } = Vector2.One;
|
||||
|
||||
public float TextureRange
|
||||
{
|
||||
get
|
||||
@@ -386,7 +402,7 @@ namespace Barotrauma.Lights
|
||||
|
||||
/// <summary>
|
||||
/// Background lights are drawn behind submarines and they don't cast shadows.
|
||||
/// </summary>
|
||||
/// </summary>
|
||||
public bool IsBackground
|
||||
{
|
||||
get;
|
||||
@@ -462,7 +478,7 @@ namespace Barotrauma.Lights
|
||||
this.ParentSub = submarine;
|
||||
this.position = position;
|
||||
lightSourceParams = new LightSourceParams(range, color);
|
||||
CastShadows = true;
|
||||
CastShadows = true;
|
||||
texture = LightTexture;
|
||||
diffToSub = new Dictionary<Submarine, Vector2>();
|
||||
if (addLight) { GameMain.LightManager.AddLight(this); }
|
||||
@@ -494,7 +510,7 @@ namespace Barotrauma.Lights
|
||||
}
|
||||
CurrentBrightness = brightness;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Update the contents of ConvexHullList and check if we need to recalculate vertices
|
||||
/// </summary>
|
||||
@@ -509,7 +525,7 @@ namespace Barotrauma.Lights
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recheck which convex hulls are in range (if needed),
|
||||
/// Recheck which convex hulls are in range (if needed),
|
||||
/// and check if we need to recalculate vertices due to changes in the convex hulls
|
||||
/// </summary>
|
||||
private void CheckHullsInRange()
|
||||
@@ -561,20 +577,20 @@ namespace Barotrauma.Lights
|
||||
chList.List.Clear();
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
RefreshConvexHullList(chList, lightPos, sub);
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
//light is inside, convexhull outside
|
||||
if (sub == null) continue;
|
||||
|
||||
|
||||
//light and convexhull are both inside the same sub
|
||||
if (sub == ParentSub)
|
||||
{
|
||||
if (NeedsHullCheck)
|
||||
{
|
||||
{
|
||||
RefreshConvexHullList(chList, lightPos, sub);
|
||||
}
|
||||
}
|
||||
@@ -582,7 +598,7 @@ namespace Barotrauma.Lights
|
||||
else
|
||||
{
|
||||
if (sub.DockedTo.Contains(ParentSub) && !NeedsHullCheck) continue;
|
||||
|
||||
|
||||
lightPos -= (sub.Position - ParentSub.Position);
|
||||
|
||||
Rectangle subBorders = sub.Borders;
|
||||
@@ -642,7 +658,7 @@ namespace Barotrauma.Lights
|
||||
foreach (ConvexHull hull in hulls)
|
||||
{
|
||||
hull.RefreshWorldPositions();
|
||||
hull.GetVisibleSegments(drawPos, visibleSegments, ignoreEdges: false);
|
||||
hull.GetVisibleSegments(drawPos, visibleSegments, ignoreEdges: false);
|
||||
}
|
||||
|
||||
//add a square-shaped boundary to make sure we've got something to construct the triangles from
|
||||
@@ -829,13 +845,13 @@ namespace Barotrauma.Lights
|
||||
if (intersection2.index < 0) return null;
|
||||
Segment seg1 = visibleSegments[intersection1.index];
|
||||
Segment seg2 = visibleSegments[intersection2.index];
|
||||
|
||||
|
||||
bool isPoint1 = MathUtils.LineToPointDistanceSquared(seg1.Start.WorldPos, seg1.End.WorldPos, p.WorldPos) < 25.0f;
|
||||
bool isPoint2 = MathUtils.LineToPointDistanceSquared(seg2.Start.WorldPos, seg2.End.WorldPos, p.WorldPos) < 25.0f;
|
||||
|
||||
if (isPoint1 && isPoint2)
|
||||
{
|
||||
//hit at the current segmentpoint -> place the segmentpoint into the list
|
||||
//hit at the current segmentpoint -> place the segmentpoint into the list
|
||||
output.Add(p.WorldPos);
|
||||
|
||||
foreach (ConvexHullList hullList in hullsInRange)
|
||||
@@ -938,7 +954,7 @@ namespace Barotrauma.Lights
|
||||
segment = i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return (segment, closestIntersection == null ? rayEnd : (Vector2)closestIntersection);
|
||||
}
|
||||
|
||||
@@ -968,8 +984,8 @@ namespace Barotrauma.Lights
|
||||
overrideTextureDims = new Vector2(OverrideLightTexture.SourceRect.Width, OverrideLightTexture.SourceRect.Height);
|
||||
|
||||
Vector2 origin = OverrideLightTextureOrigin;
|
||||
if (LightSpriteEffect == SpriteEffects.FlipHorizontally)
|
||||
{
|
||||
if (LightSpriteEffect == SpriteEffects.FlipHorizontally)
|
||||
{
|
||||
origin.X = OverrideLightTexture.SourceRect.Width - origin.X;
|
||||
cosAngle = -cosAngle;
|
||||
sinAngle = -sinAngle;
|
||||
@@ -981,7 +997,7 @@ namespace Barotrauma.Lights
|
||||
// Add a vertex for the center of the mesh
|
||||
vertices[0] = new VertexPositionColorTexture(new Vector3(position.X, position.Y, 0),
|
||||
Color.White, GetUV(new Vector2(0.5f, 0.5f) + uvOffset, LightSpriteEffect));
|
||||
|
||||
|
||||
//hacky fix to exc excessively large light volumes (they used to be up to 4x the range of the light if there was nothing to block the rays).
|
||||
//might want to tweak the raycast logic in a way that this isn't necessary
|
||||
/*float boundRadius = Range * 1.1f / (1.0f - Math.Max(Math.Abs(uvOffset.X), Math.Abs(uvOffset.Y)));
|
||||
@@ -999,7 +1015,7 @@ namespace Barotrauma.Lights
|
||||
for (int i = 0; i < rayCastHits.Count; i++)
|
||||
{
|
||||
Vector2 vertex = rayCastHits[i];
|
||||
|
||||
|
||||
//we'll use the previous and next vertices to calculate the normals
|
||||
//of the two segments this vertex belongs to
|
||||
//so we can add new vertices based on these normals
|
||||
@@ -1007,7 +1023,7 @@ namespace Barotrauma.Lights
|
||||
Vector2 nextVertex = rayCastHits[i < rayCastHits.Count - 1 ? i + 1 : 0];
|
||||
|
||||
Vector2 rawDiff = vertex - drawPos;
|
||||
|
||||
|
||||
//calculate normal of first segment
|
||||
Vector2 nDiff1 = vertex - nextVertex;
|
||||
float tx = nDiff1.X; nDiff1.X = -nDiff1.Y; nDiff1.Y = tx;
|
||||
@@ -1015,7 +1031,7 @@ namespace Barotrauma.Lights
|
||||
//if the normal is pointing towards the light origin
|
||||
//rather than away from it, invert it
|
||||
if (Vector2.DistanceSquared(nDiff1, rawDiff) > Vector2.DistanceSquared(-nDiff1, rawDiff)) nDiff1 = -nDiff1;
|
||||
|
||||
|
||||
//calculate normal of second segment
|
||||
Vector2 nDiff2 = prevVertex - vertex;
|
||||
tx = nDiff2.X; nDiff2.X = -nDiff2.Y; nDiff2.Y = tx;
|
||||
@@ -1112,13 +1128,13 @@ namespace Barotrauma.Lights
|
||||
|
||||
static Vector2 GetUV(Vector2 vert, SpriteEffects effects)
|
||||
{
|
||||
if (effects == SpriteEffects.FlipHorizontally)
|
||||
{
|
||||
vert.X = 1.0f - vert.X;
|
||||
if (effects == SpriteEffects.FlipHorizontally)
|
||||
{
|
||||
vert.X = 1.0f - vert.X;
|
||||
}
|
||||
else if (effects == SpriteEffects.FlipVertically)
|
||||
{
|
||||
vert.Y = 1.0f - vert.Y;
|
||||
else if (effects == SpriteEffects.FlipVertically)
|
||||
{
|
||||
vert.Y = 1.0f - vert.Y;
|
||||
}
|
||||
else if (effects == (SpriteEffects.FlipHorizontally | SpriteEffects.FlipVertically))
|
||||
{
|
||||
@@ -1228,10 +1244,19 @@ namespace Barotrauma.Lights
|
||||
}
|
||||
drawPos.Y = -drawPos.Y;
|
||||
|
||||
LightSprite.Draw(
|
||||
spriteBatch, drawPos,
|
||||
new Color(Color, (lightSourceParams.OverrideLightSpriteAlpha ?? Color.A / 255.0f) * CurrentBrightness),
|
||||
origin, -Rotation + MathHelper.ToRadians(LightSourceParams.Rotation), SpriteScale, LightSpriteEffect);
|
||||
Color color = new Color(Color, (lightSourceParams.OverrideLightSpriteAlpha ?? Color.A / 255.0f) * CurrentBrightness);
|
||||
|
||||
if (LightTextureTargetSize != Vector2.Zero)
|
||||
{
|
||||
LightSprite.DrawTiled(spriteBatch, drawPos, LightTextureTargetSize, color, startOffset: LightTextureOffset, textureScale: LightTextureScale);
|
||||
}
|
||||
else
|
||||
{
|
||||
LightSprite.Draw(
|
||||
spriteBatch, drawPos,
|
||||
color,
|
||||
origin, -Rotation + MathHelper.ToRadians(LightSourceParams.Rotation), SpriteScale, LightSpriteEffect);
|
||||
}
|
||||
}
|
||||
|
||||
if (GameMain.DebugDraw && Screen.Selected.Cam.Zoom > 0.1f)
|
||||
@@ -1255,7 +1280,7 @@ 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()
|
||||
@@ -1280,10 +1305,10 @@ namespace Barotrauma.Lights
|
||||
if (!CastShadows)
|
||||
{
|
||||
Texture2D currentTexture = texture ?? LightTexture;
|
||||
if (OverrideLightTexture != null) { currentTexture = OverrideLightTexture.Texture; }
|
||||
if (OverrideLightTexture != null) { currentTexture = OverrideLightTexture.Texture; }
|
||||
|
||||
Vector2 center = OverrideLightTexture == null ?
|
||||
new Vector2(currentTexture.Width / 2, currentTexture.Height / 2) :
|
||||
Vector2 center = OverrideLightTexture == null ?
|
||||
new Vector2(currentTexture.Width / 2, currentTexture.Height / 2) :
|
||||
OverrideLightTexture.Origin;
|
||||
float scale = Range / (currentTexture.Width / 2.0f);
|
||||
|
||||
@@ -1291,7 +1316,7 @@ namespace Barotrauma.Lights
|
||||
if (ParentSub != null) { drawPos += ParentSub.DrawPosition; }
|
||||
drawPos.Y = -drawPos.Y;
|
||||
|
||||
spriteBatch.Draw(currentTexture, drawPos, null, Color.Multiply(CurrentBrightness), -rotation, center, scale, SpriteEffects.None, 1);
|
||||
spriteBatch.Draw(currentTexture, drawPos, null, Color.Multiply(CurrentBrightness), -rotation + MathHelper.ToRadians(LightSourceParams.Rotation), center, scale, SpriteEffects.None, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1317,8 +1342,8 @@ namespace Barotrauma.Lights
|
||||
|
||||
Vector2 offset = ParentSub == null ? Vector2.Zero : ParentSub.DrawPosition;
|
||||
lightEffect.World =
|
||||
Matrix.CreateTranslation(-new Vector3(position, 0.0f)) *
|
||||
Matrix.CreateRotationZ(rotateVertices) *
|
||||
Matrix.CreateTranslation(-new Vector3(position, 0.0f)) *
|
||||
Matrix.CreateRotationZ(rotateVertices - MathHelper.ToRadians(LightSourceParams.Rotation)) *
|
||||
Matrix.CreateTranslation(new Vector3(position + offset + translateVertices, 0.0f)) *
|
||||
transform;
|
||||
|
||||
|
||||
@@ -265,7 +265,7 @@ namespace Barotrauma
|
||||
if (!currentDisplayLocation.Discovered)
|
||||
{
|
||||
RemoveFogOfWar(currentDisplayLocation);
|
||||
currentDisplayLocation.Discovered = true;
|
||||
currentDisplayLocation.Discover();
|
||||
if (currentDisplayLocation.MapPosition.X > furthestDiscoveredLocation.MapPosition.X)
|
||||
{
|
||||
furthestDiscoveredLocation = currentDisplayLocation;
|
||||
@@ -426,7 +426,7 @@ namespace Barotrauma
|
||||
Level.Loaded.DebugSetStartLocation(CurrentLocation);
|
||||
Level.Loaded.DebugSetEndLocation(null);
|
||||
|
||||
CurrentLocation.Discovered = true;
|
||||
CurrentLocation.Discover();
|
||||
OnLocationChanged?.Invoke(prevLocation, CurrentLocation);
|
||||
SelectLocation(-1);
|
||||
if (GameMain.Client == null)
|
||||
|
||||
@@ -6,6 +6,7 @@ using Microsoft.Xna.Framework.Input;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Barotrauma.Lights;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -17,7 +18,7 @@ namespace Barotrauma
|
||||
private static Vector2 startMovingPos = Vector2.Zero;
|
||||
|
||||
private static float keyDelay;
|
||||
|
||||
|
||||
public static Vector2 StartMovingPos => startMovingPos;
|
||||
|
||||
public event Action<Rectangle> Resized;
|
||||
@@ -97,13 +98,13 @@ namespace Barotrauma
|
||||
/// </summary>
|
||||
public float GetDrawDepth(float baseDepth, Sprite sprite)
|
||||
{
|
||||
float depth = baseDepth
|
||||
float depth = baseDepth
|
||||
//take texture into account to get entities with (roughly) the same base depth and texture to render consecutively to minimize texture swaps
|
||||
+ (sprite?.Texture?.SortingKey ?? 0) % 100 * 0.00001f
|
||||
+ ID % 100 * 0.000001f;
|
||||
return Math.Min(depth, 1.0f);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Update the selection logic in submarine editor
|
||||
/// </summary>
|
||||
@@ -218,7 +219,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition);
|
||||
MapEntity highLightedEntity = null;
|
||||
@@ -284,13 +285,13 @@ namespace Barotrauma
|
||||
//mouse released -> move the entities to the new position of the mouse
|
||||
|
||||
Vector2 moveAmount = position - startMovingPos;
|
||||
|
||||
|
||||
if (!isShiftDown)
|
||||
{
|
||||
moveAmount.X = (float)(moveAmount.X > 0.0f ? Math.Floor(moveAmount.X / Submarine.GridSize.X) : Math.Ceiling(moveAmount.X / Submarine.GridSize.X)) * Submarine.GridSize.X;
|
||||
moveAmount.Y = (float)(moveAmount.Y > 0.0f ? Math.Floor(moveAmount.Y / Submarine.GridSize.Y) : Math.Ceiling(moveAmount.Y / Submarine.GridSize.Y)) * Submarine.GridSize.Y;
|
||||
}
|
||||
|
||||
|
||||
if (Math.Abs(moveAmount.X) >= Submarine.GridSize.X || Math.Abs(moveAmount.Y) >= Submarine.GridSize.Y || isShiftDown)
|
||||
{
|
||||
if (!isShiftDown) { moveAmount = Submarine.VectorToWorldGrid(moveAmount); }
|
||||
@@ -321,10 +322,10 @@ namespace Barotrauma
|
||||
else
|
||||
{
|
||||
SoundPlayer.PlayUISound(GUISoundType.PickItemFail);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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))
|
||||
{
|
||||
@@ -423,20 +424,24 @@ namespace Barotrauma
|
||||
|
||||
//select wire if both items it's connected to are selected
|
||||
var selectedItems = SelectedList.Where(e => e is Item).Cast<Item>().ToList();
|
||||
foreach (Item item in selectedItems)
|
||||
foreach (Item item in Item.ItemList)
|
||||
{
|
||||
if (item.Connections == null) continue;
|
||||
foreach (Connection c in item.Connections)
|
||||
{
|
||||
foreach (Wire w in c.Wires)
|
||||
{
|
||||
if (w == null || SelectedList.Contains(w.Item)) continue;
|
||||
var wire = item.GetComponent<Wire>();
|
||||
if (wire == null) { continue; }
|
||||
Item item0 = wire.Connections[0]?.Item;
|
||||
Item item1 = wire.Connections[1]?.Item;
|
||||
|
||||
if (w.OtherConnection(c) != null && SelectedList.Contains(w.OtherConnection(c).Item))
|
||||
{
|
||||
SelectedList.Add(w.Item);
|
||||
}
|
||||
}
|
||||
if (item0 == null && item1 != null)
|
||||
{
|
||||
item0 = Item.ItemList.Find(it => it.GetComponent<ConnectionPanel>()?.DisconnectedWires.Contains(wire) ?? false);
|
||||
}
|
||||
else if (item0 != null && item1 == null)
|
||||
{
|
||||
item1 = Item.ItemList.Find(it => it.GetComponent<ConnectionPanel>()?.DisconnectedWires.Contains(wire) ?? false);
|
||||
}
|
||||
if (item0 != null && item1 != null && SelectedList.Contains(item0) && SelectedList.Contains(item1))
|
||||
{
|
||||
SelectedList.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -453,8 +458,8 @@ namespace Barotrauma
|
||||
{
|
||||
if (PlayerInput.PrimaryMouseButtonHeld() &&
|
||||
PlayerInput.KeyUp(Keys.Space) &&
|
||||
PlayerInput.KeyUp(Keys.LeftAlt) &&
|
||||
PlayerInput.KeyUp(Keys.RightAlt) &&
|
||||
PlayerInput.KeyUp(Keys.LeftAlt) &&
|
||||
PlayerInput.KeyUp(Keys.RightAlt) &&
|
||||
(highlightedListBox == null || (GUI.MouseOn != highlightedListBox && !highlightedListBox.IsParentOf(GUI.MouseOn))))
|
||||
{
|
||||
//if clicking a selected entity, start moving it
|
||||
@@ -482,7 +487,7 @@ namespace Barotrauma
|
||||
|
||||
int xKeysDown = (left + right);
|
||||
int yKeysDown = (up + down);
|
||||
|
||||
|
||||
if (xKeysDown != 0 || yKeysDown != 0) { keyDelay += (float) Timing.Step; } else { keyDelay = 0; }
|
||||
|
||||
|
||||
@@ -512,7 +517,7 @@ namespace Barotrauma
|
||||
bool isShiftDown = PlayerInput.IsShiftDown();
|
||||
|
||||
if (!isShiftDown) return null;
|
||||
|
||||
|
||||
foreach (MapEntity e in mapEntityList)
|
||||
{
|
||||
if (!e.SelectableInEditor ||!(e is Item potentialContainer)) { continue; }
|
||||
@@ -662,7 +667,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (SelectedList.Contains(entity)) { return; }
|
||||
SelectedList.Add(entity);
|
||||
HandleDoorGapLinks(entity,
|
||||
HandleDoorGapLinks(entity,
|
||||
onGapFound: (door, gap) =>
|
||||
{
|
||||
door.RefreshLinkedGap();
|
||||
@@ -670,8 +675,8 @@ namespace Barotrauma
|
||||
{
|
||||
SelectedList.Add(gap);
|
||||
}
|
||||
},
|
||||
onDoorFound: (door, gap) =>
|
||||
},
|
||||
onDoorFound: (door, gap) =>
|
||||
{
|
||||
if (!SelectedList.Contains(door.Item))
|
||||
{
|
||||
@@ -715,7 +720,7 @@ namespace Barotrauma
|
||||
onGapFound: (door, gap) => SelectedList.Remove(gap),
|
||||
onDoorFound: (door, gap) => SelectedList.Remove(door.Item));
|
||||
}
|
||||
|
||||
|
||||
static partial void UpdateAllProjSpecific(float deltaTime)
|
||||
{
|
||||
var entitiesToRender = Submarine.VisibleEntities ?? mapEntityList;
|
||||
@@ -748,7 +753,7 @@ namespace Barotrauma
|
||||
moveAmount.Y = -moveAmount.Y;
|
||||
|
||||
bool isShiftDown = PlayerInput.IsShiftDown();
|
||||
|
||||
|
||||
if (!isShiftDown)
|
||||
{
|
||||
moveAmount.X = (float)(moveAmount.X > 0.0f ? Math.Floor(moveAmount.X / Submarine.GridSize.X) : Math.Ceiling(moveAmount.X / Submarine.GridSize.X)) * Submarine.GridSize.X;
|
||||
@@ -761,21 +766,21 @@ namespace Barotrauma
|
||||
foreach (MapEntity e in SelectedList)
|
||||
{
|
||||
SpriteEffects spriteEffects = SpriteEffects.None;
|
||||
switch (e)
|
||||
switch (e)
|
||||
{
|
||||
case Item item:
|
||||
case Item item:
|
||||
{
|
||||
if (item.FlippedX && item.Prefab.CanSpriteFlipX) spriteEffects ^= SpriteEffects.FlipHorizontally;
|
||||
if (item.flippedY && item.Prefab.CanSpriteFlipY) spriteEffects ^= SpriteEffects.FlipVertically;
|
||||
break;
|
||||
}
|
||||
case Structure structure:
|
||||
case Structure structure:
|
||||
{
|
||||
if (structure.FlippedX && structure.Prefab.CanSpriteFlipX) spriteEffects ^= SpriteEffects.FlipHorizontally;
|
||||
if (structure.flippedY && structure.Prefab.CanSpriteFlipY) spriteEffects ^= SpriteEffects.FlipVertically;
|
||||
break;
|
||||
}
|
||||
case WayPoint wayPoint:
|
||||
case WayPoint wayPoint:
|
||||
{
|
||||
Vector2 drawPos = e.WorldPosition;
|
||||
drawPos.Y = -drawPos.Y;
|
||||
@@ -812,7 +817,7 @@ namespace Barotrauma
|
||||
|
||||
posY = -posY;
|
||||
|
||||
Vector2[] corners =
|
||||
Vector2[] corners =
|
||||
{
|
||||
new Vector2(posX, posY),
|
||||
new Vector2(posX + sizeX, posY),
|
||||
@@ -878,7 +883,7 @@ namespace Barotrauma
|
||||
{
|
||||
MapEntity firstSelected = SelectedList.First();
|
||||
|
||||
float minX = firstSelected.WorldRect.X,
|
||||
float minX = firstSelected.WorldRect.X,
|
||||
maxX = firstSelected.WorldRect.Right;
|
||||
|
||||
foreach (MapEntity entity in SelectedList)
|
||||
@@ -903,7 +908,7 @@ namespace Barotrauma
|
||||
|
||||
foreach (MapEntity entity in SelectedList)
|
||||
{
|
||||
|
||||
|
||||
minY = Math.Min(minY, entity.WorldRect.Y - entity.WorldRect.Height);
|
||||
maxY = Math.Max(maxY, entity.WorldRect.Y);
|
||||
}
|
||||
@@ -943,21 +948,21 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy the selected entities to the "clipboard" (copiedList)
|
||||
/// Copy the selected entities to the "clipboard" (copiedList)
|
||||
/// </summary>
|
||||
public static void Copy(List<MapEntity> entities)
|
||||
{
|
||||
if (entities.Count == 0) { return; }
|
||||
CopyEntities(entities);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Copy the entities to the "clipboard" (copiedList) and delete them
|
||||
/// </summary>
|
||||
public static void Cut(List<MapEntity> entities)
|
||||
{
|
||||
if (entities.Count == 0) { return; }
|
||||
|
||||
|
||||
CopyEntities(entities);
|
||||
|
||||
SubEditorScreen.StoreCommand(new AddOrDeleteCommand(new List<MapEntity>(entities), true));
|
||||
@@ -989,6 +994,10 @@ namespace Barotrauma
|
||||
clone.Move(moveAmount);
|
||||
clone.Submarine = Submarine.MainSub;
|
||||
}
|
||||
foreach (MapEntity clone in SelectedList)
|
||||
{
|
||||
(clone as Item)?.GetComponent<ItemContainer>()?.SetContainedItemPositions();
|
||||
}
|
||||
|
||||
SubEditorScreen.StoreCommand(new AddOrDeleteCommand(clones, false, handleInventoryBehavior: false));
|
||||
}
|
||||
@@ -1012,9 +1021,9 @@ namespace Barotrauma
|
||||
return newEntities;
|
||||
}
|
||||
|
||||
public virtual void AddToGUIUpdateList()
|
||||
public virtual void AddToGUIUpdateList(int order = 0)
|
||||
{
|
||||
if (editingHUD != null && editingHUD.UserData == this) editingHUD.AddToGUIUpdateList();
|
||||
if (editingHUD != null && editingHUD.UserData == this) { editingHUD.AddToGUIUpdateList(order: order); }
|
||||
}
|
||||
|
||||
public virtual void UpdateEditing(Camera cam, float deltaTime) { }
|
||||
@@ -1049,7 +1058,7 @@ namespace Barotrauma
|
||||
|
||||
editingHUD.RectTransform.Resize(
|
||||
new Point(
|
||||
editingHUD.RectTransform.NonScaledSize.X,
|
||||
editingHUD.RectTransform.NonScaledSize.X,
|
||||
MathHelper.Clamp(contentHeight + padding * 2, 50, maxHeight)), resizeChildren: false);
|
||||
listBox.RectTransform.Resize(new Point(listBox.RectTransform.NonScaledSize.X, editingHUD.RectTransform.NonScaledSize.Y - padding * 2), resizeChildren: false);
|
||||
}
|
||||
@@ -1089,7 +1098,7 @@ namespace Barotrauma
|
||||
{
|
||||
prevRect = new Rectangle(Rect.Location, Rect.Size);
|
||||
}
|
||||
|
||||
|
||||
Vector2 placePosition = new Vector2(rect.X, rect.Y);
|
||||
Vector2 placeSize = new Vector2(rect.Width, rect.Height);
|
||||
|
||||
@@ -1140,6 +1149,15 @@ namespace Barotrauma
|
||||
var oldData = new List<Rectangle> { prevRect.Value };
|
||||
SubEditorScreen.StoreCommand(new TransformCommand(new List<MapEntity> { this }, newData, oldData, true));
|
||||
}
|
||||
|
||||
if (this is Structure structure)
|
||||
{
|
||||
foreach (LightSource light in structure.Lights)
|
||||
{
|
||||
light.LightTextureTargetSize = Rect.Size.ToVector2();
|
||||
light.Position = rect.Location.ToVector2();
|
||||
}
|
||||
}
|
||||
prevRect = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,12 +14,14 @@ namespace Barotrauma
|
||||
{
|
||||
partial class Structure : MapEntity, IDamageable, IServerSerializable
|
||||
{
|
||||
public static bool ShowWalls = true, ShowStructures = true;
|
||||
public static bool ShowWalls = true, ShowStructures = true;
|
||||
|
||||
private List<ConvexHull> convexHulls;
|
||||
|
||||
private readonly Dictionary<DecorativeSprite, DecorativeSprite.State> spriteAnimState = new Dictionary<DecorativeSprite, DecorativeSprite.State>();
|
||||
|
||||
public readonly List<LightSource> Lights = new List<LightSource>();
|
||||
|
||||
public override bool SelectableInEditor
|
||||
{
|
||||
get
|
||||
@@ -41,7 +43,7 @@ namespace Barotrauma
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
}
|
||||
|
||||
partial void InitProjSpecific()
|
||||
{
|
||||
@@ -88,7 +90,23 @@ namespace Barotrauma
|
||||
if (editingHUD == null || editingHUD.UserData as Structure != this)
|
||||
{
|
||||
editingHUD = CreateEditingHUD(Screen.Selected != GameMain.SubEditorScreen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SetLightTextureOffset()
|
||||
{
|
||||
Vector2 textOffset = textureOffset;
|
||||
if (FlippedX) { textOffset.X = -textOffset.X; }
|
||||
if (FlippedY) { textOffset.Y = -textOffset.Y; }
|
||||
|
||||
foreach (LightSource light in Lights)
|
||||
{
|
||||
Vector2 bgOffset = new Vector2(
|
||||
MathUtils.PositiveModulo((int)-textOffset.X, light.texture.Width),
|
||||
MathUtils.PositiveModulo((int)-textOffset.Y, light.texture.Height));
|
||||
|
||||
light.LightTextureOffset = bgOffset;
|
||||
}
|
||||
}
|
||||
|
||||
public GUIComponent CreateEditingHUD(bool inGame = false)
|
||||
@@ -175,12 +193,12 @@ namespace Barotrauma
|
||||
buttonContainer.RectTransform.IsFixedSize = true;
|
||||
GUITextBlock.AutoScaleAndNormalize(buttonContainer.Children.Where(c => c is GUIButton).Select(b => ((GUIButton)b).TextBlock));
|
||||
editor.AddCustomContent(buttonContainer, editor.ContentCount);
|
||||
|
||||
|
||||
PositionEditingHUD();
|
||||
|
||||
return editingHUD;
|
||||
}
|
||||
|
||||
|
||||
partial void OnImpactProjSpecific(Fixture f1, Fixture f2, Contact contact)
|
||||
{
|
||||
if (!Prefab.Platform && Prefab.StairDirection == Direction.None)
|
||||
@@ -261,19 +279,21 @@ namespace Barotrauma
|
||||
else if (HiddenInGame) { return; }
|
||||
|
||||
Color color = IsIncludedInSelection && editing ? GUI.Style.Blue : IsHighlighted ? GUI.Style.Orange * Math.Max(spriteColor.A / (float) byte.MaxValue, 0.1f) : spriteColor;
|
||||
|
||||
|
||||
if (IsSelected && editing)
|
||||
{
|
||||
//color = Color.Lerp(color, Color.Gold, 0.5f);
|
||||
color = spriteColor;
|
||||
|
||||
|
||||
|
||||
Vector2 rectSize = rect.Size.ToVector2();
|
||||
if (BodyWidth > 0.0f) { rectSize.X = BodyWidth; }
|
||||
if (BodyHeight > 0.0f) { rectSize.Y = BodyHeight; }
|
||||
|
||||
Vector2 bodyPos = WorldPosition + BodyOffset;
|
||||
|
||||
GUI.DrawRectangle(spriteBatch, new Vector2(bodyPos.X, -bodyPos.Y), rectSize.X, rectSize.Y, BodyRotation, Color.White,
|
||||
GUI.DrawRectangle(spriteBatch, new Vector2(bodyPos.X, -bodyPos.Y), rectSize.X, rectSize.Y, BodyRotation, Color.White,
|
||||
thickness: Math.Max(1, (int)(2 / Screen.Selected.Cam.Zoom)));
|
||||
}
|
||||
|
||||
@@ -305,14 +325,14 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
dropShadowOffset = IsHorizontal ?
|
||||
new Vector2(0.0f, Math.Sign(Submarine.HiddenSubPosition.Y - Position.Y) * 10.0f) :
|
||||
dropShadowOffset = IsHorizontal ?
|
||||
new Vector2(0.0f, Math.Sign(Submarine.HiddenSubPosition.Y - Position.Y) * 10.0f) :
|
||||
new Vector2(Math.Sign(Submarine.HiddenSubPosition.X - Position.X) * 10.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
dropShadowOffset.Y = -dropShadowOffset.Y;
|
||||
}
|
||||
|
||||
|
||||
SpriteEffects oldEffects = Prefab.BackgroundSprite.effects;
|
||||
Prefab.BackgroundSprite.effects ^= SpriteEffects;
|
||||
|
||||
@@ -372,13 +392,13 @@ namespace Barotrauma
|
||||
if (!HasDamage && i == 0)
|
||||
{
|
||||
drawSection = new Rectangle(
|
||||
drawSection.X,
|
||||
drawSection.Y,
|
||||
drawSection.X,
|
||||
drawSection.Y,
|
||||
Sections[Sections.Length -1 ].rect.Right - drawSection.X,
|
||||
drawSection.Y - (Sections[Sections.Length - 1].rect.Y - Sections[Sections.Length - 1].rect.Height));
|
||||
i = Sections.Length;
|
||||
}
|
||||
|
||||
|
||||
Vector2 sectionOffset = new Vector2(
|
||||
Math.Abs(rect.Location.X - drawSection.Location.X),
|
||||
Math.Abs(rect.Location.Y - drawSection.Location.Y));
|
||||
@@ -496,7 +516,7 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!conditional.Matches(this)) { return false; }
|
||||
if (!conditional.Matches(this)) { return false; }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using Barotrauma.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
@@ -177,7 +178,6 @@ namespace Barotrauma
|
||||
|
||||
//drawing ----------------------------------------------------
|
||||
private static readonly HashSet<Submarine> visibleSubs = new HashSet<Submarine>();
|
||||
private static readonly HashSet<Ruin> visibleRuins = new HashSet<Ruin>();
|
||||
public static void CullEntities(Camera cam)
|
||||
{
|
||||
visibleSubs.Clear();
|
||||
@@ -197,24 +197,6 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
visibleRuins.Clear();
|
||||
if (Level.Loaded != null)
|
||||
{
|
||||
foreach (Ruin ruin in Level.Loaded.Ruins)
|
||||
{
|
||||
Rectangle worldBorders = new Rectangle(
|
||||
ruin.Area.X - 500,
|
||||
ruin.Area.Y + ruin.Area.Height + 500,
|
||||
ruin.Area.Width + 1000,
|
||||
ruin.Area.Height + 1000);
|
||||
|
||||
if (RectsOverlap(worldBorders, cam.WorldView))
|
||||
{
|
||||
visibleRuins.Add(ruin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (visibleEntities == null)
|
||||
{
|
||||
visibleEntities = new List<MapEntity>(MapEntity.mapEntityList.Count);
|
||||
@@ -231,10 +213,6 @@ namespace Barotrauma
|
||||
{
|
||||
if (!visibleSubs.Contains(entity.Submarine)) { continue; }
|
||||
}
|
||||
else if (entity.ParentRuin != null)
|
||||
{
|
||||
if (!visibleRuins.Contains(entity.ParentRuin)) { continue; }
|
||||
}
|
||||
|
||||
if (entity.IsVisible(worldView)) { visibleEntities.Add(entity); }
|
||||
}
|
||||
@@ -325,7 +303,7 @@ namespace Barotrauma
|
||||
depthSortedDamageable.Insert(i, structure);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
foreach (Structure s in depthSortedDamageable)
|
||||
{
|
||||
s.DrawDamage(spriteBatch, damageEffect, editing);
|
||||
@@ -403,6 +381,8 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
// TODO remove
|
||||
[Obsolete("Use MiniMap.CreateMiniMap()")]
|
||||
public void CreateMiniMap(GUIComponent parent, IEnumerable<Entity> pointsOfInterest = null, bool ignoreOutpost = false)
|
||||
{
|
||||
Rectangle worldBorders = GetDockedBorders();
|
||||
@@ -415,26 +395,124 @@ namespace Barotrauma
|
||||
float scale = 0.9f;
|
||||
|
||||
GUIFrame hullContainer = new GUIFrame(new RectTransform(
|
||||
(parentAspectRatio > aspectRatio ? new Vector2(aspectRatio / parentAspectRatio, 1.0f) : new Vector2(1.0f, parentAspectRatio / aspectRatio)) * scale,
|
||||
parent.RectTransform, Anchor.Center),
|
||||
style: null);
|
||||
(parentAspectRatio > aspectRatio ? new Vector2(aspectRatio / parentAspectRatio, 1.0f) : new Vector2(1.0f, parentAspectRatio / aspectRatio)) * scale,
|
||||
parent.RectTransform, Anchor.Center),
|
||||
style: null)
|
||||
{
|
||||
UserData = "hullcontainer"
|
||||
};
|
||||
|
||||
var connectedSubs = GetConnectedSubs();
|
||||
foreach (Hull hull in Hull.hullList)
|
||||
{
|
||||
if (hull.Submarine != this && !connectedSubs.Contains(hull.Submarine)) { continue; }
|
||||
if (ignoreOutpost && !IsEntityFoundOnThisSub(hull, true)) { continue; }
|
||||
|
||||
HashSet<Hull> hullList = Hull.hullList.Where(hull => hull.Submarine == this || connectedSubs.Contains(hull.Submarine)).Where(hull => !ignoreOutpost || IsEntityFoundOnThisSub(hull, true)).ToHashSet();
|
||||
|
||||
Dictionary<Hull, HashSet<Hull>> combinedHulls = new Dictionary<Hull, HashSet<Hull>>();
|
||||
|
||||
foreach (Hull hull in hullList)
|
||||
{
|
||||
if (combinedHulls.ContainsKey(hull) || combinedHulls.Values.Any(hh => hh.Contains(hull))) { continue; }
|
||||
|
||||
List<Hull> linkedHulls = new List<Hull>();
|
||||
MiniMap.GetLinkedHulls(hull, linkedHulls);
|
||||
|
||||
linkedHulls.Remove(hull);
|
||||
|
||||
foreach (Hull linkedHull in linkedHulls)
|
||||
{
|
||||
if (!combinedHulls.ContainsKey(hull))
|
||||
{
|
||||
combinedHulls.Add(hull, new HashSet<Hull>());
|
||||
}
|
||||
|
||||
combinedHulls[hull].Add(linkedHull);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Hull hull in hullList)
|
||||
{
|
||||
Vector2 relativeHullPos = new Vector2(
|
||||
(hull.WorldRect.X - worldBorders.X) / (float)worldBorders.Width,
|
||||
(hull.WorldRect.X - worldBorders.X) / (float)worldBorders.Width,
|
||||
(worldBorders.Y - hull.WorldRect.Y) / (float)worldBorders.Height);
|
||||
Vector2 relativeHullSize = new Vector2(hull.Rect.Width / (float)worldBorders.Width, hull.Rect.Height / (float)worldBorders.Height);
|
||||
|
||||
var hullFrame = new GUIFrame(new RectTransform(relativeHullSize, hullContainer.RectTransform) { RelativeOffset = relativeHullPos }, style: "MiniMapRoom", color: Color.DarkCyan * 0.8f)
|
||||
bool hideHull = combinedHulls.ContainsKey(hull) || combinedHulls.Values.Any(hh => hh.Contains(hull));
|
||||
|
||||
if (hideHull) { continue; }
|
||||
|
||||
Color color = Color.DarkCyan * 0.8f;
|
||||
|
||||
var hullFrame = new GUIFrame(new RectTransform(relativeHullSize, hullContainer.RectTransform) { RelativeOffset = relativeHullPos }, style: "MiniMapRoom", color: color)
|
||||
{
|
||||
UserData = hull
|
||||
};
|
||||
new GUIFrame(new RectTransform(Vector2.One, hullFrame.RectTransform), style: "ScanLines", color: Color.DarkCyan * 0.8f);
|
||||
|
||||
new GUIFrame(new RectTransform(Vector2.One, hullFrame.RectTransform), style: "ScanLines", color: color);
|
||||
}
|
||||
|
||||
foreach (var (mainHull, linkedHulls) in combinedHulls)
|
||||
{
|
||||
MiniMapHullData data = ConstructLinkedHulls(mainHull, linkedHulls, hullContainer, worldBorders);
|
||||
|
||||
Vector2 relativeHullPos = new Vector2(
|
||||
(data.Bounds.X - worldBorders.X) / worldBorders.Width,
|
||||
(worldBorders.Y - data.Bounds.Y) / worldBorders.Height);
|
||||
|
||||
Vector2 relativeHullSize = new Vector2(data.Bounds.Width / worldBorders.Width, data.Bounds.Height / worldBorders.Height);
|
||||
|
||||
Color color = Color.DarkCyan * 0.8f;
|
||||
|
||||
float highestY = 0f,
|
||||
highestX = 0f;
|
||||
|
||||
foreach (var (r, _) in data.RectDatas)
|
||||
{
|
||||
float y = r.Y - -r.Height,
|
||||
x = r.X;
|
||||
|
||||
if (y > highestY) { highestY = y; }
|
||||
if (x > highestX) { highestX = x; }
|
||||
}
|
||||
|
||||
HashSet<GUIFrame> frames = new HashSet<GUIFrame>();
|
||||
|
||||
foreach (var (snappredRect, hull) in data.RectDatas)
|
||||
{
|
||||
RectangleF rect = snappredRect;
|
||||
rect.Height = -rect.Height;
|
||||
rect.Y -= rect.Height;
|
||||
|
||||
var (parentW, parentH) = hullContainer.Rect.Size.ToVector2();
|
||||
Vector2 size = new Vector2(rect.Width / parentW, rect.Height / parentH);
|
||||
// TODO this won't be required if we some day switch RectTransform to use RectangleF
|
||||
Vector2 pos = new Vector2(rect.X / parentW, rect.Y / parentH);
|
||||
|
||||
GUIFrame hullFrame = new GUIFrame(new RectTransform(size, hullContainer.RectTransform) { RelativeOffset = pos }, style: "ScanLinesSeamless", color: color)
|
||||
{
|
||||
UserData = hull,
|
||||
UVOffset = new Vector2(highestX - rect.X, highestY - rect.Y)
|
||||
};
|
||||
|
||||
frames.Add(hullFrame);
|
||||
}
|
||||
|
||||
new GUICustomComponent(new RectTransform(relativeHullSize, hullContainer.RectTransform) { RelativeOffset = relativeHullPos }, (spriteBatch, component) =>
|
||||
{
|
||||
foreach (List<Vector2> list in data.Polygon)
|
||||
{
|
||||
spriteBatch.DrawPolygonInner(hullContainer.Rect.Location.ToVector2(), list, component.Color, 2f);
|
||||
}
|
||||
}, (deltaTime, component) =>
|
||||
{
|
||||
if (component.Parent.Rect.Size != data.ParentSize)
|
||||
{
|
||||
data = ConstructLinkedHulls(mainHull, linkedHulls, hullContainer, worldBorders);
|
||||
}
|
||||
})
|
||||
{
|
||||
UserData = frames,
|
||||
Color = color,
|
||||
CanBeFocused = false
|
||||
};
|
||||
}
|
||||
|
||||
if (pointsOfInterest != null)
|
||||
@@ -453,6 +531,64 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public static MiniMapHullData ConstructLinkedHulls(Hull mainHull, HashSet<Hull> linkedHulls, GUIComponent parent, Rectangle worldBorders)
|
||||
{
|
||||
Rectangle parentRect = parent.Rect;
|
||||
|
||||
Dictionary<Hull, Rectangle> rects = new Dictionary<Hull, Rectangle>();
|
||||
Rectangle worldRect = mainHull.WorldRect;
|
||||
worldRect.Y = -worldRect.Y;
|
||||
|
||||
rects.Add(mainHull, worldRect);
|
||||
|
||||
foreach (Hull hull in linkedHulls)
|
||||
{
|
||||
Rectangle rect = hull.WorldRect;
|
||||
rect.Y = -rect.Y;
|
||||
|
||||
worldRect = Rectangle.Union(worldRect, rect);
|
||||
rects.Add(hull, rect);
|
||||
}
|
||||
|
||||
worldRect.Y = -worldRect.Y;
|
||||
|
||||
List<RectangleF> normalizedRects = new List<RectangleF>();
|
||||
List<Hull> hullRefs = new List<Hull>();
|
||||
foreach (var (hull, rect) in rects)
|
||||
{
|
||||
Rectangle wRect = rect;
|
||||
wRect.Y = -wRect.Y;
|
||||
|
||||
var (posX, posY) = new Vector2(
|
||||
(wRect.X - worldBorders.X) / (float)worldBorders.Width,
|
||||
(worldBorders.Y - wRect.Y) / (float)worldBorders.Height);
|
||||
|
||||
var (scaleX, scaleY) = new Vector2(wRect.Width / (float)worldBorders.Width, wRect.Height / (float)worldBorders.Height);
|
||||
|
||||
RectangleF newRect = new RectangleF(posX * parentRect.Width, posY * parentRect.Height, scaleX * parentRect.Width, scaleY * parentRect.Height);
|
||||
|
||||
normalizedRects.Add(newRect);
|
||||
hullRefs.Add(hull);
|
||||
}
|
||||
|
||||
ImmutableArray<RectangleF> snappedRectangles = ToolBox.SnapRectangles(normalizedRects, treshold: 1);
|
||||
|
||||
List<List<Vector2>> polygon = ToolBox.CombineRectanglesIntoShape(snappedRectangles);
|
||||
|
||||
List<List<Vector2>> scaledPolygon = new List<List<Vector2>>();
|
||||
|
||||
foreach (List<Vector2> list in polygon)
|
||||
{
|
||||
var (polySizeX, polySizeY) = ToolBox.GetPolygonBoundingBoxSize(list);
|
||||
float sizeX = polySizeX - 1f,
|
||||
sizeY = polySizeY - 1f;
|
||||
|
||||
scaledPolygon.Add(ToolBox.ScalePolygon(list, new Vector2(sizeX / polySizeX, sizeY / polySizeY)));
|
||||
}
|
||||
|
||||
return new MiniMapHullData(scaledPolygon, worldRect, parentRect.Size, snappedRectangles, hullRefs.ToImmutableArray());
|
||||
}
|
||||
|
||||
public void CheckForErrors()
|
||||
{
|
||||
List<string> errorMsgs = new List<string>();
|
||||
@@ -467,7 +603,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
if (Info.Type != SubmarineType.OutpostModule ||
|
||||
if (Info.Type != SubmarineType.OutpostModule ||
|
||||
(Info.OutpostModuleInfo?.ModuleFlags.Any(f => !f.Equals("hallwayvertical", StringComparison.OrdinalIgnoreCase) && !f.Equals("hallwayhorizontal", StringComparison.OrdinalIgnoreCase)) ?? true))
|
||||
{
|
||||
if (!WayPoint.WayPointList.Any(wp => wp.ShouldBeSaved && wp.SpawnType == SpawnType.Path))
|
||||
@@ -535,7 +671,7 @@ namespace Barotrauma
|
||||
int wireCount = item.Connections[i].Wires.Count(w => w != null);
|
||||
if (doorLinks + wireCount > item.Connections[i].MaxWires)
|
||||
{
|
||||
errorMsgs.Add(TextManager.GetWithVariables("InsufficientFreeConnectionsWarning",
|
||||
errorMsgs.Add(TextManager.GetWithVariables("InsufficientFreeConnectionsWarning",
|
||||
new string[] { "[doorcount]", "[freeconnectioncount]" },
|
||||
new string[] { doorLinks.ToString(), (item.Connections[i].MaxWires - wireCount).ToString() }));
|
||||
break;
|
||||
@@ -632,7 +768,7 @@ namespace Barotrauma
|
||||
return SubEditorScreen.SuppressedWarnings.Contains(type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
||||
{
|
||||
if (type != ServerNetObject.ENTITY_POSITION)
|
||||
|
||||
@@ -600,6 +600,8 @@ namespace Barotrauma
|
||||
|
||||
var prevScissorRect = GameMain.Instance.GraphicsDevice.ScissorRectangle;
|
||||
GameMain.Instance.GraphicsDevice.ScissorRectangle = scissorRectangle;
|
||||
var prevRasterizerState = GameMain.Instance.GraphicsDevice.RasterizerState;
|
||||
GameMain.Instance.GraphicsDevice.RasterizerState = GameMain.ScissorTestEnable;
|
||||
|
||||
spriteRecorder.Render(camera);
|
||||
|
||||
@@ -643,6 +645,7 @@ namespace Barotrauma
|
||||
spriteBatch.End();
|
||||
|
||||
GameMain.Instance.GraphicsDevice.ScissorRectangle = prevScissorRect;
|
||||
GameMain.Instance.GraphicsDevice.RasterizerState = prevRasterizerState;
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred);
|
||||
}
|
||||
|
||||
|
||||
@@ -127,6 +127,13 @@ namespace Barotrauma
|
||||
ID.ToString(),
|
||||
new Vector2(DrawPosition.X - 10, -DrawPosition.Y - 30),
|
||||
color);
|
||||
if (Tunnel?.Type != null)
|
||||
{
|
||||
GUI.SmallFont.DrawString(spriteBatch,
|
||||
Tunnel.Type.ToString(),
|
||||
new Vector2(DrawPosition.X - 10, -DrawPosition.Y - 45),
|
||||
color);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsMouseOn(Vector2 position)
|
||||
@@ -164,10 +171,7 @@ namespace Barotrauma
|
||||
{
|
||||
foreach (MapEntity e in mapEntityList)
|
||||
{
|
||||
if (e.GetType() != typeof(WayPoint)) continue;
|
||||
if (e == this) continue;
|
||||
|
||||
if (!Submarine.RectContains(e.Rect, position)) continue;
|
||||
if (!(e is WayPoint) || e == this || !e.IsHighlighted) { continue; }
|
||||
|
||||
if (linkedTo.Contains(e))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user