diff options
author | QAston <none@none> | 2010-07-24 22:41:42 +0200 |
---|---|---|
committer | QAston <none@none> | 2010-07-24 22:41:42 +0200 |
commit | 2352fc7cdfff0e677f6516c0ab2b91d3efc9ab70 (patch) | |
tree | 470b0d66f513cb62b6be88863003408864d117ae | |
parent | 687cd83bddfbc5416ba11bff53c8a636747a5802 (diff) |
*Add base scripting interfce for spells - thanks to Brian for help in making it compile with GCC.
*Add hook for handling spell effects in new scripting system.
--HG--
branch : trunk
30 files changed, 1253 insertions, 14 deletions
diff --git a/sql/base/world_database.sql b/sql/base/world_database.sql index 8b5f03706a8..03ce3ba57f2 100644 --- a/sql/base/world_database.sql +++ b/sql/base/world_database.sql @@ -14570,6 +14570,20 @@ INSERT INTO `spelldifficulty_dbc` VALUES UNLOCK TABLES; -- +-- Table structure for table `spell_script_names` +-- + +DROP TABLE IF EXISTS `spell_script_names`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `spell_script_names` ( + `spell_id` mediumint(8) NOT NULL, + `ScriptName` char(64) NOT NULL, + UNIQUE (`spell_id`, `ScriptName`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- -- Table structure for table `transports` -- diff --git a/sql/updates/9012_world_spell_script_names.sql b/sql/updates/9012_world_spell_script_names.sql new file mode 100644 index 00000000000..410357f82f9 --- /dev/null +++ b/sql/updates/9012_world_spell_script_names.sql @@ -0,0 +1,6 @@ +DROP TABLE IF EXISTS `spell_script_names`; +CREATE TABLE `spell_script_names` ( + `spell_id` int(11) NOT NULL, + `ScriptName` char(64) NOT NULL, + UNIQUE (`spell_id`, `ScriptName`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; diff --git a/src/server/game/CMakeLists.txt b/src/server/game/CMakeLists.txt index 40fc77ff464..5738d7b8fc7 100644 --- a/src/server/game/CMakeLists.txt +++ b/src/server/game/CMakeLists.txt @@ -172,6 +172,7 @@ set(game_STAT_SRCS Spells/SpellEffects.cpp Spells/Spell.cpp Spells/SpellMgr.cpp + Spells/SpellScript.cpp Tools/CharacterDatabaseCleaner.cpp Tools/PlayerDump.cpp Tools/Tools.cpp diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 87f8202ddcc..31e6c0c0c72 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -46,6 +46,8 @@ #include "Vehicle.h" #include "AchievementMgr.h" #include "DisableMgr.h" +#include "ScriptMgr.h" +#include "SpellScript.h" ScriptMapMap sQuestEndScripts; ScriptMapMap sQuestStartScripts; @@ -4893,6 +4895,106 @@ void ObjectMgr::LoadWaypointScripts() } } +void ObjectMgr::LoadSpellScriptNames() +{ + mSpellScripts.clear(); // need for reload case + QueryResult_AutoPtr result = WorldDatabase.Query("SELECT spell_id, ScriptName FROM spell_script_names"); + + uint32 count = 0; + + if (!result) + { + barGoLink bar(1); + bar.step(); + + sLog.outString(); + sLog.outString(">> Loaded %u spell script names", count); + return; + } + + barGoLink bar(result->GetRowCount()); + + do + { + ++count; + bar.step(); + + Field *fields = result->Fetch(); + + int32 spellId = fields[0].GetInt32(); + const char *scriptName = fields[1].GetString(); + + bool allRanks = false; + if (spellId <=0) + { + allRanks = true; + spellId = -spellId; + } + + SpellEntry const* spellEntry = sSpellStore.LookupEntry(spellId); + if (!spellEntry) + { + sLog.outErrorDb("Scriptname:`%s` spell (spell_id:%d) does not exist in `Spell.dbc`.",scriptName,fields[0].GetInt32()); + continue; + } + + if (allRanks) + { + if (spellmgr.GetFirstSpellInChain(spellId) != spellId) + { + sLog.outErrorDb("Scriptname:`%s` spell (spell_id:%d) is not first rank of spell.",scriptName,fields[0].GetInt32()); + continue; + } + while(spellId) + { + mSpellScripts.insert(SpellScriptsMap::value_type(spellId, GetScriptId(scriptName))); + spellId = spellmgr.GetNextSpellInChain(spellId); + } + } + else + mSpellScripts.insert(SpellScriptsMap::value_type(spellId, GetScriptId(scriptName))); + + } while (result->NextRow()); + + sLog.outString(); + sLog.outString(">> Loaded %u spell script names", count); +} + +void ObjectMgr::ValidateSpellScripts() +{ + if (mSpellScripts.empty()) + { + barGoLink bar(1); + bar.step(); + + sLog.outString(); + sLog.outString(">> Validation done"); + return; + } + + barGoLink bar(mSpellScripts.size()); + for (SpellScriptsMap::iterator itr = mSpellScripts.begin(); itr != mSpellScripts.end();) + { + SpellEntry const * spellEntry = sSpellStore.LookupEntry(itr->first); + std::vector<std::pair<SpellScript *, SpellScriptsMap::iterator> > spellScripts; + sScriptMgr.CreateSpellScripts(itr->first, spellScripts); + SpellScriptsMap::iterator bitr; + itr = mSpellScripts.upper_bound(itr->first); + + for (std::vector<std::pair<SpellScript *, SpellScriptsMap::iterator> >::iterator sitr = spellScripts.begin(); sitr != spellScripts.end(); ++sitr) + { + bar.step(); + sitr->first->Register(); + if (!sitr->first->_Validate(spellEntry, objmgr.GetScriptName(sitr->second->second))) + mSpellScripts.erase(sitr->second); + delete sitr->first; + } + } + + sLog.outString(); + sLog.outString(">> Validation done"); +} + void ObjectMgr::LoadGossipScripts() { LoadScripts(sGossipScripts, "gossip_scripts"); @@ -7658,6 +7760,11 @@ uint32 ObjectMgr::GetAreaTriggerScriptId(uint32 trigger_id) return 0; } +SpellScriptsBounds ObjectMgr::GetSpellScriptsBounds(uint32 spell_id) +{ + return SpellScriptsBounds(mSpellScripts.lower_bound(spell_id),mSpellScripts.upper_bound(spell_id)); +} + SkillRangeType GetSkillRangeType(SkillLineEntry const *pSkill, bool racial) { switch(pSkill->categoryId) @@ -8451,6 +8558,8 @@ void ObjectMgr::LoadScriptNames() "UNION " "SELECT DISTINCT(ScriptName) FROM areatrigger_scripts WHERE ScriptName <> '' " "UNION " + "SELECT DISTINCT(ScriptName) FROM spell_script_names WHERE ScriptName <> '' " + "UNION " "SELECT DISTINCT(script) FROM instance_template WHERE script <> ''"); if (!result) diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index e02fe438c5c..c99a58fe7fb 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -90,6 +90,8 @@ struct ScriptInfo typedef std::multimap<uint32, ScriptInfo> ScriptMap; typedef std::map<uint32, ScriptMap > ScriptMapMap; +typedef std::multimap<uint32, uint32> SpellScriptsMap; +typedef std::pair<SpellScriptsMap::iterator, SpellScriptsMap::iterator> SpellScriptsBounds; extern ScriptMapMap sQuestEndScripts; extern ScriptMapMap sQuestStartScripts; extern ScriptMapMap sSpellScripts; @@ -521,6 +523,7 @@ class ObjectMgr AreaTrigger const* GetMapEntranceTrigger(uint32 Map) const; uint32 GetAreaTriggerScriptId(uint32 trigger_id); + SpellScriptsBounds GetSpellScriptsBounds(uint32 spell_id); ReputationOnKillEntry const* GetReputationOnKilEntry(uint32 id) const { @@ -587,6 +590,9 @@ class ObjectMgr void LoadGossipScripts(); void LoadWaypointScripts(); + void LoadSpellScriptNames(); + void ValidateSpellScripts(); + bool LoadTrinityStrings(DatabaseType& db, char const* table, int32 min_value, int32 max_value); bool LoadTrinityStrings() { return LoadTrinityStrings(WorldDatabase,"trinity_string",MIN_TRINITY_STRING_ID,MAX_TRINITY_STRING_ID); } void LoadDbScriptStrings(); @@ -1002,6 +1008,8 @@ class ObjectMgr SpellClickInfoMap mSpellClickInfoMap; + SpellScriptsMap mSpellScripts; + ItemRequiredTargetMap m_ItemRequiredTarget; VehicleAccessoryMap m_VehicleAccessoryMap; diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 115e5337e5b..54dfd749b66 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -24,6 +24,17 @@ #include "Define.h" #include <cassert> +enum SpellEffIndex +{ + EFFECT_0 = 0, + EFFECT_1 = 1, + EFFECT_2 = 2, +}; + +// used in script definitions +#define EFFECT_FIRST_FOUND 254 +#define EFFECT_ALL 255 + // loot modes for creatures and gameobjects, bitmask! enum LootModes { @@ -1177,7 +1188,7 @@ enum Targets TARGET_UNIT_MINIPET = 90, TARGET_DEST_DEST_RANDOM_DIR_DIST = 91, TARGET_UNIT_UNK_92 = 92, - TARGET_CORPSE_AREA_ENEMY_PLAYER_SRC= 93, + TARGET_CORPSE_AREA_ENEMY_PLAYER_SRC= 93, // TODO TARGET_UNIT_VEHICLE = 94, TARGET_UNIT_DRIVER = 95, TARGET_UNIT_PASSENGER_0 = 96, @@ -1190,6 +1201,9 @@ enum Targets TARGET_UNIT_PASSENGER_7 = 103, TARGET_UNIT_AREA_PATH = 104, TARGET_UNIT_UNK_105 = 105, // 1 spell + TARGET_DEST_CHANNEL_TARGET = 106, // TODO + TARGET_UNK_AREA_UNK_DST_107 = 107, // not enough info - only generic spells avalible + TARGET_GAMEOBJECT_AREA_PATH = 108, // TODO TARGET_DEST_UNK_110 = 110, // some kind of traj? }; diff --git a/src/server/game/PrecompiledHeaders/ScriptPCH.h b/src/server/game/PrecompiledHeaders/ScriptPCH.h index f8515e99f89..b716edc3a5b 100644 --- a/src/server/game/PrecompiledHeaders/ScriptPCH.h +++ b/src/server/game/PrecompiledHeaders/ScriptPCH.h @@ -22,6 +22,7 @@ #include "DBCStructure.h" #include "DBCStores.h" #include "ObjectMgr.h" +#include "SpellScript.h" #ifdef _WIN32 #include <windows.h> diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index cf378db2bac..54bd9150a91 100644 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -513,6 +513,20 @@ void AddSC_terokkar_forest(); void AddSC_zangarmarsh(); void AddSC_onevents(); +// spells +void AddSC_deathknight_spell_scripts(); +void AddSC_druid_spell_scripts(); +void AddSC_generic_spell_scripts(); +void AddSC_hunter_spell_scripts(); +void AddSC_mage_spell_scripts(); +void AddSC_paladin_spell_scripts(); +void AddSC_priest_spell_scripts(); +void AddSC_rogue_spell_scripts(); +void AddSC_shaman_spell_scripts(); +void AddSC_warlock_spell_scripts(); +void AddSC_warrior_spell_scripts(); +void AddSC_example_spell_scripts(); + #endif void AddScripts() @@ -1015,5 +1029,18 @@ void AddScripts() AddSC_zangarmarsh(); AddSC_onevents(); + // spells + AddSC_deathknight_spell_scripts(); + AddSC_druid_spell_scripts(); + AddSC_generic_spell_scripts(); + AddSC_hunter_spell_scripts(); + AddSC_mage_spell_scripts(); + AddSC_paladin_spell_scripts(); + AddSC_priest_spell_scripts(); + AddSC_rogue_spell_scripts(); + AddSC_shaman_spell_scripts(); + AddSC_warlock_spell_scripts(); + AddSC_warrior_spell_scripts(); + AddSC_example_spell_scripts(); #endif } diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index 70b1ff6be64..5f6cce4917d 100644 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -544,3 +544,25 @@ InstanceData* ScriptMgr::CreateInstanceData(Map *map) return tmpscript->GetInstanceData(map); } +void ScriptMgr::CreateSpellScripts(uint32 spell_id, std::list<SpellScript *> & script_vector) +{ + SpellScriptsBounds bounds = objmgr.GetSpellScriptsBounds(spell_id); + for (SpellScriptsMap::iterator itr = bounds.first; itr != bounds.second; ++itr) + { + Script *tmpscript = m_scripts[itr->second]; + if (!tmpscript || !tmpscript->GetSpellScript) continue; + script_vector.push_back(tmpscript->GetSpellScript()); + } +} + +void ScriptMgr::CreateSpellScripts(uint32 spell_id, std::vector<std::pair<SpellScript *, SpellScriptsMap::iterator> > & script_vector) +{ + SpellScriptsBounds bounds = objmgr.GetSpellScriptsBounds(spell_id); + script_vector.reserve(std::distance(bounds.first, bounds.second)); + for (SpellScriptsMap::iterator itr = bounds.first; itr != bounds.second; ++itr) + { + Script *tmpscript = m_scripts[itr->second]; + if (!tmpscript || !tmpscript->GetSpellScript) continue; + script_vector.push_back(std::make_pair(tmpscript->GetSpellScript(), itr)); + } +} diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index bcb26381809..d477d7a1e39 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -17,6 +17,7 @@ class Player; class Creature; class CreatureAI; class InstanceData; +class SpellScript; class Quest; class Item; class GameObject; @@ -25,6 +26,7 @@ class Map; class Unit; class WorldObject; struct ItemPrototype; +class Spell; #define MAX_SCRIPTS 5000 //72 bytes each (approx 351kb) #define VISIBLE_RANGE (166.0f) //MAX visible range (size of grid) @@ -42,7 +44,7 @@ struct Script pChooseReward(NULL), pGODestroyed(NULL), pItemHello(NULL), pGOHello(NULL), pAreaTrigger(NULL), pItemQuestAccept(NULL), pGOQuestAccept(NULL), pGOChooseReward(NULL),pItemUse(NULL), pItemExpire(NULL), pEffectDummyCreature(NULL), pEffectDummyGameObj(NULL), pEffectDummyItem(NULL), - GetAI(NULL), GetInstanceData(NULL) + GetAI(NULL), GetInstanceData(NULL), GetSpellScript(NULL) {} std::string Name; @@ -89,6 +91,9 @@ struct Script CreatureAI* (*GetAI)(Creature*); InstanceData* (*GetInstanceData)(Map*); + SpellScript*(*GetSpellScript)(); + //AuraScript*(*GetAuraScript)(); + void RegisterSelf(); }; @@ -143,6 +148,8 @@ class ScriptMgr bool EffectDummyGameObj(Unit *caster, uint32 spellId, uint32 effIndex, GameObject *gameObjTarget); bool EffectDummyItem(Unit *caster, uint32 spellId, uint32 effIndex, Item *itemTarget); InstanceData* CreateInstanceData(Map *map); + void CreateSpellScripts(uint32 spell_id, std::list<SpellScript *> & script_vector); + void CreateSpellScripts(uint32 spell_id, std::vector<std::pair<SpellScript *, SpellScriptsMap::iterator> > & script_vector); }; //Config file accessors diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index a53142bf296..eb7c2c9b4fa 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -52,6 +52,7 @@ #include "ScriptMgr.h" #include "ConditionMgr.h" #include "DisableMgr.h" +#include "SpellScript.h" #define SPELL_CHANNEL_UPDATE_INTERVAL (1 * IN_MILLISECONDS) @@ -455,6 +456,14 @@ Spell::Spell(Unit* Caster, SpellEntry const *info, bool triggered, uint64 origin Spell::~Spell() { + // unload scripts + while(!m_loadedScripts.empty()) + { + std::list<SpellScript *>::iterator itr = m_loadedScripts.begin(); + (*itr)->Unload(); + delete (*itr); + m_loadedScripts.erase(itr); + } if (m_referencedFromCurrentSpell && m_selfContainer && *m_selfContainer == this) { // Clean the reference to avoid later crash. @@ -2748,6 +2757,7 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const * triggere finish(false); return; } + LoadScripts(); if (m_caster->GetTypeId() == TYPEID_PLAYER) m_caster->ToPlayer()->SetSpellModTakingSpell(this, true); @@ -4479,7 +4489,6 @@ void Spell::HandleThreatSpells(uint32 spellId) void Spell::HandleEffects(Unit *pUnitTarget,Item *pItemTarget,GameObject *pGOTarget,uint32 i) { - if (!sScriptMgr.OnSpellCast(pUnitTarget,pItemTarget,pGOTarget,i,m_spellInfo)) return; @@ -4495,12 +4504,21 @@ void Spell::HandleEffects(Unit *pUnitTarget,Item *pItemTarget,GameObject *pGOTar sLog.outDebug("Spell: %u Effect : %u", m_spellInfo->Id, eff); + for(std::list<SpellScript *>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end() ; ++scritr) + { + std::list<SpellScript::EffectHandler>::iterator effEndItr = (*scritr)->EffectHandlers.end(), effItr = (*scritr)->EffectHandlers.begin(); + for(; effItr != effEndItr ; ++effItr) + { + if ((*effItr).IsEffectAffected(m_spellInfo, i)) + (*effItr).Call(*scritr, (SpellEffIndex)i); + } + } + //we do not need DamageMultiplier here. damage = CalculateDamage(i, NULL); if (eff < TOTAL_SPELL_EFFECTS) { - //sLog.outDebug("WORLD: Spell FX %d < TOTAL_SPELL_EFFECTS ", eff); (this->*SpellEffects[eff])(i); } } @@ -7076,3 +7094,21 @@ void Spell::SelectTrajTargets() m_targets.setDst(x, y, z, m_caster->GetOrientation()); } } + +void Spell::LoadScripts() +{ + sLog.outError("Spell::LoadScripts"); + sScriptMgr.CreateSpellScripts(m_spellInfo->Id, m_loadedScripts); + for(std::list<SpellScript *>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end() ;) + { + if (!(*itr)->_Load(this)) + { + std::list<SpellScript *>::iterator bitr = itr; + ++itr; + m_loadedScripts.erase(bitr); + continue; + } + (*itr)->Register(); + ++itr; + } +} diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 563572ec1fd..368add34926 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -29,6 +29,8 @@ class Player; class GameObject; class DynamicObject; class Aura; +struct SpellEntry; +class SpellScript; // These flags represent the inner states of the targeting system enum SpellInternalTargetFlags @@ -268,6 +270,7 @@ class Spell { friend struct Trinity::SpellNotifierCreatureAndPlayer; friend void Unit::SetCurrentCastedSpell(Spell * pSpell); + friend class SpellScript; public: void EffectNULL(uint32); @@ -506,6 +509,7 @@ class Spell Unit* GetCaster() const { return m_caster; } Unit* GetOriginalCaster() const { return m_originalCaster; } + SpellEntry const * GetSpellInfo() const { return m_spellInfo; } int32 GetPowerCost() const { return m_powerCost; } void UpdatePointers(); // must be used at call Spell code after time delay (non triggered spell cast/update spell call/etc) @@ -650,6 +654,10 @@ class Spell void SpellDamageWeaponDmg(uint32 i); void SpellDamageHeal(uint32 i); + // Scripting system + void LoadScripts(); + std::list<SpellScript *> m_loadedScripts; + // effect helpers void GetSummonPosition(uint32 i, Position &pos, float radius = 0.0f, uint32 count = 0); void SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const *properties); diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp new file mode 100644 index 00000000000..fb2944fa651 --- /dev/null +++ b/src/server/game/Spells/SpellScript.cpp @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "SpellScript.h" +#include "Spell.h" + +bool _SpellScript::_Validate(SpellEntry const * entry, const char * scriptname) +{ + if (!Validate(entry)) + { + sLog.outError("TSCR: Spell `%u` did not pass Validate() function of script `%s` - script will be not added to the spell", entry->Id, scriptname); + return false; + } + return true; +} + +_SpellScript::EffectHook::EffectHook(uint8 _effIndex) +{ + // effect index must be in range <0;2>, allow use of special effindexes + ASSERT(_effIndex == EFFECT_ALL || _effIndex == EFFECT_FIRST_FOUND || _effIndex < MAX_SPELL_EFFECTS); + effIndex = _effIndex; +} + +uint8 _SpellScript::EffectHook::GetAffectedEffectsMask(SpellEntry const * spellEntry) +{ + uint8 mask = 0; + if ((effIndex == EFFECT_ALL) || (effIndex == EFFECT_FIRST_FOUND)) + { + for(uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + if ((effIndex == EFFECT_FIRST_FOUND) && mask) + return mask; + if (CheckEffect(spellEntry, effIndex)) + mask |= (uint8)1<<effIndex; + } + } + else + { + if (CheckEffect(spellEntry, effIndex)) + mask |= (uint8)1<<effIndex; + } + return mask; +} + +bool _SpellScript::EffectHook::IsEffectAffected(SpellEntry const * spellEntry, uint8 effIndex) +{ + return GetAffectedEffectsMask(spellEntry) & 1<<effIndex; +} + +std::string _SpellScript::EffectHook::EffIndexToString() +{ + switch(effIndex) + { + case EFFECT_ALL: + return "EFFECT_ALL"; + case EFFECT_FIRST_FOUND: + return "EFFECT_FIRST_FOUND"; + case EFFECT_0: + return "EFFECT_0"; + case EFFECT_1: + return "EFFECT_1"; + case EFFECT_2: + return "EFFECT_2"; + } + return "Invalid Value"; +} + +bool _SpellScript::EffectNameCheck::Check(SpellEntry const * spellEntry, uint8 effIndex) +{ + if (!spellEntry->Effect[effIndex] && !effName) + return true; + if (!spellEntry->Effect[effIndex]) + return false; + return (effName == SPELL_EFFECT_ANY) || (spellEntry->Effect[effIndex] == effName); +} + +std::string _SpellScript::EffectNameCheck::ToString() +{ + switch(effName) + { + case SPELL_EFFECT_ANY: + return "SPELL_EFFECT_ANY"; + default: + char num[10]; + sprintf (num,"%u",effName); + return num; + } +} + +bool _SpellScript::EffectAuraNameCheck::Check(SpellEntry const * spellEntry, uint8 effIndex) +{ + if (!spellEntry->EffectApplyAuraName[effIndex] && !effAurName) + return true; + if (!spellEntry->EffectApplyAuraName[effIndex]) + return false; + return (effAurName == SPELL_EFFECT_ANY) || (spellEntry->EffectApplyAuraName[effIndex] == effAurName); +} + +std::string _SpellScript::EffectAuraNameCheck::ToString() +{ + switch(effAurName) + { + case SPELL_AURA_ANY: + return "SPELL_AURA_ANY"; + default: + char num[10]; + sprintf (num,"%u",effAurName); + return num; + } +} + +SpellScript::EffectHandler::EffectHandler(EffectHandlerFnType _pEffectHandlerScript,uint8 _effIndex, uint16 _effName) + : _SpellScript::EffectNameCheck(_effName), _SpellScript::EffectHook(_effIndex) +{ + pEffectHandlerScript = _pEffectHandlerScript; +} + +std::string SpellScript::EffectHandler::ToString() +{ + return "Index: " + EffIndexToString() + " Name: " +_SpellScript::EffectNameCheck::ToString(); +} + +bool SpellScript::EffectHandler::CheckEffect(SpellEntry const * spellEntry, uint8 effIndex) +{ + return _SpellScript::EffectNameCheck::Check(spellEntry, effIndex); +} + +void SpellScript::EffectHandler::Call(SpellScript * spellScript, SpellEffIndex effIndex) +{ + (spellScript->*pEffectHandlerScript)(effIndex); +} + +bool SpellScript::_Validate(SpellEntry const * entry, const char * scriptname) +{ + for (std::list<EffectHandler>::iterator itr = EffectHandlers.begin(); itr != EffectHandlers.end(); ++itr) + { + if (!(*itr).GetAffectedEffectsMask(entry)) + { + sLog.outError("TSCR: Spell `%u` Effect `%s` of script`%s` did not match dbc effect data - bound handler won't be executed", entry->Id, (*itr).ToString().c_str(), scriptname); + } + } + return _SpellScript::_Validate(entry, scriptname); +} + +bool SpellScript::_Load(Spell * spell) +{ + m_spell = spell; + return Load(); +} + +Unit * SpellScript::GetCaster() +{ + return m_spell->GetCaster(); +} + +Unit * SpellScript::GetOriginalCaster() +{ + return m_spell->GetOriginalCaster(); +} + +SpellEntry const * SpellScript::GetSpellInfo() +{ + return m_spell->GetSpellInfo(); +} + +Unit * SpellScript::GetEffectUnitTarget() +{ + return m_spell->unitTarget; +} + +Creature * SpellScript::GetEffectCreatureTarget() +{ + if (m_spell->unitTarget) + return m_spell->unitTarget->ToCreature(); + else + return NULL; +} + +Player * SpellScript::GetEffectPlayerTarget() +{ + if (m_spell->unitTarget) + return m_spell->unitTarget->ToPlayer(); + else + return NULL; +} + +Item * SpellScript::GetEffectItemTarget() +{ + return m_spell->itemTarget; +} + +GameObject * SpellScript::GetEffectGOTarget() +{ + return m_spell->gameObjTarget; +} + +int32 SpellScript::GetEffectValue() +{ + return m_spell->damage; +} diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h new file mode 100644 index 00000000000..73b378db20e --- /dev/null +++ b/src/server/game/Spells/SpellScript.h @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __SPELL_SCRIPT_H +#define __SPELL_SCRIPT_H + +class Unit; +struct SpellEntry; +class SpellScript; +class Spell; + +typedef void(SpellScript::*EffectHandlerFnType)(SpellEffIndex); + +#define SPELL_EFFECT_ANY (uint16)-1 +#define SPELL_AURA_ANY (uint16)-1 + +// helper class from which SpellScript and SpellAura derive, use these classes instead +class _SpellScript +{ + // internal use classes & functions + // DO NOT OVERRIDE THESE IN SCRIPTS + protected: + virtual bool _Validate(SpellEntry const * entry, const char * scriptname); + protected: + class EffectHook + { + public: + EffectHook(uint8 _effIndex); + uint8 GetAffectedEffectsMask(SpellEntry const * spellEntry); + bool IsEffectAffected(SpellEntry const * spellEntry, uint8 effIndex); + virtual bool CheckEffect(SpellEntry const * spellEntry, uint8 effIndex) = 0; + std::string EffIndexToString(); + protected: + uint8 effIndex; + }; + class EffectNameCheck + { + public: + EffectNameCheck(uint16 _effName) {effName = _effName;}; + bool Check(SpellEntry const * spellEntry, uint8 effIndex); + std::string ToString(); + private: + uint16 effName; + }; + class EffectAuraNameCheck + { + public: + EffectAuraNameCheck(uint16 _effAurName) { effAurName = _effAurName; } + bool Check(SpellEntry const * spellEntry, uint8 effIndex); + std::string ToString(); + private: + uint16 effAurName; + }; + public: + // + // SpellScript/AuraScript interface base + // these functions are safe to override, see notes below for usage instructions + // + // Function in which handler functions are registered, must be implemented in script + virtual void Register() = 0; + // Function called on server startup, if returns false script won't be used in core + // use for: dbc/template data presence/correctness checks + virtual bool Validate(SpellEntry const * spellEntry) {return true;}; + // Function called when script is created, if returns false script will be unloaded afterwards + // use for: initializing local script variables (DO NOT USE CONSTRUCTOR FOR THIS PURPOSE!) + virtual bool Load() {return true;}; + // Function called when script is destroyed + // use for: deallocating memory allocated by script + virtual void Unload() {}; +}; + +class SpellScript : public _SpellScript +{ + // internal use classes & functions + // DO NOT OVERRIDE THESE IN SCRIPTS + public: + class EffectHandler : public _SpellScript::EffectNameCheck, public _SpellScript::EffectHook + { + public: + EffectHandler(EffectHandlerFnType _pEffectHandlerScript,uint8 _effIndex, uint16 _effName); + std::string ToString(); + bool CheckEffect(SpellEntry const * spellEntry, uint8 effIndex); + void Call(SpellScript * spellScript, SpellEffIndex effIndex); + private: + EffectHandlerFnType pEffectHandlerScript; + }; + public: + bool _Validate(SpellEntry const * entry, const char * scriptname); + bool _Load(Spell * spell); + private: + Spell * m_spell; + public: + // + // SpellScript interface + // hooks to which you can attach your functions + // + // List of functions registered by EffectHandlerFn + // allows more than one hook + // example EffectHandlers += EffectHandlerFn(class::function, EffectIndexSpecifier, EffectNameSpecifier); + HookList<EffectHandler> EffectHandlers; + + // methods allowing interaction with Spell object + Unit * GetCaster(); + Unit * GetOriginalCaster(); + SpellEntry const * GetSpellInfo(); + // functions useable only during spell hit on target phase + Unit * GetEffectUnitTarget(); + Creature * GetEffectCreatureTarget(); + Player * GetEffectPlayerTarget(); + Item * GetEffectItemTarget(); + GameObject * GetEffectGOTarget(); + int32 GetEffectValue(); +}; +// SpellScript interface +// +// function registering macros, should be used only in Register() +// +// EffectHandlerFn +// called at: Spell hit on unit, just before default effect handler, called for effects matching EffectIndexSpecifier and EffectNameSpecifier conditions +// hook parameter is current effect index +// parameters: function to call, EffectIndexSpecifier, EffectNameSpecifier +#define EffectHandlerFn(F, I, N) EffectHandler((EffectHandlerFnType)&F, I, N) + +// +// definitions: +// +// EffectIndexSpecifier - specifies conditions for effects +// EFFECT_0 - first effect matches +// EFFECT_1 - second effect matches +// EFFECT_2 - third effect matches +// EFFECT_FIRST_FOUND - first effect matching other conditions matches +// EFFECT_ALL - all effects of spell match +// +// EffectNameSpecifier - specifies conditions for spell effect names +// SPELL_EFFECT_ANY - any effect but not 0 matches condition +// SPELL_EFFECT_XXX - one of values of enum SpellEffects - effect with equal name matches +// + +#endif // __SPELL_SCRIPT_H diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 5eba5f44182..610a34ee5fe 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1616,9 +1616,15 @@ void World::SetInitialWorldSettings() sLog.outString("Loading CreatureEventAI Scripts..."); CreatureEAI_Mgr.LoadCreatureEventAI_Scripts(); + sLog.outString("Loading spell script names..."); + objmgr.LoadSpellScriptNames(); + sLog.outString("Initializing Scripts..."); sScriptMgr.ScriptsInit(); + sLog.outString("Validating spell scripts..."); + objmgr.ValidateSpellScripts(); + ///- Initialize game time and timers sLog.outDebug("DEBUG:: Initialize game time and timers"); m_gameTime = time(NULL); diff --git a/src/server/scripts/Examples/example_spell.cpp b/src/server/scripts/Examples/example_spell.cpp new file mode 100644 index 00000000000..149cd09d4c9 --- /dev/null +++ b/src/server/scripts/Examples/example_spell.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * An example of a spell script file + * to bind a script to spell you have to add entry for it in `spell_script_names` + * where `spell_id` is id of the spell to bind + * and `ScriptName` is the name of a script assigned on registration + */ + +#include "ScriptPCH.h" + +class spell_ex_49375SpellScript : public SpellScript +{ +public: + std::string localVariable; + char * localVariable2; +private: + // effect handler hook - effIndex - effIndex of handled effect of a spell + void HandleDummy(SpellEffIndex effIndex) + { + // we're handling SPELL_EFFECT_DUMMY in effIndex 0 here + sLog.outError("WE ARE HANDLING DUMMY!"); + sLog.outError(localVariable.c_str()); + // make caster cast a spell on a unit target of effect + if (Unit * target = GetEffectUnitTarget()) + GetCaster()->CastSpell(target, 70522, true); + }; + void Register() + { + // we're registering our function here + // function HandleDummy will be called when unit is hit by spell, just before default effect 0 handler + EffectHandlers += EffectHandlerFn(spell_ex_49375SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + // this will prompt an error on startup because effect 0 of spell 49375 is set to SPELL_EFFECT_DUMMY, not SPELL_EFFECT_APPLY_AURA + //EffectHandlers += EffectHandlerFn(spell_gen_49375SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_APPLY_AURA); + // this will make HandleDummy function to be called on first != 0 effect of spell 49375 + //EffectHandlers += EffectHandlerFn(spell_gen_49375SpellScript::HandleDummy, EFFECT_FIRST_FOUND, SPELL_EFFECT_ANY); + // this will make HandleDummy function to be called on all != 0 effect of spell 49375 + //EffectHandlers += EffectHandlerFn(spell_gen_49375SpellScript::HandleDummy, EFFECT_ALL, SPELL_EFFECT_ANY); + }; + // function called on server startup + // checks if script has data required for it to work + bool Validate(SpellEntry const * spellEntry) + { + // check if spellid 1 exists in dbc + if (!sSpellStore.LookupEntry(70522)) + return false; + return true; + }; + // function called just after script is added to spell + // we initialize local variables if needed + bool Load() + { + localVariable = "WE'RE USING LOCAL VARIABLE"; + localVariable2 = new char; + return true; + // script will be immediately removed from the spell + // for example - we don't want this script to be executed on a creature + // if (GetCaster()->GetTypeID() != TYPEID_PLAYER) + // return false + } + // function called just before script delete + // we free allocated memory + void Unload() + { + delete localVariable2; + } +}; + +// function which creates SpellScript +SpellScript * GetSpellScript_spell_ex_49375() +{ + return new spell_ex_49375SpellScript(); +} + +// this function has to be added to function set in ScriptLoader.cpp +void AddSC_example_spell_scripts() +{ + Script *newscript; + + newscript = new Script; + // name to be put in `spell_script_names` + newscript->Name = "spell_ex_49375"; + // assign create function to the script + newscript->GetSpellScript = &GetSpellScript_spell_ex_49375; + newscript->RegisterSelf(); +}
\ No newline at end of file diff --git a/src/server/scripts/World/spell_dk.cpp b/src/server/scripts/World/spell_dk.cpp new file mode 100644 index 00000000000..b8b32d248ff --- /dev/null +++ b/src/server/scripts/World/spell_dk.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Scripts for spells with SPELLFAMILY_DEATHKNIGHT and SPELLFAMILY_GENERIC spells used by deathknight players. + * Ordered alphabetically using scriptname. + * Scriptnames of files in this file should be prefixed with "spell_dk_". + */ + +#include "ScriptPCH.h" + +void AddSC_deathknight_spell_scripts() +{ + //Script *newscript; + + /* + newscript = new Script; + newscript->Name = "spell_dk_"; + newscript->GetSpellScript = &GetSpellScript_spell_dk_; + newscript->RegisterSelf(); + */ +}
\ No newline at end of file diff --git a/src/server/scripts/World/spell_druid.cpp b/src/server/scripts/World/spell_druid.cpp new file mode 100644 index 00000000000..49f0cae2ade --- /dev/null +++ b/src/server/scripts/World/spell_druid.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Scripts for spells with SPELLFAMILY_DRUID and SPELLFAMILY_GENERIC spells used by druid players. + * Ordered alphabetically using scriptname. + * Scriptnames of files in this file should be prefixed with "spell_dru_". + */ + +#include "ScriptPCH.h" + +void AddSC_druid_spell_scripts() +{ + //Script *newscript; + + /* + newscript = new Script; + newscript->Name = "spell_dru_"; + newscript->GetSpellScript = &GetSpellScript_spell_dru_; + newscript->RegisterSelf(); + */ +}
\ No newline at end of file diff --git a/src/server/scripts/World/spell_generic.cpp b/src/server/scripts/World/spell_generic.cpp new file mode 100644 index 00000000000..7020d267345 --- /dev/null +++ b/src/server/scripts/World/spell_generic.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Scripts for spells with SPELLFAMILY_GENERIC which cannot be included in AI script file + * of creature using it or can't be bound to any player class. + * Ordered alphabetically using scriptname. + * Scriptnames of files in this file should be prefixed with "spell_gen_" + */ + +#include "ScriptPCH.h" + +void AddSC_generic_spell_scripts() +{ + //Script *newscript; + + /* + newscript = new Script; + newscript->Name = "spell_gen_"; + newscript->GetSpellScript = &GetSpellScript_spell_gen_; + newscript->RegisterSelf(); + */ +}
\ No newline at end of file diff --git a/src/server/scripts/World/spell_hunter.cpp b/src/server/scripts/World/spell_hunter.cpp new file mode 100644 index 00000000000..1a3ef010cbb --- /dev/null +++ b/src/server/scripts/World/spell_hunter.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Scripts for spells with SPELLFAMILY_HUNTER, SPELLFAMILY_PET and SPELLFAMILY_GENERIC spells used by hunter players. + * Ordered alphabetically using scriptname. + * Scriptnames of files in this file should be prefixed with "spell_hun_". + */ + +#include "ScriptPCH.h" + +void AddSC_hunter_spell_scripts() +{ + //Script *newscript; + + /* + newscript = new Script; + newscript->Name = "spell_hun_"; + newscript->GetSpellScript = &GetSpellScript_spell_hun_; + newscript->RegisterSelf(); + */ +}
\ No newline at end of file diff --git a/src/server/scripts/World/spell_mage.cpp b/src/server/scripts/World/spell_mage.cpp new file mode 100644 index 00000000000..4f609800346 --- /dev/null +++ b/src/server/scripts/World/spell_mage.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Scripts for spells with SPELLFAMILY_MAGE and SPELLFAMILY_GENERIC spells used by mage players. + * Ordered alphabetically using scriptname. + * Scriptnames of files in this file should be prefixed with "spell_mag_". + */ + +#include "ScriptPCH.h" + +void AddSC_mage_spell_scripts() +{ + //Script *newscript; + + /* + newscript = new Script; + newscript->Name = "spell_mag_"; + newscript->GetSpellScript = &GetSpellScript_spell_mag_; + newscript->RegisterSelf(); + */ +}
\ No newline at end of file diff --git a/src/server/scripts/World/spell_paladin.cpp b/src/server/scripts/World/spell_paladin.cpp new file mode 100644 index 00000000000..24141205e76 --- /dev/null +++ b/src/server/scripts/World/spell_paladin.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Scripts for spells with SPELLFAMILY_SHAMAN and SPELLFAMILY_GENERIC spells used by paladin players. + * Ordered alphabetically using scriptname. + * Scriptnames of files in this file should be prefixed with "spell_pal_". + */ + +#include "ScriptPCH.h" + +void AddSC_paladin_spell_scripts() +{ + //Script *newscript; + + /* + newscript = new Script; + newscript->Name = "spell_pal_"; + newscript->GetSpellScript = &GetSpellScript_spell_pal_; + newscript->RegisterSelf(); + */ +}
\ No newline at end of file diff --git a/src/server/scripts/World/spell_pri.cpp b/src/server/scripts/World/spell_pri.cpp new file mode 100644 index 00000000000..a659dd8effb --- /dev/null +++ b/src/server/scripts/World/spell_pri.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Scripts for spells with SPELLFAMILY_PRIEST and SPELLFAMILY_GENERIC spells used by warrior players. + * Ordered alphabetically using scriptname. + * Scriptnames of files in this file should be prefixed with "spell_pri_". + */ + +void AddSC_mage_spell_scripts() +{ + Script *newscript; + + /* + newscript = new Script; + newscript->Name = "spell_pri_"; + newscript->GetSpellScript = &GetSpellScript_spell_pri_; + newscript->RegisterSelf(); + */ +}
\ No newline at end of file diff --git a/src/server/scripts/World/spell_priest.cpp b/src/server/scripts/World/spell_priest.cpp new file mode 100644 index 00000000000..c5dc3d854ae --- /dev/null +++ b/src/server/scripts/World/spell_priest.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Scripts for spells with SPELLFAMILY_PRIEST and SPELLFAMILY_GENERIC spells used by priest players. + * Ordered alphabetically using scriptname. + * Scriptnames of files in this file should be prefixed with "spell_pri_". + */ + +#include "ScriptPCH.h" + +void AddSC_priest_spell_scripts() +{ + //Script *newscript; + + /* + newscript = new Script; + newscript->Name = "spell_pri_"; + newscript->GetSpellScript = &GetSpellScript_spell_pri_; + newscript->RegisterSelf(); + */ +}
\ No newline at end of file diff --git a/src/server/scripts/World/spell_rogue.cpp b/src/server/scripts/World/spell_rogue.cpp new file mode 100644 index 00000000000..b701443e98b --- /dev/null +++ b/src/server/scripts/World/spell_rogue.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Scripts for spells with SPELLFAMILY_ROGUE and SPELLFAMILY_GENERIC spells used by rogue players. + * Ordered alphabetically using scriptname. + * Scriptnames of files in this file should be prefixed with "spell_rog_". + */ + +#include "ScriptPCH.h" + +void AddSC_rogue_spell_scripts() +{ + //Script *newscript; + + /* + newscript = new Script; + newscript->Name = "spell_rog_"; + newscript->GetSpellScript = &GetSpellScript_spell_rog_; + newscript->RegisterSelf(); + */ +}
\ No newline at end of file diff --git a/src/server/scripts/World/spell_shaman.cpp b/src/server/scripts/World/spell_shaman.cpp new file mode 100644 index 00000000000..f689a3c68ee --- /dev/null +++ b/src/server/scripts/World/spell_shaman.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Scripts for spells with SPELLFAMILY_SHAMAN and SPELLFAMILY_GENERIC spells used by shaman players. + * Ordered alphabetically using scriptname. + * Scriptnames of files in this file should be prefixed with "spell_sha_". + */ + +#include "ScriptPCH.h" + +void AddSC_shaman_spell_scripts() +{ + //Script *newscript; + + /* + newscript = new Script; + newscript->Name = "spell_sha_"; + newscript->GetSpellScript = &GetSpellScript_spell_sha_; + newscript->RegisterSelf(); + */ +}
\ No newline at end of file diff --git a/src/server/scripts/World/spell_warlock.cpp b/src/server/scripts/World/spell_warlock.cpp new file mode 100644 index 00000000000..24ee8d682a2 --- /dev/null +++ b/src/server/scripts/World/spell_warlock.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Scripts for spells with SPELLFAMILY_WARLOCK and SPELLFAMILY_GENERIC spells used by warlock players. + * Ordered alphabetically using scriptname. + * Scriptnames of files in this file should be prefixed with "spell_warl_". + */ + +#include "ScriptPCH.h" + +void AddSC_warlock_spell_scripts() +{ + //Script *newscript; + + /* + newscript = new Script; + newscript->Name = "spell_warl_"; + newscript->GetSpellScript = &GetSpellScript_spell_warl_; + newscript->RegisterSelf(); + */ +}
\ No newline at end of file diff --git a/src/server/scripts/World/spell_warrior.cpp b/src/server/scripts/World/spell_warrior.cpp new file mode 100644 index 00000000000..dbd7901dc09 --- /dev/null +++ b/src/server/scripts/World/spell_warrior.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Scripts for spells with SPELLFAMILY_WARRIOR and SPELLFAMILY_GENERIC spells used by warrior players. + * Ordered alphabetically using scriptname. + * Scriptnames of files in this file should be prefixed with "spell_warr_". + */ + +#include "ScriptPCH.h" + +void AddSC_warrior_spell_scripts() +{ + //Script *newscript; + + /* + newscript = new Script; + newscript->Name = "spell_warr_"; + newscript->GetSpellScript = &GetSpellScript_spell_warr_; + newscript->RegisterSelf(); + */ +}
\ No newline at end of file diff --git a/src/server/shared/Utilities/Util.h b/src/server/shared/Utilities/Util.h index 68886bb0d42..bfe1eec5265 100644 --- a/src/server/shared/Utilities/Util.h +++ b/src/server/shared/Utilities/Util.h @@ -312,6 +312,29 @@ void hexEncodeByteArray(uint8* bytes, uint32 arrayLen, std::string& result); #define PAIR64_LOPART(x) (uint32)(uint64(x) & UI64LIT(0x00000000FFFFFFFF)) #endif +// simple class for not-modifyable list +template <typename T> +class HookList +{ + typedef typename std::list<T>::iterator ListIterator; + private: + typename std::list<T> m_list; + public: + HookList<T> & operator+=(T t) + { + m_list.push_back(t); + return *this; + } + ListIterator begin() + { + return m_list.begin(); + } + ListIterator end() + { + return m_list.end(); + } +}; + class flag96 { private: diff --git a/win/VC90/game.vcproj b/win/VC90/game.vcproj index f62043c7009..cad732a1500 100644 --- a/win/VC90/game.vcproj +++ b/win/VC90/game.vcproj @@ -762,6 +762,50 @@ RelativePath="..\..\src\server\scripts\World\npcs_special.cpp" > </File> + <File + RelativePath="..\..\src\server\scripts\World\spell_dk.cpp" + > + </File> + <File + RelativePath="..\..\src\server\scripts\World\spell_druid.cpp" + > + </File> + <File + RelativePath="..\..\src\server\scripts\World\spell_generic.cpp" + > + </File> + <File + RelativePath="..\..\src\server\scripts\World\spell_hunter.cpp" + > + </File> + <File + RelativePath="..\..\src\server\scripts\World\spell_mage.cpp" + > + </File> + <File + RelativePath="..\..\src\server\scripts\World\spell_paladin.cpp" + > + </File> + <File + RelativePath="..\..\src\server\scripts\World\spell_priest.cpp" + > + </File> + <File + RelativePath="..\..\src\server\scripts\World\spell_rogue.cpp" + > + </File> + <File + RelativePath="..\..\src\server\scripts\World\spell_shaman.cpp" + > + </File> + <File + RelativePath="..\..\src\server\scripts\World\spell_warlock.cpp" + > + </File> + <File + RelativePath="..\..\src\server\scripts\World\spell_warrior.cpp" + > + </File> </Filter> <Filter Name="Eastern Kingdoms" @@ -1646,6 +1690,10 @@ RelativePath="..\..\src\server\scripts\Examples\example_misc.cpp" > </File> + <File + RelativePath="..\..\src\server\scripts\Examples\example_spell.cpp" + > + </File> </Filter> <Filter Name="Kalimdor" @@ -4200,16 +4248,16 @@ <File RelativePath="..\..\src\server\game\Server\Protocol\Handlers\ChannelHandler.cpp" > - </File> - <File - RelativePath="..\..\src\server\game\Tools\CharacterDatabaseCleaner.cpp" - > - </File> - <File - RelativePath="..\..\src\server\game\Tools\CharacterDatabaseCleaner.h" - > - </File> - <File + </File> + <File + RelativePath="..\..\src\server\game\Tools\CharacterDatabaseCleaner.cpp" + > + </File> + <File + RelativePath="..\..\src\server\game\Tools\CharacterDatabaseCleaner.h" + > + </File> + <File RelativePath="..\..\src\server\game\Server\Protocol\Handlers\CharacterHandler.cpp" > </File> @@ -4471,6 +4519,14 @@ RelativePath="..\..\src\server\game\Spells\SpellMgr.h" > </File> + <File + RelativePath="..\..\src\server\game\Spells\SpellScript.cpp" + > + </File> + <File + RelativePath="..\..\src\server\game\Spells\SpellScript.h" + > + </File> <Filter Name="Auras" > |