Release 1.11.4.1 (Winter Update)
This commit is contained in:
@@ -230,7 +230,12 @@ namespace Barotrauma
|
||||
if (!primaryMouseButtonHeld && !secondaryMouseButtonHeld && !doubleClicked && !secondaryDoubleClicked) { return; }
|
||||
|
||||
Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition);
|
||||
Hull hull = FindHull(position);
|
||||
Hull hull =
|
||||
Screen.Selected is { IsEditor: true } ?
|
||||
//use the unoptimized version in the editor to make sure newly placed hulls are found
|
||||
//(FindHull uses the "EntityGrid" which is generated after loading the sub)
|
||||
FindHullUnoptimized(position) :
|
||||
FindHull(position);
|
||||
|
||||
if (hull == null || hull.IdFreed) { return; }
|
||||
if (EditWater)
|
||||
@@ -361,7 +366,7 @@ namespace Barotrauma
|
||||
new Rectangle(drawRect.X, -drawRect.Y, rect.Width, rect.Height),
|
||||
GUIStyle.Red * ((100.0f - OxygenPercentage) / 400.0f) * alpha, true, 0, (int)Math.Max(MathF.Ceiling(1.5f / Screen.Selected.Cam.Zoom), 1.0f));
|
||||
|
||||
if (GameMain.DebugDraw)
|
||||
if (GameMain.DebugDraw && Screen.Selected?.Cam is { Zoom: > 0.5f })
|
||||
{
|
||||
GUIStyle.SmallFont.DrawString(spriteBatch, "Pressure: " + ((int)pressure - rect.Y).ToString() +
|
||||
" - Oxygen: " + ((int)OxygenPercentage), new Vector2(drawRect.X + 5, -drawRect.Y + 5), Color.White);
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
namespace Barotrauma;
|
||||
|
||||
internal partial class LevelGenerationParams : PrefabWithUintIdentifier
|
||||
{
|
||||
/// <remarks>Doesn't call SpriteBatch.Begin and SpriteBatch.End; They must be called manually.</remarks>
|
||||
public void DrawBackgrounds(SpriteBatch spriteBatch, Camera cam)
|
||||
{
|
||||
if (BackgroundTopSprite == null) { return; }
|
||||
|
||||
Vector2 backgroundPos = cam.WorldViewCenter.FlipY() * 0.05f;
|
||||
int backgroundSize = (int)BackgroundTopSprite.size.Y;
|
||||
if (backgroundPos.Y >= backgroundSize) { return; }
|
||||
|
||||
if (backgroundPos.Y < 0f)
|
||||
{
|
||||
BackgroundTopSprite.SourceRect = new Rectangle((int)backgroundPos.X, (int)backgroundPos.Y, backgroundSize, (int)Math.Min(-backgroundPos.Y, backgroundSize));
|
||||
BackgroundTopSprite.DrawTiled(spriteBatch, Vector2.Zero, new Vector2(GameMain.GraphicsWidth, Math.Min(-backgroundPos.Y, GameMain.GraphicsHeight)),
|
||||
color: BackgroundTextureColor);
|
||||
}
|
||||
if (-backgroundPos.Y < GameMain.GraphicsHeight && BackgroundSprite != null)
|
||||
{
|
||||
BackgroundSprite.SourceRect = new Rectangle((int)backgroundPos.X, (int)Math.Max(backgroundPos.Y, 0), backgroundSize, backgroundSize);
|
||||
BackgroundSprite.DrawTiled(spriteBatch, (backgroundPos.Y < 0f) ? new Vector2(0f, (int)-backgroundPos.Y) : Vector2.Zero,
|
||||
new Vector2(GameMain.GraphicsWidth, (int)Math.Min(Math.Ceiling(backgroundSize - backgroundPos.Y), backgroundSize)),
|
||||
color: BackgroundTextureColor);
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks>Doesn't call SpriteBatch.Begin and SpriteBatch.End; They must be called manually.</remarks>
|
||||
public void DrawWaterParticles(SpriteBatch spriteBatch, Camera cam, Vector2 offset)
|
||||
{
|
||||
if (WaterParticles == null || cam.Zoom <= 0.05f) { return; }
|
||||
|
||||
float textureScale = WaterParticleScale;
|
||||
Vector2 textureSize = new Vector2(WaterParticles.Texture.Width, WaterParticles.Texture.Height);
|
||||
Vector2 origin = new Vector2(cam.WorldView.X, -cam.WorldView.Y);
|
||||
offset -= origin;
|
||||
|
||||
// Draw 4 layers of particles.
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
float scale = 1f - i * 0.2f;
|
||||
float alpha = MathUtils.InverseLerp(0.05f, 0.1f, cam.Zoom * scale);
|
||||
if (alpha == 0f) { continue; }
|
||||
|
||||
Vector2 newOffset = offset * scale;
|
||||
newOffset += cam.WorldView.Size.ToVector2() * (1f - scale) * 0.5f;
|
||||
newOffset -= new Vector2(256f * i);
|
||||
|
||||
float newTextureScale = scale * textureScale;
|
||||
|
||||
Vector2 newSize = textureSize * scale;
|
||||
while (newOffset.X <= -newSize.X) { newOffset.X += newSize.X; }
|
||||
while (newOffset.X > 0f) { newOffset.X -= newSize.X; }
|
||||
while (newOffset.Y <= -newSize.Y) { newOffset.Y += newSize.Y; }
|
||||
while (newOffset.Y > 0f) { newOffset.Y -= newSize.Y; }
|
||||
|
||||
WaterParticles.DrawTiled(spriteBatch, origin + newOffset, cam.WorldView.Size.ToVector2() - newOffset,
|
||||
color: WaterParticleColor * alpha, textureScale: new Vector2(newTextureScale));
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateWaterParticleOffset(ref Vector2 offset, Vector2 velocity, float deltaTime)
|
||||
{
|
||||
if (WaterParticles == null) { return; }
|
||||
Vector2 waterTextureSize = WaterParticles.size * WaterParticleScale;
|
||||
offset += velocity.FlipY() * WaterParticleScale * deltaTime;
|
||||
offset.X %= waterTextureSize.X;
|
||||
offset.Y %= waterTextureSize.Y;
|
||||
}
|
||||
}
|
||||
@@ -234,15 +234,7 @@ namespace Barotrauma
|
||||
|
||||
WaterRenderer.Instance?.ScrollWater(waterParticleVelocity, deltaTime);
|
||||
|
||||
if (level.GenerationParams.WaterParticles != null)
|
||||
{
|
||||
Vector2 waterTextureSize = level.GenerationParams.WaterParticles.size * level.GenerationParams.WaterParticleScale;
|
||||
waterParticleOffset += new Vector2(waterParticleVelocity.X, -waterParticleVelocity.Y) * level.GenerationParams.WaterParticleScale * deltaTime;
|
||||
while (waterParticleOffset.X <= -waterTextureSize.X) { waterParticleOffset.X += waterTextureSize.X; }
|
||||
while (waterParticleOffset.X >= waterTextureSize.X){ waterParticleOffset.X -= waterTextureSize.X; }
|
||||
while (waterParticleOffset.Y <= -waterTextureSize.Y) { waterParticleOffset.Y += waterTextureSize.Y; }
|
||||
while (waterParticleOffset.Y >= waterTextureSize.Y) { waterParticleOffset.Y -= waterTextureSize.Y; }
|
||||
}
|
||||
level.GenerationParams.UpdateWaterParticleOffset(ref waterParticleOffset, waterParticleVelocity, deltaTime);
|
||||
}
|
||||
|
||||
public static VertexPositionColorTexture[] GetColoredVertices(VertexPositionTexture[] vertices, Color color)
|
||||
@@ -274,36 +266,7 @@ namespace Barotrauma
|
||||
ParticleManager particleManager = null)
|
||||
{
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, SamplerState.LinearWrap);
|
||||
|
||||
Vector2 backgroundPos = cam.WorldViewCenter;
|
||||
|
||||
backgroundPos.Y = -backgroundPos.Y;
|
||||
backgroundPos *= 0.05f;
|
||||
|
||||
if (level.GenerationParams.BackgroundTopSprite != null)
|
||||
{
|
||||
int backgroundSize = (int)level.GenerationParams.BackgroundTopSprite.size.Y;
|
||||
if (backgroundPos.Y < backgroundSize)
|
||||
{
|
||||
if (backgroundPos.Y < 0)
|
||||
{
|
||||
var backgroundTop = level.GenerationParams.BackgroundTopSprite;
|
||||
backgroundTop.SourceRect = new Rectangle((int)backgroundPos.X, (int)backgroundPos.Y, backgroundSize, (int)Math.Min(-backgroundPos.Y, backgroundSize));
|
||||
backgroundTop.DrawTiled(spriteBatch, Vector2.Zero, new Vector2(GameMain.GraphicsWidth, Math.Min(-backgroundPos.Y, GameMain.GraphicsHeight)),
|
||||
color: level.BackgroundTextureColor);
|
||||
}
|
||||
if (-backgroundPos.Y < GameMain.GraphicsHeight && level.GenerationParams.BackgroundSprite != null)
|
||||
{
|
||||
var background = level.GenerationParams.BackgroundSprite;
|
||||
background.SourceRect = new Rectangle((int)backgroundPos.X, (int)Math.Max(backgroundPos.Y, 0), backgroundSize, backgroundSize);
|
||||
background.DrawTiled(spriteBatch,
|
||||
(backgroundPos.Y < 0) ? new Vector2(0.0f, (int)-backgroundPos.Y) : Vector2.Zero,
|
||||
new Vector2(GameMain.GraphicsWidth, (int)Math.Min(Math.Ceiling(backgroundSize - backgroundPos.Y), backgroundSize)),
|
||||
color: level.BackgroundTextureColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
level.GenerationParams.DrawBackgrounds(spriteBatch, cam);
|
||||
spriteBatch.End();
|
||||
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred,
|
||||
@@ -317,42 +280,7 @@ namespace Barotrauma
|
||||
backgroundCreatureManager?.Draw(spriteBatch, cam);
|
||||
}
|
||||
|
||||
if (level.GenerationParams.WaterParticles != null && cam.Zoom > 0.05f)
|
||||
{
|
||||
float textureScale = level.GenerationParams.WaterParticleScale;
|
||||
|
||||
Rectangle srcRect = new Rectangle(0, 0, 2048, 2048);
|
||||
Vector2 origin = new Vector2(cam.WorldView.X, -cam.WorldView.Y);
|
||||
Vector2 offset = -origin + waterParticleOffset;
|
||||
while (offset.X <= -srcRect.Width * textureScale) offset.X += srcRect.Width * textureScale;
|
||||
while (offset.X > 0.0f) offset.X -= srcRect.Width * textureScale;
|
||||
while (offset.Y <= -srcRect.Height * textureScale) offset.Y += srcRect.Height * textureScale;
|
||||
while (offset.Y > 0.0f) offset.Y -= srcRect.Height * textureScale;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
float scale = (1.0f - i * 0.2f);
|
||||
|
||||
//alpha goes from 1.0 to 0.0 when scale is in the range of 0.1 - 0.05
|
||||
float alpha = (cam.Zoom * scale) < 0.1f ? (cam.Zoom * scale - 0.05f) * 20.0f : 1.0f;
|
||||
if (alpha <= 0.0f) continue;
|
||||
|
||||
Vector2 offsetS = offset * scale
|
||||
+ new Vector2(cam.WorldView.Width, cam.WorldView.Height) * (1.0f - scale) * 0.5f
|
||||
- new Vector2(256.0f * i);
|
||||
|
||||
float texScale = scale * textureScale;
|
||||
|
||||
while (offsetS.X <= -srcRect.Width * texScale) offsetS.X += srcRect.Width * texScale;
|
||||
while (offsetS.X > 0.0f) offsetS.X -= srcRect.Width * texScale;
|
||||
while (offsetS.Y <= -srcRect.Height * texScale) offsetS.Y += srcRect.Height * texScale;
|
||||
while (offsetS.Y > 0.0f) offsetS.Y -= srcRect.Height * texScale;
|
||||
|
||||
level.GenerationParams.WaterParticles.DrawTiled(
|
||||
spriteBatch, origin + offsetS,
|
||||
new Vector2(cam.WorldView.Width - offsetS.X, cam.WorldView.Height - offsetS.Y),
|
||||
color: level.GenerationParams.WaterParticleColor * alpha, textureScale: new Vector2(texScale));
|
||||
}
|
||||
}
|
||||
level.GenerationParams.DrawWaterParticles(spriteBatch, cam, waterParticleOffset);
|
||||
|
||||
GameMain.ParticleManager?.Draw(spriteBatch, inWater: true, inSub: false, ParticleBlendState.AlphaBlend, background: true);
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace Barotrauma.Lights
|
||||
}
|
||||
|
||||
private float pulseAmount;
|
||||
[Editable(MinValueFloat = 0.0f, MaxValueFloat = 1.0f, DecimalCount = 2), Serialize(0.0f, IsPropertySaveable.Yes, description: "How much light pulsates (in Hz). 0 = not at all, 1 = alternates between full brightness and off.")]
|
||||
[Editable(MinValueFloat = 0.0f, MaxValueFloat = 1.0f, DecimalCount = 2), Serialize(0.0f, IsPropertySaveable.Yes, description: "How much light pulsates. 0 = not at all, 1 = alternates between full brightness and off.")]
|
||||
public float PulseAmount
|
||||
{
|
||||
get { return pulseAmount; }
|
||||
|
||||
@@ -397,7 +397,7 @@ namespace Barotrauma
|
||||
}
|
||||
if (!description.IsNullOrEmpty())
|
||||
{
|
||||
CreateTextWithIcon(description, locationTypeToDisplay.Sprite);
|
||||
CreateTextWithIcon(description, iconSprite: locationTypeToDisplay.Sprite);
|
||||
}
|
||||
|
||||
int highestSubTier = location.HighestSubmarineTierAvailable();
|
||||
@@ -417,32 +417,29 @@ namespace Barotrauma
|
||||
}
|
||||
if (highestSubTier > 0)
|
||||
{
|
||||
CreateTextWithIcon(TextManager.GetWithVariable("advancedsub.all", "[tiernumber]", highestSubTier.ToString()), icon: null, style: "LocationOverlaySubmarineIcon");
|
||||
CreateTextWithIcon(TextManager.GetWithVariable("advancedsub.all", "[tiernumber]", highestSubTier.ToString()), iconStyle: "LocationOverlaySubmarineIcon");
|
||||
}
|
||||
if (overrideTiers != null)
|
||||
{
|
||||
foreach (var (subClass, tier) in overrideTiers)
|
||||
{
|
||||
CreateTextWithIcon(TextManager.GetWithVariable($"advancedsub.{subClass}", "[tiernumber]", tier.ToString()), icon: null, style: "LocationOverlaySubmarineIcon");
|
||||
CreateTextWithIcon(TextManager.GetWithVariable($"advancedsub.{subClass}", "[tiernumber]", tier.ToString()), iconStyle: "LocationOverlaySubmarineIcon");
|
||||
}
|
||||
}
|
||||
|
||||
CreateSpacing(10);
|
||||
|
||||
void CreateTextWithIcon(LocalizedString text, Sprite icon, string style = null)
|
||||
void CreateTextWithIcon(LocalizedString text, Sprite iconSprite = null, string iconStyle = null)
|
||||
{
|
||||
var textHolder = new GUILayoutGroup(new RectTransform(new Point(content.Rect.Width, (int)GUIStyle.Font.MeasureString(text).Y), content.RectTransform), isHorizontal: true)
|
||||
{
|
||||
Stretch = true,
|
||||
CanBeFocused = true
|
||||
};
|
||||
var guiIcon =
|
||||
style == null ?
|
||||
new GUIImage(new RectTransform(Vector2.One * 1.25f, textHolder.RectTransform, scaleBasis: ScaleBasis.BothHeight), icon) :
|
||||
new GUIImage(new RectTransform(Vector2.One * 1.25f, textHolder.RectTransform, scaleBasis: ScaleBasis.BothHeight), style);
|
||||
var textBlock = new GUITextBlock(new RectTransform(new Vector2(0.9f, 1.0f), textHolder.RectTransform), text);
|
||||
textBlock.RectTransform.MinSize = new Point((int)textBlock.TextSize.X, 0);
|
||||
textHolder.RectTransform.MinSize = new Point((int)textBlock.TextSize.X + guiIcon.Rect.Width, 0);
|
||||
GUITextBlock textBox = new(new RectTransform(new Vector2(0.9f, 0f), content.RectTransform), text, wrap: true);
|
||||
|
||||
if (iconSprite == null && iconStyle == null) { return; }
|
||||
float iconSize = GUIStyle.Font.LineHeight * 1.5f;
|
||||
|
||||
textBox.Padding = textBox.Padding with { X = iconSize + 5f };
|
||||
RectTransform iconTF = new(new Point((int)iconSize), textBox.RectTransform, Anchor.CenterLeft) { IsFixedSize = true };
|
||||
if (iconSprite != null) { new GUIImage(iconTF, iconSprite, scaleToFit: true); }
|
||||
if (iconStyle != null) { new GUIImage(iconTF, iconStyle, scaleToFit: true); }
|
||||
}
|
||||
|
||||
void CreateSpacing(int height)
|
||||
@@ -486,10 +483,11 @@ namespace Barotrauma
|
||||
CreateSpacing(20);
|
||||
}
|
||||
|
||||
locationInfoOverlay.RectTransform.NonScaledSize =
|
||||
new Point(
|
||||
Math.Max(locationInfoOverlay.Rect.Width, (int)(content.Children.Max(c => c is GUITextBlock textBlock ? textBlock.TextSize.X : c.RectTransform.MinSize.X) * 1.2f)),
|
||||
(int)(content.Children.Sum(c => c.Rect.Height) / content.RectTransform.RelativeSize.Y));
|
||||
float childWidth = Math.Max(locationInfoOverlay.Rect.Width, content.Children.Max(c => c is GUITextBlock textBlock ? textBlock.TextSize.X + textBlock.Padding.X + textBlock.Padding.Z : c.RectTransform.MinSize.X));
|
||||
childWidth = Math.Max(locationInfoOverlay.Rect.Width, childWidth);
|
||||
float childHeight = content.Children.Sum(c => c.Rect.Height);
|
||||
Vector2 childSize = new Vector2(childWidth, childHeight) / content.RectTransform.RelativeSize;
|
||||
locationInfoOverlay.RectTransform.NonScaledSize = childSize.ToPoint();
|
||||
}
|
||||
|
||||
partial void ClearAnimQueue()
|
||||
|
||||
@@ -34,6 +34,8 @@ namespace Barotrauma
|
||||
|
||||
//which entities have been selected for editing
|
||||
public static HashSet<MapEntity> SelectedList { get; private set; } = new HashSet<MapEntity>();
|
||||
private static List<Rectangle> oldRects = new List<Rectangle>();
|
||||
private static Vector2 entityMovementNudge;
|
||||
|
||||
public static List<MapEntity> CopiedList = new List<MapEntity>();
|
||||
|
||||
@@ -267,7 +269,7 @@ namespace Barotrauma
|
||||
i++;
|
||||
}
|
||||
highlightedEntities.Insert(i, e);
|
||||
if (i == 0) highLightedEntity = e;
|
||||
if (i == 0) { highLightedEntity = e; }
|
||||
}
|
||||
}
|
||||
UpdateHighlighting(highlightedEntities);
|
||||
@@ -278,10 +280,19 @@ namespace Barotrauma
|
||||
|
||||
if (GUI.KeyboardDispatcher.Subscriber == null)
|
||||
{
|
||||
Vector2 nudge = GetNudgeAmount();
|
||||
if (nudge != Vector2.Zero)
|
||||
Vector2 previousNudge = entityMovementNudge;
|
||||
entityMovementNudge = GetNudgeAmount();
|
||||
if (entityMovementNudge != Vector2.Zero)
|
||||
{
|
||||
foreach (MapEntity entityToNudge in SelectedList) { entityToNudge.Move(nudge); }
|
||||
if (previousNudge == Vector2.Zero)
|
||||
{
|
||||
oldRects = SelectedList.Select(entity => entity.Rect).ToList();
|
||||
}
|
||||
foreach (MapEntity entityToNudge in SelectedList) { entityToNudge.Move(entityMovementNudge); }
|
||||
}
|
||||
else if (previousNudge != Vector2.Zero)
|
||||
{
|
||||
SubEditorScreen.StoreCommand(new TransformCommand(new List<MapEntity>(SelectedList), SelectedList.Select(entity => entity.Rect).ToList(), oldRects, resized: false));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -352,7 +363,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
SubEditorScreen.StoreCommand(new TransformCommand(new List<MapEntity>(SelectedList),SelectedList.Select(entity => entity.Rect).ToList(), oldRects, false));
|
||||
SubEditorScreen.StoreCommand(new TransformCommand(new List<MapEntity>(SelectedList), SelectedList.Select(entity => entity.Rect).ToList(), oldRects, resized: false));
|
||||
if (deposited.Any() && deposited.Any(entity => entity is Item))
|
||||
{
|
||||
var depositedItems = deposited.Where(entity => entity is Item).Cast<Item>().ToList();
|
||||
@@ -508,7 +519,7 @@ namespace Barotrauma
|
||||
selectionSize = Vector2.Zero;
|
||||
selectionPos = Vector2.Zero;
|
||||
}
|
||||
|
||||
|
||||
public static Vector2 GetNudgeAmount(bool doHold = true)
|
||||
{
|
||||
Vector2 nudgeAmount = Vector2.Zero;
|
||||
@@ -532,10 +543,10 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
if (PlayerInput.KeyHit(Keys.Up)) nudgeAmount.Y = 1f;
|
||||
if (PlayerInput.KeyHit(Keys.Down)) nudgeAmount.Y = -1f;
|
||||
if (PlayerInput.KeyHit(Keys.Left)) nudgeAmount.X = -1f;
|
||||
if (PlayerInput.KeyHit(Keys.Right)) nudgeAmount.X = 1f;
|
||||
if (PlayerInput.KeyHit(Keys.Up)) { nudgeAmount.Y = 1f; }
|
||||
if (PlayerInput.KeyHit(Keys.Down)) { nudgeAmount.Y = -1f; }
|
||||
if (PlayerInput.KeyHit(Keys.Left)) { nudgeAmount.X = -1f;}
|
||||
if (PlayerInput.KeyHit(Keys.Right)) { nudgeAmount.X = 1f; }
|
||||
|
||||
return nudgeAmount;
|
||||
}
|
||||
|
||||
@@ -172,16 +172,19 @@ namespace Barotrauma
|
||||
GUI.DrawRectangle(spriteBatch, drawPos - ExitPointSize.ToVector2() / 2, ExitPointSize.ToVector2(), Color.Cyan, thickness: 5);
|
||||
}
|
||||
|
||||
GUIStyle.SmallFont.DrawString(spriteBatch,
|
||||
ID.ToString(),
|
||||
new Vector2(DrawPosition.X - 10, -DrawPosition.Y - 30),
|
||||
color);
|
||||
if (Tunnel?.Type != null)
|
||||
if (Screen.Selected?.Cam is { Zoom: > 0.4f })
|
||||
{
|
||||
GUIStyle.SmallFont.DrawString(spriteBatch,
|
||||
Tunnel.Type.ToString(),
|
||||
new Vector2(DrawPosition.X - 10, -DrawPosition.Y - 45),
|
||||
color);
|
||||
ID.ToString(),
|
||||
new Vector2(DrawPosition.X - 10, -DrawPosition.Y - 30),
|
||||
color);
|
||||
if (Tunnel?.Type != null)
|
||||
{
|
||||
GUIStyle.SmallFont.DrawString(spriteBatch,
|
||||
Tunnel.Type.ToString(),
|
||||
new Vector2(DrawPosition.X - 10, -DrawPosition.Y - 45),
|
||||
color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user