Wise
06-08-16, 11: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]
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]