From 697fe158da50e4a0b6f3f48cd23e370927be1335 Mon Sep 17 00:00:00 2001 From: Flerp Date: Fri, 21 Nov 2025 00:14:00 -0800 Subject: [PATCH] Initial Upload --- README.md | 0 conf/mod-frontstab.conf.dist | 52 +++++++++++ src/mod_frontstab.cpp | 161 +++++++++++++++++++++++++++++++++++ src/mod_frontstab_loader.cpp | 6 ++ 4 files changed, 219 insertions(+) create mode 100644 README.md create mode 100644 conf/mod-frontstab.conf.dist create mode 100644 src/mod_frontstab.cpp create mode 100644 src/mod_frontstab_loader.cpp diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/conf/mod-frontstab.conf.dist b/conf/mod-frontstab.conf.dist new file mode 100644 index 0000000..2536135 --- /dev/null +++ b/conf/mod-frontstab.conf.dist @@ -0,0 +1,52 @@ +######################################## +# Frontstab Config +######################################## +# +# ModFrontstab.Enable +# Description: Enable the module +# Default: 1 - Enabled +# 0 - Disabled +# + +ModFrontstab.Enable = 1 +# +# ModFrontstab.RequiredItem +# Description: Allows setting an item required in bags to activate frontstab. +# Default: 0 - No Item Required +# xxxxx - Specify the item ID +# + +ModFrontstab.RequiredItem = 0 +# +# ModFrontstab.RequiredEquipment +# Description: Allows setting a piece of gear, equipped, to be required for activating frontstab +# Default: 0 - No Gear Required +# xxxxx - Specify the item ID of the piece of equipment +# + +ModFrontstab.RequiredEquipment = 0 +# +# ModFrontstab.RequiredSpell +# Description: Allows setting a SpellID of a learned spell required to activate frontstab. +# Default: 0 - No Spell Required +# xxxxx - Specify the SpellID +# + +ModFrontstab.RequiredSpell = 0 +# +# ModFrontstab.SoloOnly +# Description: Sets frontstab to only activate when not in a group +# Default: 1 +# 1 for True, 0 for False +# +# + +ModFrontstab.SoloOnly = 1 +# +# ModFrontstab.SpellList +# Description: Comma-separated list of SpellIDs that should use +# frontstab logic. +# Example: "53, 14179, 48657" +# Default: "0" - no spells handled +# +ModFrontstab.SpellList = 5221,6800,8992,9829,9830,27001,27002,48571,48572 \ No newline at end of file diff --git a/src/mod_frontstab.cpp b/src/mod_frontstab.cpp new file mode 100644 index 0000000..25a6651 --- /dev/null +++ b/src/mod_frontstab.cpp @@ -0,0 +1,161 @@ +#include "ScriptMgr.h" +#include "Config.h" +#include "Player.h" +#include "Unit.h" +#include "Item.h" +#include "SharedDefines.h" +#include "Group.h" +#include "SpellScript.h" + +#include +#include +#include +#include + +namespace +{ + bool sEnabled = true; + uint32 sRequiredItemId = 0; + uint32 sRequiredEquipId = 0; + uint32 sRequiredSpellId = 0; + bool sSoloOnly = true; + + std::unordered_set sFrontstabSpellIds; + + bool HasEquippedItem(Player* player, uint32 entry) + { + if (!player) + return false; + + if (!entry) + return true; + + for (uint8 slot = EQUIPMENT_SLOT_START; slot < EQUIPMENT_SLOT_END; ++slot) + { + if (Item* it = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot)) + { + if (it->GetEntry() == entry) + return true; + } + } + return false; + } + + bool RequirementsMet(Player* player) + { + if (!player) + return false; + + if (sSoloOnly) + { + if (player->GetGroup()) + return false; + } + + if (sRequiredItemId && !player->HasItemCount(sRequiredItemId, 1, false)) + return false; + + if (sRequiredEquipId && !HasEquippedItem(player, sRequiredEquipId)) + return false; + + if (sRequiredSpellId && !player->HasSpell(sRequiredSpellId)) + return false; + + return true; + } + + void LoadFrontstabSpellList(std::string const& str) + { + sFrontstabSpellIds.clear(); + + if (str.empty() || str == "0") + return; + + std::stringstream ss(str); + std::string token; + + while (std::getline(ss, token, ',')) + { + while (!token.empty() && (token.front() == ' ' || token.front() == '\t')) + token.erase(token.begin()); + while (!token.empty() && (token.back() == ' ' || token.back() == '\t')) + token.pop_back(); + + if (token.empty()) + continue; + + char* end = nullptr; + unsigned long val = std::strtoul(token.c_str(), &end, 10); + if (end == token.c_str() || val == 0) + continue; + + sFrontstabSpellIds.insert(static_cast(val)); + } + } + + class Frontstab_WorldScript : public WorldScript + { + public: + Frontstab_WorldScript() : WorldScript("Frontstab_WorldScript") { } + + void OnAfterConfigLoad(bool) override + { + sEnabled = sConfigMgr->GetOption("ModFrontstab.Enable", true); + sRequiredItemId = sConfigMgr->GetOption("ModFrontstab.RequiredItem", 0u); + sRequiredEquipId = sConfigMgr->GetOption("ModFrontstab.RequiredEquipment", 0u); + sRequiredSpellId = sConfigMgr->GetOption("ModFrontstab.RequiredSpell", 0u); + sSoloOnly = sConfigMgr->GetOption("ModFrontstab.SoloOnly", true); + + std::string spellList = sConfigMgr->GetOption("ModFrontstab.SpellList", "0"); + LoadFrontstabSpellList(spellList); + } + }; + + class spell_mod_frontstab : public SpellScript + { + PrepareSpellScript(spell_mod_frontstab); + + SpellCastResult CheckFrontstab() + { + Unit* caster = GetCaster(); + if (!caster) + return SPELL_CAST_OK; + + Player* player = caster->ToPlayer(); + if (!player) + return SPELL_CAST_OK; + + SpellInfo const* info = GetSpellInfo(); + if (!info) + return SPELL_CAST_OK; + + if (!sFrontstabSpellIds.empty() && sFrontstabSpellIds.find(info->Id) == sFrontstabSpellIds.end()) + return SPELL_CAST_OK; + + Unit* target = GetExplTargetUnit(); + if (!target) + return SPELL_CAST_OK; + + bool isBehind = player->isInBack(target); + + if (!sEnabled) + return isBehind ? SPELL_CAST_OK : SPELL_FAILED_NOT_BEHIND; + + if (RequirementsMet(player)) + return SPELL_CAST_OK; + + return isBehind ? SPELL_CAST_OK : SPELL_FAILED_NOT_BEHIND; + } + + void Register() override + { + OnCheckCast += SpellCheckCastFn(spell_mod_frontstab::CheckFrontstab); + } + }; +} + +void AddSC_mod_frontstab() +{ + new Frontstab_WorldScript(); + RegisterSpellScript(spell_mod_frontstab); +} \ No newline at end of file diff --git a/src/mod_frontstab_loader.cpp b/src/mod_frontstab_loader.cpp new file mode 100644 index 0000000..c6af57f --- /dev/null +++ b/src/mod_frontstab_loader.cpp @@ -0,0 +1,6 @@ +void AddSC_mod_frontstab(); + +void Addmod_frontstabScripts() +{ + AddSC_mod_frontstab(); +} \ No newline at end of file