diff --git a/EXILED/Exiled.API/Extensions/DamageTypeExtensions.cs b/EXILED/Exiled.API/Extensions/DamageTypeExtensions.cs index 95dfc3372..6fde63477 100644 --- a/EXILED/Exiled.API/Extensions/DamageTypeExtensions.cs +++ b/EXILED/Exiled.API/Extensions/DamageTypeExtensions.cs @@ -204,6 +204,13 @@ public static DamageType GetDamageType(DamageHandlerBase damageHandlerBase) Log.Warn($"{nameof(DamageTypeExtensions)}.{nameof(damageHandlerBase)}: No matching {nameof(DamageType)} for {nameof(UniversalDamageHandler)} with ID {translation.Id}, type will be reported as {DamageType.Unknown}. Report this to EXILED Devs."); return DamageType.Unknown; } + + case AttackerDamageHandler attackerDamageHandler: + { + if (Player.TryGet(attackerDamageHandler.Attacker, out Player attacker) && attacker.CurrentItem?.Type == ItemType.MarshmallowItem) + return DamageType.Marshmallow; + return DamageType.Unknown; + } } return DamageType.Unknown; diff --git a/EXILED/Exiled.API/Features/DamageHandlers/DamageHandlerBase.cs b/EXILED/Exiled.API/Features/DamageHandlers/DamageHandlerBase.cs index ec59d5ee5..248e89452 100644 --- a/EXILED/Exiled.API/Features/DamageHandlers/DamageHandlerBase.cs +++ b/EXILED/Exiled.API/Features/DamageHandlers/DamageHandlerBase.cs @@ -271,6 +271,13 @@ protected DamageType GetDamageType(BaseHandler damageHandler = null) FirearmType.FRMG0 => DamageType.Frmg0, _ => DamageType.Firearm }; + + case PlayerStatsSystem.AttackerDamageHandler attackerDamageHandler: + { + if (Player.TryGet(attackerDamageHandler.Attacker, out Player attacker) && attacker.CurrentItem?.Type == ItemType.MarshmallowItem) + return DamageType.Marshmallow; + return DamageType.Unknown; + } } return DamageType.Unknown; diff --git a/EXILED/Exiled.Events/Patches/Fixes/FixMarshmallowManFF.cs b/EXILED/Exiled.Events/Patches/Fixes/FixMarshmallowManFF.cs new file mode 100644 index 000000000..d91c2d039 --- /dev/null +++ b/EXILED/Exiled.Events/Patches/Fixes/FixMarshmallowManFF.cs @@ -0,0 +1,99 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) ExMod Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.Events.Patches.Fixes +{ + using System.Collections.Generic; + using System.Reflection.Emit; + + using CustomPlayerEffects; + using Exiled.API.Features; + using Exiled.API.Features.Pools; + using Footprinting; + using HarmonyLib; + using InventorySystem.Items.MarshmallowMan; + using InventorySystem.Items.Pickups; + using InventorySystem.Items.ThrowableProjectiles; + using Mirror; + using PlayerRoles; + using PlayerStatsSystem; + using Respawning.NamingRules; + using Subtitles; + + using static HarmonyLib.AccessTools; + + /// + /// Patches the delegate. + /// + [HarmonyPatch(typeof(MarshmallowItem), nameof(MarshmallowItem.ServerAttack))] + internal class FixMarshmallowManFF : AttackerDamageHandler + { +#pragma warning disable SA1600 // Elements should be documented + public FixMarshmallowManFF(MarshmallowItem marshmallowItem) + { + Attacker = new(marshmallowItem.Owner); + Damage = marshmallowItem._attackDamage; + AllowSelfDamage = false; + ServerLogsText = "MarshmallowManFF Fix"; + } + + public override Footprint Attacker { get; set; } + + public override bool AllowSelfDamage { get; } + + public override float Damage { get; set; } + + public override string RagdollInspectText { get; } + + public override CassieAnnouncement CassieDeathAnnouncement + { + get + { + return new CassieAnnouncement() + { + Announcement = "TERMINATED BY MARSHMALLOW MAN", + SubtitleParts = new SubtitlePart[] + { + new SubtitlePart(SubtitleType.TerminatedByMarshmallowMan, null), + }, + }; + } + } + + public override string DeathScreenText { get; } + + public override string ServerLogsText { get; } +#pragma warning restore SA1600 // Elements should be documented +#pragma warning disable SA1313 // Parameter names should begin with lower-case letter + + private static bool Prefix(MarshmallowItem __instance, ReferenceHub syncTarget) + { + foreach (IDestructible destructible in __instance.DetectDestructibles()) + { + HitboxIdentity hitboxIdentity = destructible as HitboxIdentity; + if ((hitboxIdentity == null || (!(hitboxIdentity.TargetHub != syncTarget) && (__instance.EvilMode || HitboxIdentity.IsDamageable(__instance.Owner, hitboxIdentity.TargetHub)))) && destructible.Damage(__instance._attackDamage, new FixMarshmallowManFF(__instance), destructible.CenterOfMass)) + { + HitboxIdentity hitboxIdentity2 = destructible as HitboxIdentity; + if (hitboxIdentity2 != null && !hitboxIdentity2.TargetHub.IsAlive()) + __instance.Owner.playerEffectsController.GetEffect().OnKill(); + + if (__instance.EvilMode) + __instance.EvilAHPProcess.CurrentAmount += 100f; + + Hitmarker.SendHitmarkerDirectly(__instance.Owner, 1f, true); + __instance.ServerSendPublicRpc(writer => + { + writer.WriteByte(1); + }); + break; + } + } + + return false; + } + } +}