Unstable v0.1300.0.1
This commit is contained in:
@@ -159,6 +159,11 @@ namespace Barotrauma
|
||||
get { return AbyssArea.Y + AbyssArea.Height; }
|
||||
}
|
||||
|
||||
public int AbyssEnd
|
||||
{
|
||||
get { return AbyssArea.Y; }
|
||||
}
|
||||
|
||||
public class AbyssIsland
|
||||
{
|
||||
public readonly Rectangle Area;
|
||||
@@ -1370,15 +1375,15 @@ namespace Barotrauma
|
||||
float seaFloorPos = GetBottomPosition(xPos).Y;
|
||||
|
||||
//above the bottom of the level = can't place a point here
|
||||
if (seaFloorPos > AbyssArea.Bottom) { continue; }
|
||||
if (seaFloorPos > AbyssStart) { continue; }
|
||||
|
||||
float yPos = Rand.Range(Math.Max(seaFloorPos, AbyssArea.Y), AbyssArea.Bottom);
|
||||
float yPos = MathHelper.Lerp(AbyssStart, Math.Max(seaFloorPos, AbyssArea.Y), Rand.Range(0.2f, 1.0f, Rand.RandSync.Server));
|
||||
|
||||
foreach (var abyssIsland in AbyssIslands)
|
||||
{
|
||||
if (abyssIsland.Area.Contains(new Point((int)xPos, (int)yPos)))
|
||||
{
|
||||
xPos = abyssIsland.Area.Center.X + (int)(Rand.Int(1) == 0 ? abyssIsland.Area.Width * -0.6f : 0.6f);
|
||||
xPos = abyssIsland.Area.Center.X + (int)(Rand.Int(1, Rand.RandSync.Server) == 0 ? abyssIsland.Area.Width * -0.6f : 0.6f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2035,6 +2040,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (l.Cell == null || l.Edge == null) { return false; }
|
||||
if (resourceInfo.IsIslandSpecifc && !l.Cell.Island) { return false; }
|
||||
if (!resourceInfo.AllowAtStart && l.EdgeCenter.Y > StartPosition.Y && l.EdgeCenter.X < Size.X * 0.25f) { return false; }
|
||||
if (l.EdgeCenter.Y < AbyssArea.Bottom) { return false; }
|
||||
return resourceInfo.ClusterSize <= GetMaxResourcesOnEdge(itemPrefab, l, out _);
|
||||
|
||||
@@ -3240,13 +3246,13 @@ namespace Barotrauma
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (StartLocation != null && !StartLocation.HasOutpost()) { continue; }
|
||||
if (StartLocation != null && !StartLocation.Type.HasOutpost) { continue; }
|
||||
}
|
||||
else
|
||||
{
|
||||
//don't create an end outpost for locations
|
||||
if (LevelData.Type == LevelData.LevelType.Outpost) { continue; }
|
||||
if (EndLocation != null && !EndLocation.HasOutpost()) { continue; }
|
||||
if (EndLocation != null && !EndLocation.Type.HasOutpost) { continue; }
|
||||
}
|
||||
|
||||
SubmarineInfo outpostInfo;
|
||||
@@ -3266,7 +3272,7 @@ namespace Barotrauma
|
||||
{
|
||||
var suitableParams = OutpostGenerationParams.Params
|
||||
.Where(p => location == null || p.AllowedLocationTypes.Contains(location.Type.Identifier));
|
||||
if (suitableParams.Count() == 0)
|
||||
if (!suitableParams.Any())
|
||||
{
|
||||
suitableParams = OutpostGenerationParams.Params
|
||||
.Where(p => location == null || !p.AllowedLocationTypes.Any());
|
||||
@@ -3305,7 +3311,7 @@ namespace Barotrauma
|
||||
|
||||
foreach (string categoryToHide in locationType.HideEntitySubcategories)
|
||||
{
|
||||
foreach (MapEntity entityToHide in MapEntity.mapEntityList.Where(me => me.Submarine == outpost && me.prefab.HasSubCategory(categoryToHide)))
|
||||
foreach (MapEntity entityToHide in MapEntity.mapEntityList.Where(me => me.Submarine == outpost && (me.prefab?.HasSubCategory(categoryToHide) ?? false)))
|
||||
{
|
||||
entityToHide.HiddenInGame = true;
|
||||
}
|
||||
@@ -3444,7 +3450,12 @@ namespace Barotrauma
|
||||
Item reactorItem = beaconItems.Find(it => it.GetComponent<Reactor>() != null);
|
||||
Reactor reactorComponent = reactorItem.GetComponent<Reactor>();
|
||||
ItemContainer reactorContainer = reactorItem.GetComponent<ItemContainer>();
|
||||
|
||||
Repairable repairable = reactorItem.GetComponent<Repairable>();
|
||||
reactorComponent.FuelConsumptionRate = 0.0f;
|
||||
if (repairable != null)
|
||||
{
|
||||
repairable.DeteriorationSpeed = 0.0f;
|
||||
}
|
||||
if (LevelData.IsBeaconActive)
|
||||
{
|
||||
if (reactorContainer.Inventory.IsEmpty())
|
||||
|
||||
@@ -236,6 +236,11 @@ namespace Barotrauma
|
||||
DebugConsole.ThrowError("Failed to load a linked submarine (empty XML element). The save file may be corrupted.");
|
||||
return;
|
||||
}
|
||||
if (!info.SubmarineElement.Elements().Any(e => e.Name.ToString().Equals("hull", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to load a linked submarine (the submarine contains no hulls).");
|
||||
return;
|
||||
}
|
||||
|
||||
IdRemap parentRemap = new IdRemap(Submarine.Info.SubmarineElement, Submarine.IdOffset);
|
||||
sub = Submarine.Load(info, false, parentRemap);
|
||||
@@ -322,7 +327,7 @@ namespace Barotrauma
|
||||
sub.SetPosition((linkedPort.Item.WorldPosition - portDiff) - offset);
|
||||
|
||||
myPort.Dock(linkedPort);
|
||||
myPort.Lock(true, applyEffects: false);
|
||||
myPort.Lock(isNetworkMessage: true, applyEffects: false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -579,6 +579,16 @@ namespace Barotrauma
|
||||
return false;
|
||||
}
|
||||
|
||||
public LocationType GetLocationType()
|
||||
{
|
||||
if (IsCriticallyRadiated() && LocationType.List.FirstOrDefault(lt => lt.Identifier.Equals(Type.ReplaceInRadiation, StringComparison.OrdinalIgnoreCase)) is { } newLocationType)
|
||||
{
|
||||
return newLocationType;
|
||||
}
|
||||
|
||||
return Type;
|
||||
}
|
||||
|
||||
public IEnumerable<Mission> GetMissionsInConnection(LocationConnection connection)
|
||||
{
|
||||
System.Diagnostics.Debug.Assert(Connections.Contains(connection));
|
||||
|
||||
@@ -14,6 +14,8 @@ namespace Barotrauma
|
||||
|
||||
public bool Passed;
|
||||
|
||||
public bool Locked;
|
||||
|
||||
public LevelData LevelData { get; set; }
|
||||
|
||||
public Vector2 CenterPos
|
||||
|
||||
@@ -54,8 +54,11 @@ namespace Barotrauma
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public string ReplaceInRadiation { get; }
|
||||
|
||||
public Sprite Sprite { get; private set; }
|
||||
public Sprite RadiationSprite { get; }
|
||||
|
||||
public Color SpriteColor
|
||||
{
|
||||
@@ -85,6 +88,8 @@ namespace Barotrauma
|
||||
|
||||
HideEntitySubcategories = element.GetAttributeStringArray("hideentitysubcategories", new string[0]).ToList();
|
||||
|
||||
ReplaceInRadiation = element.GetAttributeString(nameof(ReplaceInRadiation).ToLower(), "");
|
||||
|
||||
string nameFile = element.GetAttributeString("namefile", "Content/Map/locationNames.txt");
|
||||
try
|
||||
{
|
||||
@@ -140,6 +145,9 @@ namespace Barotrauma
|
||||
Sprite = new Sprite(subElement, lazyLoad: true);
|
||||
SpriteColor = subElement.GetAttributeColor("color", Color.White);
|
||||
break;
|
||||
case "radiationsymbol":
|
||||
RadiationSprite = new Sprite(subElement, lazyLoad: true);
|
||||
break;
|
||||
case "changeto":
|
||||
CanChangeTo.Add(new LocationTypeChange(Identifier, subElement, requireChangeMessages: true));
|
||||
break;
|
||||
|
||||
@@ -59,18 +59,21 @@ namespace Barotrauma
|
||||
|
||||
public Radiation Radiation;
|
||||
|
||||
public Map()
|
||||
public Map(CampaignSettings settings)
|
||||
{
|
||||
generationParams = MapGenerationParams.Instance;
|
||||
Locations = new List<Location>();
|
||||
Connections = new List<LocationConnection>();
|
||||
Radiation = new Radiation(this, generationParams.RadiationParams);
|
||||
Radiation = new Radiation(this, generationParams.RadiationParams)
|
||||
{
|
||||
Enabled = settings.RadiationEnabled
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load a previously saved campaign map from XML
|
||||
/// </summary>
|
||||
private Map(CampaignMode campaign, XElement element) : this()
|
||||
private Map(CampaignMode campaign, XElement element, CampaignSettings settings) : this(settings)
|
||||
{
|
||||
Seed = element.GetAttributeString("seed", "a");
|
||||
Rand.SetSyncedSeed(ToolBox.StringToInt(Seed));
|
||||
@@ -87,7 +90,10 @@ namespace Barotrauma
|
||||
Locations[i] = new Location(subElement);
|
||||
break;
|
||||
case "radiation":
|
||||
Radiation = new Radiation(this, generationParams.RadiationParams, subElement);
|
||||
Radiation = new Radiation(this, generationParams.RadiationParams, subElement)
|
||||
{
|
||||
Enabled = settings.RadiationEnabled
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -107,6 +113,7 @@ namespace Barotrauma
|
||||
var connection = new LocationConnection(Locations[locationIndices.X], Locations[locationIndices.Y])
|
||||
{
|
||||
Passed = subElement.GetAttributeBool("passed", false),
|
||||
Locked = subElement.GetAttributeBool("locked", false),
|
||||
Difficulty = subElement.GetAttributeFloat("difficulty", 0.0f)
|
||||
};
|
||||
Locations[locationIndices.X].Connections.Add(connection);
|
||||
@@ -162,7 +169,7 @@ namespace Barotrauma
|
||||
/// <summary>
|
||||
/// Generate a new campaign map from the seed
|
||||
/// </summary>
|
||||
public Map(CampaignMode campaign, string seed) : this()
|
||||
public Map(CampaignMode campaign, string seed, CampaignSettings settings) : this(settings)
|
||||
{
|
||||
Seed = seed;
|
||||
Rand.SetSyncedSeed(ToolBox.StringToInt(Seed));
|
||||
@@ -404,6 +411,7 @@ namespace Barotrauma
|
||||
leftMostLocation.ChangeType(LocationType.List.First(lt => lt.HasOutpost));
|
||||
}
|
||||
leftMostLocation.IsGateBetweenBiomes = true;
|
||||
Connections[i].Locked = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -688,6 +696,10 @@ namespace Barotrauma
|
||||
SelectedConnection =
|
||||
Connections.Find(c => c.Locations.Contains(GameMain.GameSession?.Campaign?.CurrentDisplayLocation) && c.Locations.Contains(SelectedLocation)) ??
|
||||
Connections.Find(c => c.Locations.Contains(CurrentLocation) && c.Locations.Contains(SelectedLocation));
|
||||
if (SelectedConnection?.Locked ?? false)
|
||||
{
|
||||
DebugConsole.ThrowError("A locked connection was selected - this should not be possible.\n" + Environment.StackTrace.CleanupStackTrace());
|
||||
}
|
||||
OnLocationSelected?.Invoke(SelectedLocation, SelectedConnection);
|
||||
}
|
||||
|
||||
@@ -703,6 +715,10 @@ namespace Barotrauma
|
||||
|
||||
SelectedLocation = location;
|
||||
SelectedConnection = Connections.Find(c => c.Locations.Contains(CurrentLocation) && c.Locations.Contains(SelectedLocation));
|
||||
if (SelectedConnection?.Locked ?? false)
|
||||
{
|
||||
DebugConsole.ThrowError("A locked connection was selected - this should not be possible.\n" + Environment.StackTrace.CleanupStackTrace());
|
||||
}
|
||||
OnLocationSelected?.Invoke(SelectedLocation, SelectedConnection);
|
||||
}
|
||||
|
||||
@@ -736,7 +752,7 @@ namespace Barotrauma
|
||||
|
||||
public void SelectRandomLocation(bool preferUndiscovered)
|
||||
{
|
||||
List<Location> nextLocations = CurrentLocation.Connections.Select(c => c.OtherLocation(CurrentLocation)).ToList();
|
||||
List<Location> nextLocations = CurrentLocation.Connections.Where(c => !c.Locked).Select(c => c.OtherLocation(CurrentLocation)).ToList();
|
||||
List<Location> undiscoveredLocations = nextLocations.FindAll(l => !l.Discovered);
|
||||
|
||||
if (undiscoveredLocations.Count > 0 && preferUndiscovered)
|
||||
@@ -943,9 +959,9 @@ namespace Barotrauma
|
||||
/// <summary>
|
||||
/// Load a previously saved map from an xml element
|
||||
/// </summary>
|
||||
public static Map Load(CampaignMode campaign, XElement element)
|
||||
public static Map Load(CampaignMode campaign, XElement element, CampaignSettings settings)
|
||||
{
|
||||
Map map = new Map(campaign, element);
|
||||
Map map = new Map(campaign, element, settings);
|
||||
map.LoadState(element, false);
|
||||
#if CLIENT
|
||||
map.DrawOffset = -map.CurrentLocation.MapPosition;
|
||||
@@ -1079,6 +1095,7 @@ namespace Barotrauma
|
||||
|
||||
var connectionElement = new XElement("connection",
|
||||
new XAttribute("passed", connection.Passed),
|
||||
new XAttribute("locked", connection.Locked),
|
||||
new XAttribute("difficulty", connection.Difficulty),
|
||||
new XAttribute("biome", connection.Biome.Identifier),
|
||||
new XAttribute("locations", Locations.IndexOf(connection.Locations[0]) + "," + Locations.IndexOf(connection.Locations[1])));
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
@@ -13,6 +14,9 @@ namespace Barotrauma
|
||||
[Serialize(defaultValue: 0f, isSaveable: true)]
|
||||
public float Amount { get; set; }
|
||||
|
||||
[Serialize(defaultValue: true, isSaveable: true)]
|
||||
public bool Enabled { get; set; }
|
||||
|
||||
public Dictionary<string, SerializableProperty> SerializableProperties { get; }
|
||||
|
||||
public readonly Map Map;
|
||||
@@ -23,8 +27,6 @@ namespace Barotrauma
|
||||
private float increasedAmount;
|
||||
private float lastIncrease;
|
||||
|
||||
public bool Enabled = true;
|
||||
|
||||
public Radiation(Map map, RadiationParams radiationParams, XElement? element = null)
|
||||
{
|
||||
SerializableProperties = SerializableProperty.DeserializeProperties(this, element);
|
||||
@@ -52,6 +54,12 @@ namespace Barotrauma
|
||||
|
||||
foreach (Location location in Map.Locations.Where(Contains))
|
||||
{
|
||||
if (location.IsGateBetweenBiomes)
|
||||
{
|
||||
location.Connections.ForEach(c => c.Locked = false);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (amountOfOutposts <= Params.MinimumOutpostAmount) { break; }
|
||||
|
||||
if (Map.CurrentLocation is { } currLocation)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -29,6 +30,15 @@ namespace Barotrauma
|
||||
[Serialize(defaultValue: 1f, isSaveable: false, "How much is the radiation affliction increased by while in a radiated zone.")]
|
||||
public float RadiationDamageAmount { get; set; }
|
||||
|
||||
[Serialize(defaultValue: "139,0,0,85", isSaveable: false, "The color of the radiated area.")]
|
||||
public Color RadiationAreaColor { get; set; }
|
||||
|
||||
[Serialize(defaultValue: "255,0,0,255", isSaveable: false, "The tint of the radiation border sprites.")]
|
||||
public Color RadiationBorderTint { get; set; }
|
||||
|
||||
[Serialize(defaultValue: 16.66f, isSaveable: false, "Speed of the border spritesheet animation.")]
|
||||
public float BorderAnimationSpeed { get; set; }
|
||||
|
||||
public RadiationParams(XElement element)
|
||||
{
|
||||
SerializableProperties = SerializableProperty.DeserializeProperties(this, element);
|
||||
|
||||
@@ -67,6 +67,9 @@ namespace Barotrauma
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize("", isSaveable: true), Editable]
|
||||
public string ReplaceInRadiation { get; set; }
|
||||
|
||||
private readonly Dictionary<string, int> moduleCounts = new Dictionary<string, int>();
|
||||
|
||||
public IEnumerable<KeyValuePair<string, int>> ModuleCounts
|
||||
|
||||
@@ -68,6 +68,15 @@ namespace Barotrauma
|
||||
private static Submarine Generate(OutpostGenerationParams generationParams, LocationType locationType, Location location, bool onlyEntrance = false)
|
||||
{
|
||||
var outpostModuleFiles = ContentPackage.GetFilesOfType(GameMain.Config.AllEnabledPackages, ContentType.OutpostModule);
|
||||
if (location != null)
|
||||
{
|
||||
if (location.IsCriticallyRadiated() && OutpostGenerationParams.Params.FirstOrDefault(p => p.Identifier.Equals(generationParams.ReplaceInRadiation, StringComparison.OrdinalIgnoreCase)) is { } newParams)
|
||||
{
|
||||
generationParams = newParams;
|
||||
}
|
||||
|
||||
locationType = location.GetLocationType();
|
||||
}
|
||||
|
||||
//load the infos of the outpost module files
|
||||
List<SubmarineInfo> outpostModules = new List<SubmarineInfo>();
|
||||
@@ -974,7 +983,7 @@ namespace Barotrauma
|
||||
var moduleEntities = MapEntity.LoadAll(sub, hallwayInfo.SubmarineElement, hallwayInfo.FilePath, -1);
|
||||
|
||||
//remove items that don't fit in the hallway
|
||||
moduleEntities.Where(e => e is Item item && item.GetComponent<Door>() == null && e.Rect.Width > hallwayLength).ForEach(e => e.Remove());
|
||||
moduleEntities.Where(e => e is Item item && item.GetComponent<Door>() == null && (isHorizontal ? e.Rect.Width : e.Rect.Height) > hallwayLength).ForEach(e => e.Remove());
|
||||
|
||||
//find the largest hull to use it as the center point of the hallway
|
||||
//and the bounds of all the hulls, used when resizing the hallway to fit between the modules
|
||||
@@ -1047,11 +1056,11 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (me is Structure structure)
|
||||
else if (me is Structure || (me is Item item && item.GetComponent<Door>() == null))
|
||||
{
|
||||
if (isHorizontal)
|
||||
{
|
||||
if (!structure.ResizeHorizontal)
|
||||
if (!me.ResizeHorizontal)
|
||||
{
|
||||
int xPos = (int)(leftHull.WorldRect.Right + (me.WorldPosition.X - hullBounds.X) * scaleFactor);
|
||||
me.Rect = new Rectangle(xPos - me.RectWidth / 2, me.Rect.Y, me.Rect.Width, me.Rect.Height);
|
||||
@@ -1065,9 +1074,9 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!structure.ResizeVertical)
|
||||
if (!me.ResizeVertical)
|
||||
{
|
||||
int yPos = (int)(topHull.WorldRect.Y - topHull.RectHeight + (me.WorldPosition.X - hullBounds.Bottom) * scaleFactor);
|
||||
int yPos = (int)(topHull.WorldRect.Y - topHull.RectHeight + (me.WorldPosition.Y - hullBounds.Bottom) * scaleFactor);
|
||||
me.Rect = new Rectangle(me.Rect.X, yPos + me.RectHeight / 2, me.Rect.Width, me.Rect.Height);
|
||||
}
|
||||
else
|
||||
@@ -1394,7 +1403,7 @@ namespace Barotrauma
|
||||
ISpatialEntity gotoTarget = SpawnAction.GetSpawnPos(SpawnAction.SpawnLocationType.Outpost, SpawnType.Human, humanPrefab.GetModuleFlags(), humanPrefab.GetSpawnPointTags());
|
||||
if (gotoTarget == null)
|
||||
{
|
||||
gotoTarget = outpost.GetHulls(true).GetRandom();
|
||||
gotoTarget = outpost.GetHulls(true).GetRandom(Rand.RandSync.Server);
|
||||
}
|
||||
characterInfo.TeamID = CharacterTeamType.FriendlyNPC;
|
||||
var npc = Character.Create(CharacterPrefab.HumanConfigFile, SpawnAction.OffsetSpawnPos(gotoTarget.WorldPosition, 100.0f), ToolBox.RandomSeed(8), characterInfo, hasAi: true, createNetworkEvent: true);
|
||||
|
||||
@@ -590,10 +590,11 @@ namespace Barotrauma
|
||||
if (item.GetComponent<Turret>() != null) { return false; }
|
||||
if (item.body != null && !item.body.Enabled) { return true; }
|
||||
}
|
||||
if (e.HiddenInGame) { return true; }
|
||||
return false;
|
||||
});
|
||||
|
||||
if (entities.Count == 0) return Rectangle.Empty;
|
||||
if (entities.Count == 0) { return Rectangle.Empty; }
|
||||
|
||||
float minX = entities[0].Rect.X, minY = entities[0].Rect.Y - entities[0].Rect.Height;
|
||||
float maxX = entities[0].Rect.Right, maxY = entities[0].Rect.Y;
|
||||
@@ -1356,7 +1357,7 @@ namespace Barotrauma
|
||||
if (me.Submarine != this) { continue; }
|
||||
if (me is Item item)
|
||||
{
|
||||
item.SpawnedInOutpost = !info.OutpostGenerationParams.AllowStealing;
|
||||
item.SpawnedInOutpost = info.OutpostGenerationParams != null && !info.OutpostGenerationParams.AllowStealing;
|
||||
if (item.GetComponent<Repairable>() != null && indestructible)
|
||||
{
|
||||
item.Indestructible = true;
|
||||
@@ -1366,7 +1367,7 @@ namespace Barotrauma
|
||||
if (ic is ConnectionPanel connectionPanel)
|
||||
{
|
||||
//prevent rewiring
|
||||
if (!info.OutpostGenerationParams.AlwaysRewireable)
|
||||
if (info.OutpostGenerationParams != null && !info.OutpostGenerationParams.AlwaysRewireable)
|
||||
{
|
||||
connectionPanel.Locked = true;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,9 @@ using Barotrauma.Extensions;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
public enum SpawnType { Path = 0, Human = 1, Enemy = 2, Cargo = 3, Corpse = 4 };
|
||||
[Flags]
|
||||
public enum SpawnType { Path = 0, Human = 1, Enemy = 2, Cargo = 4, Corpse = 8 };
|
||||
|
||||
partial class WayPoint : MapEntity
|
||||
{
|
||||
public static List<WayPoint> WayPointList = new List<WayPoint>();
|
||||
|
||||
Reference in New Issue
Block a user