(bb8a4525e) Progress on LOS effect improvements. Hiding the unnecessary shadows at spots where the ends of two walls meet works now, still got to do something about corner areas where a vertical wall meets a horizontal one.

This commit is contained in:
Joonas Rikkonen
2019-04-01 22:53:27 +03:00
parent 98e0504e1f
commit 43578f3bb2
5 changed files with 234 additions and 118 deletions
@@ -656,13 +656,6 @@ namespace Barotrauma
msg.Timer -= deltaTime; msg.Timer -= deltaTime;
msg.Pos += msg.Velocity * deltaTime; msg.Pos += msg.Velocity * deltaTime;
} }
foreach (GUIMessage msg in messages)
{
if (!msg.WorldSpace) continue;
msg.Timer -= deltaTime;
msg.Pos += msg.Velocity * deltaTime;
}
} }
messages.RemoveAll(m => m.Timer <= 0.0f); messages.RemoveAll(m => m.Timer <= 0.0f);
@@ -1,4 +1,6 @@
using Microsoft.Xna.Framework; using Barotrauma.Extensions;
using Barotrauma.Items.Components;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -90,38 +92,21 @@ namespace Barotrauma.Lights
public static List<ConvexHullList> HullLists = new List<ConvexHullList>(); public static List<ConvexHullList> HullLists = new List<ConvexHullList>();
public static BasicEffect shadowEffect; public static BasicEffect shadowEffect;
public static BasicEffect penumbraEffect; public static BasicEffect penumbraEffect;
private Segment[] segments = new Segment[4];
private SegmentPoint[] vertices = new SegmentPoint[4];
private SegmentPoint[] losVertices = new SegmentPoint[4];
Segment[] segments = new Segment[4]; private readonly bool[] backFacing;
SegmentPoint[] vertices = new SegmentPoint[4]; private readonly bool[] ignoreEdge;
SegmentPoint[] losVertices = new SegmentPoint[4];
private bool[] backFacing;
private bool[] ignoreEdge;
private VertexPositionColor[] shadowVertices; private readonly bool isHorizontal;
private VertexPositionTexture[] penumbraVertices;
public VertexPositionColor[] ShadowVertices public VertexPositionColor[] ShadowVertices { get; private set; }
{ public VertexPositionTexture[] PenumbraVertices { get; private set; }
get { return shadowVertices; } public int ShadowVertexCount { get; private set; }
}
public VertexPositionTexture[] PenumbraVertices public MapEntity ParentEntity { get; private set; }
{
get { return penumbraVertices; }
}
public int shadowVertexCount;
private MapEntity parentEntity;
private Rectangle boundingBox;
public MapEntity ParentEntity
{
get { return parentEntity; }
}
private bool enabled; private bool enabled;
public bool Enabled public bool Enabled
@@ -147,17 +132,16 @@ namespace Barotrauma.Lights
private set; private set;
} }
public Rectangle BoundingBox public Rectangle BoundingBox { get; private set; }
{
get { return boundingBox; }
}
public ConvexHull(Vector2[] points, Color color, MapEntity parent) public ConvexHull(Vector2[] points, Color color, MapEntity parent)
{ {
if (shadowEffect == null) if (shadowEffect == null)
{ {
shadowEffect = new BasicEffect(GameMain.Instance.GraphicsDevice); shadowEffect = new BasicEffect(GameMain.Instance.GraphicsDevice)
shadowEffect.VertexColorEnabled = true; {
VertexColorEnabled = true
};
} }
if (penumbraEffect == null) if (penumbraEffect == null)
{ {
@@ -169,22 +153,29 @@ namespace Barotrauma.Lights
}; };
} }
parentEntity = parent; ParentEntity = parent;
//cachedShadows = new Dictionary<LightSource, CachedShadow>(); ShadowVertices = new VertexPositionColor[6 * 2];
PenumbraVertices = new VertexPositionTexture[6];
shadowVertices = new VertexPositionColor[6 * 2];
penumbraVertices = new VertexPositionTexture[6];
backFacing = new bool[4]; backFacing = new bool[4];
ignoreEdge = new bool[4]; ignoreEdge = new bool[4];
//vertices = points; SetVertices(points);
SetVertices(points);
//CalculateDimensions();
Enabled = true; Enabled = true;
isHorizontal = BoundingBox.Width > BoundingBox.Height;
if (ParentEntity is Structure structure)
{
isHorizontal = structure.IsHorizontal;
}
else if (ParentEntity is Item item)
{
var door = item.GetComponent<Door>();
if (door != null) { isHorizontal = door.IsHorizontal; }
}
var chList = HullLists.Find(x => x.Submarine == parent.Submarine); var chList = HullLists.Find(x => x.Submarine == parent.Submarine);
if (chList == null) if (chList == null)
{ {
@@ -204,40 +195,56 @@ namespace Barotrauma.Lights
private void MergeOverlappingSegments(ConvexHull ch) private void MergeOverlappingSegments(ConvexHull ch)
{ {
if (ch == this) return; if (ch == this) return;
//hide segments that are roughly at the some position as some other segment (e.g. the ends of two adjacent wall pieces) if (isHorizontal == ch.isHorizontal)
//TODO: prevent "gaps" between shadows when the segments are not exactly at the same position (see the hatches in Humpback for example)
/*float mergeDist = 16;
float mergeDistSqr = mergeDist * mergeDist;
for (int i = 0; i < segments.Length; i++)
{ {
for (int j = 0; j < ch.segments.Length; j++) //hide segments that are roughly at the some position as some other segment (e.g. the ends of two adjacent wall pieces)
float mergeDist = 32;
float mergeDistSqr = mergeDist * mergeDist;
for (int i = 0; i < segments.Length; i++)
{ {
if (Vector2.DistanceSquared(segments[i].Start.Pos, ch.segments[j].Start.Pos) < mergeDistSqr && for (int j = 0; j < ch.segments.Length; j++)
Vector2.DistanceSquared(segments[i].End.Pos, ch.segments[j].End.Pos) < mergeDistSqr)
{ {
ignoreEdge[i] = true; if (segments[i].IsHorizontal != ch.segments[j].IsHorizontal) { continue; }
ch.ignoreEdge[j] = true;
}
else if (Vector2.DistanceSquared(segments[i].Start.Pos, ch.segments[j].End.Pos) < mergeDistSqr &&
Vector2.DistanceSquared(segments[i].End.Pos, ch.segments[j].Start.Pos) < mergeDistSqr)
{
ignoreEdge[i] = true;
ch.ignoreEdge[j] = true;
}
}
}*/
//the segments must be at different sides of the convex hulls to be merged
//(e.g. the right edge of a wall piece and the left edge of another one)
var segment1Center = (segments[i].Start.Pos + segments[i].End.Pos) / 2.0f;
var segment2Center = (ch.segments[j].Start.Pos + ch.segments[j].End.Pos) / 2.0f;
if (Vector2.Dot(segment1Center - BoundingBox.Center.ToVector2(), segment2Center - ch.BoundingBox.Center.ToVector2()) > 0) { continue; }
if (Vector2.DistanceSquared(segments[i].Start.Pos, ch.segments[j].Start.Pos) < mergeDistSqr &&
Vector2.DistanceSquared(segments[i].End.Pos, ch.segments[j].End.Pos) < mergeDistSqr)
{
ignoreEdge[i] = true;
ch.ignoreEdge[j] = true;
MergeSegments(segments[i], ch.segments[j], true);
}
else if (Vector2.DistanceSquared(segments[i].Start.Pos, ch.segments[j].End.Pos) < mergeDistSqr &&
Vector2.DistanceSquared(segments[i].End.Pos, ch.segments[j].Start.Pos) < mergeDistSqr)
{
ignoreEdge[i] = true;
ch.ignoreEdge[j] = true;
MergeSegments(segments[i], ch.segments[j], false);
}
}
}
}
else
{
//TODO: do something to corner areas where a vertical wall meets a horizontal one
}
//ignore edges that are inside some other convex hull //ignore edges that are inside some other convex hull
for (int i = 0; i < vertices.Length; i++) for (int i = 0; i < vertices.Length; i++)
{ {
if (vertices[i].Pos.X >= ch.boundingBox.X && vertices[i].Pos.X <= ch.boundingBox.Right && if (vertices[i].Pos.X >= ch.BoundingBox.X && vertices[i].Pos.X <= ch.BoundingBox.Right &&
vertices[i].Pos.Y >= ch.boundingBox.Y && vertices[i].Pos.Y <= ch.boundingBox.Bottom) vertices[i].Pos.Y >= ch.BoundingBox.Y && vertices[i].Pos.Y <= ch.BoundingBox.Bottom)
{ {
Vector2 p = vertices[(i + 1) % vertices.Length].Pos; Vector2 p = vertices[(i + 1) % vertices.Length].Pos;
if (p.X >= ch.boundingBox.X && p.X <= ch.boundingBox.Right && if (p.X >= ch.BoundingBox.X && p.X <= ch.BoundingBox.Right &&
p.Y >= ch.boundingBox.Y && p.Y <= ch.boundingBox.Bottom) p.Y >= ch.BoundingBox.Y && p.Y <= ch.BoundingBox.Bottom)
{ {
ignoreEdge[i] = true; ignoreEdge[i] = true;
} }
@@ -245,6 +252,44 @@ namespace Barotrauma.Lights
} }
} }
private void MergeSegments(Segment segment1, Segment segment2, bool startPointsMatch)
{
int startPointIndex = -1, endPointIndex = -1;
for (int i = 0; i < vertices.Length; i++)
{
if (vertices[i].Pos.NearlyEquals(segment1.Start.Pos))
startPointIndex = i;
else if (vertices[i].Pos.NearlyEquals(segment1.End.Pos))
endPointIndex = i;
}
if (startPointIndex == -1 || endPointIndex == -1) { return; }
int startPoint2Index = -1, endPoint2Index = -1;
for (int i = 0; i < segment2.ConvexHull.vertices.Length; i++)
{
if (segment2.ConvexHull.vertices[i].Pos.NearlyEquals(segment2.Start.Pos))
startPoint2Index = i;
else if (segment2.ConvexHull.vertices[i].Pos.NearlyEquals(segment2.End.Pos))
endPoint2Index = i;
}
if (startPoint2Index == -1 || endPoint2Index == -1) { return; }
if (startPointsMatch)
{
losVertices[startPointIndex].Pos = segment2.ConvexHull.losVertices[startPoint2Index].Pos =
(segment1.Start.Pos + segment2.Start.Pos) / 2.0f;
losVertices[endPointIndex].Pos = segment2.ConvexHull.losVertices[endPoint2Index].Pos =
(segment1.End.Pos + segment2.End.Pos) / 2.0f;
}
else
{
losVertices[startPointIndex].Pos = segment2.ConvexHull.losVertices[startPoint2Index].Pos =
(segment1.Start.Pos + segment2.End.Pos) / 2.0f;
losVertices[endPointIndex].Pos = segment2.ConvexHull.losVertices[endPoint2Index].Pos =
(segment1.End.Pos + segment2.Start.Pos) / 2.0f;
}
}
public void Rotate(Vector2 origin, float amount) public void Rotate(Vector2 origin, float amount)
{ {
Matrix rotationMatrix = Matrix rotationMatrix =
@@ -267,7 +312,7 @@ namespace Barotrauma.Lights
if (vertices[i].Pos.Y > minY) maxY = vertices[i].Pos.Y; if (vertices[i].Pos.Y > minY) maxY = vertices[i].Pos.Y;
} }
boundingBox = new Rectangle((int)minX, (int)minY, (int)(maxX - minX), (int)(maxY - minY)); BoundingBox = new Rectangle((int)minX, (int)minY, (int)(maxX - minX), (int)(maxY - minY));
} }
public void Move(Vector2 amount) public void Move(Vector2 amount)
@@ -296,11 +341,6 @@ namespace Barotrauma.Lights
{ {
vertices[i] = new SegmentPoint(points[i], this); vertices[i] = new SegmentPoint(points[i], this);
losVertices[i] = new SegmentPoint(points[i], this); losVertices[i] = new SegmentPoint(points[i], this);
}
for (int i = 0; i < 4; i++)
{
segments[i] = new Segment(vertices[i], vertices[(i + 1) % 4], this);
} }
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
@@ -332,12 +372,16 @@ namespace Barotrauma.Lights
losVertices[i].Pos = Vector2.Transform(losVertices[i].Pos, rotationMatrix.Value); losVertices[i].Pos = Vector2.Transform(losVertices[i].Pos, rotationMatrix.Value);
} }
} }
for (int i = 0; i < 4; i++)
{
segments[i] = new Segment(vertices[i], vertices[(i + 1) % 4], this);
}
CalculateDimensions(); CalculateDimensions();
if (parentEntity == null) return; if (ParentEntity == null) return;
var chList = HullLists.Find(x => x.Submarine == parentEntity.Submarine); var chList = HullLists.Find(x => x.Submarine == ParentEntity.Submarine);
if (chList != null) if (chList != null)
{ {
foreach (ConvexHull ch in chList.List) foreach (ConvexHull ch in chList.List)
@@ -351,11 +395,11 @@ namespace Barotrauma.Lights
{ {
if (!Enabled) return false; if (!Enabled) return false;
Rectangle transformedBounds = boundingBox; Rectangle transformedBounds = BoundingBox;
if (parentEntity != null && parentEntity.Submarine != null) if (ParentEntity != null && ParentEntity.Submarine != null)
{ {
transformedBounds.X += (int)parentEntity.Submarine.Position.X; transformedBounds.X += (int)ParentEntity.Submarine.Position.X;
transformedBounds.Y += (int)parentEntity.Submarine.Position.Y; transformedBounds.Y += (int)ParentEntity.Submarine.Position.Y;
} }
return transformedBounds.Intersects(rect); return transformedBounds.Intersects(rect);
} }
@@ -396,24 +440,24 @@ namespace Barotrauma.Lights
segments[i].Start.WorldPos = segments[i].Start.Pos; segments[i].Start.WorldPos = segments[i].Start.Pos;
segments[i].End.WorldPos = segments[i].End.Pos; segments[i].End.WorldPos = segments[i].End.Pos;
} }
if (parentEntity == null || parentEntity.Submarine == null) { return; } if (ParentEntity == null || ParentEntity.Submarine == null) { return; }
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
{ {
vertices[i].WorldPos += parentEntity.Submarine.DrawPosition; vertices[i].WorldPos += ParentEntity.Submarine.DrawPosition;
segments[i].Start.WorldPos += parentEntity.Submarine.DrawPosition; segments[i].Start.WorldPos += ParentEntity.Submarine.DrawPosition;
segments[i].End.WorldPos += parentEntity.Submarine.DrawPosition; segments[i].End.WorldPos += ParentEntity.Submarine.DrawPosition;
} }
} }
public void CalculateShadowVertices(Vector2 lightSourcePos, bool los = true) public void CalculateShadowVertices(Vector2 lightSourcePos, bool los = true)
{ {
Vector3 offset = Vector3.Zero; Vector3 offset = Vector3.Zero;
if (parentEntity != null && parentEntity.Submarine != null) if (ParentEntity != null && ParentEntity.Submarine != null)
{ {
offset = new Vector3(parentEntity.Submarine.DrawPosition.X, parentEntity.Submarine.DrawPosition.Y, 0.0f); offset = new Vector3(ParentEntity.Submarine.DrawPosition.X, ParentEntity.Submarine.DrawPosition.Y, 0.0f);
} }
shadowVertexCount = 0; ShadowVertexCount = 0;
var vertices = los ? losVertices : this.vertices; var vertices = los ? losVertices : this.vertices;
@@ -456,16 +500,16 @@ namespace Barotrauma.Lights
//nr of vertices that are in the shadow //nr of vertices that are in the shadow
if (endingIndex > startingIndex) if (endingIndex > startingIndex)
shadowVertexCount = endingIndex - startingIndex + 1; ShadowVertexCount = endingIndex - startingIndex + 1;
else else
shadowVertexCount = 4 + 1 - startingIndex + endingIndex; ShadowVertexCount = 4 + 1 - startingIndex + endingIndex;
//shadowVertices = new VertexPositionColor[shadowVertexCount * 2]; //shadowVertices = new VertexPositionColor[shadowVertexCount * 2];
//create a triangle strip that has the shape of the shadow //create a triangle strip that has the shape of the shadow
int currentIndex = startingIndex; int currentIndex = startingIndex;
int svCount = 0; int svCount = 0;
while (svCount != shadowVertexCount * 2) while (svCount != ShadowVertexCount * 2)
{ {
Vector3 vertexPos = new Vector3(vertices[currentIndex].Pos, 0.0f); Vector3 vertexPos = new Vector3(vertices[currentIndex].Pos, 0.0f);
@@ -473,18 +517,22 @@ namespace Barotrauma.Lights
int j = los ? svCount + 1 : svCount; int j = los ? svCount + 1 : svCount;
//one vertex on the hull //one vertex on the hull
shadowVertices[i] = new VertexPositionColor(); ShadowVertices[i] = new VertexPositionColor
shadowVertices[i].Color = los ? Color.Black : Color.Transparent; {
shadowVertices[i].Position = vertexPos+ offset; Color = los ? Color.Black : Color.Transparent,
Position = vertexPos + offset
};
//one extruded by the light direction //one extruded by the light direction
shadowVertices[j] = new VertexPositionColor(); ShadowVertices[j] = new VertexPositionColor
shadowVertices[j].Color = shadowVertices[i].Color; {
Color = ShadowVertices[i].Color
};
Vector3 L2P = vertexPos - new Vector3(lightSourcePos, 0); Vector3 L2P = vertexPos - new Vector3(lightSourcePos, 0);
L2P.Normalize(); L2P.Normalize();
shadowVertices[j].Position = new Vector3(lightSourcePos, 0) + L2P * 9000 + offset; ShadowVertices[j].Position = new Vector3(lightSourcePos, 0) + L2P * 9000 + offset;
svCount += 2; svCount += 2;
currentIndex = (currentIndex + 1) % 4; currentIndex = (currentIndex + 1) % 4;
@@ -501,23 +549,24 @@ namespace Barotrauma.Lights
var vertices = los ? losVertices : this.vertices; var vertices = los ? losVertices : this.vertices;
Vector3 offset = Vector3.Zero; Vector3 offset = Vector3.Zero;
if (parentEntity != null && parentEntity.Submarine != null) if (ParentEntity != null && ParentEntity.Submarine != null)
{ {
offset = new Vector3(parentEntity.Submarine.DrawPosition.X, parentEntity.Submarine.DrawPosition.Y, 0.0f); offset = new Vector3(ParentEntity.Submarine.DrawPosition.X, ParentEntity.Submarine.DrawPosition.Y, 0.0f);
} }
for (int n = 0; n < 4; n += 3) for (int n = 0; n < 4; n += 3)
{ {
Vector3 penumbraStart = new Vector3((n == 0) ? vertices[startingIndex].Pos : vertices[endingIndex].Pos, 0.0f); Vector3 penumbraStart = new Vector3((n == 0) ? vertices[startingIndex].Pos : vertices[endingIndex].Pos, 0.0f);
penumbraVertices[n] = new VertexPositionTexture(); PenumbraVertices[n] = new VertexPositionTexture
penumbraVertices[n].Position = penumbraStart + offset; {
penumbraVertices[n].TextureCoordinate = new Vector2(0.0f, 1.0f); Position = penumbraStart + offset,
//penumbraVertices[0].te = fow ? Color.Black : Color.Transparent; TextureCoordinate = new Vector2(0.0f, 1.0f)
};
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
{ {
penumbraVertices[n + i + 1] = new VertexPositionTexture(); PenumbraVertices[n + i + 1] = new VertexPositionTexture();
Vector3 vertexDir = penumbraStart - new Vector3(lightSourcePos, 0); Vector3 vertexDir = penumbraStart - new Vector3(lightSourcePos, 0);
vertexDir.Normalize(); vertexDir.Normalize();
@@ -526,23 +575,23 @@ namespace Barotrauma.Lights
vertexDir = penumbraStart - (new Vector3(lightSourcePos, 0) - normal * 20.0f); vertexDir = penumbraStart - (new Vector3(lightSourcePos, 0) - normal * 20.0f);
vertexDir.Normalize(); vertexDir.Normalize();
penumbraVertices[n + i + 1].Position = new Vector3(lightSourcePos, 0) + vertexDir * 9000 + offset; PenumbraVertices[n + i + 1].Position = new Vector3(lightSourcePos, 0) + vertexDir * 9000 + offset;
if (los) if (los)
{ {
penumbraVertices[n + i + 1].TextureCoordinate = (i == 0) ? new Vector2(0.05f, 0.0f) : new Vector2(1.0f, 0.0f); PenumbraVertices[n + i + 1].TextureCoordinate = (i == 0) ? new Vector2(0.05f, 0.0f) : new Vector2(1.0f, 0.0f);
} }
else else
{ {
penumbraVertices[n + i + 1].TextureCoordinate = (i == 0) ? new Vector2(1.0f, 0.0f) : Vector2.Zero; PenumbraVertices[n + i + 1].TextureCoordinate = (i == 0) ? new Vector2(1.0f, 0.0f) : Vector2.Zero;
} }
} }
if (n > 0) if (n > 0)
{ {
var temp = penumbraVertices[4]; var temp = PenumbraVertices[4];
penumbraVertices[4] = penumbraVertices[5]; PenumbraVertices[4] = PenumbraVertices[5];
penumbraVertices[5] = temp; PenumbraVertices[5] = temp;
} }
} }
} }
@@ -614,7 +663,7 @@ namespace Barotrauma.Lights
public void Remove() public void Remove()
{ {
var chList = HullLists.Find(x => x.Submarine == parentEntity.Submarine); var chList = HullLists.Find(x => x.Submarine == ParentEntity.Submarine);
if (chList != null) if (chList != null)
{ {
@@ -583,7 +583,7 @@ namespace Barotrauma.Lights
convexHull.CalculateShadowVertices(relativeLightPos, true); convexHull.CalculateShadowVertices(relativeLightPos, true);
//convert triangle strips to a triangle list //convert triangle strips to a triangle list
for (int i = 0; i < convexHull.shadowVertexCount * 2 - 2; i++) for (int i = 0; i < convexHull.ShadowVertexCount * 2 - 2; i++)
{ {
if (i % 2 == 0) if (i % 2 == 0)
{ {
@@ -1216,6 +1216,43 @@ namespace Barotrauma
targetingTag = "room"; targetingTag = "room";
} }
if (door != null) if (door != null)
{
// If there's not a more specific tag for the door
if (string.IsNullOrEmpty(targetingTag) || targetingTag == "room")
{
targetingTag = "door";
}
bool isOutdoor = door.LinkedGap?.FlowTargetHull != null && !door.LinkedGap.IsRoomToRoom;
bool isOpen = door.IsOpen || door.Item.Condition <= 0.0f;
//increase priority if the character is outside and an aggressive boarder, and the door is from outside to inside
if (aggressiveBoarding)
{
if (character.CurrentHull == null)
{
valueModifier = isOutdoor ? 1 : 0;
valueModifier *= isOpen ? 5 : 1;
}
}
else
{
// Ignore disabled walls
bool isDisabled = true;
for (int i = 0; i < s.Sections.Length; i++)
{
valueModifier = isOutdoor ? 0 : 1;
valueModifier *= isOpen ? 0 : 1;
}
if (isDisabled)
{
valueModifier = 0;
}
}
}
else
{
targetingTag = "room";
}
if (door != null)
{ {
// If there's not a more specific tag for the door // If there's not a more specific tag for the door
if (string.IsNullOrEmpty(targetingTag) || targetingTag == "room") if (string.IsNullOrEmpty(targetingTag) || targetingTag == "room")
@@ -1242,6 +1279,10 @@ namespace Barotrauma
{ {
continue; continue;
} }
else if (isOpen) //ignore broken and open doors
{
continue;
}
} }
else if (target.Entity is IDamageable targetDamageable && targetDamageable.Health <= 0.0f) else if (target.Entity is IDamageable targetDamageable && targetDamageable.Health <= 0.0f)
{ {
@@ -1532,6 +1532,39 @@ namespace Barotrauma
AllowedLinks = element.GetAttributeStringArray("allowedlinks", new string[0], convertToLowerInvariant: true).ToList(); AllowedLinks = element.GetAttributeStringArray("allowedlinks", new string[0], convertToLowerInvariant: true).ToList();
if (sprite == null)
{
DebugConsole.ThrowError("Item \"" + Name + "\" has no sprite!");
#if SERVER
sprite = new Sprite("", Vector2.Zero);
sprite.SourceRect = new Rectangle(0, 0, 32, 32);
#else
sprite = new Sprite(TextureLoader.PlaceHolderTexture, null, null)
{
Origin = TextureLoader.PlaceHolderTexture.Bounds.Size.ToVector2() / 2
};
#endif
size = sprite.size;
sprite.EntityID = identifier;
}
if (!category.HasFlag(MapEntityCategory.Legacy) && string.IsNullOrEmpty(identifier))
{
DebugConsole.ThrowError(
"Item prefab \"" + name + "\" has no identifier. All item prefabs have a unique identifier string that's used to differentiate between items during saving and loading.");
}
if (!string.IsNullOrEmpty(identifier))
{
MapEntityPrefab existingPrefab = List.Find(e => e.Identifier == identifier);
if (existingPrefab != null)
{
DebugConsole.ThrowError(
"Map entity prefabs \"" + name + "\" and \"" + existingPrefab.Name + "\" have the same identifier!");
}
}
AllowedLinks = element.GetAttributeStringArray("allowedlinks", new string[0], convertToLowerInvariant: true).ToList();
List.Add(this); List.Add(this);
} }