diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 061176b7..35416297 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,7 +1,7 @@ # These are supported funding model platforms github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] -patreon: MapEditorReborn +patreon: # MapEditorReborn open_collective: # Replace with a single Open Collective username ko_fi: # Replace with a single Ko-fi username tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel diff --git a/MapEditorReborn/API/API.cs b/MapEditorReborn/API/API.cs index f1678ada..3c90521a 100644 --- a/MapEditorReborn/API/API.cs +++ b/MapEditorReborn/API/API.cs @@ -13,10 +13,13 @@ namespace MapEditorReborn.API using Enums; using Exiled.API.Enums; using Exiled.API.Features; + using Exiled.API.Features.Toys; using Extensions; using Features; using Features.Objects; using Features.Serializable; + using MapGeneration; + using Mirror; using UnityEngine; /// @@ -39,8 +42,6 @@ public static class API /// internal static MapSchematic? MapSchematic; - internal static ReadOnlyCollection? RoomTypes; - /// /// Gets or sets currently loaded . /// @@ -50,11 +51,42 @@ public static MapSchematic? CurrentLoadedMap set => MapUtils.LoadMap(value); } + private static ReadOnlyCollection? _spawnedRoomTypes; + private static ReadOnlyCollection? _nonDistinctRoomTypes; + /// /// Gets the readonly list of that spawned this round. /// public static ReadOnlyCollection SpawnedRoomTypes => - RoomTypes ??= new List(Room.List.Select(x => x.Type).Distinct()).AsReadOnly(); + _spawnedRoomTypes; // ??= Room.List.Select(x => x.Type).Distinct().ToList().AsReadOnly(); + + /// + /// Gets the readonly list of that spawned this round AND are not distinct (there are multiple rooms of the same type). + /// + public static ReadOnlyCollection NonDistinctRoomTypes => + _nonDistinctRoomTypes; // ??= SpawnedRoomTypes.Where(roomType => Room.List.Count(x => x.Type == roomType) > 1).ToList().AsReadOnly(); + + internal static void PopulateRoomTypeLists() + { + List spawnedRoomTypes = new(); + List nonDistinctRoomTypes = new(); + + foreach (Room room in Room.List) + { + RoomType type = room.Type; + if (!spawnedRoomTypes.Contains(type)) + spawnedRoomTypes.Add(type); + } + + foreach (RoomType spawnedRoomType in spawnedRoomTypes) + { + if (Room.List.Count(x => x.Type == spawnedRoomType) > 1) + nonDistinctRoomTypes.Add(spawnedRoomType); + } + + _spawnedRoomTypes = spawnedRoomTypes.AsReadOnly(); + _nonDistinctRoomTypes = nonDistinctRoomTypes.AsReadOnly(); + } /// /// Gets the dictionary that stores currently selected by . @@ -62,6 +94,7 @@ public static MapSchematic? CurrentLoadedMap internal static Dictionary ToolGuns { get; private set; } = new(); internal static Dictionary GravityGuns { get; private set; } = new(); + internal static HashSet PickupsLocked { get; private set; } = new(); internal static Dictionary PickupsUsesLeft { get; private set; } = new(); @@ -76,8 +109,47 @@ public static MapSchematic? CurrentLoadedMap /// public static ReadOnlyDictionary ObjectPrefabs { get; internal set; } + internal static void GetObjectPrefabs() + { + Dictionary objectList = new(21); + DoorSpawnpoint[] doorList = Object.FindObjectsOfType(); + + objectList.Add(ObjectType.LczDoor, doorList.First(x => x.TargetPrefab.name.Contains("LCZ")).TargetPrefab.gameObject); + objectList.Add(ObjectType.HczDoor, doorList.First(x => x.TargetPrefab.name.Contains("HCZ")).TargetPrefab.gameObject); + objectList.Add(ObjectType.EzDoor, doorList.First(x => x.TargetPrefab.name.Contains("EZ")).TargetPrefab.gameObject); + + objectList.Add(ObjectType.WorkStation, NetworkClient.prefabs.Values.First(x => x.name.Contains("Work Station"))); + + objectList.Add(ObjectType.ItemSpawnPoint, new GameObject("ItemSpawnPointObject")); + objectList.Add(ObjectType.PlayerSpawnPoint, new GameObject("PlayerSpawnPointObject")); + objectList.Add(ObjectType.RagdollSpawnPoint, new GameObject("RagdollSpawnPointObject")); + objectList.Add(ObjectType.DummySpawnPoint, new GameObject("DummySpawnPointObject")); + + objectList.Add(ObjectType.SportShootingTarget, ToysHelper.SportShootingTargetObject.gameObject); + objectList.Add(ObjectType.DboyShootingTarget, ToysHelper.DboyShootingTargetObject.gameObject); + objectList.Add(ObjectType.BinaryShootingTarget, ToysHelper.BinaryShootingTargetObject.gameObject); + + objectList.Add(ObjectType.Primitive, ToysHelper.PrimitiveBaseObject.gameObject); + objectList.Add(ObjectType.LightSource, ToysHelper.LightBaseObject.gameObject); + + objectList.Add(ObjectType.RoomLight, new GameObject("LightControllerObject")); + + GameObject teleportPrefab = GameObject.CreatePrimitive(PrimitiveType.Cube); + teleportPrefab.name = "TeleportObject"; + objectList.Add(ObjectType.Teleporter, teleportPrefab); + + objectList.Add(ObjectType.PedestalLocker, NetworkClient.prefabs.Values.First(x => x.name == "Scp500PedestalStructure Variant")); + objectList.Add(ObjectType.LargeGunLocker, NetworkClient.prefabs.Values.First(x => x.name == "LargeGunLockerStructure")); + objectList.Add(ObjectType.RifleRackLocker, NetworkClient.prefabs.Values.First(x => x.name == "RifleRackStructure")); + objectList.Add(ObjectType.MiscLocker, NetworkClient.prefabs.Values.First(x => x.name == "MiscLocker")); + objectList.Add(ObjectType.MedkitLocker, NetworkClient.prefabs.Values.First(x => x.name == "RegularMedkitStructure")); + objectList.Add(ObjectType.AdrenalineLocker, NetworkClient.prefabs.Values.First(x => x.name == "AdrenalineMedkitStructure")); + + ObjectPrefabs = new ReadOnlyDictionary(objectList); + } + /// - /// Gets or sets a random from the . + /// Gets a random from the . /// /// The from which the room should be chosen. /// A random that has of the argument. diff --git a/MapEditorReborn/API/Features/MapUtils.cs b/MapEditorReborn/API/Features/MapUtils.cs index de0a13fd..9da0e962 100644 --- a/MapEditorReborn/API/Features/MapUtils.cs +++ b/MapEditorReborn/API/Features/MapUtils.cs @@ -207,7 +207,7 @@ public static void LoadMap(MapSchematic? map) foreach (SchematicSerializable schematicObject in map.Schematics) { Log.Debug($"Trying to spawn a schematic named \"{schematicObject.SchematicName}\" at {schematicObject.RoomType}... ({schematicObject.Position.x}, {schematicObject.Position.y}, {schematicObject.Position.z})"); - MapEditorObject schematic = ObjectSpawner.SpawnSchematic(schematicObject); + MapEditorObject schematic = ObjectSpawner.SpawnSchematic(schematicObject, null, null, null, null, true); if (schematic == null) { diff --git a/MapEditorReborn/API/Features/ObjectSpawner.cs b/MapEditorReborn/API/Features/ObjectSpawner.cs index 64d3e1f0..924e6bb1 100644 --- a/MapEditorReborn/API/Features/ObjectSpawner.cs +++ b/MapEditorReborn/API/Features/ObjectSpawner.cs @@ -62,7 +62,9 @@ public static T SpawnObject(params object[] args) return null; } - return SpawnSchematic(schematicObject, forcedPosition, forcedRotation, forcedScale, data) as T; + bool isStatic = ParseArgument(5, args); + + return SpawnSchematic(schematicObject, forcedPosition, forcedRotation, forcedScale, data, isStatic) as T; } case nameof(LockerObject): @@ -285,9 +287,21 @@ public static LockerObject SpawnLocker(LockerSerializable locker, Vector3? force /// The schematic' scale. /// The schematic data. /// The spawned . + [Obsolete] public static SchematicObject SpawnSchematic(string schematicName, Vector3 position, Quaternion? rotation = null, Vector3? scale = null, SchematicObjectDataList data = null) { - return SpawnSchematic(new SchematicSerializable(schematicName), position, rotation, scale, data); + return SpawnSchematic(new SchematicSerializable(schematicName), position, rotation, scale, data, false); + } + + public static SchematicObject SpawnSchematic(string schematicName, Vector3 position, Quaternion? rotation = null, Vector3? scale = null, SchematicObjectDataList data = null, bool isStatic = false) + { + return SpawnSchematic(new SchematicSerializable(schematicName), position, rotation, scale, data, isStatic); + } + + [Obsolete] + public static SchematicObject SpawnSchematic(SchematicSerializable schematicObject, Vector3? forcedPosition = null, Quaternion? forcedRotation = null, Vector3? forcedScale = null, SchematicObjectDataList data = null) + { + return SpawnSchematic(schematicObject, forcedPosition, forcedRotation, forcedScale, data, false); } /// @@ -299,7 +313,7 @@ public static SchematicObject SpawnSchematic(string schematicName, Vector3 posit /// Used to force exact object scale. /// The schematic data. /// The spawned . - public static SchematicObject SpawnSchematic(SchematicSerializable schematicObject, Vector3? forcedPosition = null, Quaternion? forcedRotation = null, Vector3? forcedScale = null, SchematicObjectDataList data = null) + public static SchematicObject SpawnSchematic(SchematicSerializable schematicObject, Vector3? forcedPosition = null, Quaternion? forcedRotation = null, Vector3? forcedScale = null, SchematicObjectDataList data = null, bool isStatic = false) { if (data == null) { @@ -325,8 +339,10 @@ public static SchematicObject SpawnSchematic(SchematicSerializable schematicObje }, }; - SchematicObject schematicObjectComponent = gameObject.AddComponent().Init(schematicObject, data); + SchematicObject schematicObjectComponent = gameObject.AddComponent().Init(schematicObject, data, isStatic); gameObject.transform.localScale = forcedScale ?? schematicObject.Scale; + if (schematicObjectComponent.IsStatic) + schematicObjectComponent.UpdateObject(); SchematicSpawnedEventArgs ev = new SchematicSpawnedEventArgs(schematicObjectComponent, schematicObject.SchematicName); Schematic.OnSchematicSpawned(ev); @@ -357,7 +373,7 @@ public static MapEditorObject SpawnPropertyObject(Vector3 position, MapEditorObj ShootingTargetObject shootingTarget => SpawnShootingTarget(new ShootingTargetSerializable().CopyProperties(shootingTarget.Base), position, rotation, scale), PrimitiveObject primitive => SpawnPrimitive(new PrimitiveSerializable().CopyProperties(primitive.Base), position + (Vector3.up * 0.5f), rotation, scale), LockerObject locker => SpawnLocker(new LockerSerializable().CopyProperties(locker.Base), position, rotation, scale), - SchematicObject schematic => SpawnSchematic(new SchematicSerializable().CopyProperties(schematic.Base), position, rotation, scale), + SchematicObject schematic => SpawnSchematic(new SchematicSerializable().CopyProperties(schematic.Base), position, rotation, scale, isStatic: true), _ => null, }; } diff --git a/MapEditorReborn/API/Features/Objects/LightSourceObject.cs b/MapEditorReborn/API/Features/Objects/LightSourceObject.cs index 7d7c0082..87963b88 100644 --- a/MapEditorReborn/API/Features/Objects/LightSourceObject.cs +++ b/MapEditorReborn/API/Features/Objects/LightSourceObject.cs @@ -38,7 +38,7 @@ private void Awake() public LightSourceObject Init(LightSourceSerializable lightSourceSerializable, bool spawn = true) { Base = lightSourceSerializable; - Light.MovementSmoothing = 60; + // Light.MovementSmoothing = 60; ForcedRoomType = lightSourceSerializable.RoomType != RoomType.Unknown ? lightSourceSerializable.RoomType : FindRoom().Type; UpdateObject(); @@ -46,7 +46,7 @@ public LightSourceObject Init(LightSourceSerializable lightSourceSerializable, b if (spawn) NetworkServer.Spawn(gameObject); - _lightSourceToy.enabled = false; + IsStatic = false; return this; } @@ -56,9 +56,11 @@ public override MapEditorObject Init(SchematicBlockData block) base.Init(block); Base = new(block); - Light.MovementSmoothing = 60; + // Light.MovementSmoothing = 60; UpdateObject(); + IsStatic = true; + // _lightSourceToy.enabled = false; return this; } @@ -82,6 +84,17 @@ public Light Light } } + public bool IsStatic + { + get => _isStatic; + set + { + _lightSourceToy.enabled = !value; + Light.MovementSmoothing = (byte)(value ? 0 : 60); + _isStatic = value; + } + } + /// public override bool IsRotatable => false; @@ -122,5 +135,7 @@ private void UpdateTransformProperties() { _lightSourceToy.NetworkPosition = _transform.position; } + + private bool _isStatic; } } \ No newline at end of file diff --git a/MapEditorReborn/API/Features/Objects/PrimitiveObject.cs b/MapEditorReborn/API/Features/Objects/PrimitiveObject.cs index e99eb63e..1d0dd875 100644 --- a/MapEditorReborn/API/Features/Objects/PrimitiveObject.cs +++ b/MapEditorReborn/API/Features/Objects/PrimitiveObject.cs @@ -19,9 +19,9 @@ namespace MapEditorReborn.API.Features.Objects public class PrimitiveObject : MapEditorObject { private Transform _transform; - private Rigidbody _rigidbody; + private Rigidbody? _rigidbody; private PrimitiveObjectToy _primitiveObjectToy; - private Primitive _exiledPrimitive; + private Primitive? _exiledPrimitive; private void Awake() { @@ -37,13 +37,13 @@ private void Awake() public PrimitiveObject Init(PrimitiveSerializable primitiveSerializable) { Base = primitiveSerializable; - Primitive.MovementSmoothing = 60; + // Primitive.MovementSmoothing = 60; _prevScale = transform.localScale; ForcedRoomType = primitiveSerializable.RoomType == RoomType.Unknown ? FindRoom().Type : primitiveSerializable.RoomType; UpdateObject(); - _primitiveObjectToy.enabled = false; + IsStatic = false; return this; } @@ -53,9 +53,10 @@ public override MapEditorObject Init(SchematicBlockData block) base.Init(block); Base = new(block); - Primitive.MovementSmoothing = 60; + // Primitive.MovementSmoothing = 60; UpdateObject(); + IsStatic = true; return this; } @@ -78,12 +79,23 @@ public Rigidbody Rigidbody return _rigidbody; if (TryGetComponent(out _rigidbody)) - return _rigidbody; + return _rigidbody!; return _rigidbody = gameObject.AddComponent(); } } + public bool IsStatic + { + get => _isStatic; + set + { + _primitiveObjectToy.enabled = !value; + Primitive.MovementSmoothing = (byte)(value ? 0 : 60); + _isStatic = value; + } + } + /// public override void UpdateObject() { @@ -113,6 +125,7 @@ private void UpdateTransformProperties() _primitiveObjectToy.NetworkScale = _transform.root != _transform ? Vector3.Scale(_transform.localScale, _transform.root.localScale) : _transform.localScale; } + private bool _isStatic; private Vector3 _prevScale; } } \ No newline at end of file diff --git a/MapEditorReborn/API/Features/Objects/RagdollSpawnPointObject.cs b/MapEditorReborn/API/Features/Objects/RagdollSpawnPointObject.cs index 16408c40..cd95ee44 100644 --- a/MapEditorReborn/API/Features/Objects/RagdollSpawnPointObject.cs +++ b/MapEditorReborn/API/Features/Objects/RagdollSpawnPointObject.cs @@ -1,4 +1,4 @@ -// ----------------------------------------------------------------------- +// ----------------------------------------------------------------------- // // Copyright (c) MapEditorReborn. All rights reserved. // Licensed under the CC BY-SA 3.0 license. @@ -10,6 +10,7 @@ namespace MapEditorReborn.API.Features.Objects using System.Collections.Generic; using Exiled.API.Enums; using Exiled.API.Features; + using PlayerRoles.Ragdolls; using PlayerStatsSystem; using Serializable; using UnityEngine; @@ -84,4 +85,4 @@ private void OnDestroy() /// public Ragdoll AttachedRagdoll; } -} \ No newline at end of file +} diff --git a/MapEditorReborn/API/Features/Objects/SchematicObject.cs b/MapEditorReborn/API/Features/Objects/SchematicObject.cs index 0c6ec3ac..a9b5a61b 100644 --- a/MapEditorReborn/API/Features/Objects/SchematicObject.cs +++ b/MapEditorReborn/API/Features/Objects/SchematicObject.cs @@ -44,9 +44,9 @@ public class SchematicObject : MapEditorObject /// The to instantiate. /// The object data from a file. /// Instance of this component. - public SchematicObject Init(SchematicSerializable schematicSerializable, SchematicObjectDataList data) + public SchematicObject Init(SchematicSerializable schematicSerializable, SchematicObjectDataList data, bool isStatic) { - Log.Info($"Initializing schematic \"{schematicSerializable.SchematicName}\""); + Log.Debug($"Initializing schematic \"{schematicSerializable.SchematicName}\""); Base = schematicSerializable; SchematicData = data; @@ -62,7 +62,7 @@ public SchematicObject Init(SchematicSerializable schematicSerializable, Schemat CreateTeleporters(); AddRigidbodies(); - if (Config.SchematicBlockSpawnDelay != -1f) + if (Config.SchematicBlockSpawnDelay >= 0f) { Timing.RunCoroutine(SpawnDelayed()); } @@ -71,10 +71,21 @@ public SchematicObject Init(SchematicSerializable schematicSerializable, Schemat foreach (NetworkIdentity networkIdentity in NetworkIdentities) NetworkServer.Spawn(networkIdentity.gameObject); - AddAnimators(); + // if (!AddAnimators() && isStatic) + // { + // Log.Debug($"Schematic {Name} has no animators, making it static..."); + // IsStatic = true; + // } + IsBuilt = true; } + bool animated = AddAnimators(); + bool value = !animated && isStatic; + IsStatic = value; + if (value) + Log.Debug($"Schematic {Name} has no animators, making it static..."); + AttachedBlocks.CollectionChanged += OnCollectionChanged; UpdateObject(); @@ -130,22 +141,61 @@ public ReadOnlyCollection NetworkIdentities { get { - if (_networkIdentities == null) + if (_networkIdentities != null) + return _networkIdentities; + + List list = new(); + foreach (GameObject block in AttachedBlocks) + { + if (block.TryGetComponent(out NetworkIdentity networkIdentity)) + list.Add(networkIdentity); + } + + _networkIdentities = list.AsReadOnly(); + return _networkIdentities; + } + } + + public ReadOnlyCollection AdminToyBases + { + get + { + if (_adminToyBases != null) + return _adminToyBases; + + List list = new(); + foreach (NetworkIdentity netId in NetworkIdentities) { - List list = new(); + if (netId.TryGetComponent(out AdminToyBase adminToyBase)) + list.Add(adminToyBase); + } + + _adminToyBases = list.AsReadOnly(); + return _adminToyBases; + } + } - foreach (GameObject block in AttachedBlocks) + public bool IsStatic + { + get => _isStatic; + set + { + foreach (AdminToyBase toy in AdminToyBases) + { + if (toy.TryGetComponent(out PrimitiveObject primitiveObject)) { - if (block.TryGetComponent(out NetworkIdentity networkIdentity)) - { - list.Add(networkIdentity); - } + primitiveObject.IsStatic = value; + continue; } - _networkIdentities = list.AsReadOnly(); + if (toy.TryGetComponent(out LightSourceObject lightSourceObject)) + { + // lightSourceObject.IsStatic = value; + lightSourceObject.IsStatic = false; + } } - return _networkIdentities; + _isStatic = value; } } @@ -154,7 +204,7 @@ public override void UpdateObject() { if (IsRootSchematic && Base.SchematicName != name.Split('-')[1]) { - SchematicObject newObject = ObjectSpawner.SpawnSchematic(Base, transform.position, transform.rotation, transform.localScale); + SchematicObject newObject = ObjectSpawner.SpawnSchematic(Base, transform.position, transform.rotation, transform.localScale, null, true); if (newObject != null) { @@ -196,13 +246,26 @@ public override void UpdateObject() teleport.FixTransform(); } + if (IsStatic) + { + foreach (AdminToyBase adminToyBase in AdminToyBases) + { + if (adminToyBase.TryGetComponent(out PrimitiveObject primitiveObject)) + primitiveObject.UpdateObject(); + } + } + if (!IsRootSchematic) return; // Timing.CallDelayed(0.1f, () => Patches.OverridePositionPatch.ResetValues()); } - private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) => _networkIdentities = null; + private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + _networkIdentities = null; + _adminToyBases = null; + } private void CreateRecursiveFromID(int id, List blocks, Transform parentGameObject) { @@ -368,7 +431,7 @@ private Transform CreateObject(SchematicBlockData block, Transform parentTransfo { string schematicName = block.Properties["SchematicName"].ToString(); - gameObject = ObjectSpawner.SpawnSchematic(schematicName, transform.position + block.Position, Quaternion.Euler(transform.eulerAngles + block.Rotation)).gameObject; + gameObject = ObjectSpawner.SpawnSchematic(schematicName, transform.position + block.Position, Quaternion.Euler(transform.eulerAngles + block.Rotation), null, null, true).gameObject; gameObject.transform.parent = parentTransform; gameObject.name = schematicName; @@ -401,7 +464,7 @@ private bool TryGetAnimatorController(string animatorName, out RuntimeAnimatorCo if (!File.Exists(path)) { - Log.Warn($"{gameObject.name} block of {name} should have a {animatorName} animator attached, but the file does not exist!"); + Log.Warn($"{gameObject.name} block of {Name} should have a {animatorName} animator attached, but the file does not exist!"); return false; } @@ -412,13 +475,19 @@ private bool TryGetAnimatorController(string animatorName, out RuntimeAnimatorCo return true; } - private void AddAnimators() + private bool AddAnimators() { - foreach (KeyValuePair pair in _animators) - pair.Key.AddComponent().runtimeAnimatorController = pair.Value; + bool isAnimated = false; + if (!_animators.IsEmpty()) + { + isAnimated = true; + foreach (KeyValuePair pair in _animators) + pair.Key.AddComponent().runtimeAnimatorController = pair.Value; + } _animators = null; AssetBundle.UnloadAllAssetBundles(false); + return isAnimated; } private IEnumerator SpawnDelayed() @@ -429,9 +498,9 @@ private IEnumerator SpawnDelayed() yield return Timing.WaitForSeconds(Config.SchematicBlockSpawnDelay); } - AddAnimators(); IsBuilt = true; + /* if (Base.CullingType != CullingType.Distance) yield break; @@ -442,6 +511,7 @@ private IEnumerator SpawnDelayed() player.DestroyNetworkIdentity(networkIdentity); } } + */ } private void CreateTeleporters() @@ -518,7 +588,9 @@ private void OnDestroy() internal bool IsBuilt; internal Dictionary ObjectFromId = new(); - private ReadOnlyCollection _networkIdentities; + private bool _isStatic; + private ReadOnlyCollection? _networkIdentities; + private ReadOnlyCollection? _adminToyBases; private Dictionary _transformProperties = new(); private Dictionary _animators = new(); diff --git a/MapEditorReborn/API/Features/Objects/TeleportObject.cs b/MapEditorReborn/API/Features/Objects/TeleportObject.cs index e99034ae..663bf5ae 100644 --- a/MapEditorReborn/API/Features/Objects/TeleportObject.cs +++ b/MapEditorReborn/API/Features/Objects/TeleportObject.cs @@ -173,8 +173,8 @@ private void OnTriggerEnter(Collider collider) Player player = Player.Get(gameObject); if (player is not null && !Base.AllowedRoles.Contains(player.Role.Type.ToString())) return; - - if (player is not null && player.Role.As().ActiveTime.TotalMilliseconds < 250) + + if (player is not null && player.Role.Base.ActiveTime < 0.25f) return; int choosenTeleporter = Choose(Base.TargetTeleporters); diff --git a/MapEditorReborn/API/Features/Serializable/SerializableTeleport.cs b/MapEditorReborn/API/Features/Serializable/SerializableTeleport.cs index b1c768bc..16a7c475 100644 --- a/MapEditorReborn/API/Features/Serializable/SerializableTeleport.cs +++ b/MapEditorReborn/API/Features/Serializable/SerializableTeleport.cs @@ -20,6 +20,8 @@ public class SerializableTeleport : SchematicBlockData "Scp106", "Scp173", "Scp939", + "Scp3114", + "ZombieFlamingo", "ClassD", "Scientist", "FacilityGuard", @@ -32,6 +34,8 @@ public class SerializableTeleport : SchematicBlockData "ChaosRepressor", "ChaosMarauder", "Tutorial", + "AlphaFlamingo", + "Flamingo", }; public float Cooldown { get; set; } = 10f; diff --git a/MapEditorReborn/Commands/ToolgunCommands/CreateObject.cs b/MapEditorReborn/Commands/ToolgunCommands/CreateObject.cs index 7631dd71..0294fd67 100644 --- a/MapEditorReborn/Commands/ToolgunCommands/CreateObject.cs +++ b/MapEditorReborn/Commands/ToolgunCommands/CreateObject.cs @@ -115,7 +115,7 @@ public bool Execute(ArraySegment arguments, ICommandSender sender, out s { SchematicObject schematicObject; - SpawnedObjects.Add(schematicObject = ObjectSpawner.SpawnSchematic(objectName, position, Quaternion.identity, Vector3.one, data)); + SpawnedObjects.Add(schematicObject = ObjectSpawner.SpawnSchematic(objectName, position, Quaternion.identity, Vector3.one, data, true)); if (MapEditorReborn.Singleton.Config.AutoSelect) TrySelectObject(player, schematicObject); diff --git a/MapEditorReborn/Commands/UtilityCommands/GravityGun.cs b/MapEditorReborn/Commands/UtilityCommands/GravityGun.cs index 9f98fbec..05e794d5 100644 --- a/MapEditorReborn/Commands/UtilityCommands/GravityGun.cs +++ b/MapEditorReborn/Commands/UtilityCommands/GravityGun.cs @@ -1,4 +1,4 @@ -// ----------------------------------------------------------------------- +// ----------------------------------------------------------------------- // // Copyright (c) MapEditorReborn. All rights reserved. // Licensed under the CC BY-SA 3.0 license. @@ -58,8 +58,8 @@ public bool Execute(ArraySegment arguments, ICommandSender sender, out s return false; } - Item gravityGun = player.AddItem(ItemType.GunRevolver, new List()); - ((Firearm)gravityGun).Ammo = 0; + Item gravityGun = player.AddItem(ItemType.GunRevolver); + ((Firearm)gravityGun).Ammo = 0; GravityGuns.Add(gravityGun.Serial, GravityGunMode.Movement); response = "You now have the Gravity Gun!"; diff --git a/MapEditorReborn/Configs/Config.cs b/MapEditorReborn/Configs/Config.cs index 4464d612..c8aa252e 100644 --- a/MapEditorReborn/Configs/Config.cs +++ b/MapEditorReborn/Configs/Config.cs @@ -50,7 +50,7 @@ public sealed class Config : IConfig /// Gets a delay between spawning each block of a custom schematic. /// [Description("The delay (in seconds) between spawning each block of a custom schematic. Setting this to -1 will disable it.")] - public float SchematicBlockSpawnDelay { get; private set; } = 0f; + public float SchematicBlockSpawnDelay { get; private set; } = -1f; /// /// Gets a value indicating whether gets or sets a value whether the plugin tracking is enabled. This is used to count how many servers are using the plugin. diff --git a/MapEditorReborn/Events/EventArgs/BringingObjectEventArgs.cs b/MapEditorReborn/Events/EventArgs/BringingObjectEventArgs.cs index 5c424ff7..6b4d58ab 100644 --- a/MapEditorReborn/Events/EventArgs/BringingObjectEventArgs.cs +++ b/MapEditorReborn/Events/EventArgs/BringingObjectEventArgs.cs @@ -7,7 +7,6 @@ namespace MapEditorReborn.Events.EventArgs { - using System; using API.Features.Objects; using Exiled.API.Features; using Exiled.Events.EventArgs.Interfaces; @@ -16,7 +15,7 @@ namespace MapEditorReborn.Events.EventArgs /// /// Contains all information before a is brought. /// - public class BringingObjectEventArgs : EventArgs, IExiledEvent + public class BringingObjectEventArgs : IPlayerEvent { /// /// Initializes a new instance of the class. diff --git a/MapEditorReborn/Events/EventArgs/ButtonInteractedEventArgs.cs b/MapEditorReborn/Events/EventArgs/ButtonInteractedEventArgs.cs index d3b746c2..87a1ac05 100644 --- a/MapEditorReborn/Events/EventArgs/ButtonInteractedEventArgs.cs +++ b/MapEditorReborn/Events/EventArgs/ButtonInteractedEventArgs.cs @@ -13,7 +13,7 @@ namespace MapEditorReborn.Events.EventArgs using Exiled.API.Features.Pickups; using Exiled.Events.EventArgs.Interfaces; - public class ButtonInteractedEventArgs : EventArgs, IExiledEvent + public class ButtonInteractedEventArgs : IPlayerEvent, IPickupEvent { public ButtonInteractedEventArgs(Pickup button, Player player, SchematicObject schematic) { @@ -24,6 +24,8 @@ public ButtonInteractedEventArgs(Pickup button, Player player, SchematicObject s public Pickup Button { get; } + public Pickup Pickup => Button; + public Player Player { get; } public SchematicObject Schematic { get; } diff --git a/MapEditorReborn/Events/EventArgs/ChangingObjectPositionEventArgs.cs b/MapEditorReborn/Events/EventArgs/ChangingObjectPositionEventArgs.cs index 3642b022..56f9c73f 100644 --- a/MapEditorReborn/Events/EventArgs/ChangingObjectPositionEventArgs.cs +++ b/MapEditorReborn/Events/EventArgs/ChangingObjectPositionEventArgs.cs @@ -16,7 +16,7 @@ namespace MapEditorReborn.Events.EventArgs /// /// Contains all information before a is changed. /// - public class ChangingObjectPositionEventArgs : EventArgs, IExiledEvent + public class ChangingObjectPositionEventArgs : IDeniableEvent, IPlayerEvent { /// /// Initializes a new instance of the class. diff --git a/MapEditorReborn/Events/EventArgs/ChangingObjectRotationEventArgs.cs b/MapEditorReborn/Events/EventArgs/ChangingObjectRotationEventArgs.cs index ed5aa439..64aa888a 100644 --- a/MapEditorReborn/Events/EventArgs/ChangingObjectRotationEventArgs.cs +++ b/MapEditorReborn/Events/EventArgs/ChangingObjectRotationEventArgs.cs @@ -16,7 +16,7 @@ namespace MapEditorReborn.Events.EventArgs /// /// Contains all information before a is changed. /// - public class ChangingObjectRotationEventArgs : EventArgs, IExiledEvent + public class ChangingObjectRotationEventArgs : IDeniableEvent, IPlayerEvent { /// /// Initializes a new instance of the class. diff --git a/MapEditorReborn/Events/EventArgs/ChangingObjectScaleEventArgs.cs b/MapEditorReborn/Events/EventArgs/ChangingObjectScaleEventArgs.cs index f9fab49a..358594d0 100644 --- a/MapEditorReborn/Events/EventArgs/ChangingObjectScaleEventArgs.cs +++ b/MapEditorReborn/Events/EventArgs/ChangingObjectScaleEventArgs.cs @@ -16,7 +16,7 @@ namespace MapEditorReborn.Events.EventArgs /// /// Contains all information before a is changed. /// - public class ChangingObjectScaleEventArgs : EventArgs, IExiledEvent + public class ChangingObjectScaleEventArgs : IDeniableEvent, IPlayerEvent { /// /// Initializes a new instance of the class. diff --git a/MapEditorReborn/Events/EventArgs/CopyingObjectEventArgs.cs b/MapEditorReborn/Events/EventArgs/CopyingObjectEventArgs.cs index 14c5085d..42399665 100644 --- a/MapEditorReborn/Events/EventArgs/CopyingObjectEventArgs.cs +++ b/MapEditorReborn/Events/EventArgs/CopyingObjectEventArgs.cs @@ -15,7 +15,7 @@ namespace MapEditorReborn.Events.EventArgs /// /// Contains all information before a is deleted. /// - public class CopyingObjectEventArgs : EventArgs, IExiledEvent + public class CopyingObjectEventArgs : IDeniableEvent, IPlayerEvent { /// /// Initializes a new instance of the class. diff --git a/MapEditorReborn/Events/EventArgs/DeletingObjectEventArgs.cs b/MapEditorReborn/Events/EventArgs/DeletingObjectEventArgs.cs index 4e09160a..404b6d0e 100644 --- a/MapEditorReborn/Events/EventArgs/DeletingObjectEventArgs.cs +++ b/MapEditorReborn/Events/EventArgs/DeletingObjectEventArgs.cs @@ -15,7 +15,7 @@ namespace MapEditorReborn.Events.EventArgs /// /// Contains all information before a is deleted. /// - public class DeletingObjectEventArgs : EventArgs, IExiledEvent + public class DeletingObjectEventArgs : IDeniableEvent, IPlayerEvent { /// /// Initializes a new instance of the class. diff --git a/MapEditorReborn/Events/EventArgs/DroppingToolGunEventArgs.cs b/MapEditorReborn/Events/EventArgs/DroppingToolGunEventArgs.cs index 0301f394..2c977832 100644 --- a/MapEditorReborn/Events/EventArgs/DroppingToolGunEventArgs.cs +++ b/MapEditorReborn/Events/EventArgs/DroppingToolGunEventArgs.cs @@ -14,7 +14,7 @@ namespace MapEditorReborn.Events.EventArgs /// /// Contains all information before dropping the ToolGun. /// - public class DroppingToolGunEventArgs : EventArgs, IExiledEvent + public class DroppingToolGunEventArgs : IDeniableEvent, IPlayerEvent { /// /// Initializes a new instance of the class. diff --git a/MapEditorReborn/Events/EventArgs/GrabbingObjectEventArgs.cs b/MapEditorReborn/Events/EventArgs/GrabbingObjectEventArgs.cs index 11c3c1bf..0fc64df7 100644 --- a/MapEditorReborn/Events/EventArgs/GrabbingObjectEventArgs.cs +++ b/MapEditorReborn/Events/EventArgs/GrabbingObjectEventArgs.cs @@ -15,7 +15,7 @@ namespace MapEditorReborn.Events.EventArgs /// /// Contains all information before a is grabbed. /// - public class GrabbingObjectEventArgs : EventArgs, IExiledEvent + public class GrabbingObjectEventArgs : IDeniableEvent, IPlayerEvent { /// /// Initializes a new instance of the class. diff --git a/MapEditorReborn/Events/EventArgs/LoadingMapEventArgs.cs b/MapEditorReborn/Events/EventArgs/LoadingMapEventArgs.cs index 96555fac..cfdf305b 100644 --- a/MapEditorReborn/Events/EventArgs/LoadingMapEventArgs.cs +++ b/MapEditorReborn/Events/EventArgs/LoadingMapEventArgs.cs @@ -14,7 +14,7 @@ namespace MapEditorReborn.Events.EventArgs /// /// Contains all information before the is loaded. /// - public class LoadingMapEventArgs : EventArgs, IExiledEvent + public class LoadingMapEventArgs : IDeniableEvent { /// /// Initializes a new instance of the class. diff --git a/MapEditorReborn/Events/EventArgs/PickingUpToolGunEventArgs.cs b/MapEditorReborn/Events/EventArgs/PickingUpToolGunEventArgs.cs index 5f95b3c9..3e863dd4 100644 --- a/MapEditorReborn/Events/EventArgs/PickingUpToolGunEventArgs.cs +++ b/MapEditorReborn/Events/EventArgs/PickingUpToolGunEventArgs.cs @@ -14,7 +14,7 @@ namespace MapEditorReborn.Events.EventArgs /// /// Contains all information before a picking up the ToolGun. /// - public class PickingUpToolGunEventArgs : EventArgs, IExiledEvent + public class PickingUpToolGunEventArgs : IDeniableEvent, IPlayerEvent { /// /// Initializes a new instance of the class. diff --git a/MapEditorReborn/Events/EventArgs/ReleasingObjectEventArgs.cs b/MapEditorReborn/Events/EventArgs/ReleasingObjectEventArgs.cs index 855180b2..3b9e8988 100644 --- a/MapEditorReborn/Events/EventArgs/ReleasingObjectEventArgs.cs +++ b/MapEditorReborn/Events/EventArgs/ReleasingObjectEventArgs.cs @@ -15,7 +15,7 @@ namespace MapEditorReborn.Events.EventArgs /// /// Contains all information before a is released. /// - public class ReleasingObjectEventArgs : EventArgs, IExiledEvent + public class ReleasingObjectEventArgs : IDeniableEvent, IPlayerEvent { /// /// Initializes a new instance of the class. diff --git a/MapEditorReborn/Events/EventArgs/SchematicDestroyedEventArgs.cs b/MapEditorReborn/Events/EventArgs/SchematicDestroyedEventArgs.cs index 681cd21f..d7fce756 100644 --- a/MapEditorReborn/Events/EventArgs/SchematicDestroyedEventArgs.cs +++ b/MapEditorReborn/Events/EventArgs/SchematicDestroyedEventArgs.cs @@ -11,7 +11,7 @@ namespace MapEditorReborn.Events.EventArgs using API.Features.Objects; using Exiled.Events.EventArgs.Interfaces; - public class SchematicDestroyedEventArgs : EventArgs, IExiledEvent + public class SchematicDestroyedEventArgs : IExiledEvent { public SchematicDestroyedEventArgs(SchematicObject schematic, string name) { diff --git a/MapEditorReborn/Events/EventArgs/SchematicSpawnedEventArgs.cs b/MapEditorReborn/Events/EventArgs/SchematicSpawnedEventArgs.cs index d3894cdd..0dfdf3c1 100644 --- a/MapEditorReborn/Events/EventArgs/SchematicSpawnedEventArgs.cs +++ b/MapEditorReborn/Events/EventArgs/SchematicSpawnedEventArgs.cs @@ -11,7 +11,7 @@ namespace MapEditorReborn.Events.EventArgs using API.Features.Objects; using Exiled.Events.EventArgs.Interfaces; - public class SchematicSpawnedEventArgs : EventArgs, IExiledEvent + public class SchematicSpawnedEventArgs : IExiledEvent { public SchematicSpawnedEventArgs(SchematicObject schematic, string name) { diff --git a/MapEditorReborn/Events/EventArgs/SelectingObjectEventArgs.cs b/MapEditorReborn/Events/EventArgs/SelectingObjectEventArgs.cs index 008fb4af..df994016 100644 --- a/MapEditorReborn/Events/EventArgs/SelectingObjectEventArgs.cs +++ b/MapEditorReborn/Events/EventArgs/SelectingObjectEventArgs.cs @@ -16,7 +16,7 @@ namespace MapEditorReborn.Events.EventArgs /// /// Contains all information before a is selected. /// - public class SelectingObjectEventArgs : EventArgs, IExiledEvent + public class SelectingObjectEventArgs : IDeniableEvent, IPlayerEvent { /// /// Initializes a new instance of the class. diff --git a/MapEditorReborn/Events/EventArgs/ShowingObjectHintEventArgs.cs b/MapEditorReborn/Events/EventArgs/ShowingObjectHintEventArgs.cs index 078a7598..cc2c1107 100644 --- a/MapEditorReborn/Events/EventArgs/ShowingObjectHintEventArgs.cs +++ b/MapEditorReborn/Events/EventArgs/ShowingObjectHintEventArgs.cs @@ -15,7 +15,7 @@ namespace MapEditorReborn.Events.EventArgs /// /// Contains all information before showing a 's hint. /// - public class ShowingObjectHintEventArgs : EventArgs, IExiledEvent + public class ShowingObjectHintEventArgs : IDeniableEvent, IPlayerEvent { /// /// Initializes a new instance of the class. diff --git a/MapEditorReborn/Events/EventArgs/SpawningObjectEventArgs.cs b/MapEditorReborn/Events/EventArgs/SpawningObjectEventArgs.cs index 4224a3fd..01de5cee 100644 --- a/MapEditorReborn/Events/EventArgs/SpawningObjectEventArgs.cs +++ b/MapEditorReborn/Events/EventArgs/SpawningObjectEventArgs.cs @@ -17,7 +17,7 @@ namespace MapEditorReborn.Events.EventArgs /// /// Contains all information before a is spawned. /// - public class SpawningObjectEventArgs : EventArgs, IExiledEvent + public class SpawningObjectEventArgs : IDeniableEvent, IPlayerEvent { /// /// Initializes a new instance of the class. diff --git a/MapEditorReborn/Events/EventArgs/TeleportingEventArgs.cs b/MapEditorReborn/Events/EventArgs/TeleportingEventArgs.cs index f2a8e7e1..c4da13d4 100644 --- a/MapEditorReborn/Events/EventArgs/TeleportingEventArgs.cs +++ b/MapEditorReborn/Events/EventArgs/TeleportingEventArgs.cs @@ -16,7 +16,7 @@ namespace MapEditorReborn.Events.EventArgs /// /// Contains all information before the object gets teleported. /// - public class TeleportingEventArgs : EventArgs, IExiledEvent + public class TeleportingEventArgs : IDeniableEvent, IPlayerEvent { /// /// Initializes a new instance of the class. diff --git a/MapEditorReborn/Events/EventArgs/UnloadingMapEventArgs.cs b/MapEditorReborn/Events/EventArgs/UnloadingMapEventArgs.cs index 55f05fcb..e25bfe21 100644 --- a/MapEditorReborn/Events/EventArgs/UnloadingMapEventArgs.cs +++ b/MapEditorReborn/Events/EventArgs/UnloadingMapEventArgs.cs @@ -15,7 +15,7 @@ namespace MapEditorReborn.Events.EventArgs /// /// Contains all information before the is unloaded. /// - public class UnloadingMapEventArgs : EventArgs, IExiledEvent + public class UnloadingMapEventArgs : IDeniableEvent, IPlayerEvent { /// /// Initializes a new instance of the class. diff --git a/MapEditorReborn/Events/Handlers/Internal/EventHandler.cs b/MapEditorReborn/Events/Handlers/Internal/EventHandler.cs index 51ba6078..f7c5149f 100644 --- a/MapEditorReborn/Events/Handlers/Internal/EventHandler.cs +++ b/MapEditorReborn/Events/Handlers/Internal/EventHandler.cs @@ -9,9 +9,7 @@ namespace MapEditorReborn.Events.Handlers.Internal { using System; using System.Collections.Generic; - using System.Collections.ObjectModel; using System.IO; - using System.Linq; using API.Enums; using API.Features; using API.Features.Objects; @@ -22,20 +20,16 @@ namespace MapEditorReborn.Events.Handlers.Internal using Exiled.API.Features; using Exiled.API.Features.Items; using Exiled.API.Features.Pools; - using Exiled.API.Features.Toys; using Exiled.CustomItems.API.Features; using Exiled.Events.EventArgs.Map; using Exiled.Events.EventArgs.Player; using Exiled.Loader; using Interactables.Interobjects.DoorUtils; using InventorySystem.Items.Firearms.Modules; - using MapGeneration; using MEC; - using Mirror; using UnityEngine; using static API.API; using Config = Configs.Config; - using Object = UnityEngine.Object; /// /// Handles mostly EXILED events. @@ -45,44 +39,9 @@ internal static class EventHandler /// internal static void OnGenerated() { - RoomTypes = null; SpawnedObjects.Clear(); - - Dictionary objectList = new(21); - DoorSpawnpoint[] doorList = Object.FindObjectsOfType(); - - objectList.Add(ObjectType.LczDoor, doorList.First(x => x.TargetPrefab.name.Contains("LCZ")).TargetPrefab.gameObject); - objectList.Add(ObjectType.HczDoor, doorList.First(x => x.TargetPrefab.name.Contains("HCZ")).TargetPrefab.gameObject); - objectList.Add(ObjectType.EzDoor, doorList.First(x => x.TargetPrefab.name.Contains("EZ")).TargetPrefab.gameObject); - - objectList.Add(ObjectType.WorkStation, NetworkClient.prefabs.Values.First(x => x.name.Contains("Work Station"))); - - objectList.Add(ObjectType.ItemSpawnPoint, new GameObject("ItemSpawnPointObject")); - objectList.Add(ObjectType.PlayerSpawnPoint, new GameObject("PlayerSpawnPointObject")); - objectList.Add(ObjectType.RagdollSpawnPoint, new GameObject("RagdollSpawnPointObject")); - objectList.Add(ObjectType.DummySpawnPoint, new GameObject("DummySpawnPointObject")); - - objectList.Add(ObjectType.SportShootingTarget, ToysHelper.SportShootingTargetObject.gameObject); - objectList.Add(ObjectType.DboyShootingTarget, ToysHelper.DboyShootingTargetObject.gameObject); - objectList.Add(ObjectType.BinaryShootingTarget, ToysHelper.BinaryShootingTargetObject.gameObject); - - objectList.Add(ObjectType.Primitive, ToysHelper.PrimitiveBaseObject.gameObject); - objectList.Add(ObjectType.LightSource, ToysHelper.LightBaseObject.gameObject); - - objectList.Add(ObjectType.RoomLight, new GameObject("LightControllerObject")); - - GameObject teleportPrefab = GameObject.CreatePrimitive(PrimitiveType.Cube); - teleportPrefab.name = "TeleportObject"; - objectList.Add(ObjectType.Teleporter, teleportPrefab); - - objectList.Add(ObjectType.PedestalLocker, NetworkClient.prefabs.Values.First(x => x.name == "Scp500PedestalStructure Variant")); - objectList.Add(ObjectType.LargeGunLocker, NetworkClient.prefabs.Values.First(x => x.name == "LargeGunLockerStructure")); - objectList.Add(ObjectType.RifleRackLocker, NetworkClient.prefabs.Values.First(x => x.name == "RifleRackStructure")); - objectList.Add(ObjectType.MiscLocker, NetworkClient.prefabs.Values.First(x => x.name == "MiscLocker")); - objectList.Add(ObjectType.MedkitLocker, NetworkClient.prefabs.Values.First(x => x.name == "RegularMedkitStructure")); - objectList.Add(ObjectType.AdrenalineLocker, NetworkClient.prefabs.Values.First(x => x.name == "AdrenalineMedkitStructure")); - - ObjectPrefabs = new ReadOnlyDictionary(objectList); + PopulateRoomTypeLists(); + GetObjectPrefabs(); PlayerSpawnPointObject.RegisterSpawnPoints(); VanillaDoorObject.NameUnnamedDoors(); @@ -102,6 +61,7 @@ internal static void OnGenerated() /// internal static void OnWarheadDetonated() => AutoLoadMaps(Config.LoadMapOnEvent.OnWarheadDetonated); + /// internal static void OnShootingDoor(ShootingEventArgs ev) { Vector3 forward = ev.Player.CameraTransform.forward; diff --git a/MapEditorReborn/MapEditorReborn.cs b/MapEditorReborn/MapEditorReborn.cs index 232d98c5..55afb7d4 100644 --- a/MapEditorReborn/MapEditorReborn.cs +++ b/MapEditorReborn/MapEditorReborn.cs @@ -212,9 +212,9 @@ public override void OnDisabled() public override string Author => "Michal78900"; /// - public override Version Version { get; } = new (3, 0, 2); + public override Version Version { get; } = new (3, 1, 0); /// - public override Version RequiredExiledVersion { get; } = new (8, 0, 0); + public override Version RequiredExiledVersion { get; } = new (8, 7, 0); } } \ No newline at end of file diff --git a/MapEditorReborn/MapEditorReborn.csproj b/MapEditorReborn/MapEditorReborn.csproj index fa8117b9..d243321a 100644 --- a/MapEditorReborn/MapEditorReborn.csproj +++ b/MapEditorReborn/MapEditorReborn.csproj @@ -1,4 +1,4 @@ - + 10 @@ -22,7 +22,7 @@ - + diff --git a/MapEditorReborn/ServerCountHandler.cs b/MapEditorReborn/ServerCountHandler.cs index 19e829f0..da6c55f3 100644 --- a/MapEditorReborn/ServerCountHandler.cs +++ b/MapEditorReborn/ServerCountHandler.cs @@ -14,7 +14,7 @@ internal static void Loop() { try { - HttpQuery.Get($"https://mer.sfnetwork.pl/?address={Server.IpAddress}:{Server.Port}"); + HttpQuery.Get($"https://mer.scpsecretlab.pl/?address={Server.IpAddress}:{Server.Port}"); } catch (Exception) { diff --git a/README.md b/README.md index 7749b03f..23a503de 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,15 @@ -[![MapEditorReborn](https://cdn.discordapp.com/attachments/835633260339003392/971053338412089364/unknown.png)](https://mer.sfnetwork.pl) -[![Discord](https://img.shields.io/discord/947849283514814486?color=%235865F2&label=Discord&style=for-the-badge)](https://discord.gg/JwAfeSd79u) -[![Downloads](https://img.shields.io/github/downloads/Michal78900/MapEditorReborn/total?color=brown&label=Downloads&style=for-the-badge)](https://github.com/Michal78900/MapEditorReborn/releases) -[![Patreons](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fshieldsio-patreon.vercel.app%2Fapi%3Fusername%3DMapEditorReborn%26type%3Dpatrons&style=for-the-badge)](https://www.patreon.com/MapEditorReborn) -![Lines](https://img.shields.io/tokei/lines/github/Michal78900/MapEditorReborn?style=for-the-badge) +[![MapEditorReborn](https://cdn.discordapp.com/attachments/835633260339003392/971053338412089364/unknown.png)](https://discord.gg/JwAfeSd79u) -# MapEditorReborn -MapEditorReborn is an [SCP: Secret Laboratory](https://store.steampowered.com/app/700330/SCP_Secret_Laboratory/) plugin allowing to spawn and modify various objects. +

MapEditorReborn

+

SCP: Secret Laboratory plugin allowing to spawn and modify various objects.

+
+ +Downloads + + Chat on Discord + + +
# Installation You will need **latest** [EXILED Version](https://github.com/Exiled-Team/EXILED/releases/latest) installed on your server. @@ -13,15 +17,12 @@ You will need **latest** [EXILED Version](https://github.com/Exiled-Team/EXILED/ Put your [`MapEditorReborn.dll`](https://github.com/Michal78900/MapEditorReborn/releases/latest) file in `EXILED/Plugins` path. Once your plugin will load, it will create directory `EXILED/Configs/MapEditorReborn`; This directory will contain two sub-directories **Schematics** and **Maps** -**[Full tutorial installation tutorial](https://mer.sfnetwork.pl/docs/index.html)** +**[Full MER tutorial](https://docs.google.com/document/d/10V2PnqobeBFb2xTFIHSGmM2KK9_h2wethiVQdcjyhGc/edit?usp=sharing)** -# Documentation and tutorials -All of tutorials can be found on [MER docs site](https://mer.sfnetwork.pl/docs/index.html) +**More support can be found on a [Discord](https://discord.gg/JwAfeSd79u) server** # Credits - Plugin made by [Michal78900](https://github.com/Michal78900) - Original plugin idea and code overhaul by [Killers0992](https://github.com/Killers0992) - Another code overhaul and documentation by [Nao](https://github.com/NaoUnderscore) -- Testing the plugin by Cegła, The Jukers server staff and others -- The Surface map was taken from [SCP: Secret Laboratory](https://store.steampowered.com/app/700330/SCP_Secret_Laboratory/) game files, under use of [CC-BY-SA 3.](https://creativecommons.org/licenses/by/3.0/) Original credit goes to Northwood and Undertow Games. https://scpslgame.com/ https://www.scpcbgame.com/ -- This project uses [NaughtyAttributes](https://github.com/dbrizov/NaughtyAttributes) made by dbrizov under MIT license https://github.com/dbrizov/NaughtyAttributes \ No newline at end of file +- Testing the plugin by Cegła, The Jukers server staff and others \ No newline at end of file