1 using Microsoft.Xna.Framework;
8 using Microsoft.Xna.Framework.Graphics;
21 private Rectangle sourceRect;
36 public Vector2
size = Vector2.One;
41 public SpriteEffects effects = SpriteEffects.None;
48 get {
return sourceRect; }
49 set { sourceRect = value; }
55 set {
depth = MathHelper.Clamp(value, 0.001f, 0.999f); }
67 _relativeOrigin =
new Vector2(
origin.X / sourceRect.Width,
origin.Y / sourceRect.Height);
71 private Vector2 _relativeOrigin;
77 get => _relativeOrigin;
80 _relativeOrigin = value;
81 origin =
new Vector2(_relativeOrigin.X * sourceRect.Width, _relativeOrigin.Y * sourceRect.Height);
102 public string Name {
get;
set; }
104 partial
void LoadTexture(ref Vector4 sourceVector, ref
bool shouldReturn);
106 partial
void CalculateSourceRect();
108 static partial
void AddToList(
Sprite sprite);
110 public Sprite(
ContentXElement element,
string path =
"",
string file =
"",
bool lazyLoad =
false,
float sourceRectScale = 1)
114 DebugConsole.ThrowError($
"Sprite: xml element null in {file}. Failed to create the sprite!");
122 var overrideElement = GetLocalizationOverrideElement();
123 if (overrideElement !=
null && overrideElement.Attribute(
"sourcerect") !=
null)
125 sourceVector = overrideElement.GetAttributeVector4(
"sourcerect", Vector4.Zero);
127 if ((overrideElement ??
SourceElement).Attribute(
"sheetindex") !=
null)
129 Point sheetElementSize = (overrideElement ??
SourceElement).GetAttributePoint(
"sheetelementsize", Point.Zero);
130 Point sheetIndex = (overrideElement ??
SourceElement).GetAttributePoint(
"sheetindex", Point.Zero);
131 sourceVector =
new Vector4(sheetIndex.X * sheetElementSize.X, sheetIndex.Y * sheetElementSize.Y, sheetElementSize.X, sheetElementSize.Y);
134 bool shouldReturn =
false;
137 LoadTexture(ref sourceVector, ref shouldReturn);
139 if (shouldReturn) {
return; }
140 sourceRect =
new Rectangle((
int)(sourceVector.X * sourceRectScale), (
int)(sourceVector.Y * sourceRectScale), (
int)(sourceVector.Z * sourceRectScale), (
int)(sourceVector.W * sourceRectScale));
143 size.X *= sourceRect.Width;
144 size.Y *= sourceRect.Height;
152 internal void LoadParams(SpriteParams spriteParams,
bool isFlipped)
155 sourceRect = spriteParams.SourceRect;
161 depth = spriteParams.Depth;
164 public Sprite(
string newFile, Vector2 newOrigin)
166 Init(newFile, newOrigin: newOrigin);
172 Init(newFile, sourceRectangle: sourceRectangle, newOrigin:
origin, newRotation:
rotation);
176 private void Init(
string newFile, Rectangle? sourceRectangle =
null, Vector2? newOrigin =
null, Vector2? newOffset =
null,
float newRotation = 0)
179 Vector4 sourceVector = Vector4.Zero;
180 bool shouldReturn =
false;
181 LoadTexture(ref sourceVector, ref shouldReturn);
182 if (shouldReturn)
return;
183 if (sourceRectangle.HasValue)
185 sourceRect = sourceRectangle.Value;
189 CalculateSourceRect();
191 offset = newOffset ?? Vector2.Zero;
192 if (newOrigin.HasValue)
196 size =
new Vector2(sourceRect.Width, sourceRect.Height);
207 if (sourceElement ==
null) {
return "".ToIdentifier(); }
208 var parentElement = sourceElement.Parent;
209 return $
"{sourceElement}{parentElement?.ToString() ?? ""}".ToIdentifier();
212 static partial
void RemoveFromList(
Sprite sprite);
216 RemoveFromList(
this);
225 partial
void DisposeTexture();
234 if (
string.IsNullOrWhiteSpace(path))
236 DebugConsole.NewMessage($
"[Sprite] Could not parse the content path from the source element ({SourceElement}) uri: {SourceElement.BaseUri}", Color.Yellow);
239 var doc = XMLExtensions.TryLoadXml(path);
240 if (doc ==
null) {
return; }
241 if (
string.IsNullOrWhiteSpace(
Name) &&
string.IsNullOrWhiteSpace(
EntityIdentifier.Value)) {
return; }
242 var spriteElements = doc.Descendants(
"sprite").Concat(doc.Descendants(
"Sprite"));
243 var sourceElements = spriteElements.Where(e => e.GetAttributeString(
"name",
null) ==
Name);
244 if (sourceElements.None())
247 sourceElements = spriteElements.Where(e => e.Parent?.GetAttributeString(
"identifier",
null) ==
EntityIdentifier);
248 if (sourceElements.None())
250 sourceElements = spriteElements.Where(e => e.Parent?.GetAttributeString(
"name",
null) ==
Name);
253 if (sourceElements.Multiple())
255 DebugConsole.NewMessage($
"[Sprite] Multiple matching elements found by name ({Name}) or identifier ({EntityIdentifier})!: {SourceElement}", Color.Yellow);
257 else if (sourceElements.None())
259 DebugConsole.NewMessage($
"[Sprite] Cannot find matching source element by comparing the name attribute ({Name}) or identifier ({EntityIdentifier})! Cannot reload the xml for sprite element \"{SourceElement.ToString()}\"!", Color.Yellow);
268 var overrideElement = GetLocalizationOverrideElement();
269 if (overrideElement !=
null && overrideElement.Attribute(
"sourcerect") !=
null)
271 sourceRect = overrideElement.GetAttributeRect(
"sourcerect", Rectangle.Empty);
273 if ((overrideElement ??
SourceElement).Attribute(
"sheetindex") !=
null)
275 Point sheetElementSize = (overrideElement ??
SourceElement).GetAttributePoint(
"sheetelementsize", Point.Zero);
276 Point sheetIndex = (overrideElement ??
SourceElement).GetAttributePoint(
"sheetindex", Point.Zero);
277 sourceRect =
new Rectangle(sheetIndex.X * sheetElementSize.X, sheetIndex.Y * sheetElementSize.Y, sheetElementSize.X, sheetElementSize.Y);
280 size.X *= sourceRect.Width;
281 size.Y *= sourceRect.Height;
296 var overrideElement = GetLocalizationOverrideElement();
297 if (overrideElement !=
null)
299 string overrideFile = overrideElement.GetAttributeStringUnrestricted(
"texture",
"");
300 if (!
string.IsNullOrEmpty(overrideFile)) { file = overrideFile; }
305 DebugConsole.ThrowError(
"Sprite " +
SourceElement.
Element +
" doesn't have a texture specified!",
309 if (!
string.IsNullOrEmpty(path))
311 if (!path.EndsWith(
"/")) path +=
"/";
317 private XElement GetLocalizationOverrideElement()
321 if (subElement.Name.ToString().Equals(
"override", StringComparison.OrdinalIgnoreCase))
323 LanguageIdentifier language = subElement.GetAttributeIdentifier(
"language",
"").ToLanguageIdentifier();
324 if (GameSettings.CurrentConfig.Language == language)
static ContentPath FromRaw(string? rawValue)
string? GetAttributeString(string key, string? def)
Vector4 GetAttributeVector4(string key, in Vector4 def)
float GetAttributeFloat(string key, float def)
ContentPackage? ContentPackage
string GetAttributeStringUnrestricted(string key, string def)
IEnumerable< ContentXElement > Elements()
string ParseContentPathFromUri()
readonly XElement Element
Vector2 GetAttributeVector2(string key, in Vector2 def)
bool GetAttributeBool(string key, bool def)
Rectangle GetAttributeRect(string key, in Rectangle def)
Vector2 RelativeOrigin
0 - 1
Sprite(string newFile, Rectangle? sourceRectangle, Vector2? origin=null, float rotation=0)
static Identifier GetIdentifier(XElement sourceElement)
Creates a supposedly unique identifier from the parent element. If the parent element is not found,...
Identifier EntityIdentifier
Identifier of the Map Entity so that we can link the sprite to its owner.
bool ParseTexturePath(string path="", string file="")
Sprite(string newFile, Vector2 newOrigin)
override string ToString()
Sprite(ContentXElement element, string path="", string file="", bool lazyLoad=false, float sourceRectScale=1)
ContentXElement SourceElement
Reference to the xml element from where the sprite was created. Can be null if the sprite was not def...
void ReloadXML()
Works only if there is a name attribute defined for the sprite. For items and structures,...