mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 04:37:00 +00:00
[11989] Add support to call spell_scripts in more cases
* Support to script Dummy spells with spell_scripts * Support to script TriggerSpell spells which have no existing triggered spell Note that the order which spell-effect actually triggers the DB script is well-defined (SCRIPT_EFFECT before DUMMY before other) Signed-off-by: Schmoozerd <schmoozerd@scriptdev2.com>
This commit is contained in:
parent
dd1d913ff2
commit
83d7d86255
9 changed files with 86 additions and 22 deletions
|
|
@ -11,6 +11,7 @@ Copyright (C) 2010-2012 MaNGOS <http://getmangos.com/>
|
|||
creature_movement_scripts DB project self defined id
|
||||
event_scripts Event id. Several sources: spell effect 61, taxi/transport nodes, gameobject_template data
|
||||
gameobject_scripts Gameobject guid
|
||||
gameobject_template_scripts Gameobject entry
|
||||
gossip_scripts DB project self defined id
|
||||
quest_end_scripts DB project self defined id (generally quest entry)
|
||||
quest_start_scripts DB project self defined id (generally quest entry)
|
||||
|
|
@ -90,6 +91,7 @@ event_scripts
|
|||
Spell (effect 61)
|
||||
Source: caster. Target: Target
|
||||
gameobject_scripts
|
||||
gameobject_template_scripts
|
||||
Gameobject use
|
||||
Source: user: Target: GO
|
||||
gossip_scripts
|
||||
|
|
@ -103,7 +105,9 @@ quest_start_scripts
|
|||
`quest_template`
|
||||
Source: quest giver (creature/GO). Target: player
|
||||
spell_scripts
|
||||
Spell (effect 77)
|
||||
Spell (effect 77 - SCRIPT_EFFECT)
|
||||
Spell (effect 3 - DUMMY)
|
||||
Spell (effect 64 - TRIGGER_SPELL, with non-existing triggered spell)
|
||||
Source: caster: Target: target of spell (Unit)
|
||||
|
||||
-- --------------------------
|
||||
|
|
|
|||
|
|
@ -1606,12 +1606,12 @@ void BattleGroundMap::UnloadAll(bool pForce)
|
|||
}
|
||||
|
||||
/// Put scripts in the execution queue
|
||||
void Map::ScriptsStart(ScriptMapMapName const& scripts, uint32 id, Object* source, Object* target)
|
||||
bool Map::ScriptsStart(ScriptMapMapName const& scripts, uint32 id, Object* source, Object* target)
|
||||
{
|
||||
///- Find the script map
|
||||
ScriptMapMap::const_iterator s = scripts.second.find(id);
|
||||
if (s == scripts.second.end())
|
||||
return;
|
||||
return false;
|
||||
|
||||
// prepare static data
|
||||
ObjectGuid sourceGuid = source->GetObjectGuid();
|
||||
|
|
@ -1634,6 +1634,8 @@ void Map::ScriptsStart(ScriptMapMapName const& scripts, uint32 id, Object* sourc
|
|||
///- If one of the effects should be immediate, launch the script execution
|
||||
if (immedScript)
|
||||
ScriptsProcess();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Map::ScriptCommandStart(ScriptInfo const& script, uint32 delay, Object* source, Object* target)
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>
|
|||
PlayerList const& GetPlayers() const { return m_mapRefManager; }
|
||||
|
||||
//per-map script storage
|
||||
void ScriptsStart(ScriptMapMapName const& scripts, uint32 id, Object* source, Object* target);
|
||||
bool ScriptsStart(ScriptMapMapName const& scripts, uint32 id, Object* source, Object* target);
|
||||
void ScriptCommandStart(ScriptInfo const& script, uint32 delay, Object* source, Object* target);
|
||||
|
||||
// must called with AddToWorld
|
||||
|
|
|
|||
|
|
@ -85,6 +85,43 @@ ScriptMgr::~ScriptMgr()
|
|||
// /////////////////////////////////////////////////////////
|
||||
// DB SCRIPTS (loaders of static data)
|
||||
// /////////////////////////////////////////////////////////
|
||||
// returns priority (0 == cannot start script)
|
||||
uint8 GetSpellStartDBScriptPriority(SpellEntry const* spellinfo, SpellEffectIndex effIdx)
|
||||
{
|
||||
if (spellinfo->Effect[effIdx] == SPELL_EFFECT_SCRIPT_EFFECT)
|
||||
return 10;
|
||||
|
||||
if (spellinfo->Effect[effIdx] == SPELL_EFFECT_DUMMY)
|
||||
return 9;
|
||||
|
||||
// NonExisting triggered spells can also start DB-Spell-Scripts
|
||||
if (spellinfo->Effect[effIdx] == SPELL_EFFECT_TRIGGER_SPELL && !sSpellStore.LookupEntry(spellinfo->EffectTriggerSpell[effIdx]))
|
||||
return 5;
|
||||
|
||||
// Can not start script
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Priorize: SCRIPT_EFFECT before DUMMY before Non-Existing triggered spell, for same priority the first effect with the priority triggers
|
||||
bool ScriptMgr::CanSpellEffectStartDBScript(SpellEntry const* spellinfo, SpellEffectIndex effIdx)
|
||||
{
|
||||
uint8 priority = GetSpellStartDBScriptPriority(spellinfo, effIdx);
|
||||
if (!priority)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
{
|
||||
uint8 currentPriority = GetSpellStartDBScriptPriority(spellinfo, SpellEffectIndex(i));
|
||||
if (currentPriority < priority) // lower priority, continue checking
|
||||
continue;
|
||||
if (currentPriority > priority) // take other index with higher priority
|
||||
return false;
|
||||
if (i < effIdx) // same priority at lower index
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ScriptMgr::LoadScripts(ScriptMapMapName& scripts, const char* tablename)
|
||||
{
|
||||
|
|
@ -640,25 +677,20 @@ void ScriptMgr::LoadSpellScripts()
|
|||
LoadScripts(sSpellScripts, "spell_scripts");
|
||||
|
||||
// check ids
|
||||
for(ScriptMapMap::const_iterator itr = sSpellScripts.second.begin(); itr != sSpellScripts.second.end(); ++itr)
|
||||
for (ScriptMapMap::const_iterator itr = sSpellScripts.second.begin(); itr != sSpellScripts.second.end(); ++itr)
|
||||
{
|
||||
SpellEntry const* spellInfo = sSpellStore.LookupEntry(itr->first);
|
||||
|
||||
if (!spellInfo)
|
||||
{
|
||||
sLog.outErrorDb("Table `spell_scripts` has not existing spell (Id: %u) as script id", itr->first);
|
||||
continue;
|
||||
}
|
||||
|
||||
//check for correct spellEffect
|
||||
// check for correct spellEffect
|
||||
bool found = false;
|
||||
for(int i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
for (int i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
{
|
||||
// skip empty effects
|
||||
if (!spellInfo->Effect[i])
|
||||
continue;
|
||||
|
||||
if (spellInfo->Effect[i] == SPELL_EFFECT_SCRIPT_EFFECT)
|
||||
if (GetSpellStartDBScriptPriority(spellInfo, SpellEffectIndex(i)))
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
|
|
@ -666,7 +698,7 @@ void ScriptMgr::LoadSpellScripts()
|
|||
}
|
||||
|
||||
if (!found)
|
||||
sLog.outErrorDb("Table `spell_scripts` has unsupported spell (Id: %u) without SPELL_EFFECT_SCRIPT_EFFECT (%u) spell effect", itr->first, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
sLog.outErrorDb("Table `spell_scripts` has unsupported spell (Id: %u)", itr->first);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -437,6 +437,7 @@ class ScriptMgr
|
|||
uint32 DecreaseScheduledScriptCount() { return (uint32)--m_scheduledScripts; }
|
||||
uint32 DecreaseScheduledScriptCount(size_t count) { return (uint32)(m_scheduledScripts -= count); }
|
||||
bool IsScriptScheduled() const { return m_scheduledScripts > 0; }
|
||||
static bool CanSpellEffectStartDBScript(SpellEntry const* spellinfo, SpellEffectIndex effIdx);
|
||||
|
||||
CreatureAI* GetCreatureAI(Creature* pCreature);
|
||||
InstanceData* CreateInstanceData(Map* pMap);
|
||||
|
|
|
|||
|
|
@ -846,7 +846,7 @@ void Spell::AddUnitTarget(Unit* pVictim, SpellEffectIndex effIndex)
|
|||
TargetInfo target;
|
||||
target.targetGUID = targetGUID; // Store target GUID
|
||||
target.effectMask = immuned ? 0 : (1 << effIndex); // Store index of effect if not immuned
|
||||
target.processed = false; // Effects not apply on target
|
||||
target.processed = false; // Effects not applied on target
|
||||
|
||||
// Calculate hit result
|
||||
target.missCondition = m_caster->SpellHitResult(pVictim, m_spellInfo, m_canReflect);
|
||||
|
|
|
|||
|
|
@ -495,6 +495,7 @@ class Spell
|
|||
void ClearCastItem();
|
||||
|
||||
static void SelectMountByAreaAndSkill(Unit* target, SpellEntry const* parentSpell, uint32 spellId75, uint32 spellId150, uint32 spellId225, uint32 spellId300, uint32 spellIdSpecial);
|
||||
|
||||
protected:
|
||||
bool HasGlobalCooldown();
|
||||
void TriggerGlobalCooldown();
|
||||
|
|
|
|||
|
|
@ -3333,12 +3333,23 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx)
|
|||
|
||||
// Script based implementation. Must be used only for not good for implementation in core spell effects
|
||||
// So called only for not processed cases
|
||||
bool libraryResult = false;
|
||||
if (gameObjTarget)
|
||||
sScriptMgr.OnEffectDummy(m_caster, m_spellInfo->Id, eff_idx, gameObjTarget);
|
||||
libraryResult = sScriptMgr.OnEffectDummy(m_caster, m_spellInfo->Id, eff_idx, gameObjTarget);
|
||||
else if (unitTarget && unitTarget->GetTypeId() == TYPEID_UNIT)
|
||||
sScriptMgr.OnEffectDummy(m_caster, m_spellInfo->Id, eff_idx, (Creature*)unitTarget);
|
||||
libraryResult = sScriptMgr.OnEffectDummy(m_caster, m_spellInfo->Id, eff_idx, (Creature*)unitTarget);
|
||||
else if (itemTarget)
|
||||
sScriptMgr.OnEffectDummy(m_caster, m_spellInfo->Id, eff_idx, itemTarget);
|
||||
libraryResult = sScriptMgr.OnEffectDummy(m_caster, m_spellInfo->Id, eff_idx, itemTarget);
|
||||
|
||||
if (libraryResult || !unitTarget)
|
||||
return;
|
||||
|
||||
// Previous effect might have started script
|
||||
if (!ScriptMgr::CanSpellEffectStartDBScript(m_spellInfo, eff_idx))
|
||||
return;
|
||||
|
||||
DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Spell ScriptStart spellid %u in EffectDummy", m_spellInfo->Id);
|
||||
m_caster->GetMap()->ScriptsStart(sSpellScripts, m_spellInfo->Id, m_caster, unitTarget);
|
||||
}
|
||||
|
||||
void Spell::EffectTriggerSpellWithValue(SpellEffectIndex eff_idx)
|
||||
|
|
@ -3518,10 +3529,19 @@ void Spell::EffectTriggerSpell(SpellEffectIndex effIndex)
|
|||
}
|
||||
|
||||
// normal case
|
||||
SpellEntry const *spellInfo = sSpellStore.LookupEntry( triggered_spell_id );
|
||||
SpellEntry const* spellInfo = sSpellStore.LookupEntry(triggered_spell_id);
|
||||
if (!spellInfo)
|
||||
{
|
||||
sLog.outError("EffectTriggerSpell of spell %u: triggering unknown spell id %i", m_spellInfo->Id,triggered_spell_id);
|
||||
// No previous Effect might have started a script
|
||||
bool startDBScript = unitTarget && ScriptMgr::CanSpellEffectStartDBScript(m_spellInfo, effIndex);
|
||||
if (startDBScript)
|
||||
{
|
||||
DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Spell ScriptStart spellid %u in EffectTriggerSpell", m_spellInfo->Id);
|
||||
startDBScript = m_caster->GetMap()->ScriptsStart(sSpellScripts, m_spellInfo->Id, m_caster, unitTarget);
|
||||
}
|
||||
|
||||
if (!startDBScript)
|
||||
sLog.outError("EffectTriggerSpell of spell %u: triggering unknown spell id %i", m_spellInfo->Id, triggered_spell_id);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -8039,7 +8059,11 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx)
|
|||
if (!unitTarget)
|
||||
return;
|
||||
|
||||
DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Spell ScriptStart spellid %u in EffectScriptEffect ", m_spellInfo->Id);
|
||||
// Previous effect might have started script
|
||||
if (!ScriptMgr::CanSpellEffectStartDBScript(m_spellInfo, eff_idx))
|
||||
return;
|
||||
|
||||
DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Spell ScriptStart spellid %u in EffectScriptEffect", m_spellInfo->Id);
|
||||
m_caster->GetMap()->ScriptsStart(sSpellScripts, m_spellInfo->Id, m_caster, unitTarget);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "11988"
|
||||
#define REVISION_NR "11989"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue