Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 55 additions & 31 deletions EXILED/Exiled.API/Features/DamageHandlers/GenericDamageHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,33 @@ namespace Exiled.API.Features.DamageHandlers
using System;

using Enums;

using Exiled.API.Extensions;
using Exiled.API.Features.Pickups.Projectiles;

using Footprinting;

using InventorySystem;
using InventorySystem.Items;
using InventorySystem.Items.Firearms;
using InventorySystem.Items.Firearms.Modules;
using InventorySystem.Items.Firearms.ShotEvents;
using InventorySystem.Items.Scp1509;

using Items;

using PlayerRoles;
using PlayerRoles.PlayableScps.Scp096;
using PlayerRoles.PlayableScps.Scp1507;
using PlayerRoles.PlayableScps.Scp3114;
using PlayerRoles.PlayableScps.Scp939;

using PlayerStatsSystem;

using UnityEngine;

using Object = UnityEngine.Object;

/// <summary>
/// Allows generic damage to a player.
/// </summary>
Expand Down Expand Up @@ -59,7 +73,7 @@ public GenericDamageHandler(Player player, Player attacker, float damage, Damage
if (customCassieAnnouncement is not null)
customCassieAnnouncement.Announcement ??= $"{player.Nickname} killed by {attacker.Nickname} utilizing {damageType}";

Attacker = attacker.Footprint;
Attacker = attacker != null ? attacker.Footprint : Server.Host.Footprint;
AllowSelfDamage = true;
Damage = damage;
ServerLogsText = $"GenericDamageHandler damage processing";
Expand Down Expand Up @@ -123,55 +137,57 @@ public GenericDamageHandler(Player player, Player attacker, float damage, Damage
Base = new GrayCandyDamageHandler(Attacker.Hub, damage);
break;
case DamageType.MicroHid:
InventorySystem.Items.MicroHID.MicroHIDItem microHidOwner = new();
microHidOwner.Owner = attacker.ReferenceHub;
InventorySystem.Items.MicroHID.MicroHIDItem microHidOwner = new()
{
Owner = attacker.ReferenceHub,
};
Base = new MicroHidDamageHandler(damage, microHidOwner);
break;
case DamageType.Explosion:
Base = new ExplosionDamageHandler(attacker.Footprint, UnityEngine.Vector3.zero, damage, 0, ExplosionType.Grenade);
Base = new ExplosionDamageHandler(attacker.Footprint, Vector3.zero, damage, 0, ExplosionType.Grenade);
break;
case DamageType.Firearm:
case DamageType.AK:
GenericFirearm(player, attacker, damage, damageType, ItemType.GunAK);
GenericFirearm(damage, ItemType.GunAK);
break;
case DamageType.Crossvec:
GenericFirearm(player, attacker, damage, damageType, ItemType.GunCrossvec);
GenericFirearm(damage, ItemType.GunCrossvec);
break;
case DamageType.Logicer:
GenericFirearm(player, attacker, damage, damageType, ItemType.GunLogicer);
GenericFirearm(damage, ItemType.GunLogicer);
break;
case DamageType.Revolver:
GenericFirearm(player, attacker, damage, damageType, ItemType.GunRevolver);
GenericFirearm(damage, ItemType.GunRevolver);
break;
case DamageType.Shotgun:
GenericFirearm(player, attacker, damage, damageType, ItemType.GunShotgun);
GenericFirearm(damage, ItemType.GunShotgun);
break;
case DamageType.Com15:
GenericFirearm(player, attacker, damage, damageType, ItemType.GunCOM15);
GenericFirearm(damage, ItemType.GunCOM15);
break;
case DamageType.Com18:
GenericFirearm(player, attacker, damage, damageType, ItemType.GunCOM18);
GenericFirearm(damage, ItemType.GunCOM18);
break;
case DamageType.Fsp9:
GenericFirearm(player, attacker, damage, damageType, ItemType.GunFSP9);
GenericFirearm(damage, ItemType.GunFSP9);
break;
case DamageType.E11Sr:
GenericFirearm(player, attacker, damage, damageType, ItemType.GunE11SR);
GenericFirearm(damage, ItemType.GunE11SR);
break;
case DamageType.Com45:
GenericFirearm(player, attacker, damage, damageType, ItemType.GunCom45);
GenericFirearm(damage, ItemType.GunCom45);
break;
case DamageType.Frmg0:
GenericFirearm(player, attacker, damage, damageType, ItemType.GunFRMG0);
GenericFirearm(damage, ItemType.GunFRMG0);
break;
case DamageType.A7:
GenericFirearm(player, attacker, damage, damageType, ItemType.GunA7);
GenericFirearm(damage, ItemType.GunA7);
break;
case DamageType.Scp127:
GenericFirearm(player, attacker, damage, damageType, ItemType.GunSCP127);
GenericFirearm(damage, ItemType.GunSCP127);
break;
case DamageType.ParticleDisruptor:
Base = new DisruptorDamageHandler(new (Item.Create(ItemType.ParticleDisruptor, attacker).Base as InventorySystem.Items.Firearms.Firearm, InventorySystem.Items.Firearms.Modules.DisruptorActionModule.FiringState.FiringSingle), Vector3.up, damage);
Base = new DisruptorDamageHandler(new DisruptorShotEvent(default, Attacker, InventorySystem.Items.Firearms.Modules.DisruptorActionModule.FiringState.FiringSingle), Vector3.up, damage);
break;
case DamageType.Scp096:
Scp096Role curr096 = attacker.ReferenceHub.roleManager.CurrentRole as Scp096Role ?? new Scp096Role();
Expand All @@ -193,9 +209,12 @@ public GenericDamageHandler(Player player, Player attacker, float damage, Damage
Base = new PlayerStatsSystem.ScpDamageHandler(attacker.ReferenceHub, damage, DeathTranslations.Unknown);
break;
case DamageType.Scp018:
Scp018Projectile scp018Projectile = Projectile.Create<Scp018Projectile>(ProjectileType.Scp018);
scp018Projectile.PreviousOwner = attacker;
Base = new Scp018DamageHandler(scp018Projectile.Base, damage, true);
InventorySystem.Items.ThrowableProjectiles.Scp018Projectile dummy018 = new()
{
PreviousOwner = Attacker,
};

Base = new Scp018DamageHandler(dummy018, damage, true);
break;
case DamageType.Scp207:
Base = new PlayerStatsSystem.ScpDamageHandler(attacker.ReferenceHub, damage, DeathTranslations.Scp207);
Expand Down Expand Up @@ -303,21 +322,26 @@ public override HandlerOutput ApplyDamage(ReferenceHub ply)
/// <summary>
/// Generic firearm path for handle type.
/// </summary>
/// <param name="player"> Current player. </param>
/// <param name="attacker"> Current attacker. </param>
/// <param name="amount"> Damage amount. </param>
/// <param name="damageType"> Damage type. </param>
/// <param name="itemType"> ItemType. </param>
private void GenericFirearm(Player player, Player attacker, float amount, DamageType damageType, ItemType itemType)
private void GenericFirearm(float amount, ItemType itemType)
{
Firearm firearm = new(itemType)
ItemType ammoType = ItemType.None;

if (InventoryItemLoader.TryGetItem(itemType, out InventorySystem.Items.Firearms.Firearm firearmTemplate))
{
Base =
{
Owner = attacker.ReferenceHub,
},
Items.Firearm firearm = new(firearmTemplate);
ammoType = firearm.AmmoType.GetItemType();
}

Base = new PlayerStatsSystem.FirearmDamageHandler
{
Damage = amount,
Attacker = Attacker,
AmmoType = ammoType,
WeaponType = itemType,
Firearm = firearmTemplate,
};
Base = new PlayerStatsSystem.FirearmDamageHandler() { Firearm = firearm.Base, Damage = amount };
}
}
}
14 changes: 13 additions & 1 deletion EXILED/Exiled.API/Features/Items/Item.cs
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,19 @@ public static T Create<T>(ItemType type, Player owner = null)
/// <summary>
/// Destroy this item.
/// </summary>
public void Destroy() => Owner.RemoveItem(this);
public void Destroy()
{
if (Owner.RemoveItem(this))
return;

if (Base != null)
{
BaseToItem.Remove(Base);

if (Base.gameObject != null)
Object.Destroy(Base.gameObject);
}
}

/// <summary>
/// Creates the <see cref="Pickup"/> that based on this <see cref="Item"/>.
Expand Down
21 changes: 19 additions & 2 deletions EXILED/Exiled.API/Features/Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2324,7 +2324,23 @@ public void Heal(float amount, bool overrideMaxHealth = false)
/// </summary>
/// <param name="usableItem">The ItemType to be used.</param>
/// <returns><see langword="true"/> if item was used successfully. Otherwise, <see langword="false"/>.</returns>
public bool UseItem(ItemType usableItem) => UseItem(Item.Create(usableItem));
public bool UseItem(ItemType usableItem)
{
if (usableItem.GetTemplate() is not UsableItem)
return false;

Item item = Item.Create(usableItem);

if (item is not Usable usable)
{
item.Destroy();
return false;
}

UseItem(usable);
item.Destroy();
return true;
}

/// <summary>
/// Forces the player to use an item.
Expand Down Expand Up @@ -2388,7 +2404,8 @@ public void Vaporize(Player attacker = null, string cassieAnnouncement = "")
if ((Role.Side != Side.Scp) && !string.IsNullOrEmpty(cassieAnnouncement))
Cassie.Message(cassieAnnouncement);

Kill(new DisruptorDamageHandler(new DisruptorShotEvent(Item.Create(ItemType.ParticleDisruptor, attacker).Base as InventorySystem.Items.Firearms.Firearm, DisruptorActionModule.FiringState.FiringSingle), Vector3.up, -1));
Footprint footprint = attacker != null ? attacker.Footprint : Server.Host.Footprint;
Kill(new DisruptorDamageHandler(new DisruptorShotEvent(default, footprint, DisruptorActionModule.FiringState.FiringSingle), Vector3.up, -1));
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion EXILED/Exiled.CustomItems/API/Features/CustomArmor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public override void Give(Player player, bool displayMessage = true)
if (AmmoLimits.Count != 0)
armor.AmmoLimits = AmmoLimits;

if (AmmoLimits.Count != 0)
if (CategoryLimits.Count != 0)
armor.CategoryLimits = CategoryLimits;

player.AddItem(armor);
Expand Down
36 changes: 26 additions & 10 deletions EXILED/Exiled.CustomItems/API/Features/CustomGrenade.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,14 @@ namespace Exiled.CustomItems.API.Features
using Exiled.Events.EventArgs.Player;

using Footprinting;

using InventorySystem;
using InventorySystem.Items;
using InventorySystem.Items.Pickups;
using InventorySystem.Items.ThrowableProjectiles;

using Mirror;

using UnityEngine;

using Object = UnityEngine.Object;
Expand Down Expand Up @@ -70,31 +74,43 @@ public override ItemType Type
/// <returns>The <see cref="Pickup"/> spawned.</returns>
public virtual Pickup Throw(Vector3 position, float force, float weight, float fuseTime = 3f, ItemType grenadeType = ItemType.GrenadeHE, Player? player = null)
{
if (player is null)
player = Server.Host;
player ??= Server.Host;

player.Role.Is(out FpcRole fpcRole);
Vector3 velocity = fpcRole.FirstPersonController.FpcModule.Motor.Velocity;
Vector3 velocity = Vector3.zero;
Quaternion rotation = Quaternion.identity;

Throwable throwable = (Throwable)Item.Create(grenadeType, player);
if (player != Server.Host)
{
if (player.Role.Is(out FpcRole fpcRole))
velocity = fpcRole.FirstPersonController.FpcModule.Motor.Velocity;

if (player.CameraTransform != null)
rotation = player.CameraTransform.rotation;
}

ThrownProjectile thrownProjectile = Object.Instantiate(throwable.Base.Projectile, position, throwable.Owner.CameraTransform.rotation);
InventoryItemLoader.TryGetItem(grenadeType, out ThrowableItem template);

ThrownProjectile thrownProjectile = Object.Instantiate(template.Projectile, position, rotation);

PickupSyncInfo newInfo = new()
{
ItemId = throwable.Type,
Locked = !throwable.Base._repickupable,
ItemId = grenadeType,
Locked = !template._repickupable,
Serial = ItemSerialGenerator.GenerateNext(),
WeightKg = weight,
};

if (thrownProjectile is TimeGrenade time)
time._fuseTime = fuseTime;

thrownProjectile.NetworkInfo = newInfo;
thrownProjectile.PreviousOwner = new Footprint(throwable.Owner.ReferenceHub);
thrownProjectile.PreviousOwner = player.Footprint;
NetworkServer.Spawn(thrownProjectile.gameObject);
thrownProjectile.InfoReceivedHook(default, newInfo);

if (thrownProjectile.TryGetComponent(out Rigidbody component))
throwable.Base.PropelBody(component, throwable.Base.FullThrowSettings.StartTorque, ThrowableNetworkHandler.GetLimitedVelocity(velocity));
template.PropelBody(component, template.FullThrowSettings.StartTorque, ThrowableNetworkHandler.GetLimitedVelocity(velocity));

thrownProjectile.ServerActivate();

return Pickup.Get(thrownProjectile);
Expand Down
3 changes: 2 additions & 1 deletion EXILED/Exiled.CustomItems/API/Features/CustomItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,7 @@ public static IEnumerable<CustomItem> UnregisterItems(IEnumerable<Type> targetTy

Pickup? pickup = Spawn(position, item, previousOwner);

UnityEngine.Object.Destroy(item.Base);
item.Destroy();
return pickup;
}

Expand All @@ -554,6 +554,7 @@ public static IEnumerable<CustomItem> UnregisterItems(IEnumerable<Type> targetTy
public virtual Pickup? Spawn(Vector3 position, Item item, Player? previousOwner = null)
{
Pickup? pickup = item.CreatePickup(position);

pickup.Scale = Scale;
pickup.Weight = Weight;

Expand Down
21 changes: 16 additions & 5 deletions EXILED/Exiled.CustomItems/API/Features/CustomWeapon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ namespace Exiled.CustomItems.API.Features
using Exiled.API.Features.Pickups;
using Exiled.Events.EventArgs.Item;
using Exiled.Events.EventArgs.Player;

using InventorySystem.Items.Firearms.Attachments;
using InventorySystem.Items.Firearms.Attachments.Components;
using InventorySystem.Items.Firearms.Modules;

using UnityEngine;

using Firearm = Exiled.API.Features.Items.Firearm;
Expand Down Expand Up @@ -69,32 +71,39 @@ public override ItemType Type
/// <inheritdoc />
public override Pickup? Spawn(Vector3 position, Player? previousOwner = null)
{
if (Item.Create(Type) is not Firearm firearm)
Item item = Item.Create(Type);
if (item is not Firearm firearm)
{
Log.Debug($"{nameof(Spawn)}: Item is not Firearm.");
item.Destroy();
return null;
}

if (!Attachments.IsEmpty())
firearm.AddAttachment(Attachments);

Pickup? pickup = firearm.CreatePickup(position);
if (ClipSize > 0)
firearm.MagazineAmmo = ClipSize;

FirearmPickup? pickup = (FirearmPickup?)firearm.CreatePickup(position, spawn: false);
item.Destroy();

if (pickup is null)
{
Log.Debug($"{nameof(Spawn)}: Pickup is null.");
return null;
}

if (ClipSize > 0)
firearm.MagazineAmmo = ClipSize;

pickup.Weight = Weight;
pickup.Scale = Scale;

if (previousOwner is not null)
pickup.PreviousOwner = previousOwner;

pickup.Spawn();

TrackedSerials.Add(pickup.Serial);

return pickup;
}

Expand All @@ -108,9 +117,11 @@ public override ItemType Type

if (ClipSize > 0)
firearm.MagazineAmmo = ClipSize;

int ammo = firearm.MagazineAmmo;
Log.Debug($"{nameof(Name)}.{nameof(Spawn)}: Spawning weapon with {ammo} ammo.");
Pickup? pickup = firearm.CreatePickup(position);
item.Destroy();
pickup.Scale = Scale;

if (previousOwner is not null)
Expand Down
Loading
Loading