PDA

View Full Version : [TrinityCore] 3.3.5 Spell Regulator/Modifier



Wise
06-08-16, 10:34 PM
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:


#include "../Custom/SpellRegulator.h"

You should now have something like :


#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


Unit:DealDamage

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

Find this:


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

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

Add this code below OnDamage



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

You should now have


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


Unit::SendSpellNonMeleeDamageLog(SpellNonMeleeDama ge* log)

You'll see this 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


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 :


void Unit::SendPeriodicAuraLog(SpellPeriodicAuraLogInfo * pInfo)

You'll see


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

Change to


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:


#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


#include "SpellRegulator.h"

void AddSC_SpellRegulator()
{
new RegulatorLoader;
}


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



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.


https://www.youtube.com/watch?v=REsywl5imeA&feature=youtu.be[/QUOTE]