Faction Test v1.0.1.0
This commit is contained in:
@@ -129,20 +129,15 @@ namespace Barotrauma
|
||||
|
||||
Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition);
|
||||
|
||||
foreach (MapEntity entity in mapEntityList)
|
||||
foreach (MapEntity entity in HighlightedEntities)
|
||||
{
|
||||
if (entity == this || !entity.IsHighlighted) { continue; }
|
||||
if (entity == this) { continue; }
|
||||
if (!entity.IsMouseOn(position)) { continue; }
|
||||
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.linkedTo.Contains(this))
|
||||
{
|
||||
entity.linkedTo.Remove(this);
|
||||
linkedTo.Remove(entity);
|
||||
}
|
||||
entity.linkedTo.Remove(this);
|
||||
linkedTo.Remove(entity);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Content;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -65,15 +64,9 @@ namespace Barotrauma
|
||||
|
||||
public Texture2D WaterTexture { get; }
|
||||
|
||||
public WaterRenderer(GraphicsDevice graphicsDevice, ContentManager content)
|
||||
public WaterRenderer(GraphicsDevice graphicsDevice)
|
||||
{
|
||||
#if WINDOWS
|
||||
WaterEffect = content.Load<Effect>("Effects/watershader");
|
||||
#endif
|
||||
#if LINUX || OSX
|
||||
|
||||
WaterEffect = content.Load<Effect>("Effects/watershader_opengl");
|
||||
#endif
|
||||
WaterEffect = EffectLoader.Load("Effects/watershader");
|
||||
|
||||
WaterTexture = TextureLoader.FromFile("Content/Effects/waterbump.png");
|
||||
WaterEffect.Parameters["xWaterBumpMap"].SetValue(WaterTexture);
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using Barotrauma.Items.Components;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using SharpFont;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
@@ -12,28 +11,14 @@ namespace Barotrauma.Lights
|
||||
{
|
||||
class ConvexHullList
|
||||
{
|
||||
private List<ConvexHull> list;
|
||||
public HashSet<ConvexHull> IsHidden;
|
||||
|
||||
public readonly Submarine Submarine;
|
||||
public List<ConvexHull> List
|
||||
{
|
||||
get { return list; }
|
||||
set
|
||||
{
|
||||
Debug.Assert(value != null);
|
||||
Debug.Assert(!list.Contains(null));
|
||||
list = value;
|
||||
IsHidden.RemoveWhere(ch => !list.Contains(ch));
|
||||
}
|
||||
}
|
||||
|
||||
public HashSet<ConvexHull> IsHidden = new HashSet<ConvexHull>();
|
||||
public readonly List<ConvexHull> List = new List<ConvexHull>();
|
||||
|
||||
public ConvexHullList(Submarine submarine)
|
||||
{
|
||||
Submarine = submarine;
|
||||
list = new List<ConvexHull>();
|
||||
IsHidden = new HashSet<ConvexHull>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -354,7 +339,7 @@ namespace Barotrauma.Lights
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsSegmentAInB(Segment a, Segment b)
|
||||
public static bool IsSegmentAInB(Segment a, Segment b)
|
||||
{
|
||||
if (Vector2.DistanceSquared(a.Start.Pos, a.End.Pos) > Vector2.DistanceSquared(b.Start.Pos, b.End.Pos))
|
||||
{
|
||||
@@ -362,15 +347,16 @@ namespace Barotrauma.Lights
|
||||
}
|
||||
|
||||
Vector2 min = new Vector2(Math.Min(b.Start.Pos.X, b.End.Pos.X), Math.Min(b.Start.Pos.Y, b.End.Pos.Y));
|
||||
Vector2 max = new Vector2(Math.Max(b.Start.Pos.X, b.End.Pos.X), Math.Max(b.Start.Pos.Y, b.End.Pos.Y));
|
||||
min.X -= 1.0f; min.Y -= 1.0f;
|
||||
max.X += 1.0f; max.Y += 1.0f;
|
||||
|
||||
if (a.Start.Pos.X < min.X) { return false; }
|
||||
if (a.Start.Pos.Y < min.Y) { return false; }
|
||||
if (a.End.Pos.X < min.X) { return false; }
|
||||
if (a.End.Pos.Y < min.Y) { return false; }
|
||||
|
||||
Vector2 max = new Vector2(Math.Max(b.Start.Pos.X, b.End.Pos.X), Math.Max(b.Start.Pos.Y, b.End.Pos.Y));
|
||||
max.X += 1.0f; max.Y += 1.0f;
|
||||
|
||||
if (a.Start.Pos.X > max.X) { return false; }
|
||||
if (a.Start.Pos.Y > max.Y) { return false; }
|
||||
if (a.End.Pos.X > max.X) { return false; }
|
||||
@@ -628,7 +614,7 @@ namespace Barotrauma.Lights
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (ignoreEdge[i] && ignoreEdges) continue;
|
||||
if (ignoreEdge[i] && ignoreEdges) { continue; }
|
||||
|
||||
Vector2 pos1 = vertices[i].WorldPos;
|
||||
Vector2 pos2 = vertices[(i + 1) % 4].WorldPos;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Content;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System;
|
||||
@@ -73,12 +72,14 @@ namespace Barotrauma.Lights
|
||||
|
||||
private int recalculationCount;
|
||||
|
||||
private float time;
|
||||
|
||||
public IEnumerable<LightSource> Lights
|
||||
{
|
||||
get { return lights; }
|
||||
}
|
||||
|
||||
public LightManager(GraphicsDevice graphics, ContentManager content)
|
||||
public LightManager(GraphicsDevice graphics)
|
||||
{
|
||||
lights = new List<LightSource>(100);
|
||||
|
||||
@@ -96,13 +97,8 @@ namespace Barotrauma.Lights
|
||||
{
|
||||
CreateRenderTargets(graphics);
|
||||
|
||||
#if WINDOWS
|
||||
LosEffect = content.Load<Effect>("Effects/losshader");
|
||||
SolidColorEffect = content.Load<Effect>("Effects/solidcolor");
|
||||
#else
|
||||
LosEffect = content.Load<Effect>("Effects/losshader_opengl");
|
||||
SolidColorEffect = content.Load<Effect>("Effects/solidcolor_opengl");
|
||||
#endif
|
||||
LosEffect = EffectLoader.Load("Effects/losshader");
|
||||
SolidColorEffect = EffectLoader.Load("Effects/solidcolor");
|
||||
|
||||
if (lightEffect == null)
|
||||
{
|
||||
@@ -171,10 +167,12 @@ namespace Barotrauma.Lights
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
//wrap around if the timer gets very large, otherwise we'd start running into floating point accuracy issues
|
||||
time = (time + deltaTime) % 100000.0f;
|
||||
foreach (LightSource light in activeLights)
|
||||
{
|
||||
if (!light.Enabled) { continue; }
|
||||
light.Update(deltaTime);
|
||||
light.Update(time);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -451,9 +449,9 @@ namespace Barotrauma.Lights
|
||||
{
|
||||
highlightedEntities.Add(Character.Controlled.FocusedCharacter);
|
||||
}
|
||||
foreach (Item item in Item.ItemList)
|
||||
foreach (MapEntity me in MapEntity.HighlightedEntities)
|
||||
{
|
||||
if ((item.IsHighlighted || item.IconStyle != null) && !highlightedEntities.Contains(item))
|
||||
if (me is Item item && item != Character.Controlled.FocusedItem)
|
||||
{
|
||||
highlightedEntities.Add(item);
|
||||
}
|
||||
|
||||
@@ -200,12 +200,10 @@ namespace Barotrauma.Lights
|
||||
|
||||
private static Texture2D lightTexture;
|
||||
|
||||
private float blinkTimer, flickerState, pulseState;
|
||||
|
||||
private VertexPositionColorTexture[] vertices;
|
||||
private short[] indices;
|
||||
|
||||
private readonly List<ConvexHullList> hullsInRange;
|
||||
private readonly List<ConvexHullList> convexHullsInRange;
|
||||
|
||||
public Texture2D texture;
|
||||
|
||||
@@ -236,7 +234,7 @@ namespace Barotrauma.Lights
|
||||
{
|
||||
if (!needsRecalculation && value)
|
||||
{
|
||||
foreach (ConvexHullList chList in hullsInRange)
|
||||
foreach (ConvexHullList chList in convexHullsInRange)
|
||||
{
|
||||
chList.IsHidden.Clear();
|
||||
}
|
||||
@@ -476,7 +474,7 @@ namespace Barotrauma.Lights
|
||||
|
||||
public LightSource(Vector2 position, float range, Color color, Submarine submarine, bool addLight=true)
|
||||
{
|
||||
hullsInRange = new List<ConvexHullList>();
|
||||
convexHullsInRange = new List<ConvexHullList>();
|
||||
this.ParentSub = submarine;
|
||||
this.position = position;
|
||||
lightSourceParams = new LightSourceParams(range, color);
|
||||
@@ -486,12 +484,12 @@ namespace Barotrauma.Lights
|
||||
if (addLight) { GameMain.LightManager.AddLight(this); }
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
public void Update(float time)
|
||||
{
|
||||
float brightness = 1.0f;
|
||||
if (lightSourceParams.BlinkFrequency > 0.0f)
|
||||
{
|
||||
blinkTimer = (blinkTimer + deltaTime * lightSourceParams.BlinkFrequency) % 1.0f;
|
||||
float blinkTimer = (time * lightSourceParams.BlinkFrequency) % 1.0f;
|
||||
if (blinkTimer > 0.5f)
|
||||
{
|
||||
CurrentBrightness = 0.0f;
|
||||
@@ -500,14 +498,13 @@ namespace Barotrauma.Lights
|
||||
}
|
||||
if (lightSourceParams.PulseFrequency > 0.0f && lightSourceParams.PulseAmount > 0.0f)
|
||||
{
|
||||
pulseState = (pulseState + deltaTime * lightSourceParams.PulseFrequency) % 1.0f;
|
||||
float pulseState = (time * lightSourceParams.PulseFrequency) % 1.0f;
|
||||
//oscillate between 0-1
|
||||
brightness *= 1.0f - (float)(Math.Sin(pulseState * MathHelper.TwoPi) + 1.0f) / 2.0f * lightSourceParams.PulseAmount;
|
||||
}
|
||||
if (lightSourceParams.Flicker > 0.0f)
|
||||
if (lightSourceParams.Flicker > 0.0f && lightSourceParams.FlickerSpeed > 0.0f)
|
||||
{
|
||||
flickerState += deltaTime * lightSourceParams.FlickerSpeed;
|
||||
flickerState %= 255;
|
||||
float flickerState = (time * lightSourceParams.FlickerSpeed) % 255;
|
||||
brightness *= 1.0f - PerlinNoise.GetPerlin(flickerState, flickerState * 0.5f) * lightSourceParams.Flicker;
|
||||
}
|
||||
CurrentBrightness = brightness;
|
||||
@@ -518,19 +515,25 @@ namespace Barotrauma.Lights
|
||||
/// </summary>
|
||||
private void RefreshConvexHullList(ConvexHullList chList, Vector2 lightPos, Submarine sub)
|
||||
{
|
||||
var fullChList = ConvexHull.HullLists.Find(x => x.Submarine == sub);
|
||||
var fullChList = ConvexHull.HullLists.FirstOrDefault(chList => chList.Submarine == sub);
|
||||
if (fullChList == null) { return; }
|
||||
|
||||
chList.List = fullChList.List.FindAll(ch => ch.Enabled && MathUtils.CircleIntersectsRectangle(lightPos, TextureRange, ch.BoundingBox));
|
||||
|
||||
NeedsHullCheck = true;
|
||||
chList.List.Clear();
|
||||
foreach (var convexHull in fullChList.List)
|
||||
{
|
||||
if (!convexHull.Enabled) { continue; }
|
||||
if (!MathUtils.CircleIntersectsRectangle(lightPos, TextureRange, convexHull.BoundingBox)) { continue; }
|
||||
chList.List.Add(convexHull);
|
||||
}
|
||||
chList.IsHidden.RemoveWhere(ch => !chList.List.Contains(ch));
|
||||
NeedsHullCheck = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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()
|
||||
private void CheckConvexHullsInRange()
|
||||
{
|
||||
foreach (Submarine sub in Submarine.Loaded)
|
||||
{
|
||||
@@ -543,21 +546,13 @@ namespace Barotrauma.Lights
|
||||
private void CheckHullsInRange(Submarine sub)
|
||||
{
|
||||
//find the list of convexhulls that belong to the sub
|
||||
ConvexHullList chList = null;
|
||||
foreach (var ch in hullsInRange)
|
||||
{
|
||||
if (ch.Submarine == sub)
|
||||
{
|
||||
chList = ch;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ConvexHullList chList = convexHullsInRange.FirstOrDefault(chList => chList.Submarine == sub);
|
||||
|
||||
//not found -> create one
|
||||
if (chList == null)
|
||||
{
|
||||
chList = new ConvexHullList(sub);
|
||||
hullsInRange.Add(chList);
|
||||
convexHullsInRange.Add(chList);
|
||||
NeedsRecalculation = true;
|
||||
}
|
||||
|
||||
@@ -649,6 +644,10 @@ namespace Barotrauma.Lights
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly List<Segment> visibleSegments = new List<Segment>();
|
||||
private static readonly List<SegmentPoint> points = new List<SegmentPoint>();
|
||||
private static readonly List<Vector2> output = new List<Vector2>();
|
||||
private static readonly SegmentPoint[] boundaryCorners = new SegmentPoint[4];
|
||||
private List<Vector2> FindRaycastHits()
|
||||
{
|
||||
if (!CastShadows || Range < 1.0f || Color.A < 1) { return null; }
|
||||
@@ -656,12 +655,17 @@ namespace Barotrauma.Lights
|
||||
Vector2 drawPos = position;
|
||||
if (ParentSub != null) { drawPos += ParentSub.DrawPosition; }
|
||||
|
||||
var hulls = new List<ConvexHull>();
|
||||
foreach (ConvexHullList chList in hullsInRange)
|
||||
visibleSegments.Clear();
|
||||
foreach (ConvexHullList chList in convexHullsInRange)
|
||||
{
|
||||
foreach (ConvexHull hull in chList.List)
|
||||
{
|
||||
if (!chList.IsHidden.Contains(hull)) { hulls.Add(hull); }
|
||||
if (!chList.IsHidden.Contains(hull))
|
||||
{
|
||||
//find convexhull segments that are close enough and facing towards the light source
|
||||
hull.RefreshWorldPositions();
|
||||
hull.GetVisibleSegments(drawPos, visibleSegments, ignoreEdges: false);
|
||||
}
|
||||
}
|
||||
foreach (ConvexHull hull in chList.List)
|
||||
{
|
||||
@@ -669,23 +673,13 @@ namespace Barotrauma.Lights
|
||||
}
|
||||
}
|
||||
|
||||
float bounds = TextureRange;
|
||||
//find convexhull segments that are close enough and facing towards the light source
|
||||
List<Segment> visibleSegments = new List<Segment>();
|
||||
List<SegmentPoint> points = new List<SegmentPoint>();
|
||||
foreach (ConvexHull hull in hulls)
|
||||
{
|
||||
hull.RefreshWorldPositions();
|
||||
hull.GetVisibleSegments(drawPos, visibleSegments, ignoreEdges: false);
|
||||
}
|
||||
|
||||
//add a square-shaped boundary to make sure we've got something to construct the triangles from
|
||||
//even if there aren't enough hull segments around the light source
|
||||
|
||||
//(might be more effective to calculate if we actually need these extra points)
|
||||
|
||||
Vector2 drawOffset = Vector2.Zero;
|
||||
float boundsExtended = bounds;
|
||||
float boundsExtended = TextureRange;
|
||||
if (OverrideLightTexture != null)
|
||||
{
|
||||
float cosAngle = (float)Math.Cos(Rotation);
|
||||
@@ -709,12 +703,12 @@ namespace Barotrauma.Lights
|
||||
drawOffset.Y = origin.X * sinAngle + origin.Y * cosAngle;
|
||||
}
|
||||
|
||||
var boundaryCorners = new SegmentPoint[] {
|
||||
new SegmentPoint(new Vector2(drawPos.X + drawOffset.X + boundsExtended, drawPos.Y + drawOffset.Y + boundsExtended), null),
|
||||
new SegmentPoint(new Vector2(drawPos.X + drawOffset.X + boundsExtended, drawPos.Y + drawOffset.Y - boundsExtended), null),
|
||||
new SegmentPoint(new Vector2(drawPos.X + drawOffset.X - boundsExtended, drawPos.Y + drawOffset.Y - boundsExtended), null),
|
||||
new SegmentPoint(new Vector2(drawPos.X + drawOffset.X - boundsExtended, drawPos.Y + drawOffset.Y + boundsExtended), null)
|
||||
};
|
||||
Vector2 boundsMin = drawPos + drawOffset + new Vector2(-boundsExtended, -boundsExtended);
|
||||
Vector2 boundsMax = drawPos + drawOffset + new Vector2(boundsExtended, boundsExtended);
|
||||
boundaryCorners[0] = new SegmentPoint(boundsMax, null);
|
||||
boundaryCorners[1] = new SegmentPoint(new Vector2(boundsMax.X, boundsMin.Y), null);
|
||||
boundaryCorners[2] = new SegmentPoint(boundsMin, null);
|
||||
boundaryCorners[3] = new SegmentPoint(new Vector2(boundsMin.X, boundsMax.Y), null);
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
@@ -798,6 +792,7 @@ namespace Barotrauma.Lights
|
||||
}
|
||||
}
|
||||
|
||||
points.Clear();
|
||||
//remove segments that fall out of bounds
|
||||
for (int i = 0; i < visibleSegments.Count; i++)
|
||||
{
|
||||
@@ -817,7 +812,18 @@ namespace Barotrauma.Lights
|
||||
}
|
||||
}
|
||||
|
||||
visibleSegments = visibleSegments.OrderBy(s => MathUtils.LineToPointDistanceSquared(s.Start.WorldPos, s.End.WorldPos, drawPos)).ToList();
|
||||
//remove points that are very close to each other
|
||||
for (int i = 0; i < points.Count; i++)
|
||||
{
|
||||
for (int j = Math.Min(i + 4, points.Count-1); j > i; j--)
|
||||
{
|
||||
if (Math.Abs(points[i].WorldPos.X - points[j].WorldPos.X) < 6 &&
|
||||
Math.Abs(points[i].WorldPos.Y - points[j].WorldPos.Y) < 6)
|
||||
{
|
||||
points.RemoveAt(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var compareCCW = new CompareSegmentPointCW(drawPos);
|
||||
try
|
||||
@@ -833,23 +839,12 @@ namespace Barotrauma.Lights
|
||||
}
|
||||
DebugConsole.ThrowError(sb.ToString(), e);
|
||||
}
|
||||
|
||||
visibleSegments.Sort((s1, s2) =>
|
||||
MathUtils.LineToPointDistanceSquared(s1.Start.WorldPos, s1.End.WorldPos, drawPos)
|
||||
.CompareTo(MathUtils.LineToPointDistanceSquared(s2.Start.WorldPos, s2.End.WorldPos, drawPos)));
|
||||
|
||||
List<Vector2> output = new List<Vector2>();
|
||||
//List<Pair<int, Vector2>> preOutput = new List<Pair<int, Vector2>>();
|
||||
|
||||
//remove points that are very close to each other
|
||||
for (int i = 0; i < points.Count; i++)
|
||||
{
|
||||
for (int j = Math.Min(i + 4, points.Count-1); j > i; j--)
|
||||
{
|
||||
if (Math.Abs(points[i].WorldPos.X - points[j].WorldPos.X) < 6 &&
|
||||
Math.Abs(points[i].WorldPos.Y - points[j].WorldPos.Y) < 6)
|
||||
{
|
||||
points.RemoveAt(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
output.Clear();
|
||||
foreach (SegmentPoint p in points)
|
||||
{
|
||||
Vector2 dir = Vector2.Normalize(p.WorldPos - drawPos);
|
||||
@@ -857,10 +852,10 @@ namespace Barotrauma.Lights
|
||||
|
||||
//do two slightly offset raycasts to hit the segment itself and whatever's behind it
|
||||
var intersection1 = RayCast(drawPos, drawPos + dir * boundsExtended * 2 - dirNormal, visibleSegments);
|
||||
if (intersection1.index < 0) { return null; }
|
||||
var intersection2 = RayCast(drawPos, drawPos + dir * boundsExtended * 2 + dirNormal, visibleSegments);
|
||||
if (intersection2.index < 0) { return null; }
|
||||
|
||||
if (intersection1.index < 0) return null;
|
||||
if (intersection2.index < 0) return null;
|
||||
Segment seg1 = visibleSegments[intersection1.index];
|
||||
Segment seg2 = visibleSegments[intersection2.index];
|
||||
|
||||
@@ -872,7 +867,7 @@ namespace Barotrauma.Lights
|
||||
//hit at the current segmentpoint -> place the segmentpoint into the list
|
||||
output.Add(p.WorldPos);
|
||||
|
||||
foreach (ConvexHullList hullList in hullsInRange)
|
||||
foreach (ConvexHullList hullList in convexHullsInRange)
|
||||
{
|
||||
hullList.IsHidden.Remove(p.ConvexHull);
|
||||
hullList.IsHidden.Remove(seg1.ConvexHull);
|
||||
@@ -886,7 +881,7 @@ namespace Barotrauma.Lights
|
||||
output.Add(isPoint1 ? p.WorldPos : intersection1.pos);
|
||||
output.Add(isPoint2 ? p.WorldPos : intersection2.pos);
|
||||
|
||||
foreach (ConvexHullList hullList in hullsInRange)
|
||||
foreach (ConvexHullList hullList in convexHullsInRange)
|
||||
{
|
||||
hullList.IsHidden.Remove(p.ConvexHull);
|
||||
hullList.IsHidden.Remove(seg1.ConvexHull);
|
||||
@@ -914,7 +909,7 @@ namespace Barotrauma.Lights
|
||||
return output;
|
||||
}
|
||||
|
||||
private (int index, Vector2 pos) RayCast(Vector2 rayStart, Vector2 rayEnd, List<Segment> segments)
|
||||
private static (int index, Vector2 pos) RayCast(Vector2 rayStart, Vector2 rayEnd, List<Segment> segments)
|
||||
{
|
||||
Vector2? closestIntersection = null;
|
||||
int segment = -1;
|
||||
@@ -939,13 +934,13 @@ namespace Barotrauma.Lights
|
||||
//same for the x-axis
|
||||
if (s.Start.WorldPos.X > s.End.WorldPos.X)
|
||||
{
|
||||
if (s.Start.WorldPos.X < minX) continue;
|
||||
if (s.End.WorldPos.X > maxX) continue;
|
||||
if (s.Start.WorldPos.X < minX) { continue; }
|
||||
if (s.End.WorldPos.X > maxX) { continue; }
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s.End.WorldPos.X < minX) continue;
|
||||
if (s.Start.WorldPos.X > maxX) continue;
|
||||
if (s.End.WorldPos.X < minX) { continue; }
|
||||
if (s.Start.WorldPos.X > maxX) { continue; }
|
||||
}
|
||||
|
||||
bool intersects;
|
||||
@@ -1338,7 +1333,7 @@ namespace Barotrauma.Lights
|
||||
return;
|
||||
}
|
||||
|
||||
CheckHullsInRange();
|
||||
CheckConvexHullsInRange();
|
||||
|
||||
if (NeedsRecalculation && allowRecalculation)
|
||||
{
|
||||
@@ -1390,7 +1385,7 @@ namespace Barotrauma.Lights
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
hullsInRange.Clear();
|
||||
convexHullsInRange.Clear();
|
||||
diffToSub.Clear();
|
||||
NeedsHullCheck = true;
|
||||
NeedsRecalculation = true;
|
||||
|
||||
@@ -70,9 +70,9 @@ namespace Barotrauma
|
||||
|
||||
Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition);
|
||||
|
||||
foreach (MapEntity entity in mapEntityList)
|
||||
foreach (MapEntity entity in HighlightedEntities)
|
||||
{
|
||||
if (entity == this || !entity.IsHighlighted || !(entity is Item) || !entity.IsMouseOn(position)) { continue; }
|
||||
if (entity == this|| entity is not Item || !entity.IsMouseOn(position)) { continue; }
|
||||
if (((Item)entity).GetComponent<DockingPort>() == null) { continue; }
|
||||
if (linkedTo.Contains(entity))
|
||||
{
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace Barotrauma
|
||||
|
||||
private (Rectangle targetArea, RichString tip)? tooltip;
|
||||
|
||||
private (SubmarineInfo pendingSub, float realWorldCrushDepth) pendingSubInfo;
|
||||
private SubmarineInfo.PendingSubInfo pendingSubInfo;
|
||||
|
||||
private RichString beaconStationActiveText, beaconStationInactiveText;
|
||||
|
||||
@@ -213,11 +213,17 @@ namespace Barotrauma
|
||||
currLocationIndicatorPos = CurrentLocation.MapPosition;
|
||||
}
|
||||
|
||||
RemoveFogOfWar(newLocation);
|
||||
if (newLocation.Visited)
|
||||
{
|
||||
RemoveFogOfWar(newLocation);
|
||||
}
|
||||
}
|
||||
|
||||
partial void RemoveFogOfWarProjSpecific(Location location) => RemoveFogOfWar(location);
|
||||
|
||||
private void RemoveFogOfWar(Location location, bool removeFromAdjacentLocations = true)
|
||||
{
|
||||
if (mapTiles == null) { return; }
|
||||
if (location == null) { return; }
|
||||
|
||||
var mapTile = generationParams.MapTiles.Values.FirstOrDefault().FirstOrDefault();
|
||||
@@ -453,6 +459,7 @@ namespace Barotrauma
|
||||
};
|
||||
new GUICustomComponent(new RectTransform(new Vector2(0.6f, 1.0f), repBarHolder.RectTransform), onDraw: (sb, component) =>
|
||||
{
|
||||
if (location.Reputation == null) { return; }
|
||||
RoundSummary.DrawReputationBar(sb, component.Rect, location.Reputation.NormalizedValue);
|
||||
});
|
||||
|
||||
@@ -681,6 +688,7 @@ namespace Barotrauma
|
||||
Level.Loaded.DebugSetEndLocation(null);
|
||||
|
||||
Discover(CurrentLocation);
|
||||
Visit(CurrentLocation);
|
||||
OnLocationChanged?.Invoke(new LocationChangeInfo(prevLocation, CurrentLocation));
|
||||
SelectLocation(-1);
|
||||
if (GameMain.Client == null)
|
||||
@@ -695,12 +703,6 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
if (PlayerInput.KeyDown(Microsoft.Xna.Framework.Input.Keys.LeftShift) && PlayerInput.PrimaryMouseButtonClicked() && HighlightedLocation != null)
|
||||
{
|
||||
int distance = DistanceToClosestLocationWithOutpost(HighlightedLocation, out Location foundLocation);
|
||||
DebugConsole.NewMessage($"Distance to closest outpost from {HighlightedLocation.Name} to {foundLocation?.Name} is {distance}");
|
||||
}
|
||||
|
||||
if (PlayerInput.PrimaryMouseButtonClicked() && HighlightedLocation == null)
|
||||
{
|
||||
SelectLocation(-1);
|
||||
@@ -729,6 +731,8 @@ namespace Barotrauma
|
||||
|
||||
Vector2 rectCenter = new Vector2(rect.Center.X, rect.Center.Y);
|
||||
|
||||
float missionIconScale = generationParams.MissionIcon != null ? 18.0f / generationParams.MissionIcon.SourceRect.Width : 1.0f;
|
||||
|
||||
Rectangle prevScissorRect = GameMain.Instance.GraphicsDevice.ScissorRectangle;
|
||||
spriteBatch.End();
|
||||
spriteBatch.GraphicsDevice.ScissorRectangle = Rectangle.Intersect(prevScissorRect, rect);
|
||||
@@ -807,10 +811,22 @@ namespace Barotrauma
|
||||
drawRect.X = (int)pos.X - drawRect.Width / 2;
|
||||
drawRect.Y = (int)pos.Y - drawRect.Width / 2;
|
||||
|
||||
if (drawRect.X > rect.Right - GUI.IntScale(100) && generationParams.MissionIcon != null && location.AvailableMissions.Any())
|
||||
{
|
||||
Vector2 offScreenMissionIconPos = new Vector2(rect.Right - GUI.IntScale(50), drawRect.Center.Y);
|
||||
generationParams.MissionIcon.Draw(spriteBatch,
|
||||
offScreenMissionIconPos,
|
||||
generationParams.IndicatorColor, scale: missionIconScale * zoom);
|
||||
GUI.Arrow.Draw(spriteBatch,
|
||||
offScreenMissionIconPos + Vector2.UnitX * generationParams.MissionIcon.size.X * missionIconScale * zoom,
|
||||
generationParams.IndicatorColor, MathHelper.PiOver2, scale: 0.5f);
|
||||
}
|
||||
|
||||
|
||||
if (!rect.Intersects(drawRect)) { continue; }
|
||||
|
||||
Color color = location.Type.SpriteColor;
|
||||
if (!location.Discovered) { color = Color.White; }
|
||||
if (!location.Visited) { color = Color.White; }
|
||||
if (location.Connections.Find(c => c.Locations.Contains(currentDisplayLocation)) == null)
|
||||
{
|
||||
color *= 0.5f;
|
||||
@@ -890,7 +906,6 @@ namespace Barotrauma
|
||||
location.AvailableMissions.Any(m => m.Locations[0] == m.Locations[1]))
|
||||
{
|
||||
Vector2 missionIconPos = pos + new Vector2(1.35f, 0.35f) * generationParams.LocationIconSize * 0.5f * zoom;
|
||||
float missionIconScale = 18.0f / generationParams.MissionIcon.SourceRect.Width;
|
||||
generationParams.MissionIcon.Draw(spriteBatch, missionIconPos, generationParams.IndicatorColor, scale: missionIconScale * zoom);
|
||||
if (Vector2.Distance(PlayerInput.MousePosition, missionIconPos) < generationParams.MissionIcon.SourceRect.Width * zoom && IsPreferredTooltip(missionIconPos))
|
||||
{
|
||||
@@ -908,10 +923,17 @@ namespace Barotrauma
|
||||
Vector2 dPos = pos;
|
||||
if (location == HighlightedLocation)
|
||||
{
|
||||
dPos.Y += 48;
|
||||
GUI.DrawString(spriteBatch, dPos + new Vector2(15, 32), "Faction: "+(location.Faction?.Prefab.Name ?? "none"), Color.White, Color.Black, font: GUIStyle.SubHeadingFont);
|
||||
dPos.Y -= 80;
|
||||
GUI.DrawString(spriteBatch, dPos + new Vector2(15, 32), "Faction: " + (location.Faction?.Prefab.Name ?? "none"), Color.White, Color.Black, font: GUIStyle.SubHeadingFont);
|
||||
GUI.DrawString(spriteBatch, dPos + new Vector2(15, 50), "Secondary Faction: " + (location.SecondaryFaction?.Prefab.Name ?? "none"), Color.White, Color.Black, font: GUIStyle.SubHeadingFont);
|
||||
dPos.Y += 48;
|
||||
|
||||
if (PlayerInput.KeyDown(Keys.LeftShift))
|
||||
{
|
||||
GUI.DrawString(spriteBatch, new Vector2(150,150), "Dist: " +
|
||||
GetDistanceToClosestLocationOrConnection(CurrentLocation, int.MaxValue, loc => loc == location), Color.White, Color.Black, font: GUIStyle.SubHeadingFont);
|
||||
|
||||
}
|
||||
}
|
||||
dPos.Y += 48;
|
||||
GUI.DrawString(spriteBatch, dPos, $"Difficulty: {location.LevelData.Difficulty.FormatSingleDecimal()}", Color.White, Color.Black * 0.8f, 4, font: GUIStyle.SmallFont);
|
||||
@@ -1045,7 +1067,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
float a = 1.0f;
|
||||
if (!connection.Locations[0].Discovered && !connection.Locations[1].Discovered)
|
||||
if (!connection.Locations[0].Visited && !connection.Locations[1].Visited)
|
||||
{
|
||||
if (IsInFogOfWar(connection.Locations[0]))
|
||||
{
|
||||
@@ -1089,39 +1111,8 @@ namespace Barotrauma
|
||||
if (connection.LevelData.HasHuntingGrounds) { iconCount++; }
|
||||
if (connection.Locked) { iconCount++; }
|
||||
string tooltip = null;
|
||||
float subCrushDepth = Level.DefaultRealWorldCrushDepth;
|
||||
var currentOrPendingSub = SubmarineSelection.CurrentOrPendingSubmarine();
|
||||
if (Submarine.MainSub != null && Submarine.MainSub.Info == currentOrPendingSub)
|
||||
{
|
||||
subCrushDepth = Submarine.MainSub.RealWorldCrushDepth;
|
||||
}
|
||||
else if (currentOrPendingSub != null)
|
||||
{
|
||||
if (pendingSubInfo.pendingSub != currentOrPendingSub)
|
||||
{
|
||||
// Store the real world crush depth for the pending sub so that we don't have to calculate it again every time
|
||||
pendingSubInfo = (currentOrPendingSub, currentOrPendingSub.GetRealWorldCrushDepth());
|
||||
}
|
||||
subCrushDepth = pendingSubInfo.realWorldCrushDepth;
|
||||
}
|
||||
if (GameMain.GameSession?.Campaign?.UpgradeManager != null)
|
||||
{
|
||||
var hullUpgradePrefab = UpgradePrefab.Find("increasewallhealth".ToIdentifier());
|
||||
if (hullUpgradePrefab != null)
|
||||
{
|
||||
int pendingLevel = GameMain.GameSession.Campaign.UpgradeManager.GetUpgradeLevel(hullUpgradePrefab, hullUpgradePrefab.UpgradeCategories.First());
|
||||
int currentLevel = GameMain.GameSession.Campaign.UpgradeManager.GetRealUpgradeLevel(hullUpgradePrefab, hullUpgradePrefab.UpgradeCategories.First());
|
||||
if (pendingLevel > currentLevel)
|
||||
{
|
||||
string updateValueStr = hullUpgradePrefab.SourceElement?.GetChildElement("Structure")?.GetAttributeString("crushdepth", null);
|
||||
if (!string.IsNullOrEmpty(updateValueStr))
|
||||
{
|
||||
subCrushDepth = PropertyReference.CalculateUpgrade(subCrushDepth, pendingLevel - currentLevel, updateValueStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float subCrushDepth = SubmarineInfo.GetSubCrushDepth(SubmarineSelection.CurrentOrPendingSubmarine(), ref pendingSubInfo);
|
||||
string crushDepthWarningIconStyle = null;
|
||||
if (connection.LevelData.InitialDepth * Physics.DisplayToRealWorldRatio > subCrushDepth)
|
||||
{
|
||||
@@ -1277,6 +1268,14 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets <see cref="pendingSubInfo"/> and forces crush depth to be calculated again for icon displaying purposes
|
||||
/// </summary>
|
||||
public void ResetPendingSub()
|
||||
{
|
||||
pendingSubInfo = new SubmarineInfo.PendingSubInfo();
|
||||
}
|
||||
|
||||
partial void RemoveProjSpecific()
|
||||
{
|
||||
noiseOverlay?.Remove();
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace Barotrauma
|
||||
|
||||
public static List<MapEntity> CopiedList = new List<MapEntity>();
|
||||
|
||||
private static List<MapEntity> highlightedList = new List<MapEntity>();
|
||||
private static List<MapEntity> highlightedInEditorList = new List<MapEntity>();
|
||||
|
||||
private static float highlightTimer;
|
||||
|
||||
@@ -131,10 +131,7 @@ namespace Barotrauma
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (MapEntity e in mapEntityList)
|
||||
{
|
||||
e.isHighlighted = false;
|
||||
}
|
||||
ClearHighlightedEntities();
|
||||
|
||||
if (DisableSelect)
|
||||
{
|
||||
@@ -262,11 +259,10 @@ namespace Barotrauma
|
||||
if (i == 0) highLightedEntity = e;
|
||||
}
|
||||
}
|
||||
|
||||
UpdateHighlighting(highlightedEntities);
|
||||
}
|
||||
|
||||
if (highLightedEntity != null) highLightedEntity.isHighlighted = true;
|
||||
if (highLightedEntity != null) { highLightedEntity.IsHighlighted = true; }
|
||||
}
|
||||
|
||||
if (GUI.KeyboardDispatcher.Subscriber == null)
|
||||
@@ -288,7 +284,6 @@ namespace Barotrauma
|
||||
if (startMovingPos != Vector2.Zero)
|
||||
{
|
||||
Item targetContainer = GetPotentialContainer(position, SelectedList);
|
||||
|
||||
if (targetContainer != null) { targetContainer.IsHighlighted = true; }
|
||||
|
||||
if (PlayerInput.PrimaryMouseButtonReleased())
|
||||
@@ -610,10 +605,10 @@ namespace Barotrauma
|
||||
if (highlightedListBox != null)
|
||||
{
|
||||
if (GUI.MouseOn == highlightedListBox || highlightedListBox.IsParentOf(GUI.MouseOn)) return;
|
||||
if (highlightedEntities.SequenceEqual(highlightedList)) return;
|
||||
if (highlightedEntities.SequenceEqual(highlightedInEditorList)) return;
|
||||
}
|
||||
|
||||
highlightedList = highlightedEntities;
|
||||
highlightedInEditorList = highlightedEntities;
|
||||
|
||||
highlightedListBox = new GUIListBox(new RectTransform(new Point(180, highlightedEntities.Count * 18 + 5), GUI.Canvas)
|
||||
{
|
||||
@@ -1096,7 +1091,7 @@ namespace Barotrauma
|
||||
|
||||
private void UpdateResizing(Camera cam)
|
||||
{
|
||||
isHighlighted = true;
|
||||
IsHighlighted = true;
|
||||
|
||||
int startX = ResizeHorizontal ? -1 : 0;
|
||||
int StartY = ResizeVertical ? -1 : 0;
|
||||
@@ -1197,7 +1192,7 @@ namespace Barotrauma
|
||||
|
||||
private void DrawResizing(SpriteBatch spriteBatch, Camera cam)
|
||||
{
|
||||
isHighlighted = true;
|
||||
IsHighlighted = true;
|
||||
|
||||
int startX = ResizeHorizontal ? -1 : 0;
|
||||
int StartY = ResizeVertical ? -1 : 0;
|
||||
|
||||
@@ -89,7 +89,11 @@ namespace Barotrauma
|
||||
CreateSpecsWindow(descriptionBox, font, includeDescription: true);
|
||||
}
|
||||
|
||||
public void CreateSpecsWindow(GUIListBox parent, GUIFont font, bool includeTitle = true, bool includeClass = true, bool includeDescription = false)
|
||||
public void CreateSpecsWindow(GUIListBox parent, GUIFont font,
|
||||
bool includeTitle = true,
|
||||
bool includeClass = true,
|
||||
bool includeDescription = false,
|
||||
bool includeCrushDepth = false)
|
||||
{
|
||||
float leftPanelWidth = 0.6f;
|
||||
float rightPanelWidth = 0.4f / leftPanelWidth;
|
||||
@@ -155,6 +159,22 @@ namespace Barotrauma
|
||||
{ CanBeFocused = false };
|
||||
cargoCapacityText.RectTransform.MinSize = new Point(0, cargoCapacityText.Children.First().Rect.Height);
|
||||
|
||||
if (includeCrushDepth)
|
||||
{
|
||||
var crushDepthText = new GUITextBlock(new RectTransform(new Vector2(leftPanelWidth, 0), parent.Content.RectTransform),
|
||||
TextManager.Get("CrushDepth"), textAlignment: Alignment.TopLeft, font: font, wrap: true)
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
new GUITextBlock(new RectTransform(new Vector2(rightPanelWidth, 0.0f), crushDepthText.RectTransform, Anchor.TopRight, Pivot.TopLeft),
|
||||
TextManager.GetWithVariable("meterformat", "[meters]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", GetSubCrushDepth())),
|
||||
textAlignment: Alignment.TopLeft, font: font, wrap: true)
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
crushDepthText.RectTransform.MinSize = new Point(0, crushDepthText.Children.First().Rect.Height);
|
||||
}
|
||||
|
||||
if (RecommendedCrewSizeMax > 0)
|
||||
{
|
||||
var crewSizeText = new GUITextBlock(new RectTransform(new Vector2(leftPanelWidth, 0), parent.Content.RectTransform),
|
||||
@@ -227,5 +247,57 @@ namespace Barotrauma
|
||||
GUITextBlock.AutoScaleAndNormalize(parent.Content.GetAllChildren<GUITextBlock>().Where(c => c != submarineNameText && c != descBlock));
|
||||
parent.ForceLayoutRecalculation();
|
||||
}
|
||||
|
||||
public readonly record struct PendingSubInfo(SubmarineInfo PendingSub = null, bool StructuresDefineRealWorldCrushDepth = false, float RealWorldCrushDepth = Level.DefaultRealWorldCrushDepth);
|
||||
|
||||
private float GetSubCrushDepth()
|
||||
{
|
||||
var pendingSubInfo = new PendingSubInfo();
|
||||
return GetSubCrushDepth(this, ref pendingSubInfo);
|
||||
}
|
||||
|
||||
public static float GetSubCrushDepth(SubmarineInfo subInfo, ref PendingSubInfo pendingSubInfo)
|
||||
{
|
||||
float subCrushDepth = Level.DefaultRealWorldCrushDepth;
|
||||
if (Submarine.MainSub != null && Submarine.MainSub.Info == subInfo)
|
||||
{
|
||||
subCrushDepth = Submarine.MainSub.RealWorldCrushDepth;
|
||||
}
|
||||
else if (subInfo != null)
|
||||
{
|
||||
if (pendingSubInfo.PendingSub != subInfo)
|
||||
{
|
||||
// Store the real world crush depth for the pending sub so that we don't have to calculate it again every time
|
||||
pendingSubInfo = new PendingSubInfo(subInfo, subInfo.IsCrushDepthDefinedInStructures(out float realWorldCrushDepth), realWorldCrushDepth);
|
||||
}
|
||||
subCrushDepth = pendingSubInfo.RealWorldCrushDepth;
|
||||
}
|
||||
if (GameMain.GameSession?.Campaign?.UpgradeManager != null && UpgradePrefab.Find("increasewallhealth".ToIdentifier()) is UpgradePrefab hullUpgradePrefab)
|
||||
{
|
||||
int pendingLevel = GameMain.GameSession.Campaign.UpgradeManager.GetUpgradeLevel(hullUpgradePrefab, hullUpgradePrefab.UpgradeCategories.First(), info: subInfo);
|
||||
// If there is a sub switch pending, unless its structures have crush depth defined in their elements,
|
||||
// calculate the value based on the default crush depth and pending upgrade level
|
||||
int currentLevel = 0;
|
||||
if (pendingSubInfo.PendingSub is null || pendingSubInfo.StructuresDefineRealWorldCrushDepth)
|
||||
{
|
||||
currentLevel = GameMain.GameSession.Campaign.UpgradeManager.GetRealUpgradeLevelForSub(hullUpgradePrefab, hullUpgradePrefab.UpgradeCategories.First(), subInfo);
|
||||
}
|
||||
if (pendingLevel > currentLevel)
|
||||
{
|
||||
string updateValueStr = hullUpgradePrefab.SourceElement?.GetChildElement("Structure")?.GetAttributeString("crushdepth", null);
|
||||
if (!string.IsNullOrEmpty(updateValueStr))
|
||||
{
|
||||
if (currentLevel > 0)
|
||||
{
|
||||
// If the current level is greater than 0, reset the crush depth value back to the base value before calculating the upgrade
|
||||
int upgradePercentage = UpgradePrefab.ParsePercentage(updateValueStr, Identifier.Empty, suppressWarnings: true);
|
||||
subCrushDepth /= (1f + (upgradePercentage / 100f * currentLevel));
|
||||
}
|
||||
subCrushDepth = PropertyReference.CalculateUpgrade(subCrushDepth, pendingLevel, updateValueStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
return subCrushDepth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,26 +4,29 @@ using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.Items.Components;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
class SubmarinePreview : IDisposable
|
||||
sealed class SubmarinePreview : IDisposable
|
||||
{
|
||||
private SpriteRecorder spriteRecorder;
|
||||
private readonly SubmarineInfo submarineInfo;
|
||||
|
||||
private SpriteRecorder spriteRecorder;
|
||||
private Camera camera;
|
||||
private Task loadTask;
|
||||
private (Vector2 Min, Vector2 Max) bounds;
|
||||
|
||||
private volatile bool isDisposed;
|
||||
|
||||
private GUIFrame previewFrame;
|
||||
|
||||
private class HullCollection
|
||||
private sealed class HullCollection
|
||||
{
|
||||
public readonly List<Rectangle> Rects;
|
||||
public readonly LocalizedString Name;
|
||||
@@ -42,7 +45,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private struct Door
|
||||
private readonly struct Door
|
||||
{
|
||||
public readonly Rectangle Rect;
|
||||
|
||||
@@ -113,7 +116,7 @@ namespace Barotrauma
|
||||
bool isMouseOnComponent = GUI.MouseOn == component;
|
||||
camera.MoveCamera(deltaTime, allowZoom: isMouseOnComponent, followSub: false);
|
||||
if (isMouseOnComponent &&
|
||||
(PlayerInput.MidButtonHeld() || PlayerInput.LeftButtonHeld()))
|
||||
(PlayerInput.MidButtonHeld() || PlayerInput.PrimaryMouseButtonHeld()))
|
||||
{
|
||||
Vector2 moveSpeed = PlayerInput.MouseSpeed * (float)deltaTime * 60.0f / camera.Zoom;
|
||||
moveSpeed.X = -moveSpeed.X;
|
||||
@@ -150,7 +153,9 @@ namespace Barotrauma
|
||||
ScrollBarVisible = false,
|
||||
Spacing = GUI.IntScale(5)
|
||||
};
|
||||
subInfo.CreateSpecsWindow(specsContainer, GUIStyle.Font, includeTitle: false, includeDescription: true);
|
||||
subInfo.CreateSpecsWindow(specsContainer, GUIStyle.Font,
|
||||
includeTitle: false,
|
||||
includeDescription: true);
|
||||
int width = specsContainer.Rect.Width;
|
||||
void recalculateSpecsContainerHeight()
|
||||
{
|
||||
@@ -186,7 +191,22 @@ namespace Barotrauma
|
||||
});
|
||||
recalculateSpecsContainerHeight();
|
||||
|
||||
GeneratePreviewMeshes();
|
||||
TaskPool.Add(nameof(GeneratePreviewMeshes), GeneratePreviewMeshes(), _ =>
|
||||
{
|
||||
if (isDisposed) { return; }
|
||||
// Reset the camera's position on the main thread,
|
||||
// because the Camera class is not thread-safe and
|
||||
// it's possible for its state to not get updated
|
||||
// properly if done within a task
|
||||
camera.Position = (bounds.Min + bounds.Max) * (0.5f, -0.5f);
|
||||
Vector2 span2d = bounds.Max - bounds.Min;
|
||||
Vector2 scaledSpan2d = span2d / camera.Resolution.ToVector2();
|
||||
float scaledSpan = Math.Max(scaledSpan2d.X, scaledSpan2d.Y);
|
||||
camera.MinZoom = Math.Min(0.1f, 0.4f / scaledSpan);
|
||||
camera.Zoom = 0.7f / scaledSpan;
|
||||
camera.StopMovement();
|
||||
camera.UpdateTransform(interpolate: false, updateListener: false);
|
||||
});
|
||||
}
|
||||
|
||||
public static void AddToGUIUpdateList()
|
||||
@@ -207,6 +227,7 @@ namespace Barotrauma
|
||||
spriteRecorder.Begin(SpriteSortMode.BackToFront);
|
||||
|
||||
HashSet<int> toIgnore = new HashSet<int>();
|
||||
HashSet<int> wires = new HashSet<int>();
|
||||
|
||||
foreach (var subElement in submarineInfo.SubmarineElement.Elements())
|
||||
{
|
||||
@@ -221,7 +242,7 @@ namespace Barotrauma
|
||||
ExtractItemContainerIds(component, toIgnore);
|
||||
break;
|
||||
case "connectionpanel":
|
||||
ExtractConnectionPanelLinks(component, toIgnore);
|
||||
ExtractConnectionPanelLinks(component, wires);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -231,20 +252,25 @@ namespace Barotrauma
|
||||
await Task.Yield();
|
||||
}
|
||||
|
||||
var wireNodes = new List<XElement>();
|
||||
|
||||
foreach (var subElement in submarineInfo.SubmarineElement.Elements())
|
||||
{
|
||||
if (subElement.GetAttributeBool("hiddeningame", false)) { continue; }
|
||||
switch (subElement.Name.LocalName.ToLowerInvariant())
|
||||
{
|
||||
case "structure":
|
||||
case "item":
|
||||
if (!toIgnore.Contains(subElement.GetAttributeInt("ID", 0)))
|
||||
var id = subElement.GetAttributeInt("ID", 0);
|
||||
if (wires.Contains(id))
|
||||
{
|
||||
wireNodes.Add(subElement);
|
||||
}
|
||||
else if (!toIgnore.Contains(id))
|
||||
{
|
||||
BakeMapEntity(subElement);
|
||||
}
|
||||
break;
|
||||
case "structure":
|
||||
BakeMapEntity(subElement);
|
||||
break;
|
||||
case "hull":
|
||||
Identifier identifier = subElement.GetAttributeIdentifier("roomname", "");
|
||||
if (!identifier.IsEmpty)
|
||||
@@ -261,15 +287,14 @@ namespace Barotrauma
|
||||
if (isDisposed) { return; }
|
||||
await Task.Yield();
|
||||
}
|
||||
spriteRecorder.End();
|
||||
|
||||
camera.Position = (spriteRecorder.Min + spriteRecorder.Max) * 0.5f;
|
||||
float scaledSpan = (spriteRecorder.Max - spriteRecorder.Min).X / camera.Resolution.X;
|
||||
camera.Zoom = 0.8f / scaledSpan;
|
||||
camera.StopMovement();
|
||||
bounds = (spriteRecorder.Min, spriteRecorder.Max);
|
||||
wireNodes.ForEach(BakeWireNodes);
|
||||
|
||||
spriteRecorder.End();
|
||||
}
|
||||
|
||||
private void ExtractItemContainerIds(XElement component, HashSet<int> ids)
|
||||
private static void ExtractItemContainerIds(XElement component, HashSet<int> ids)
|
||||
{
|
||||
string containedString = component.GetAttributeString("contained", "");
|
||||
string[] itemIdStrings = containedString.Split(',');
|
||||
@@ -283,7 +308,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private void ExtractConnectionPanelLinks(XElement component, HashSet<int> ids)
|
||||
private static void ExtractConnectionPanelLinks(XElement component, HashSet<int> ids)
|
||||
{
|
||||
var pins = component.Elements("input").Concat(component.Elements("output"));
|
||||
foreach (var pin in pins)
|
||||
@@ -297,6 +322,39 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private void BakeWireNodes(XElement element)
|
||||
{
|
||||
var prefabIdentifier = element.GetAttributeIdentifier("identifier", "");
|
||||
if (prefabIdentifier.IsEmpty) { return; }
|
||||
if (!ItemPrefab.Prefabs.TryGet(prefabIdentifier, out var prefab)) { return; }
|
||||
|
||||
var prefabWireComponentElement = prefab.ConfigElement.GetChildElement("wire");
|
||||
if (prefabWireComponentElement is null) { return; }
|
||||
|
||||
var wireComponent = element.GetChildElement("wire");
|
||||
if (wireComponent is null) { return; }
|
||||
|
||||
var color = element.GetAttributeColor("spritecolor") ?? Color.White;
|
||||
|
||||
var nodes = Wire.ExtractNodes(wireComponent).ToImmutableArray();
|
||||
var wireSprite = Wire.ExtractWireSprite(prefab.ConfigElement);
|
||||
|
||||
var useSpriteDepth = element.GetAttributeBool("usespritedepth", false);
|
||||
var depth =
|
||||
useSpriteDepth
|
||||
? element.GetAttributeFloat("spritedepth", 1.0f)
|
||||
: wireSprite.Depth;
|
||||
|
||||
var width = prefabWireComponentElement.GetAttributeFloat("width", 0.3f);
|
||||
|
||||
for (int i = 0; i < nodes.Length - 1; i++)
|
||||
{
|
||||
var line = (Start: nodes[i], End: nodes[i + 1]);
|
||||
var wireSegment = new Wire.WireSection(line.Start, line.End);
|
||||
wireSegment.Draw(spriteRecorder, wireSprite, color, Vector2.Zero, depth, width);
|
||||
}
|
||||
}
|
||||
|
||||
private void BakeMapEntity(XElement element)
|
||||
{
|
||||
Identifier identifier = element.GetAttributeIdentifier("identifier", Identifier.Empty);
|
||||
@@ -313,27 +371,27 @@ namespace Barotrauma
|
||||
|
||||
float rotation = element.GetAttributeFloat("rotation", 0f);
|
||||
|
||||
MapEntityPrefab prefab = null;
|
||||
if (element.Name.ToString().Equals("item", StringComparison.OrdinalIgnoreCase) &&
|
||||
ItemPrefab.Prefabs.TryGet(identifier, out ItemPrefab ip))
|
||||
MapEntityPrefab prefab;
|
||||
if (element.NameAsIdentifier() == "item"
|
||||
&& ItemPrefab.Prefabs.TryGet(identifier, out ItemPrefab ip))
|
||||
{
|
||||
prefab = ip;
|
||||
}
|
||||
else
|
||||
{
|
||||
prefab = MapEntityPrefab.List.FirstOrDefault(p => p.Identifier == identifier);
|
||||
prefab = MapEntityPrefab.FindByIdentifier(identifier);
|
||||
}
|
||||
if (prefab == null) { return; }
|
||||
|
||||
var texture = prefab.Sprite.Texture;
|
||||
var srcRect = prefab.Sprite.SourceRect;
|
||||
flippedX &= prefab.CanSpriteFlipX;
|
||||
flippedY &= prefab.CanSpriteFlipY;
|
||||
|
||||
SpriteEffects spriteEffects = SpriteEffects.None;
|
||||
if (flippedX && ((prefab as ItemPrefab)?.CanSpriteFlipX ?? true))
|
||||
if (flippedX)
|
||||
{
|
||||
spriteEffects |= SpriteEffects.FlipHorizontally;
|
||||
}
|
||||
if (flippedY && ((prefab as ItemPrefab)?.CanSpriteFlipY ?? true))
|
||||
if (flippedY)
|
||||
{
|
||||
spriteEffects |= SpriteEffects.FlipVertically;
|
||||
}
|
||||
@@ -419,8 +477,8 @@ namespace Barotrauma
|
||||
{
|
||||
float offsetState = 0f;
|
||||
Vector2 offset = decorativeSprite.GetOffset(ref offsetState, Vector2.Zero) * scale;
|
||||
if (flippedX && itemPrefab.CanSpriteFlipX) { offset.X = -offset.X; }
|
||||
if (flippedY && itemPrefab.CanSpriteFlipY) { offset.Y = -offset.Y; }
|
||||
if (flippedX) { offset.X = -offset.X; }
|
||||
if (flippedY) { offset.Y = -offset.Y; }
|
||||
decorativeSprite.Sprite.DrawTiled(spriteRecorder,
|
||||
new Vector2(spritePos.X + offset.X - rect.Width / 2, -(spritePos.Y + offset.Y + rect.Height / 2)),
|
||||
rect.Size.ToVector2(), color: color,
|
||||
@@ -451,8 +509,8 @@ namespace Barotrauma
|
||||
float rotationState = 0f; float offsetState = 0f;
|
||||
float rot = decorativeSprite.GetRotation(ref rotationState, 0f);
|
||||
Vector2 offset = decorativeSprite.GetOffset(ref offsetState, Vector2.Zero) * scale;
|
||||
if (flippedX && itemPrefab.CanSpriteFlipX) { offset.X = -offset.X; }
|
||||
if (flippedY && itemPrefab.CanSpriteFlipY) { offset.Y = -offset.Y; }
|
||||
if (flippedX) { offset.X = -offset.X; }
|
||||
if (flippedY) { offset.Y = -offset.Y; }
|
||||
decorativeSprite.Sprite.Draw(spriteRecorder, new Vector2(spritePos.X + offset.X, -(spritePos.Y + offset.Y)), color,
|
||||
MathHelper.ToRadians(rotation) + rot, decorativeSprite.GetScale(0f) * scale, prefab.Sprite.effects,
|
||||
depth: Math.Min(depth + (decorativeSprite.Sprite.Depth - prefab.Sprite.Depth), 0.999f));
|
||||
@@ -472,6 +530,7 @@ namespace Barotrauma
|
||||
{
|
||||
overrideSprite = false;
|
||||
|
||||
float relativeScale = scale / prefab.Scale;
|
||||
foreach (var subElement in prefab.ConfigElement.Elements())
|
||||
{
|
||||
switch (subElement.Name.LocalName.ToLowerInvariant())
|
||||
@@ -498,7 +557,6 @@ namespace Barotrauma
|
||||
relativeBarrelPos,
|
||||
MathHelper.ToRadians(rotation));
|
||||
|
||||
float relativeScale = scale / prefab.Scale;
|
||||
Vector2 drawPos = new Vector2(rect.X + rect.Width * relativeScale / 2 + transformedBarrelPos.X * relativeScale, rect.Y - rect.Height * relativeScale / 2 - transformedBarrelPos.Y * relativeScale);
|
||||
drawPos.Y = -drawPos.Y;
|
||||
|
||||
@@ -516,20 +574,22 @@ namespace Barotrauma
|
||||
|
||||
break;
|
||||
case "door":
|
||||
doors.Add(new Door(rect));
|
||||
var scaledRect = rect with { Size = (rect.Size.ToVector2() * relativeScale).ToPoint() };
|
||||
|
||||
doors.Add(new Door(scaledRect));
|
||||
|
||||
var doorSpriteElem = subElement.Elements().FirstOrDefault(e => e.Name.LocalName.Equals("sprite", StringComparison.OrdinalIgnoreCase));
|
||||
if (doorSpriteElem != null)
|
||||
{
|
||||
string texturePath = doorSpriteElem.GetAttributeString("texture", "");
|
||||
Vector2 pos = rect.Location.ToVector2() * new Vector2(1f, -1f);
|
||||
string texturePath = doorSpriteElem.GetAttributeStringUnrestricted("texture", "");
|
||||
Vector2 pos = scaledRect.Location.ToVector2() * new Vector2(1f, -1f);
|
||||
if (subElement.GetAttributeBool("horizontal", false))
|
||||
{
|
||||
pos.Y += (float)rect.Height * 0.5f;
|
||||
pos.Y += (float)scaledRect.Height * 0.5f;
|
||||
}
|
||||
else
|
||||
{
|
||||
pos.X += (float)rect.Width * 0.5f;
|
||||
pos.X += (float)scaledRect.Width * 0.5f;
|
||||
}
|
||||
Sprite doorSprite = new Sprite(doorSpriteElem, texturePath.Contains("/") ? "" : Path.GetDirectoryName(prefab.FilePath));
|
||||
spriteRecorder.Draw(doorSprite.Texture, pos,
|
||||
@@ -555,7 +615,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public void ParseUpgrades(XElement prefabConfigElement, ref float scale)
|
||||
private void ParseUpgrades(XElement prefabConfigElement, ref float scale)
|
||||
{
|
||||
foreach (var upgrade in prefabConfigElement.Elements("Upgrade"))
|
||||
{
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace Barotrauma
|
||||
{
|
||||
Color clr = CurrentHull == null ? Color.DodgerBlue : GUIStyle.Green;
|
||||
if (spawnType != SpawnType.Path) { clr = Color.Gray; }
|
||||
if (isObstructed)
|
||||
if (!IsTraversable)
|
||||
{
|
||||
clr = Color.Black;
|
||||
}
|
||||
@@ -84,7 +84,7 @@ namespace Barotrauma
|
||||
GUI.DrawLine(spriteBatch,
|
||||
drawPos,
|
||||
new Vector2(e.DrawPosition.X, -e.DrawPosition.Y),
|
||||
(isObstructed ? Color.Gray : GUIStyle.Green) * 0.7f, width: 5, depth: 0.002f);
|
||||
(IsTraversable ? GUIStyle.Green : Color.Gray) * 0.7f, width: 5, depth: 0.002f);
|
||||
}
|
||||
if (ConnectedGap != null)
|
||||
{
|
||||
@@ -175,9 +175,9 @@ namespace Barotrauma
|
||||
|
||||
if (PlayerInput.KeyDown(Keys.Space))
|
||||
{
|
||||
foreach (MapEntity e in mapEntityList)
|
||||
foreach (MapEntity e in HighlightedEntities)
|
||||
{
|
||||
if (!(e is WayPoint) || e == this || !e.IsHighlighted) { continue; }
|
||||
if (e is not WayPoint || e == this) { continue; }
|
||||
|
||||
if (linkedTo.Contains(e))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user