diff --git a/overlay/oxide/plugins/RunicGateway.cs b/overlay/oxide/plugins/RunicGateway.cs index 32b679c..4217de3 100644 --- a/overlay/oxide/plugins/RunicGateway.cs +++ b/overlay/oxide/plugins/RunicGateway.cs @@ -1875,7 +1875,22 @@ namespace Oxide.Plugins // two meanings of one word would be two answers to "how many NPCs did I kill". // `animalKills` counts it AGAIN, separately (§5.2): the public NPC column keeps its // meaning mid-wipe, and the site takes the human NPCs as the difference. - if (entity is BaseNpc) + // + // Rust's own animals are now `Rust.Ai.Gen2.BaseNPC2` — stag, boar, wolf, bears, big cats, + // crocodile, farm animals, critters, sea life — and not `BaseNpc`, which is all this + // tested until the RunicNPC 9d walk found no animal kill had counted at all. `BaseNpc` + // stays for whatever still derives from it. `ScientistNPC2` is the one person among + // them, so it is a human NPC kill, not an animal. + if (entity is Rust.Ai.Gen2.ScientistNPC2) + { + Tally tally = TallyFor(attacker); + tally.NpcKills++; + tally.Killed(info, entity, false); + CreditKill(attacker, false); + return; + } + + if (entity is BaseNpc || entity is Rust.Ai.Gen2.BaseNPC2) { Tally tally = TallyFor(attacker); tally.NpcKills++; @@ -2065,55 +2080,56 @@ namespace Oxide.Plugins }); } - // A syringe on a downed player raises `OnPlayerRevive` and then `OnHealingItemUse` for the - // same use; one act of help is one heal. The revive is remembered for the frame it happened in. - private ulong _reviveHealer; - private ulong _reviveTarget; - private int _reviveFrame = -1; + // A syringe on a downed player raises `OnHealingItemUse` and then, from inside the same + // `GiveEffectsTo`, `OnPlayerRevive`; one act of help is one heal. The last one counted is + // remembered for the frame it happened in, and the other hook skips the same pair. + private ulong _helpHealer; + private ulong _helpTarget; + private int _helpFrame = -1; - /// - /// Void: a non-null return refuses the heal. is what is healed; - /// the tool's owner is who heals. Healing yourself is not a heal (D174). - /// - /// - /// The target is taken as object: the game's `GiveEffectsTo` now takes an - /// `IMedicalToolTarget`, which is not always a player, and a parameter typed - /// `BasePlayer` would simply never be called for the hook's current shape. Only a - /// player healed counts. - /// - /// - private void OnHealingItemUse(MedicalTool tool, object target) + /// Counts one act of help unless it is yourself, an NPC, or the other hook already did this frame. + private void CountHelp(BasePlayer healer, BasePlayer player) { - MarkHook("OnHealingItemUse"); - - BasePlayer player = target as BasePlayer; - BasePlayer healer = tool != null ? tool.GetOwnerPlayer() : null; - if (healer == null || healer.IsNpc || player == null || player.IsNpc || (ulong)healer.userID == (ulong)player.userID) return; - if (_reviveFrame == UnityEngine.Time.frameCount - && _reviveHealer == (ulong)healer.userID && _reviveTarget == (ulong)player.userID) + int frame = UnityEngine.Time.frameCount; + + if (_helpFrame == frame && _helpHealer == (ulong)healer.userID && _helpTarget == (ulong)player.userID) return; + _helpHealer = healer.userID; + _helpTarget = player.userID; + _helpFrame = frame; + TallyFor(healer).Healed++; } + /// + /// Void: a non-null return refuses the heal. Healing yourself is not a heal (D174). + /// + /// + /// Rust's `MedicalTool.GiveEffectsTo(fromPlayer, toTarget)` raises it as + /// (tool, fromPlayer, toTarget). Until the RunicNPC 9d walk this took two + /// parameters, so the second — the healer — arrived as the target, every heal looked like + /// healing yourself, and none counted. The target is object: `IMedicalToolTarget` + /// is not always a player, and only a player healed counts. + /// + /// + private void OnHealingItemUse(MedicalTool tool, BasePlayer fromPlayer, object target) + { + MarkHook("OnHealingItemUse"); + + CountHelp(fromPlayer ?? (tool != null ? tool.GetOwnerPlayer() : null), target as BasePlayer); + } + /// Void: a non-null return refuses the revive. Reviving yourself is not possible, and is not counted. private void OnPlayerRevive(BasePlayer reviver, BasePlayer player) { MarkHook("OnPlayerRevive"); - if (reviver == null || reviver.IsNpc || player == null || player.IsNpc - || (ulong)reviver.userID == (ulong)player.userID) - return; - - _reviveHealer = reviver.userID; - _reviveTarget = player.userID; - _reviveFrame = UnityEngine.Time.frameCount; - - TallyFor(reviver).Healed++; + CountHelp(reviver, player); } /// No return behaviour. One rocket leaving a launcher.