Originally posted by Jameyboor


People these days are lazy ****s and want everything to be easily doable, spell buffing/nerfing is no exception here.



So today I present a simple spell buffing/nerfing system.
This system currently only works for spell DoT's and Direct Damage spells ( this includes abilities and melee stuff like mortal strike), no healing.
You could say it's quite hacky since it directly modifies the damage done but it's a good method for simple spell nerf/buffing.

You're going to need to do some core edits so let's get to that first:

Open up Unit.cpp and find the header #includes, after the last line, add:

Code:
#include "../Custom/SpellRegulator.h"
You should now have something like :

Code:
#include "Unit.h"
#include "Common.h"
#include "Battlefield.h"
#include "BattlefieldMgr.h"
#include "Battleground.h"
#include "BattlegroundScore.h"
#include "CellImpl.h"
#include "ChatTextBuilder.h"
#include "ConditionMgr.h"
#include "CreatureAI.h"
#include "CreatureAIImpl.h"
#include "CreatureGroups.h"
#include "Creature.h"
#include "Formulas.h"
#include "GridNotifiersImpl.h"
#include "Group.h"
#include "InstanceSaveMgr.h"
#include "InstanceScript.h"
#include "Log.h"
#include "MapManager.h"
#include "MoveSpline.h"
#include "MoveSplineInit.h"
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
#include "Object.h"
#include "Opcodes.h"
#include "OutdoorPvP.h"
#include "PassiveAI.h"
#include "PetAI.h"
#include "Pet.h"
#include "Player.h"
#include "QuestDef.h"
#include "ReputationMgr.h"
#include "SpellAuraEffects.h"
#include "SpellAuras.h"
#include "Spell.h"
#include "SpellInfo.h"
#include "SpellMgr.h"
#include "TemporarySummon.h"
#include "Totem.h"
#include "Transport.h"
#include "UpdateFieldFlags.h"
#include "Util.h"
#include "Vehicle.h"
#include "World.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include "Guild.h"
#include "../Custom/SpellRegulator.h"

Now CTRL + F and find

Code:
Unit:DealDamage

It's around line 600 for me but it can differ depending on your revision.

Find this:

Code:
if (IsAIEnabled)
        GetAI()->DamageDealt(victim, damage, damagetype);

    // Hook for OnDamage Event
    sScriptMgr->OnDamage(this, victim, damage);

Add this code below OnDamage


Code:
if ((damagetype == SPELL_DIRECT_DAMAGE || damagetype == DOT) && spellProto)
    sSpellRegulator->Regulate(damage, spellProto->Id

You should now have

Code:
if (IsAIEnabled)
        GetAI()->DamageDealt(victim, damage, damagetype);

    // Hook for OnDamage Event
    sScriptMgr->OnDamage(this, victim, damage);

    if ((damagetype == SPELL_DIRECT_DAMAGE || damagetype == DOT) && spellProto)
        sSpellRegulator->Regulate(damage, spellProto->Id);

Moving on, CTRL + F and find
Code:

Unit::SendSpellNonMeleeDamageLog(SpellNonMeleeDama  ge* log)
You'll see this code

Code:
WorldPacket data(SMSG_SPELLNONMELEEDAMAGELOG, (16+4+4+4+1+4+4+1+1+4+4+1)); // we guess size
    data << log->target->GetPackGUID();
    data << log->attacker->GetPackGUID();

Add code above so you have this

Code:
sSpellRegulator->Regulate(log->damage, log->SpellID);
    WorldPacket data(SMSG_SPELLNONMELEEDAMAGELOG, (16+4+4+4+1+4+4+1+1+4+4+1)); // we guess size
    data << log->target->GetPackGUID();
    data << log->attacker->GetPackGUID();

Next one, CTRL + F :
Code:

void Unit::SendPeriodicAuraLog(SpellPeriodicAuraLogInfo  * pInfo)
You'll see

Code:
AuraEffect const* aura = pInfo->auraEff;
    WorldPacket data(SMSG_PERIODICAURALOG, 30);
    data << GetPackGUID();
    data << aura->GetCasterGUID().WriteAsPacked();

Change to

Code:
AuraEffect const* aura = pInfo->auraEff;
    sSpellRegulator->Regulate(pInfo->damage, aura->GetId());
    WorldPacket data(SMSG_PERIODICAURALOG, 30);
    data << GetPackGUID();
    data << aura->GetCasterGUID().WriteAsPacked();

Now, create a new header file in your scripts project named "SpellRegulator.h", paste this in:

Code:
#pragma once

class SpellRegulator
{
public:
    static SpellRegulator* instance()
    {
        static SpellRegulator instance;
        return &instance;
    }

    void Regulate(uint32& damage, uint32 spellId)
    {
        if (RegulatorContainer.find(spellId) == RegulatorContainer.end())
            return;


        float val = RegulatorContainer[spellId];

        if (!val || val == 100.0f)
            return;

        damage = (damage / 100.0f) * val;
    }

    void LoadFromDB()
    {
        RegulatorContainer.clear();
        uint32 msTime = getMSTime();
        QueryResult result = WorldDatabase.Query("SELECT * FROM spellregulator");

        if (!result)
            return;

        uint32 count = 0;
        do{
            Field* fields = result->Fetch();
            RegulatorContainer[fields[0].GetUInt32()] = fields[1].GetFloat();
            ++count;
        } while (result->NextRow());
        TC_LOG_INFO("server.loading", "Loaded %u regulated spells in %u ms", count, GetMSTimeDiffToNow(msTime));
    }

private:
    std::unordered_map<uint32, float> RegulatorContainer; // spellid, percentage
};

#define sSpellRegulator SpellRegulator::instance()

class RegulatorLoader : public WorldScript
{
public:
    RegulatorLoader() : WorldScript("SpellRegulatorLoader") {}

    void OnStartup() override
    {
        sSpellRegulator->LoadFromDB();
    }
};

Now create a .cpp file and add it to your scripts project as well, paste this in

Code:
#include "SpellRegulator.h"

void AddSC_SpellRegulator()
{
    new RegulatorLoader;
}



Now open up your Database editor and execute this query in your world database


Code:
CREATE TABLE `spellregulator` (
    `spellId` INT(11) UNSIGNED NOT NULL,
    `percentage` FLOAT NOT NULL DEFAULT '100',
    PRIMARY KEY (`spellId`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB;


Now just make sure you have the 2 new files in your Custom folder, add void AddSC_SpellRegulator() to your scriptloader and the 2 new files to your CmakeLists.txt and recompile.
[/QUOTE]


› See More: 3.3.5 Spell Regulator/Modifier