Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Item::<T>Get() and Pickup::<T>Get() #17

Merged
merged 14 commits into from
Aug 9, 2024
57 changes: 43 additions & 14 deletions EXILED/Exiled.API/Features/Doors/Door.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ namespace Exiled.API.Features.Doors
using Exiled.API.Enums;
using Exiled.API.Extensions;
using Exiled.API.Features.Core;
using Exiled.API.Features.Hazards;
using Exiled.API.Interfaces;
using global::Hazards;
using Interactables.Interobjects;
using Interactables.Interobjects.DoorUtils;
using MEC;
Expand Down Expand Up @@ -309,6 +311,31 @@ public static Door Get(DoorVariant doorVariant)
return DoorVariantToDoor[doorVariant];
}

/// <summary>
/// Gets the <see cref="Door"/> by <see cref="DoorVariant"/>.
/// </summary>
/// <param name="doorVariant">The <see cref="DoorVariant"/> to convert into an door.</param>
/// <typeparam name="T">The specified <see cref="Door"/> type.</typeparam>
/// <returns>The door wrapper for the given <see cref="DoorVariant"/>.</returns>
public static T Get<T>(DoorVariant doorVariant)
where T : Door => Get(doorVariant) as T;

/// <summary>
/// Gets a <see cref="Door"/> given the specified <see cref="DoorType"/>.
/// </summary>
/// <param name="doorType">The <see cref="DoorType"/> to search for.</param>
/// <returns>The <see cref="Door"/> with the given <see cref="DoorType"/> or <see langword="null"/> if not found.</returns>
public static Door Get(DoorType doorType) => List.FirstOrDefault(x => x.Type == doorType);

/// <summary>
/// Gets the <see cref="Door"/> by <see cref="DoorVariant"/>.
/// </summary>
/// <param name="doorType">The <see cref="DoorVariant"/> to convert into an door.</param>
/// <typeparam name="T">The specified <see cref="Door"/> type.</typeparam>
/// <returns>The door wrapper for the given <see cref="DoorVariant"/>.</returns>
public static T Get<T>(DoorType doorType)
where T : Door => Get(doorType) as T;

/// <summary>
/// Gets a <see cref="Door"/> given the specified name.
/// </summary>
Expand All @@ -320,27 +347,22 @@ public static Door Get(string name)
return nameExtension is null ? null : Get(nameExtension.TargetDoor);
}

/// <summary>
/// Gets the <see cref="Door"/> by <see cref="DoorVariant"/>.
/// </summary>
/// <param name="name">The name to search for.</param>
/// <typeparam name="T">The specified <see cref="Door"/> type.</typeparam>
/// <returns>The door wrapper for the given <see cref="DoorVariant"/>.</returns>
public static T Get<T>(string name)
where T : Door => Get(name) as T;

/// <summary>
/// Gets the door object associated with a specific <see cref="UnityEngine.GameObject"/>, or creates a new one if there isn't one.
/// </summary>
/// <param name="gameObject">The base-game <see cref="UnityEngine.GameObject"/>.</param>
/// <returns>The <see cref="Door"/> with the given name or <see langword="null"/> if not found.</returns>
public static Door Get(GameObject gameObject) => gameObject is null ? null : Get(gameObject.GetComponentInChildren<DoorVariant>());

/// <summary>
/// Gets a <see cref="IEnumerable{T}"/> of <see cref="Door"/> filtered based on a predicate.
/// </summary>
/// <param name="predicate">The condition to satify.</param>
/// <returns>A <see cref="IEnumerable{T}"/> of <see cref="Door"/> which contains elements that satify the condition.</returns>
public static IEnumerable<Door> Get(Func<Door, bool> predicate) => List.Where(predicate);

/// <summary>
/// Gets a <see cref="Door"/> given the specified <see cref="DoorType"/>.
/// </summary>
/// <param name="doorType">The <see cref="DoorType"/> to search for.</param>
/// <returns>The <see cref="Door"/> with the given <see cref="DoorType"/> or <see langword="null"/> if not found.</returns>
public static Door Get(DoorType doorType) => List.FirstOrDefault(x => x.Type == doorType);

/// <summary>
/// Returns the closest <see cref="Door"/> to the given <paramref name="position"/>.
/// </summary>
Expand All @@ -367,6 +389,13 @@ public static Door Random(ZoneType type = ZoneType.Unspecified, bool onlyUnbroke
return doors[UnityEngine.Random.Range(0, doors.Count)];
}

/// <summary>
/// Gets a <see cref="IEnumerable{T}"/> of <see cref="Door"/> filtered based on a predicate.
/// </summary>
/// <param name="predicate">The condition to satify.</param>
/// <returns>A <see cref="IEnumerable{T}"/> of <see cref="Door"/> which contains elements that satify the condition.</returns>
public static IEnumerable<Door> Get(Func<Door, bool> predicate) => List.Where(predicate);

/// <summary>
/// Locks all <see cref="Door">doors</see> given the specified <see cref="ZoneType"/>.
/// </summary>
Expand Down
9 changes: 9 additions & 0 deletions EXILED/Exiled.API/Features/Hazards/Hazard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,15 @@ public static Hazard Get(EnvironmentalHazard environmentalHazard) =>
_ => new Hazard(environmentalHazard)
};

/// <summary>
/// Gets the <see cref="Hazard"/> by <see cref="EnvironmentalHazard"/>.
/// </summary>
/// <param name="environmentalHazard">The <see cref="EnvironmentalHazard"/> to convert into an hazard.</param>
/// <typeparam name="T">The specified <see cref="Hazard"/> type.</typeparam>
/// <returns>The hazard wrapper for the given <see cref="EnvironmentalHazard"/>.</returns>
public static T Get<T>(EnvironmentalHazard environmentalHazard)
where T : Hazard => Get(environmentalHazard) as T;

/// <summary>
/// Gets the hazard by the room where it's located.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion EXILED/Exiled.API/Features/Items/ExplosiveGrenade.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ public ExplosionGrenadeProjectile SpawnActive(Vector3 position, Player owner = n

ipb.Info = new PickupSyncInfo(Type, Weight, ItemSerialGenerator.GenerateNext());

ExplosionGrenadeProjectile grenade = (ExplosionGrenadeProjectile)Pickup.Get(ipb);
ExplosionGrenadeProjectile grenade = Pickup.Get<ExplosionGrenadeProjectile>(ipb);

grenade.Base.gameObject.SetActive(true);

Expand Down
2 changes: 1 addition & 1 deletion EXILED/Exiled.API/Features/Items/FlashGrenade.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public FlashbangProjectile SpawnActive(Vector3 position, Player owner = null)

ipb.Info = new PickupSyncInfo(Type, Weight, ItemSerialGenerator.GenerateNext());

FlashbangProjectile grenade = (FlashbangProjectile)Pickup.Get(ipb);
FlashbangProjectile grenade = Pickup.Get<FlashbangProjectile>(ipb);

grenade.Base.gameObject.SetActive(true);

Expand Down
45 changes: 43 additions & 2 deletions EXILED/Exiled.API/Features/Items/Item.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,13 @@ namespace Exiled.API.Features.Items
using InventorySystem.Items.Radio;
using InventorySystem.Items.ThrowableProjectiles;
using InventorySystem.Items.ToggleableLights;
using InventorySystem.Items.ToggleableLights.Flashlight;
using InventorySystem.Items.Usables;
using InventorySystem.Items.Usables.Scp1576;
using InventorySystem.Items.Usables.Scp244;
using InventorySystem.Items.Usables.Scp330;
using UnityEngine;

using BaseConsumable = InventorySystem.Items.Usables.Consumable;
using Object = UnityEngine.Object;

/// <summary>
/// A wrapper class for <see cref="ItemBase"/>.
Expand Down Expand Up @@ -219,6 +217,15 @@ public static Item Get(ItemBase itemBase)
};
}

/// <summary>
/// Gets an existing <see cref="Item"/> or creates a new instance of one.
/// </summary>
/// <param name="itemBase">The <see cref="ItemBase"/> to convert into an item.</param>
/// <typeparam name="T">The specified <see cref="Item"/> type.</typeparam>
/// <returns>The item wrapper for the given <see cref="ItemBase"/>.</returns>
public static T Get<T>(ItemBase itemBase)
where T : Item => Get(itemBase) as T;

/// <summary>
/// Gets the Item belonging to the specified serial.
/// </summary>
Expand Down Expand Up @@ -279,6 +286,40 @@ ItemType.KeycardGuard or ItemType.KeycardJanitor or ItemType.KeycardO5 or ItemTy
_ => new Item(type),
};

/// <summary>
/// Creates a new <see cref="Item"/> with the proper inherited subclass.
/// <para>
/// Based on the <paramref name="type"/>, the returned <see cref="Item"/> can be casted into a subclass to gain more control over the object.
/// <br />- Usable items (Adrenaline, Medkit, Painkillers, SCP-207, SCP-268, and SCP-500) should be casted to the <see cref="Usable"/> class.
/// <br />- All valid ammo should be casted to the <see cref="Ammo"/> class.
/// <br />- All valid firearms (not including the Micro HID) should be casted to the <see cref="Firearm"/> class.
/// <br />- All valid keycards should be casted to the <see cref="Keycard"/> class.
/// <br />- All valid armor should be casted to the <see cref="Armor"/> class.
/// <br />- Explosive grenades and SCP-018 should be casted to the <see cref="ExplosiveGrenade"/> class.
/// <br />- Flash grenades should be casted to the <see cref="FlashGrenade"/> class.
/// </para>
/// <para>
/// <br />The following have their own respective classes:
/// <br />- Flashlights can be casted to <see cref="Flashlight"/>.
/// <br />- Radios can be casted to <see cref="Radio"/>.
/// <br />- The Micro HID can be casted to <see cref="MicroHid"/>.
/// <br />- SCP-244 A and B variants can be casted to <see cref="Scp244"/>.
/// <br />- SCP-330 can be casted to <see cref="Scp330"/>.
/// <br />- SCP-2176 can be casted to the <see cref="Scp2176"/> class.
/// <br />- SCP-1576 can be casted to the <see cref="Scp1576"/> class.
/// <br />- Jailbird can be casted to the <see cref="Jailbird"/> class.
/// </para>
/// <para>
/// Items that are not listed above do not have a subclass, and can only use the base <see cref="Item"/> class.
/// </para>
/// </summary>
/// <param name="type">The <see cref="ItemType"/> of the item to create.</param>
/// <param name="owner">The <see cref="Player"/> who owns the item by default.</param>
/// <typeparam name="T">The specified <see cref="Item"/> type.</typeparam>
/// <returns>The <see cref="Item"/> created. This can be cast as a subclass.</returns>
public static Item Create<T>(ItemType type, Player owner = null)
where T : Item => Create(type, owner) as T;

/// <summary>
/// Gives this item to a <see cref="Player"/>.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion EXILED/Exiled.API/Features/Items/Scp018.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public Scp018Projectile SpawnActive(Vector3 position, Player owner = null)

ipb.Info = new PickupSyncInfo(Type, Weight, ItemSerialGenerator.GenerateNext());

Scp018Projectile grenade = (Scp018Projectile)Pickup.Get(ipb);
Scp018Projectile grenade = Pickup.Get<Scp018Projectile>(ipb);

grenade.Base.gameObject.SetActive(true);

Expand Down
2 changes: 1 addition & 1 deletion EXILED/Exiled.API/Features/Items/Scp2176.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public Scp2176Projectile SpawnActive(Vector3 position, Player owner = null)

ipb.Info = new PickupSyncInfo(Type, Weight, ItemSerialGenerator.GenerateNext());

Scp2176Projectile grenade = (Scp2176Projectile)Pickup.Get(ipb);
Scp2176Projectile grenade = Pickup.Get<Scp2176Projectile>(ipb);

grenade.Base.gameObject.SetActive(true);

Expand Down
4 changes: 2 additions & 2 deletions EXILED/Exiled.API/Features/Items/Scp330.cs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ public IEnumerable<Scp330Pickup> DropCandy(CandyKindID type, bool dropAll = fals

ipb.Info = new(Type, Weight, ItemSerialGenerator.GenerateNext());

Scp330Pickup pickup = (Scp330Pickup)Pickup.Get(ipb);
Scp330Pickup pickup = Pickup.Get<Scp330Pickup>(ipb);

if (exposedType is not CandyKindID.None)
pickup.ExposedCandy = exposedType;
Expand All @@ -218,7 +218,7 @@ public IEnumerable<Scp330Pickup> DropCandy(CandyKindID type, bool dropAll = fals

ipb.Info = new(Type, Weight, ItemSerialGenerator.GenerateNext());

Scp330Pickup pickup = (Scp330Pickup)Pickup.Get(ipb);
Scp330Pickup pickup = Pickup.Get<Scp330Pickup>(ipb);

if (exposedType is not CandyKindID.None)
pickup.ExposedCandy = exposedType;
Expand Down
2 changes: 1 addition & 1 deletion EXILED/Exiled.API/Features/Items/Throwable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public Throwable(ThrowableItem itemBase)
{
Base = itemBase;
Base.Projectile.gameObject.SetActive(false);
Projectile = (Projectile)Pickup.Get(Object.Instantiate(Base.Projectile));
Projectile = Pickup.Get<Projectile>(Object.Instantiate(Base.Projectile));
Base.Projectile.gameObject.SetActive(true);
Projectile.Serial = Serial;
}
Expand Down
4 changes: 2 additions & 2 deletions EXILED/Exiled.API/Features/Lift.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ internal Lift(ElevatorChamber elevator)
/// <summary>
/// Gets a value of the internal doors list.
/// </summary>
public IReadOnlyCollection<Doors.ElevatorDoor> Doors => internalDoorsList.Select(x => Door.Get(x).As<Doors.ElevatorDoor>()).ToList();
public IReadOnlyCollection<Doors.ElevatorDoor> Doors => internalDoorsList.Select(x => Door.Get<Doors.ElevatorDoor>(x)).ToList();

/// <summary>
/// Gets a <see cref="IEnumerable{T}"/> of <see cref="Player"/> in the <see cref="Room"/>.
Expand Down Expand Up @@ -201,7 +201,7 @@ public float AnimationTime
/// <summary>
/// Gets the <see cref="CurrentDestination"/>.
/// </summary>
public Doors.ElevatorDoor CurrentDestination => Door.Get(Base.CurrentDestination).As<Doors.ElevatorDoor>();
public Doors.ElevatorDoor CurrentDestination => Door.Get<Doors.ElevatorDoor>(Base.CurrentDestination);

/// <summary>
/// Gets a <see cref="IEnumerable{T}"/> of <see cref="Lift"/> which contains all the <see cref="Lift"/> instances from the specified <see cref="Status"/>.
Expand Down
2 changes: 1 addition & 1 deletion EXILED/Exiled.API/Features/Map.cs
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ public static TantrumHazard PlaceTantrum(Vector3 position, bool isActive = true)

NetworkServer.Spawn(tantrum.gameObject);

return Hazard.Get(tantrum).Cast<TantrumHazard>();
return Hazard.Get<TantrumHazard>(tantrum);
}

/// <summary>
Expand Down
52 changes: 52 additions & 0 deletions EXILED/Exiled.API/Features/Pickups/Pickup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,15 @@ public static Pickup Get(ItemPickupBase pickupBase)
};
}

/// <summary>
/// Gets an existing <see cref="Pickup"/> or creates a new instance of one.
/// </summary>
/// <param name="pickupBase">The <see cref="ItemPickupBase"/> to convert into an pickup.</param>
/// <typeparam name="T">The specified <see cref="Pickup"/> type.</typeparam>
/// <returns>The pickup wrapper for the given <see cref="ItemPickupBase"/>.</returns>
public static T Get<T>(ItemPickupBase pickupBase)
where T : Pickup => Get(pickupBase) as T;

/// <summary>
/// Gets the <see cref="Pickup"/> given a <see cref="Serial"/>.
/// </summary>
Expand Down Expand Up @@ -487,6 +496,36 @@ public static IEnumerable<T> Get<T>(IEnumerable<GameObject> gameObjects)
_ => new Pickup(type),
};

/// <summary>
/// Creates and returns a new <see cref="Pickup"/> with the proper inherited subclass.
/// <para>
/// Based on the <paramref name="type"/>, the returned <see cref="Pickup"/> can be cast into a subclass to gain more control over the object.
/// <br />- All valid ammo should be cast to the <see cref="AmmoPickup"/> class.
/// <br />- All valid firearms (not including the Micro HID) should be cast to the <see cref="FirearmPickup"/> class.
/// <br />- All valid keycards should be cast to the <see cref="KeycardPickup"/> class.
/// <br />- All valid armor should be cast to the <see cref="BodyArmorPickup"/> class.
/// <br />- All grenades and throwables (not including SCP-018 and SCP-2176) should be cast to the <see cref="GrenadePickup"/> class.
/// </para>
/// <para>
/// <br />The following have their own respective classes:
/// <br />- Radios can be cast to <see cref="RadioPickup"/>.
/// <br />- The Micro HID can be cast to <see cref="MicroHIDPickup"/>.
/// <br />- SCP-244 A and B variants can be cast to <see cref="Scp244Pickup"/>.
/// <br />- SCP-330 can be cast to <see cref="Scp330Pickup"/>.
/// <br />- SCP-018 can be cast to <see cref="Projectiles.Scp018Projectile"/>.
/// <br />- SCP-2176 can be cast to <see cref="Projectiles.Scp2176Projectile"/>.
/// </para>
/// <para>
/// Items that are not listed above do not have a subclass, and can only use the base <see cref="Pickup"/> class.
/// </para>
/// </summary>
/// <param name="type">The <see cref="ItemType"/> of the pickup.</param>
/// <typeparam name="T">The specified <see cref="Pickup"/> type.</typeparam>
/// <returns>The created <see cref="Pickup"/>.</returns>
/// <seealso cref="Projectile.Create(Enums.ProjectileType)"/>
public static Pickup Create<T>(ItemType type)
where T : Pickup => Create(type) as T;

/// <summary>
/// Creates and spawns a <see cref="Pickup"/>.
/// </summary>
Expand All @@ -498,6 +537,19 @@ public static IEnumerable<T> Get<T>(IEnumerable<GameObject> gameObjects)
/// <seealso cref="Projectile.CreateAndSpawn(Enums.ProjectileType, Vector3, Quaternion, bool, Player)"/>
public static Pickup CreateAndSpawn(ItemType type, Vector3 position, Quaternion rotation, Player previousOwner = null) => Create(type).Spawn(position, rotation, previousOwner);

/// <summary>
/// Creates and spawns a <see cref="Pickup"/>.
/// </summary>
/// <param name="type">The <see cref="ItemType"/> of the pickup.</param>
/// <param name="position">The position to spawn the <see cref="Pickup"/> at.</param>
/// <param name="rotation">The rotation to spawn the <see cref="Pickup"/>.</param>
/// <param name="previousOwner">An optional previous owner of the item.</param>
/// <typeparam name="T">The specified <see cref="Pickup"/> type.</typeparam>
/// <returns>The <see cref="Pickup"/>. See documentation of <see cref="Create(ItemType)"/> for more information on casting.</returns>
/// <seealso cref="Projectile.CreateAndSpawn(Enums.ProjectileType, Vector3, Quaternion, bool, Player)"/>
public static Pickup CreateAndSpawn<T>(ItemType type, Vector3 position, Quaternion rotation, Player previousOwner = null)
where T : Pickup => CreateAndSpawn(type, position, rotation, previousOwner) as T;

/// <summary>
/// Spawns a <see cref="Pickup"/>.
/// </summary>
Expand Down
Loading
Loading