From f4075f0f945c842fe2b1a08ea4a7fa253e8e2e53 Mon Sep 17 00:00:00 2001 From: Subv2112 Date: Sat, 14 Jan 2012 17:37:28 +0100 Subject: Core/LFG: Fix priority of the player when its added to the lfg group Better implementation of the Dungeon Deserter debuff Rewrite the NeedBeforeGreed loot Fixed players being shown as Unknown Entity when entering the lfg group Some incremental optimizations after original patch Thanks to Retriman and Paecman for base implementation Signed-off-by: Machiavelli --- src/server/scripts/Spells/spell_generic.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src/server/scripts/Spells') diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 38e5771ccca..3fb2c4f3319 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -1445,7 +1445,17 @@ class spell_gen_luck_of_the_draw : public SpellScriptLoader if (GetUnitOwner()->GetTypeId() != TYPEID_PLAYER) return; - LFGDungeonEntry const* randomDungeon = sLFGDungeonStore.LookupEntry(*(sLFGMgr->GetSelectedDungeons(GetUnitOwner()->GetGUID()).begin())); + const LfgDungeonSet dungeons = sLFGMgr->GetSelectedDungeons(GetUnitOwner()->GetGUID()); + LfgDungeonSet::const_iterator itr = dungeons.begin(); + + if (itr == dungeons.end()) + { + Remove(AURA_REMOVE_BY_DEFAULT); + return; + } + + + LFGDungeonEntry const* randomDungeon = sLFGDungeonStore.LookupEntry(*itr); Group* group = GetUnitOwner()->ToPlayer()->GetGroup(); Map const* map = GetUnitOwner()->GetMap(); if (group && group->isLFGGroup()) -- cgit v1.2.3 From 4bdc5353735a7ec73c23e11f824adb378eea3adf Mon Sep 17 00:00:00 2001 From: Souler Date: Tue, 17 Jan 2012 12:55:54 +0100 Subject: Script/Quest: Solve some related problems with "An Audience With The Arcanist" and "A Meeting With The Magister" --- sql/updates/world/2012_01_17_00_world_misc.sql | 27 +++++++++ src/server/scripts/Northrend/dalaran.cpp | 13 ++++- src/server/scripts/Spells/spell_generic.cpp | 80 +++++++++++++++++++++++++- 3 files changed, 116 insertions(+), 4 deletions(-) create mode 100644 sql/updates/world/2012_01_17_00_world_misc.sql (limited to 'src/server/scripts/Spells') diff --git a/sql/updates/world/2012_01_17_00_world_misc.sql b/sql/updates/world/2012_01_17_00_world_misc.sql new file mode 100644 index 00000000000..300d239bd43 --- /dev/null +++ b/sql/updates/world/2012_01_17_00_world_misc.sql @@ -0,0 +1,27 @@ +DELETE FROM `spell_script_names` WHERE `spell_id` IN (69672,69673); +INSERT INTO `spell_script_names`(`spell_id`,`ScriptName`) VALUES +(69672,'spell_gen_sunreaver_disguise'), +(69673,'spell_gen_silver_covenant_disguise'); + +-- Update spells used on script. Now they are always casting the female spell, +-- since the spell script is fixed we should cast now the correct spell. +UPDATE `smart_scripts` SET `action_param1`=69672 WHERE `entryorguid`=36669 AND `action_type`=11 AND `action_param1`=70973; +UPDATE `smart_scripts` SET `action_param1`=69673 WHERE `entryorguid`=36670 AND `action_type`=11 AND `action_param1`=70971; +-- Set correct gossip menus ids for renewing the disguise +UPDATE `smart_scripts` SET `event_param1`=10858 WHERE `entryorguid`=36669 AND `event_param1`=10857; +UPDATE `smart_scripts` SET `event_param1`=10857 WHERE `entryorguid`=36670 AND `event_param1`=10858; + +-- Gossip options were crossed. They should offer to cast the oposing faction disguise,instead of his own faction disguise. +UPDATE `gossip_menu_option` SET `option_text`="Would you renew my Covenant disguise?" WHERE `menu_id`=10857 AND `id`=1; +UPDATE `gossip_menu_option` SET `option_text`="Would you renew my Sunreaver disguise?" WHERE `menu_id`=10858 AND `id`=1; + +-- Correct quest ids on conditios for showing the renew disguise option. +-- Also add a check for male disguise aura. +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup` IN (10857,10858) AND `SourceEntry`=1; +INSERT INTO `conditions`(`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES +(15,10858,1,0,11,70973,0,0,0,'',NULL), +(15,10858,1,0,11,70974,0,0,0,'',NULL), +(15,10858,1,0,9,20439,0,0,0,'',NULL), +(15,10857,1,0,11,70971,0,0,0,'',NULL), +(15,10857,1,0,11,70972,0,0,0,'',NULL), +(15,10857,1,0,9,24451,0,0,0,'',NULL); diff --git a/src/server/scripts/Northrend/dalaran.cpp b/src/server/scripts/Northrend/dalaran.cpp index 57007a93fa7..cd3cbf29d0d 100644 --- a/src/server/scripts/Northrend/dalaran.cpp +++ b/src/server/scripts/Northrend/dalaran.cpp @@ -32,7 +32,12 @@ Script Data End */ enum Spells { SPELL_TRESPASSER_A = 54028, - SPELL_TRESPASSER_H = 54029 + SPELL_TRESPASSER_H = 54029, + + SPELL_SUNREAVER_DISGUISE_FEMALE = 70973, + SPELL_SUNREAVER_DISGUISE_MALE = 70974, + SPELL_SILVER_COVENANT_DISGUISE_FEMALE = 70971, + SPELL_SILVER_COVENANT_DISGUISE_MALE = 70972, }; enum NPCs // All outdoor guards are within 35.0f of these NPCs @@ -71,8 +76,10 @@ public: Player* player = who->GetCharmerOrOwnerPlayerOrPlayerItself(); - // If player has Disguise aura for quest A Meeting With The Magister or An Audience With The Arcanist, do not teleport it away but let it pass - if (!player || player->isGameMaster() || player->IsBeingTeleported() || player->HasAura(70973) || player->HasAura(70971)) + if (!player || player->isGameMaster() || player->IsBeingTeleported() || + // If player has Disguise aura for quest A Meeting With The Magister or An Audience With The Arcanist, do not teleport it away but let it pass + player->HasAura(SPELL_SUNREAVER_DISGUISE_FEMALE) || player->HasAura(SPELL_SUNREAVER_DISGUISE_MALE) || + player->HasAura(SPELL_SILVER_COVENANT_DISGUISE_FEMALE) || player->HasAura(SPELL_SILVER_COVENANT_DISGUISE_MALE)) return; switch (me->GetEntry()) diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 38e5771ccca..bb3e63af8e4 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -1471,6 +1471,82 @@ class spell_gen_luck_of_the_draw : public SpellScriptLoader } }; +enum DalaranDisguiseSpells +{ + SPELL_SUNREAVER_DISGUISE_TRIGGER = 69672, + SPELL_SUNREAVER_DISGUISE_FEMALE = 70973, + SPELL_SUNREAVER_DISGUISE_MALE = 70974, + + SPELL_SILVER_COVENANT_DISGUISE_TRIGGER = 69673, + SPELL_SILVER_COVENANT_DISGUISE_FEMALE = 70971, + SPELL_SILVER_COVENANT_DISGUISE_MALE = 70972, +}; + +class spell_gen_dalaran_disguise : public SpellScriptLoader +{ + public: + spell_gen_dalaran_disguise(const char* name) : SpellScriptLoader(name) {} + + class spell_gen_dalaran_disguise_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_dalaran_disguise_SpellScript); + bool Validate(SpellInfo const* spellEntry) + { + switch (spellEntry->Id) + { + case SPELL_SUNREAVER_DISGUISE_TRIGGER: + if (!sSpellMgr->GetSpellInfo(SPELL_SUNREAVER_DISGUISE_FEMALE)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_SUNREAVER_DISGUISE_MALE)) + return false; + break; + case SPELL_SILVER_COVENANT_DISGUISE_TRIGGER: + if (!sSpellMgr->GetSpellInfo(SPELL_SILVER_COVENANT_DISGUISE_FEMALE)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_SILVER_COVENANT_DISGUISE_MALE)) + return false; + break; + } + return true; + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + + if (Player* player = GetHitPlayer()) + { + uint8 gender = player->getGender(); + + uint32 spellId = GetSpellInfo()->Id; + + switch (spellId) + { + case SPELL_SUNREAVER_DISGUISE_TRIGGER: + spellId = gender ? SPELL_SUNREAVER_DISGUISE_FEMALE : SPELL_SUNREAVER_DISGUISE_MALE; + break; + case SPELL_SILVER_COVENANT_DISGUISE_TRIGGER: + spellId = gender ? SPELL_SILVER_COVENANT_DISGUISE_FEMALE : SPELL_SILVER_COVENANT_DISGUISE_MALE; + break; + default: + break; + } + + GetCaster()->CastSpell(player, spellId, true); + } + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_gen_dalaran_disguise_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_gen_dalaran_disguise_SpellScript(); + } +}; + void AddSC_generic_spell_scripts() { new spell_gen_absorb0_hitlimit1(); @@ -1504,4 +1580,6 @@ void AddSC_generic_spell_scripts() new spell_gen_oracle_wolvar_reputation(); new spell_gen_damage_reduction_aura(); new spell_gen_luck_of_the_draw(); -} + new spell_gen_dalaran_disguise("spell_gen_sunreaver_disguise"); + new spell_gen_dalaran_disguise("spell_gen_silver_covenant_disguise"); +} \ No newline at end of file -- cgit v1.2.3 From 126d3c8339a220de2c29bfd74de10b637470069d Mon Sep 17 00:00:00 2001 From: Discover- Date: Tue, 24 Jan 2012 21:23:05 +0100 Subject: Scripts/Spells: Script spell Refocus --- .../2012_01_24_00_world_spell_script_names.sql | 4 ++ src/server/scripts/Spells/spell_item.cpp | 46 ++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 sql/updates/world/2012_01_24_00_world_spell_script_names.sql (limited to 'src/server/scripts/Spells') diff --git a/sql/updates/world/2012_01_24_00_world_spell_script_names.sql b/sql/updates/world/2012_01_24_00_world_spell_script_names.sql new file mode 100644 index 00000000000..3bf6ddd71ae --- /dev/null +++ b/sql/updates/world/2012_01_24_00_world_spell_script_names.sql @@ -0,0 +1,4 @@ +-- Scriptname for Refocus spell +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_item_refocus'; +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(24531,'spell_item_refocus'); \ No newline at end of file diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp index 5a0ffbd2c90..b40879d500e 100644 --- a/src/server/scripts/Spells/spell_item.cpp +++ b/src/server/scripts/Spells/spell_item.cpp @@ -1128,6 +1128,51 @@ class spell_magic_eater_food : public SpellScriptLoader } }; +enum Refocus +{ + SPELL_AIMED_SHOT = 19434, + SPELL_MULTISHOT = 2643, + SPELL_VOLLEY = 42243, +}; + +class spell_item_refocus : public SpellScriptLoader +{ + public: + spell_item_refocus() : SpellScriptLoader("spell_item_refocus") { } + + class spell_item_refocus_SpellScript : public SpellScript + { + PrepareSpellScript(spell_item_refocus_SpellScript); + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Player* caster = GetCaster()->ToPlayer(); + + if (!caster || caster->getClass() != CLASS_HUNTER) + return; + + if (caster->HasSpellCooldown(SPELL_AIMED_SHOT)) + caster->RemoveSpellCooldown(SPELL_AIMED_SHOT, true); + + if (caster->HasSpellCooldown(SPELL_MULTISHOT)) + caster->RemoveSpellCooldown(SPELL_MULTISHOT, true); + + if (caster->HasSpellCooldown(SPELL_VOLLEY)) + caster->RemoveSpellCooldown(SPELL_VOLLEY, true); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_item_refocus_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_item_refocus_SpellScript(); + } +}; + void AddSC_item_spell_scripts() { // 23074 Arcanite Dragonling @@ -1160,4 +1205,5 @@ void AddSC_item_spell_scripts() new spell_item_ashbringer(); new spell_magic_eater_food(); + new spell_item_refocus(); } -- cgit v1.2.3 From 50a6ec015eb1cfd7e55129026bd1e3e34d9603a0 Mon Sep 17 00:00:00 2001 From: Souler Date: Sun, 29 Jan 2012 03:49:55 +0100 Subject: Scripts/Spells: Fixed behaviour of Elune's Candle, Rockets and Rocket Clusters. Scripts/NPC: Implemented AI for Omen and his summoning ritual. --- sql/updates/world/2012_01_28_01_world_misc.sql | 102 +++++++++ src/server/scripts/Kalimdor/moonglade.cpp | 146 ++++++++++++- src/server/scripts/Spells/spell_generic.cpp | 70 ++++++ src/server/scripts/World/npcs_special.cpp | 281 +++++++++++++++++++++++++ 4 files changed, 598 insertions(+), 1 deletion(-) create mode 100644 sql/updates/world/2012_01_28_01_world_misc.sql (limited to 'src/server/scripts/Spells') diff --git a/sql/updates/world/2012_01_28_01_world_misc.sql b/sql/updates/world/2012_01_28_01_world_misc.sql new file mode 100644 index 00000000000..c6c90dd9e0d --- /dev/null +++ b/sql/updates/world/2012_01_28_01_world_misc.sql @@ -0,0 +1,102 @@ +DELETE FROM `spell_script_names` WHERE `spell_id` IN (26374); +INSERT INTO `spell_script_names`(`spell_id`,`ScriptName`) VALUES +(26374,'spell_gen_elune_candle'); + +-- Set Gigant Spotlight as not selectable +UPDATE `creature_template` SET `unit_flags`=33554432 WHERE `entry`=15902; + +DELETE FROM `creature_template_addon` WHERE (`entry`IN(15902,15466)); +INSERT INTO `creature_template_addon`(`entry`,`path_id`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES +(15466,0,0,0,0,0,17327), -- Add spirit particles to Omen minions +(15902,0,0,0,0,0,50236); -- Add Spotlight aura to Gigant Spotlight (ummoned by 26392 on Omen's death) + +UPDATE `creature_template` SET `ScriptName`='npc_giant_spotlight' WHERE `entry`=15902; +UPDATE `creature_template` SET `RegenHealth`=0,`ScriptName`='npc_omen' WHERE `entry`=15467; +UPDATE `creature_template` SET `ScriptName`='npc_firework',`AIName`='',`faction_A`=35,`faction_H`=35,`unit_flags`=33555200 WHERE `entry` IN (15879,15880,15881,15882,15883,15884,15885,15886,15887,15888,15889,15890,15872,15873,15874,15875,15876,15877,15911,15912,15913,15914,15915,15916,15918); +-- Cleanup EventAI and SmartAI +DELETE FROM `creature_ai_scripts` WHERE `creature_id` IN (15879,15880,15881,15882,15883,15884,15885,15886,15887,15888,15889,15890,15872,15873,15874,15875,15876,15877,15911,15912,15913,15914,15915,15916,15918); +DELETE FROM `smart_scripts` WHERE `source_type`=0 AND `entryorguid` IN (15879,15880,15881,15882,15883,15884,15885,15886,15887,15888,15889,15890,15872,15873,15874,15875,15876,15877,15911,15912,15913,15914,15915,15916,15918); + +-- Update al targeting stuff for Fireworks and Rocket clusters +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry` IN (26294,26295,26333,26334,26336,26337,26338,26488,26490,26517,26521,26344,26347,26345,26348,26349,26351,26352,26354,26355,26356); +INSERT INTO `conditions`(`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES +-- Targeting Firework Launcher +(13,0,26294,0,18,0,180771,0,0,'',"Small White Rocket target Firework Launcher"), +(13,0,26294,0,18,0,180850,0,0,'',"Small White Rocket target Firework Launcher"), +(13,0,26294,0,18,0,180868,0,0,'',"Small White Rocket target Firework Launcher"), +(13,0,26295,0,18,0,180771,0,0,'',"Small Yellow Rocket target Firework Launcher"), +(13,0,26295,0,18,0,180850,0,0,'',"Small Yellow Rocket target Firework Launcher"), +(13,0,26295,0,18,0,180868,0,0,'',"Small Yellow Rocket target Firework Launcher"), +(13,0,26333,0,18,0,180771,0,0,'',"Large Blue Rocket target Firework Launcher"), +(13,0,26333,0,18,0,180850,0,0,'',"Large Blue Rocket target Firework Launcher"), +(13,0,26333,0,18,0,180868,0,0,'',"Large Blue Rocket target Firework Launcher"), +(13,0,26334,0,18,0,180771,0,0,'',"Large Green Rocket target Firework Launcher"), +(13,0,26334,0,18,0,180850,0,0,'',"Large Green Rocket target Firework Launcher"), +(13,0,26334,0,18,0,180868,0,0,'',"Large Green Rocket target Firework Launcher"), +(13,0,26336,0,18,0,180771,0,0,'',"Large Red Rocket target Firework Launcher"), +(13,0,26336,0,18,0,180850,0,0,'',"Large Red Rocket target Firework Launcher"), +(13,0,26336,0,18,0,180868,0,0,'',"Large Red Rocket target Firework Launcher"), +(13,0,26337,0,18,0,180771,0,0,'',"Large White Rocket target Firework Launcher"), +(13,0,26337,0,18,0,180850,0,0,'',"Large White Rocket target Firework Launcher"), +(13,0,26337,0,18,0,180868,0,0,'',"Large White Rocket target Firework Launcher"), +(13,0,26338,0,18,0,180771,0,0,'',"Large Yellow Rocket target Firework Launcher"), +(13,0,26338,0,18,0,180850,0,0,'',"Large Yellow Rocket target Firework Launcher"), +(13,0,26338,0,18,0,180868,0,0,'',"Large Yellow Rocket target Firework Launcher"), +-- Targeting Cluster Launcher +(13,0,26488,0,18,0,180772,0,0,'',"Large Blue Rocket Cluster target Cluster Launcher"), +(13,0,26488,0,18,0,180859,0,0,'',"Large Blue Rocket Cluster target Cluster Launcher"), +(13,0,26488,0,18,0,180869,0,0,'',"Large Blue Rocket Cluster target Cluster Launcher"), +(13,0,26488,0,18,0,180874,0,0,'',"Large Blue Rocket Cluster target Cluster Launcher"), +(13,0,26490,0,18,0,180772,0,0,'',"Large Green Rocket Cluster target Cluster Launcher"), +(13,0,26490,0,18,0,180859,0,0,'',"Large Green Rocket Cluster target Cluster Launcher"), +(13,0,26490,0,18,0,180869,0,0,'',"Large Green Rocket Cluster target Cluster Launcher"), +(13,0,26490,0,18,0,180874,0,0,'',"Large Green Rocket Cluster target Cluster Launcher"), +(13,0,26517,0,18,0,180772,0,0,'',"Large Red Rocket Cluster target Cluster Launcher"), +(13,0,26517,0,18,0,180859,0,0,'',"Large Red Rocket Cluster target Cluster Launcher"), +(13,0,26517,0,18,0,180869,0,0,'',"Large Red Rocket Cluster target Cluster Launcher"), +(13,0,26517,0,18,0,180874,0,0,'',"Large Red Rocket Cluster target Cluster Launcher"), +(13,0,26521,0,18,0,180772,0,0,'',"Lucky Lunar rocket Cluster target Cluster Launcher"), +(13,0,26521,0,18,0,180859,0,0,'',"Lucky Lunar rocket Cluster target Cluster Launcher"), +(13,0,26521,0,18,0,180869,0,0,'',"Lucky Lunar rocket Cluster target Cluster Launcher"), +(13,0,26521,0,18,0,180874,0,0,'',"Lucky Lunar rocket Cluster target Cluster Launcher"), +-- Targeting Firework Launcher (Again) +(13,0,26347,0,18,0,180771,0,0,'',"Rocket, RED target Firework Launcher"), +(13,0,26347,0,18,0,180850,0,0,'',"Rocket, RED target Firework Launcher"), +(13,0,26347,0,18,0,180868,0,0,'',"Rocket, RED target Firework Launcher"), +(13,0,26344,0,18,0,180771,0,0,'',"Rocket, BLUE target Firework Launcher"), +(13,0,26344,0,18,0,180850,0,0,'',"Rocket, BLUE target Firework Launcher"), +(13,0,26344,0,18,0,180868,0,0,'',"Rocket, BLUE target Firework Launcher"), +(13,0,26345,0,18,0,180771,0,0,'',"Rocket, GREEEN target Firework Launcher"), +(13,0,26345,0,18,0,180850,0,0,'',"Rocket, GREEEN target Firework Launcher"), +(13,0,26345,0,18,0,180868,0,0,'',"Rocket, GREEEN target Firework Launcher"), +(13,0,26348,0,18,0,180771,0,0,'',"Rocket, WHITE target Firework Launcher"), +(13,0,26348,0,18,0,180850,0,0,'',"Rocket, WHITE target Firework Launcher"), +(13,0,26348,0,18,0,180868,0,0,'',"Rocket, WHITE target Firework Launcher"), +(13,0,26349,0,18,0,180771,0,0,'',"Rocket, YELLOW target Firework Launcher"), +(13,0,26349,0,18,0,180850,0,0,'',"Rocket, YELLOW target Firework Launcher"), +(13,0,26349,0,18,0,180868,0,0,'',"Rocket, YELLOW target Firework Launcher"), +(13,0,26351,0,18,0,180771,0,0,'',"Rocket, BLUE BIG target Firework Launcher"), +(13,0,26351,0,18,0,180850,0,0,'',"Rocket, BLUE BIG target Firework Launcher"), +(13,0,26351,0,18,0,180868,0,0,'',"Rocket, BLUE BIG target Firework Launcher"), +(13,0,26352,0,18,0,180771,0,0,'',"Rocket, GREEN BIG target Firework Launcher"), +(13,0,26352,0,18,0,180850,0,0,'',"Rocket, GREEN BIG target Firework Launcher"), +(13,0,26352,0,18,0,180868,0,0,'',"Rocket, GREEN BIG target Firework Launcher"), +(13,0,26354,0,18,0,180771,0,0,'',"Rocket, RED BIG target Firework Launcher"), +(13,0,26354,0,18,0,180850,0,0,'',"Rocket, RED BIG target Firework Launcher"), +(13,0,26354,0,18,0,180868,0,0,'',"Rocket, RED BIG target Firework Launcher"), +(13,0,26355,0,18,0,180771,0,0,'',"Rocket, WHITE BIG target Firework Launcher"), +(13,0,26355,0,18,0,180850,0,0,'',"Rocket, WHITE BIG target Firework Launcher"), +(13,0,26355,0,18,0,180868,0,0,'',"Rocket, WHITE BIG target Firework Launcher"), +(13,0,26356,0,18,0,180771,0,0,'',"Rocket, YELLOW BIG target Firework Launcher"), +(13,0,26356,0,18,0,180850,0,0,'',"Rocket, YELLOW BIG target Firework Launcher"), +(13,0,26356,0,18,0,180868,0,0,'',"Rocket, YELLOW BIG target Firework Launcher"); + +UPDATE `creature_template` SET `AIName`='SmartAI' WHERE `entry`=15466; +DELETE FROM `smart_scripts` WHERE (`entryorguid`=15466 AND `source_type`=0); +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(15466,0,0,0,8,0,100,0,26636,0,8000,9000,11,25495,0,0,0,0,0,1,0,0,0,0,0,0,0,"Minion of Omen - Cast Firework Dazzled when hitted by Elune's Candle firework"); + +-- Cast quest credit spell when getting Elune's Blessing buff +DELETE FROM `spell_scripts` WHERE `id`=26393; +INSERT INTO `spell_scripts`(`id`,`effIndex`,`delay`,`command`,`datalong`,`datalong2`,`dataint`,`x`,`y`,`z`,`o`) VALUES +(26393,1,0,15,26394,2,0,0,0,0,0); \ No newline at end of file diff --git a/src/server/scripts/Kalimdor/moonglade.cpp b/src/server/scripts/Kalimdor/moonglade.cpp index 595a72ec2bf..f9e4bce34d0 100644 --- a/src/server/scripts/Kalimdor/moonglade.cpp +++ b/src/server/scripts/Kalimdor/moonglade.cpp @@ -573,9 +573,151 @@ public: }; /*#### -# +# npc_omen ####*/ +enum Omen +{ + NPC_OMEN = 15467, + + SPELL_OMEN_CLEAVE = 15284, + SPELL_OMEN_STARFALL = 26540, + SPELL_OMEN_SUMMON_SPOTLIGHT = 26392, + SPELL_ELUNE_CANDLE = 26374, + + GO_ELUNE_TRAP_1 = 180876, + GO_ELUNE_TRAP_2 = 180877, + + EVENT_CAST_CLEAVE = 1, + EVENT_CAST_STARFALL = 2, + EVENT_DESPAWN = 3, +}; + +class npc_omen : public CreatureScript +{ +public: + npc_omen() : CreatureScript("npc_omen") { } + + struct npc_omenAI : public ScriptedAI + { + npc_omenAI(Creature* creature) : ScriptedAI(creature) + { + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + me->GetMotionMaster()->MovePoint(1, 7549.977f, -2855.137f, 456.9678f); + } + + EventMap events; + + void MovementInform(uint32 type, uint32 pointId) + { + if (type != POINT_MOTION_TYPE) + return; + + if (pointId == 1) + { + me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + if (Player* player = me->SelectNearestPlayer(40.0f)) + AttackStart(player); + } + } + + void EnterCombat(Unit* /*attacker*/) + { + events.Reset(); + events.ScheduleEvent(EVENT_CAST_CLEAVE, urand(3000, 5000)); + events.ScheduleEvent(EVENT_CAST_STARFALL, urand(8000, 10000)); + } + + void JustDied(Unit* /*killer*/) + { + DoCast(SPELL_OMEN_SUMMON_SPOTLIGHT); + } + + void SpellHit(Unit* /*caster*/, const SpellInfo* spell) + { + if (spell->Id == SPELL_ELUNE_CANDLE) + { + if (me->HasAura(SPELL_OMEN_STARFALL)) + me->RemoveAurasDueToSpell(SPELL_OMEN_STARFALL); + + events.RescheduleEvent(EVENT_CAST_STARFALL, urand(14000, 16000)); + } + } + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; + + events.Update(diff); + + switch (events.ExecuteEvent()) + { + case EVENT_CAST_CLEAVE: + DoCastVictim(SPELL_OMEN_CLEAVE); + events.ScheduleEvent(EVENT_CAST_CLEAVE, urand(8000, 10000)); + break; + case EVENT_CAST_STARFALL: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_OMEN_STARFALL); + events.ScheduleEvent(EVENT_CAST_STARFALL, urand(14000, 16000)); + break; + } + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_omenAI(creature); + } +}; + +class npc_giant_spotlight : public CreatureScript +{ +public: + npc_giant_spotlight() : CreatureScript("npc_giant_spotlight") { } + + struct npc_giant_spotlightAI : public ScriptedAI + { + npc_giant_spotlightAI(Creature* creature) : ScriptedAI(creature) {} + + EventMap events; + + void Reset() + { + events.Reset(); + events.ScheduleEvent(EVENT_DESPAWN, 5*MINUTE*IN_MILLISECONDS); + } + + void UpdateAI(const uint32 diff) + { + events.Update(diff); + + if (events.ExecuteEvent() == EVENT_DESPAWN) + { + if (GameObject* trap = me->FindNearestGameObject(GO_ELUNE_TRAP_1, 5.0f)) + trap->RemoveFromWorld(); + + if (GameObject* trap = me->FindNearestGameObject(GO_ELUNE_TRAP_2, 5.0f)) + trap->RemoveFromWorld(); + + if (Creature* omen = me->FindNearestCreature(NPC_OMEN, 5.0f, false)) + omen->DespawnOrUnsummon(); + + me->DespawnOrUnsummon(); + } + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_giant_spotlightAI(creature); + } +}; + void AddSC_moonglade() { new npc_bunthen_plainswind(); @@ -583,4 +725,6 @@ void AddSC_moonglade() new npc_silva_filnaveth(); new npc_clintar_dreamwalker(); new npc_clintar_spirit(); + new npc_omen(); + new npc_giant_spotlight(); } diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 2b31a50510d..d0307966795 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -412,6 +412,75 @@ class spell_gen_leeching_swarm : public SpellScriptLoader } }; +enum EluneCandle +{ + NPC_OMEN = 15467, + + SPELL_ELUNE_CANDLE_OMEN_HEAD = 26622, + SPELL_ELUNE_CANDLE_OMEN_CHEST = 26624, + SPELL_ELUNE_CANDLE_OMEN_HAND_R = 26625, + SPELL_ELUNE_CANDLE_OMEN_HAND_L = 26649, + SPELL_ELUNE_CANDLE_NORMAL = 26636, +}; + +class spell_gen_elune_candle : public SpellScriptLoader +{ + public: + spell_gen_elune_candle() : SpellScriptLoader("spell_gen_elune_candle") {} + + class spell_gen_elune_candle_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_elune_candle_SpellScript); + bool Validate(SpellInfo const* /*spellEntry*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_ELUNE_CANDLE_OMEN_HEAD)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_ELUNE_CANDLE_OMEN_CHEST)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_ELUNE_CANDLE_OMEN_HAND_R)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_ELUNE_CANDLE_OMEN_HAND_L)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_ELUNE_CANDLE_NORMAL)) + return false; + return true; + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (Unit* target = GetHitUnit()) + { + uint32 spellId = 0; + + if (target->GetEntry() == NPC_OMEN) + { + switch (urand(0, 3)) + { + case 0: spellId = SPELL_ELUNE_CANDLE_OMEN_HEAD; break; + case 1: spellId = SPELL_ELUNE_CANDLE_OMEN_CHEST; break; + case 2: spellId = SPELL_ELUNE_CANDLE_OMEN_HAND_R; break; + case 3: spellId = SPELL_ELUNE_CANDLE_OMEN_HAND_L; break; + } + } + else + spellId = SPELL_ELUNE_CANDLE_NORMAL; + + GetCaster()->CastSpell(target, spellId, true, NULL); + } + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_gen_elune_candle_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_gen_elune_candle_SpellScript(); + } +}; + // 24750 Trick enum eTrickSpells { @@ -1592,4 +1661,5 @@ void AddSC_generic_spell_scripts() new spell_gen_luck_of_the_draw(); new spell_gen_dalaran_disguise("spell_gen_sunreaver_disguise"); new spell_gen_dalaran_disguise("spell_gen_silver_covenant_disguise"); + new spell_gen_elune_candle(); } diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp index 21e4fe6a3a0..9227c0c1138 100644 --- a/src/server/scripts/World/npcs_special.cpp +++ b/src/server/scripts/World/npcs_special.cpp @@ -40,6 +40,7 @@ npc_sayge 100% Darkmoon event fortune teller, buff player based npc_snake_trap_serpents 80% AI for snakes that summoned by Snake Trap npc_shadowfiend 100% restore 5% of owner's mana when shadowfiend die from damage npc_locksmith 75% list of keys needs to be confirmed +npc_firework 100% NPC's summoned by rockets and rocket clusters, for making them cast visual EndContentData */ #include "ScriptPCH.h" @@ -2764,6 +2765,285 @@ public: } }; +enum Fireworks +{ + NPC_OMEN = 15467, + NPC_MINION_OF_OMEN = 15466, + NPC_FIREWORK_BLUE = 15879, + NPC_FIREWORK_GREEN = 15880, + NPC_FIREWORK_PURPLE = 15881, + NPC_FIREWORK_RED = 15882, + NPC_FIREWORK_YELLOW = 15883, + NPC_FIREWORK_WHITE = 15884, + NPC_FIREWORK_BIG_BLUE = 15885, + NPC_FIREWORK_BIG_GREEN = 15886, + NPC_FIREWORK_BIG_PURPLE = 15887, + NPC_FIREWORK_BIG_RED = 15888, + NPC_FIREWORK_BIG_YELLOW = 15889, + NPC_FIREWORK_BIG_WHITE = 15890, + + NPC_CLUSTER_BLUE = 15872, + NPC_CLUSTER_RED = 15873, + NPC_CLUSTER_GREEN = 15874, + NPC_CLUSTER_PURPLE = 15875, + NPC_CLUSTER_WHITE = 15876, + NPC_CLUSTER_YELLOW = 15877, + NPC_CLUSTER_BIG_BLUE = 15911, + NPC_CLUSTER_BIG_GREEN = 15912, + NPC_CLUSTER_BIG_PURPLE = 15913, + NPC_CLUSTER_BIG_RED = 15914, + NPC_CLUSTER_BIG_WHITE = 15915, + NPC_CLUSTER_BIG_YELLOW = 15916, + NPC_CLUSTER_ELUNE = 15918, + + GO_FIREWORK_LAUNCHER_1 = 180771, + GO_FIREWORK_LAUNCHER_2 = 180868, + GO_FIREWORK_LAUNCHER_3 = 180850, + GO_CLUSTER_LAUNCHER_1 = 180772, + GO_CLUSTER_LAUNCHER_2 = 180859, + GO_CLUSTER_LAUNCHER_3 = 180869, + GO_CLUSTER_LAUNCHER_4 = 180874, + + SPELL_ROCKET_BLUE = 26344, + SPELL_ROCKET_GREEN = 26345, + SPELL_ROCKET_PURPLE = 26346, + SPELL_ROCKET_RED = 26347, + SPELL_ROCKET_WHITE = 26348, + SPELL_ROCKET_YELLOW = 26349, + SPELL_ROCKET_BIG_BLUE = 26351, + SPELL_ROCKET_BIG_GREEN = 26352, + SPELL_ROCKET_BIG_PURPLE = 26353, + SPELL_ROCKET_BIG_RED = 26354, + SPELL_ROCKET_BIG_WHITE = 26355, + SPELL_ROCKET_BIG_YELLOW = 26356, + SPELL_LUNAR_FORTUNE = 26522, + + ANIM_GO_LAUNCH_FIREWORK = 3, + ZONE_MOONGLADE = 493, +}; + +Position omenSummonPos = {7558.993f, -2839.999f, 450.0214f, 4.46f}; + +class npc_firework : public CreatureScript +{ +public: + npc_firework() : CreatureScript("npc_firework") { } + + struct npc_fireworkAI : public ScriptedAI + { + npc_fireworkAI(Creature* creature) : ScriptedAI(creature) {} + + bool isCluster() + { + switch (me->GetEntry()) + { + case NPC_FIREWORK_BLUE: + case NPC_FIREWORK_GREEN: + case NPC_FIREWORK_PURPLE: + case NPC_FIREWORK_RED: + case NPC_FIREWORK_YELLOW: + case NPC_FIREWORK_WHITE: + case NPC_FIREWORK_BIG_BLUE: + case NPC_FIREWORK_BIG_GREEN: + case NPC_FIREWORK_BIG_PURPLE: + case NPC_FIREWORK_BIG_RED: + case NPC_FIREWORK_BIG_YELLOW: + case NPC_FIREWORK_BIG_WHITE: + return false; + case NPC_CLUSTER_BLUE: + case NPC_CLUSTER_GREEN: + case NPC_CLUSTER_PURPLE: + case NPC_CLUSTER_RED: + case NPC_CLUSTER_YELLOW: + case NPC_CLUSTER_WHITE: + case NPC_CLUSTER_BIG_BLUE: + case NPC_CLUSTER_BIG_GREEN: + case NPC_CLUSTER_BIG_PURPLE: + case NPC_CLUSTER_BIG_RED: + case NPC_CLUSTER_BIG_YELLOW: + case NPC_CLUSTER_BIG_WHITE: + case NPC_CLUSTER_ELUNE: + default: + return true; + } + } + + GameObject* FindNearestLauncher() + { + GameObject* launcher = NULL; + + if (isCluster()) + { + GameObject* launcher1 = GetClosestGameObjectWithEntry(me, GO_CLUSTER_LAUNCHER_1, 0.5f); + GameObject* launcher2 = GetClosestGameObjectWithEntry(me, GO_CLUSTER_LAUNCHER_2, 0.5f); + GameObject* launcher3 = GetClosestGameObjectWithEntry(me, GO_CLUSTER_LAUNCHER_3, 0.5f); + GameObject* launcher4 = GetClosestGameObjectWithEntry(me, GO_CLUSTER_LAUNCHER_4, 0.5f); + + if (launcher1) + launcher = launcher1; + else if (launcher2) + launcher = launcher2; + else if (launcher3) + launcher = launcher3; + else if (launcher4) + launcher = launcher4; + } + else + { + GameObject* launcher1 = GetClosestGameObjectWithEntry(me, GO_FIREWORK_LAUNCHER_1, 0.5f); + GameObject* launcher2 = GetClosestGameObjectWithEntry(me, GO_FIREWORK_LAUNCHER_2, 0.5f); + GameObject* launcher3 = GetClosestGameObjectWithEntry(me, GO_FIREWORK_LAUNCHER_3, 0.5f); + + if (launcher1) + launcher = launcher1; + else if (launcher2) + launcher = launcher2; + else if (launcher3) + launcher = launcher3; + } + + return launcher; + } + + uint32 GetFireworkSpell(uint32 entry) + { + switch (entry) + { + case NPC_FIREWORK_BLUE: + return SPELL_ROCKET_BLUE; + case NPC_FIREWORK_GREEN: + return SPELL_ROCKET_GREEN; + case NPC_FIREWORK_PURPLE: + return SPELL_ROCKET_PURPLE; + case NPC_FIREWORK_RED: + return SPELL_ROCKET_RED; + case NPC_FIREWORK_YELLOW: + return SPELL_ROCKET_YELLOW; + case NPC_FIREWORK_WHITE: + return SPELL_ROCKET_WHITE; + case NPC_FIREWORK_BIG_BLUE: + return SPELL_ROCKET_BIG_BLUE; + case NPC_FIREWORK_BIG_GREEN: + return SPELL_ROCKET_BIG_GREEN; + case NPC_FIREWORK_BIG_PURPLE: + return SPELL_ROCKET_BIG_PURPLE; + case NPC_FIREWORK_BIG_RED: + return SPELL_ROCKET_BIG_RED; + case NPC_FIREWORK_BIG_YELLOW: + return SPELL_ROCKET_BIG_YELLOW; + case NPC_FIREWORK_BIG_WHITE: + return SPELL_ROCKET_BIG_WHITE; + default: + return 0; + } + } + + uint32 GetFireworkGameObjectId() + { + uint32 spellId = 0; + + switch (me->GetEntry()) + { + case NPC_CLUSTER_BLUE: + spellId = GetFireworkSpell(NPC_FIREWORK_BLUE); + break; + case NPC_CLUSTER_GREEN: + spellId = GetFireworkSpell(NPC_FIREWORK_GREEN); + break; + case NPC_CLUSTER_PURPLE: + spellId = GetFireworkSpell(NPC_FIREWORK_PURPLE); + break; + case NPC_CLUSTER_RED: + spellId = GetFireworkSpell(NPC_FIREWORK_RED); + break; + case NPC_CLUSTER_YELLOW: + spellId = GetFireworkSpell(NPC_FIREWORK_YELLOW); + break; + case NPC_CLUSTER_WHITE: + spellId = GetFireworkSpell(NPC_FIREWORK_WHITE); + break; + case NPC_CLUSTER_BIG_BLUE: + spellId = GetFireworkSpell(NPC_FIREWORK_BIG_BLUE); + break; + case NPC_CLUSTER_BIG_GREEN: + spellId = GetFireworkSpell(NPC_FIREWORK_BIG_GREEN); + break; + case NPC_CLUSTER_BIG_PURPLE: + spellId = GetFireworkSpell(NPC_FIREWORK_BIG_PURPLE); + break; + case NPC_CLUSTER_BIG_RED: + spellId = GetFireworkSpell(NPC_FIREWORK_BIG_RED); + break; + case NPC_CLUSTER_BIG_YELLOW: + spellId = GetFireworkSpell(NPC_FIREWORK_BIG_YELLOW); + break; + case NPC_CLUSTER_BIG_WHITE: + spellId = GetFireworkSpell(NPC_FIREWORK_BIG_WHITE); + break; + case NPC_CLUSTER_ELUNE: + spellId = GetFireworkSpell(urand(NPC_FIREWORK_BLUE, NPC_FIREWORK_WHITE)); + break; + } + + const SpellInfo* spellInfo = sSpellMgr->GetSpellInfo(spellId); + + if (spellInfo && spellInfo->Effects[0].Effect == SPELL_EFFECT_SUMMON_OBJECT_WILD) + return spellInfo->Effects[0].MiscValue; + + return 0; + } + + void Reset() + { + if (GameObject* launcher = FindNearestLauncher()) + { + launcher->SendCustomAnim(ANIM_GO_LAUNCH_FIREWORK); + me->SetOrientation(launcher->GetOrientation() + M_PI/2); + } + else + return; + + if (isCluster()) + { + // Check if we are near Elune'ara lake south, if so try to summon Omen or a minion + if (me->GetZoneId() == ZONE_MOONGLADE) + { + if (!me->FindNearestCreature(NPC_OMEN, 100.0f, false) && me->GetDistance2d(omenSummonPos.GetPositionX(), omenSummonPos.GetPositionY()) <= 100.0f) + { + switch (urand(0,9)) + { + case 0: + case 1: + case 2: + case 3: + if (Creature* minion = me->SummonCreature(NPC_MINION_OF_OMEN, me->GetPositionX()+frand(-5.0f, 5.0f), me->GetPositionY()+frand(-5.0f, 5.0f), me->GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000)) + minion->AI()->AttackStart(me->SelectNearestPlayer(20.0f)); + break; + case 9: + me->SummonCreature(NPC_OMEN, omenSummonPos); + break; + } + } + } + if (me->GetEntry() == NPC_CLUSTER_ELUNE) + DoCast(SPELL_LUNAR_FORTUNE); + + float displacement = 0.7f; + for (uint8 i = 0; i < 4; i++) + me->SummonGameObject(GetFireworkGameObjectId(), me->GetPositionX() + (i%2 == 0 ? displacement : -displacement), me->GetPositionY() + (i > 1 ? displacement : -displacement), me->GetPositionZ() + 4.0f, me->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 1); + } + else + //me->CastSpell(me, GetFireworkSpell(me->GetEntry()), true); + me->CastSpell(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), GetFireworkSpell(me->GetEntry()), true); + } + }; + + CreatureAI *GetAI(Creature* creature) const + { + return new npc_fireworkAI(creature); + } +}; + void AddSC_npcs_special() { new npc_air_force_bots; @@ -2796,5 +3076,6 @@ void AddSC_npcs_special() new npc_experience; new npc_fire_elemental; new npc_earth_elemental; + new npc_firework; } -- cgit v1.2.3 From 75992143c193ec6afdd5897e06eb3694fc80a13f Mon Sep 17 00:00:00 2001 From: Souler Date: Mon, 30 Jan 2012 00:21:42 +0100 Subject: Scripts/Spells: Fix Argent Tournament mount spells: * Break-Shield * Charge * Defend (visual) * Mounted duel * Faction Pennants when riding argent tournament mounts Closes #4917. --- sql/updates/world/2012_01_29_04_world_misc.sql | 116 ++++ src/server/game/Entities/Player/Player.h | 3 +- src/server/game/Entities/Unit/Unit.cpp | 33 +- src/server/game/Spells/SpellEffects.cpp | 2 + src/server/game/Spells/SpellMgr.cpp | 17 + src/server/scripts/Spells/spell_generic.cpp | 749 +++++++++++++++++++++++ src/server/scripts/World/achievement_scripts.cpp | 12 + 7 files changed, 929 insertions(+), 3 deletions(-) create mode 100644 sql/updates/world/2012_01_29_04_world_misc.sql (limited to 'src/server/scripts/Spells') diff --git a/sql/updates/world/2012_01_29_04_world_misc.sql b/sql/updates/world/2012_01_29_04_world_misc.sql new file mode 100644 index 00000000000..3686957e433 --- /dev/null +++ b/sql/updates/world/2012_01_29_04_world_misc.sql @@ -0,0 +1,116 @@ +-- remove aura_required for clickspells on tournament mounts and add more cases (Thanks to @Tassader) +DELETE FROM `npc_spellclick_spells` WHERE npc_entry IN (33842,33796,33798,33791,33792,33799,33843,33800,33795,33790,33793,33794); +INSERT INTO `npc_spellclick_spells`(`npc_entry`,`spell_id`,`quest_start`,`quest_start_active`,`quest_end`,`cast_flags`,`aura_required`,`aura_forbidden`,`user_type`) VALUES +(33842,63791,13668,0,13687,1,0,0,0),-- Aspirant +(33799,62783,13691,0,0,1,0,0,0),-- A Valiant Of Orgrimmar +(33799,62783,13707,0,0,1,0,0,0),-- Valiant Of Orgrimmar +(33796,62784,13693,0,0,1,0,0,0),-- A Valiant Of Sen'jin +(33796,62784,13708,0,0,1,0,0,0),-- Valiant Of Sen'jin +(33792,62785,13694,0,0,1,0,0,0),-- A Valiant Of Thunder Bluff +(33792,62785,13709,0,0,1,0,0,0),-- Valiant Of Thunder Bluff +(33791,62786,13696,0,0,1,0,0,0),-- A Valiant Of Silvermoon +(33791,62786,13711,0,0,1,0,0,0),-- Valiant Of Silvermoon +(33798,62787,13695,0,0,1,0,0,0),-- A Valiant Of Undercity +(33798,62787,13710,0,0,1,0,0,0), -- Valiant Of Undercity +(33843,63792,13667,0,13686,1,0,0,0),-- Aspirant +(33800,62774,13593,0,0,1,0,0,0),-- A Valiant Of Stormwind +(33800,62774,13684,0,0,1,0,0,0),-- Valiant Of Stormwind +(33795,62779,13685,0,0,1,0,0,0),-- A Valiant Of Ironforge +(33795,62779,13703,0,0,1,0,0,0),-- Valiant Of Ironforge +(33793,62780,13688,0,0,1,0,0,0),-- A Valiant Of Gnomregan +(33793,62780,13704,0,0,1,0,0,0),-- Valiant Of Gnomregan +(33790,62781,13690,0,0,1,0,0,0),-- A Valiant Of Exodar +(33790,62781,13705,0,0,1,0,0,0),-- Valiant Of Exodar +(33794,62782,13689,0,0,1,0,0,0),-- A Valiant Of Darnassus +(33794,62782,13706,0,0,1,0,0,0); -- Valiant Of Darnassus +UPDATE `npc_spellclick_spells` SET `aura_required`=0 WHERE `aura_required`=62853; + +-- Break-Shield spells +DELETE FROM `spell_script_names` WHERE `spell_id` IN (62575,62626,64342,64507,64590,64595,64686,65147,66480,68504); +-- Charge spells +DELETE FROM `spell_script_names` WHERE `spell_id` IN (62874,62960,63661,62563,63003,63010,64591,66481,68282,68284,68321,68498,68501); +-- Defend spells +DELETE FROM `spell_script_names` WHERE `spell_id` IN (62552,62719,66482); +-- Pennant and summon spells +DELETE FROM `spell_script_names` WHERE `spell_id` IN (62863,63034,62774,62779,62780,62781,62782,62783,62784,62785,62786,62787,63663,63791,63792,62595,62596,62594,63394,63395,63396,63397,63398,63401,63402,63403,63404,63405,63406,63421,63422,63423,63425,63426,63427,63428,63429,63430,63431,63432,63433,63434,63435,63436,63606,63500,63501,63607,63608,63609); +INSERT INTO `spell_script_names`(`spell_id`,`ScriptName`) VALUES +(62575,'spell_gen_break_shield'), +(62626,'spell_gen_break_shield'), +(64342,'spell_gen_break_shield'), +(64507,'spell_gen_break_shield'), +(64590,'spell_gen_break_shield'), +(64595,'spell_gen_break_shield'), +(64686,'spell_gen_break_shield'), +(65147,'spell_gen_break_shield'), +(66480,'spell_gen_break_shield'), +(68504,'spell_gen_break_shield'), +(62874,'spell_gen_mounted_charge'), +(62960,'spell_gen_mounted_charge'), +(63661,'spell_gen_mounted_charge'), +(62563,'spell_gen_mounted_charge'), +(63003,'spell_gen_mounted_charge'), +(63010,'spell_gen_mounted_charge'), +(64591,'spell_gen_mounted_charge'), +(66481,'spell_gen_mounted_charge'), +(68282,'spell_gen_mounted_charge'), +(68284,'spell_gen_mounted_charge'), +(68321,'spell_gen_mounted_charge'), +(68498,'spell_gen_mounted_charge'), +(68501,'spell_gen_mounted_charge'), +(62552,'spell_gen_defend'), +(62719,'spell_gen_defend'), +(66482,'spell_gen_defend'), +(62863 ,'spell_gen_tournament_duel'), +(63034,'spell_gen_on_tournament_mount'), +(62595,'spell_gen_tournament_pennant'), +(62596,'spell_gen_tournament_pennant'), +(62594,'spell_gen_tournament_pennant'), +(63394,'spell_gen_tournament_pennant'), +(63395,'spell_gen_tournament_pennant'), +(63396,'spell_gen_tournament_pennant'), +(63397,'spell_gen_tournament_pennant'), +(63398,'spell_gen_tournament_pennant'), +(63401,'spell_gen_tournament_pennant'), +(63402,'spell_gen_tournament_pennant'), +(63403,'spell_gen_tournament_pennant'), +(63404,'spell_gen_tournament_pennant'), +(63405,'spell_gen_tournament_pennant'), +(63406,'spell_gen_tournament_pennant'), +(63421,'spell_gen_tournament_pennant'), +(63422,'spell_gen_tournament_pennant'), +(63423,'spell_gen_tournament_pennant'), +(63425,'spell_gen_tournament_pennant'), +(63426,'spell_gen_tournament_pennant'), +(63427,'spell_gen_tournament_pennant'), +(63428,'spell_gen_tournament_pennant'), +(63429,'spell_gen_tournament_pennant'), +(63430,'spell_gen_tournament_pennant'), +(63431,'spell_gen_tournament_pennant'), +(63432,'spell_gen_tournament_pennant'), +(63433,'spell_gen_tournament_pennant'), +(63434,'spell_gen_tournament_pennant'), +(63435,'spell_gen_tournament_pennant'), +(63436,'spell_gen_tournament_pennant'), +(63606,'spell_gen_tournament_pennant'), +(63500,'spell_gen_tournament_pennant'), +(63501,'spell_gen_tournament_pennant'), +(63607,'spell_gen_tournament_pennant'), +(63608,'spell_gen_tournament_pennant'), +(63609,'spell_gen_tournament_pennant'), +(62774,'spell_gen_summon_tournament_mount'), +(62779,'spell_gen_summon_tournament_mount'), +(62780,'spell_gen_summon_tournament_mount'), +(62781,'spell_gen_summon_tournament_mount'), +(62782,'spell_gen_summon_tournament_mount'), +(62783,'spell_gen_summon_tournament_mount'), +(62784,'spell_gen_summon_tournament_mount'), +(62785,'spell_gen_summon_tournament_mount'), +(62786,'spell_gen_summon_tournament_mount'), +(62787,'spell_gen_summon_tournament_mount'), +(63663,'spell_gen_summon_tournament_mount'), +(63791,'spell_gen_summon_tournament_mount'), +(63792,'spell_gen_summon_tournament_mount'); + +DELETE FROM `achievement_criteria_data` WHERE `criteria_id`=9798 AND `type`=11; +INSERT INTO `achievement_criteria_data` (`criteria_id`,`type`,`value1`,`value2`,`ScriptName`) VALUES +(9798,11,0,0, 'achievement_tilted'); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index c39d29db12a..2fa171cf3f9 100755 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -274,13 +274,14 @@ struct PvPInfo struct DuelInfo { - DuelInfo() : initiator(NULL), opponent(NULL), startTimer(0), startTime(0), outOfBound(0) {} + DuelInfo() : initiator(NULL), opponent(NULL), startTimer(0), startTime(0), outOfBound(0), isMounted(false) {} Player* initiator; Player* opponent; time_t startTimer; time_t startTime; time_t outOfBound; + bool isMounted; }; struct Areas diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 6bab63acf1b..e02331e00e7 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -628,6 +628,7 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam // duel ends when player has 1 or less hp bool duel_hasEnded = false; + bool duel_wasMounted = false; if (victim->GetTypeId() == TYPEID_PLAYER && victim->ToPlayer()->duel && damage >= (health-1)) { // prevent kill only if killed in duel and killed by opponent or opponent controlled creature @@ -636,6 +637,20 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam duel_hasEnded = true; } + else if (victim->IsVehicle() && damage >= (health-1) && victim->GetCharmer() && victim->GetCharmer()->GetTypeId() == TYPEID_PLAYER) + { + Player* victimRider = victim->GetCharmer()->ToPlayer(); + + if (victimRider && victimRider->duel && victimRider->duel->isMounted) + { + // prevent kill only if killed in duel and killed by opponent or opponent controlled creature + if (victimRider->duel->opponent == this || victimRider->duel->opponent->GetGUID() == GetCharmerGUID()) + damage = health - 1; + + duel_wasMounted = true; + duel_hasEnded = true; + } + } if (GetTypeId() == TYPEID_PLAYER && this != victim) { @@ -745,8 +760,18 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam // last damage from duel opponent if (duel_hasEnded) { - ASSERT(victim->GetTypeId() == TYPEID_PLAYER); - Player* he = victim->ToPlayer(); + Player* he; + + if (duel_wasMounted) + { + ASSERT(victim->GetCharmer()->GetTypeId() == TYPEID_PLAYER); + he = victim->GetCharmer()->ToPlayer(); + } + else + { + ASSERT(victim->GetTypeId() == TYPEID_PLAYER); + he = victim->ToPlayer(); + } ASSERT(he->duel); @@ -16954,6 +16979,10 @@ void Unit::_ExitVehicle(Position const* exitPosition) m_vehicle->RemovePassenger(this); + // If player is on mouted duel and exits the mount should immediatly lose the duel + if (GetTypeId() == TYPEID_PLAYER && ToPlayer()->duel && ToPlayer()->duel->isMounted) + ToPlayer()->DuelComplete(DUEL_FLED); + // This should be done before dismiss, because there may be some aura removal Vehicle* vehicle = m_vehicle; m_vehicle = NULL; diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index c3357b99601..d5a9bf923b4 100755 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -5607,6 +5607,7 @@ void Spell::EffectDuel(SpellEffIndex effIndex) duel->opponent = target; duel->startTime = 0; duel->startTimer = 0; + duel->isMounted = (GetSpellInfo()->Id == 62875); // Mounted Duel caster->duel = duel; DuelInfo* duel2 = new DuelInfo; @@ -5614,6 +5615,7 @@ void Spell::EffectDuel(SpellEffIndex effIndex) duel2->opponent = caster; duel2->startTime = 0; duel2->startTimer = 0; + duel2->isMounted = (GetSpellInfo()->Id == 62875); // Mounted Duel target->duel = duel2; caster->SetUInt64Value(PLAYER_DUEL_ARBITER, pGameObj->GetGUID()); diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index f3d5697c672..171382ba4f7 100755 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -2889,6 +2889,22 @@ void SpellMgr::LoadSpellCustomAttr() case 69293: // Wing Buffet case 74439: // Machine Gun case 63278: // Mark of the Faceless (General Vezax) + case 62544: // Thrust (Argent Tournament) + case 64588: // Thrust (Argent Tournament) + case 66479: // Thrust (Argent Tournament) + case 68505: // Thrust (Argent Tournament) + case 62626: // Break-Shield (Argent Tournament, Player) + case 64590: // Break-Shield (Argent Tournament, Player) + case 64342: // Break-Shield (Argent Tournament, NPC) + case 64686: // Break-Shield (Argent Tournament, NPC) + case 65147: // Break-Shield (Argent Tournament, NPC) + case 68504: // Break-Shield (Argent Tournament, NPC) + case 62874: // Charge (Argent Tournament, Player) + case 68498: // Charge (Argent Tournament, Player) + case 64591: // Charge (Argent Tournament, Player) + case 63003: // Charge (Argent Tournament, NPC) + case 63010: // Charge (Argent Tournament, NPC) + case 68321: // Charge (Argent Tournament, NPC) case 72255: // Mark of the Fallen Champion (Deathbringer Saurfang) case 72444: // Mark of the Fallen Champion (Deathbringer Saurfang) case 72445: // Mark of the Fallen Champion (Deathbringer Saurfang) @@ -2972,6 +2988,7 @@ void SpellMgr::LoadDbcDataCorrections() spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_TARGET_ENEMY; spellInfo->EffectImplicitTargetB[0] = 0; break; + case 63665: // Charge (Argent Tournament emote on riders) case 31447: // Mark of Kaz'rogal (needs target selection script) case 31298: // Sleep (needs target selection script) case 51904: // Summon Ghouls On Scarlet Crusade (this should use conditions table, script for this spell needs to be fixed) diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index d0307966795..96d259817c0 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -1626,6 +1626,748 @@ class spell_gen_dalaran_disguise : public SpellScriptLoader } }; +/* DOCUMENTATION: Break-Shield spells + Break-Shield spells can be classified in three groups: + + - Spells on vehicle bar used by players: + + EFFECT_0: SCRIPT_EFFECT + + EFFECT_1: NONE + + EFFECT_2: NONE + - Spells casted by players triggered by script: + + EFFECT_0: SCHOOL_DAMAGE + + EFFECT_1: SCRIPT_EFFECT + + EFFECT_2: FORCE_CAST + - Spells casted by NPCs on players: + + EFFECT_0: SCHOOL_DAMAGE + + EFFECT_1: SCRIPT_EFFECT + + EFFECT_2: NONE + + In the following script we handle the SCRIPT_EFFECT for effIndex EFFECT_0 and EFFECT_1. + - When handling EFFECT_0 we're in the "Spells on vehicle bar used by players" case + and we'll trigger "Spells casted by players triggered by script" + - When handling EFFECT_1 we're in the "Spells casted by players triggered by script" + or "Spells casted by NPCs on players" so we'll search for the first defend layer and drop it. +*/ + +enum BreakShieldSpells +{ + SPELL_BREAK_SHIELD_DAMAGE_2K = 62626, + SPELL_BREAK_SHIELD_DAMAGE_10K = 64590, + + SPELL_BREAK_SHIELD_TRIGGER_FACTION_MOUNTS = 62575, // Also on ToC5 mounts + SPELL_BREAK_SHIELD_TRIGGER_CAMPAING_WARHORSE = 64595, + SPELL_BREAK_SHIELD_TRIGGER_UNK = 66480, +}; + +class spell_gen_break_shield: public SpellScriptLoader +{ +public: + spell_gen_break_shield() : SpellScriptLoader("spell_gen_break_shield") { } + + class spell_gen_break_shield_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_break_shield_SpellScript) + + void HandleScriptEffect(SpellEffIndex effIndex) + { + Unit* caster = GetCaster(); + Unit* target = GetTargetUnit(); + + if (!caster || !target) + return; + + switch (effIndex) + { + case EFFECT_0: // On spells wich trigger the damaging spell (and also the visual) + uint32 spellId; + switch (GetSpellInfo()->Id) + { + case SPELL_BREAK_SHIELD_TRIGGER_UNK: + case SPELL_BREAK_SHIELD_TRIGGER_CAMPAING_WARHORSE: + spellId = SPELL_BREAK_SHIELD_DAMAGE_10K; + break; + case SPELL_BREAK_SHIELD_TRIGGER_FACTION_MOUNTS: + spellId = SPELL_BREAK_SHIELD_DAMAGE_2K; + break; + default: + return; + } + + if (Unit* rider = caster->GetCharmer()) + rider->CastSpell(target, spellId, false); + else + caster->CastSpell(target, spellId, false); + break; + case EFFECT_1: // On damaging spells, for removing the a defend layer + Unit::AuraApplicationMap const& auras = target->GetAppliedAuras(); + for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + { + Aura* aura = itr->second->GetBase(); + SpellInfo const* auraInfo = aura->GetSpellInfo(); + if (aura && auraInfo->SpellIconID == 2007 && aura->HasEffectType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN)) + aura->ModStackAmount(-1, AURA_REMOVE_BY_ENEMY_SPELL); + } + break; + } + } + + void Register() + { + OnEffectHit += SpellEffectFn(spell_gen_break_shield_SpellScript::HandleScriptEffect, EFFECT_FIRST_FOUND, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_gen_break_shield_SpellScript(); + } +}; + +/* DOCUMENTATION: Charge spells + Charge spells can be classified in four groups: + + - Spells on vehicle bar used by players: + + EFFECT_0: SCRIPT_EFFECT + + EFFECT_1: TRIGGER_SPELL + + EFFECT_2: NONE + - Spells casted by player's mounts triggered by script: + + EFFECT_0: CHARGE + + EFFECT_1: TRIGGER_SPELL + + EFFECT_2: APPLY_AURA + - Spells casted by players on the target triggered by script: + + EFFECT_0: SCHOOL_DAMAGE + + EFFECT_1: SCRIPT_EFFECT + + EFFECT_2: NONE + - Spells casted by NPCs on players: + + EFFECT_0: SCHOOL_DAMAGE + + EFFECT_1: CHARGE + + EFFECT_2: SCRIPT_EFFECT + + In the following script we handle the SCRIPT_EFFECT and CHARGE + - When handling SCRIPT_EFFECT: + + EFFECT_0: Corresponds to "Spells on vehicle bar used by players" and we make player's mount cast + the charge effect on the current target ("Spells casted by player's mounts triggered by script"). + + EFFECT_1 and EFFECT_2: Triggered when "Spells casted by player's mounts triggered by script" hits target, + corresponding to "Spells casted by players on the target triggered by script" and "Spells casted by + NPCs on players" and we check Defend layers and drop a charge of the first found. + - When handling CHARGE: + + Only launched for "Spells casted by player's mounts triggered by script", makes the player cast the + damaging spell on target with a small chance of failing it. +*/ + +enum ChargeSpells +{ + SPELL_CHARGE_DAMAGE_8K5 = 62874, + SPELL_CHARGE_DAMAGE_20K = 68498, + SPELL_CHARGE_DAMAGE_45K = 64591, + + SPELL_CHARGE_CHARGING_EFFECT_8K5 = 63661, + SPELL_CHARGE_CHARGING_EFFECT_20K_1 = 68284, + SPELL_CHARGE_CHARGING_EFFECT_20K_2 = 68501, + SPELL_CHARGE_CHARGING_EFFECT_45K_1 = 62563, + SPELL_CHARGE_CHARGING_EFFECT_45K_2 = 66481, + + SPELL_CHARGE_TRIGGER_FACTION_MOUNTS = 62960, + SPELL_CHARGE_TRIGGER_TRIAL_CHAMPION = 68282, + + SPELL_CHARGE_MISS_EFFECT = 62977, +}; + +class spell_gen_mounted_charge: public SpellScriptLoader +{ +public: + spell_gen_mounted_charge() : SpellScriptLoader("spell_gen_mounted_charge") { } + + class spell_gen_mounted_charge_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_mounted_charge_SpellScript) + + void HandleScriptEffect(SpellEffIndex effIndex) + { + Unit* caster = GetCaster(); + Unit* target = GetTargetUnit(); + + if (!caster || !target) + return; + + switch (effIndex) + { + case EFFECT_0: // On spells wich trigger the damaging spell (and also the visual) + uint32 spellId; + + switch (GetSpellInfo()->Id) + { + case SPELL_CHARGE_TRIGGER_TRIAL_CHAMPION: + spellId = SPELL_CHARGE_CHARGING_EFFECT_20K_1; + case SPELL_CHARGE_TRIGGER_FACTION_MOUNTS: + spellId = SPELL_CHARGE_CHARGING_EFFECT_8K5; + break; + default: + return; + } + + if (Unit* vehicle = caster->GetVehicleBase()) + vehicle->CastSpell(target, spellId, false); + else + caster->CastSpell(target, spellId, false); + break; + case EFFECT_1: // On damaging spells, for removing the a defend layer + case EFFECT_2: + Unit::AuraApplicationMap const& auras = target->GetAppliedAuras(); + for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + { + Aura* aura = itr->second->GetBase(); + SpellInfo const* auraInfo = aura->GetSpellInfo(); + if (aura && auraInfo->SpellIconID == 2007 && aura->HasEffectType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN)) + aura->ModStackAmount(-1, AURA_REMOVE_BY_ENEMY_SPELL); + } + break; + } + } + + void HandleChargeEffect(SpellEffIndex effIndex) + { + Unit* caster = GetCaster(); + Unit* target = GetTargetUnit(); + + if (!caster || !target) + return; + + uint32 spellId; + + switch (GetSpellInfo()->Id) + { + case SPELL_CHARGE_CHARGING_EFFECT_8K5: + spellId = SPELL_CHARGE_DAMAGE_8K5; + break; + case SPELL_CHARGE_CHARGING_EFFECT_20K_1: + case SPELL_CHARGE_CHARGING_EFFECT_20K_2: + spellId = SPELL_CHARGE_DAMAGE_20K; + break; + case SPELL_CHARGE_CHARGING_EFFECT_45K_1: + case SPELL_CHARGE_CHARGING_EFFECT_45K_2: + spellId = SPELL_CHARGE_DAMAGE_45K; + break; + default: + return; + } + + // If target isn't a training dummy there's a chance of failing the charge + if (!target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE) && urand(0,7) == 0) + spellId = SPELL_CHARGE_MISS_EFFECT; + + if (Unit* rider = caster->GetCharmer()) + rider->CastSpell(target, spellId, false); + else + caster->CastSpell(target, spellId, false); + } + + void Register() + { + SpellInfo const* spell = sSpellMgr->GetSpellInfo(m_scriptSpellId); + + if (spell->HasEffect(SPELL_EFFECT_SCRIPT_EFFECT)) + OnEffectHit += SpellEffectFn(spell_gen_mounted_charge_SpellScript::HandleScriptEffect, EFFECT_FIRST_FOUND, SPELL_EFFECT_SCRIPT_EFFECT); + + if (spell->Effects[EFFECT_0].Effect == SPELL_EFFECT_CHARGE) + OnEffectHit += SpellEffectFn(spell_gen_mounted_charge_SpellScript::HandleChargeEffect, EFFECT_0, SPELL_EFFECT_CHARGE); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_gen_mounted_charge_SpellScript(); + } +}; + +enum DefendVisuals +{ + SPELL_VISUAL_SHIELD_1 = 63130, + SPELL_VISUAL_SHIELD_2 = 63131, + SPELL_VISUAL_SHIELD_3 = 63132, +}; + +class spell_gen_defend : public SpellScriptLoader +{ + public: + spell_gen_defend() : SpellScriptLoader("spell_gen_defend") { } + + class spell_gen_defendAuraScript : public AuraScript + { + PrepareAuraScript(spell_gen_defendAuraScript); + + bool Validate(SpellInfo const* /*spellEntry*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_VISUAL_SHIELD_1)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_VISUAL_SHIELD_2)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_VISUAL_SHIELD_3)) + return false; + return true; + } + + void RefreshVisualShields(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* caster = GetCaster(); + Unit* target = GetTarget(); + + if(!target) + return; + + if (!caster) + { + target->RemoveAurasDueToSpell(GetId()); + return; + } + + for (uint8 i = 0; i < GetSpellInfo()->StackAmount; ++i) + target->RemoveAurasDueToSpell(SPELL_VISUAL_SHIELD_1 + i); + + target->CastSpell(target, SPELL_VISUAL_SHIELD_1 + GetAura()->GetStackAmount() - 1); + } + + void RemoveVisualShields(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + + if(!target) + return; + + for (uint8 i = 0; i < GetSpellInfo()->StackAmount; ++i) + target->RemoveAurasDueToSpell(SPELL_VISUAL_SHIELD_1 + i); + } + + void RemoveDummyFromDriver(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* caster = GetCaster(); + + if (caster && caster->ToTempSummon()) + if (Unit* rider = caster->ToTempSummon()->GetSummoner()) + rider->RemoveAurasDueToSpell(GetId()); + } + + void Register() + { + SpellInfo const* spell = sSpellMgr->GetSpellInfo(m_scriptSpellId); + + // Defend spells casted by NPCs (add visuals) + if (spell->Effects[EFFECT_0].ApplyAuraName == SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN) + { + AfterEffectApply += AuraEffectApplyFn(spell_gen_defendAuraScript::RefreshVisualShields, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + OnEffectRemove += AuraEffectRemoveFn(spell_gen_defendAuraScript::RemoveVisualShields, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL); + } + + // Remove Defend spell from player when he dismounts + if (spell->Effects[EFFECT_2].ApplyAuraName == SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN) + OnEffectRemove += AuraEffectRemoveFn(spell_gen_defendAuraScript::RemoveDummyFromDriver, EFFECT_2, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL); + + // Defend spells casted by players (add/remove visuals) + if (spell->Effects[EFFECT_1].ApplyAuraName == SPELL_AURA_DUMMY) + { + AfterEffectApply += AuraEffectApplyFn(spell_gen_defendAuraScript::RefreshVisualShields, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + OnEffectRemove += AuraEffectRemoveFn(spell_gen_defendAuraScript::RemoveVisualShields, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_gen_defendAuraScript(); + } +}; + +enum MountedDuelSpells +{ + SPELL_ON_TOURNAMENT_MOUNT = 63034, + SPELL_MOUNTED_DUEL = 62875, +}; + +class spell_gen_tournament_duel : public SpellScriptLoader +{ + public: + spell_gen_tournament_duel() : SpellScriptLoader("spell_gen_tournament_duel") { } + + class spell_gen_tournament_duel_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_tournament_duel_SpellScript); + + bool Validate(SpellInfo const* /*spellEntry*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_ON_TOURNAMENT_MOUNT)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_MOUNTED_DUEL)) + return false; + return true; + } + + void HandleScriptEffect(SpellEffIndex effIndex) + { + Unit* caster = GetCaster(); + Unit* target = GetTargetUnit(); + Unit* player = GetCaster()->GetCharmer(); + + if (!caster || !target || !player) + return; + + if (target->GetTypeId() == TYPEID_PLAYER) + { + + if (!target->HasAura(SPELL_ON_TOURNAMENT_MOUNT) || !target->GetVehicleBase()) + return; + + player->CastSpell(target, SPELL_MOUNTED_DUEL, true); + } + else if (target->GetTypeId() == TYPEID_UNIT) + { + if (!target->GetCharmer() || target->GetCharmer()->GetTypeId() != TYPEID_PLAYER || !target->GetCharmer()->HasAura(SPELL_ON_TOURNAMENT_MOUNT)) + return; + + player->CastSpell(target->GetCharmer(), SPELL_MOUNTED_DUEL, true); + } + } + + void Register() + { + OnEffectHit += SpellEffectFn(spell_gen_tournament_duel_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_gen_tournament_duel_SpellScript(); + } +}; + +enum TournamentMountsSpells +{ + SPELL_LANCE_EQUIPPED = 62853, +}; + +class spell_gen_summon_tournament_mount : public SpellScriptLoader +{ + public: + spell_gen_summon_tournament_mount() : SpellScriptLoader("spell_gen_summon_tournament_mount") { } + + class spell_gen_summon_tournament_mount_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_summon_tournament_mount_SpellScript); + + bool Validate(SpellInfo const* /*spellEntry*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_LANCE_EQUIPPED)) + return false; + return true; + } + + SpellCastResult CheckIfLanceEquiped() + { + Unit* caster = GetCaster(); + + if (!caster->HasAura(SPELL_LANCE_EQUIPPED)) + { + SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_MUST_HAVE_LANCE_EQUIPPED); + return SPELL_FAILED_CUSTOM_ERROR; + } + + return SPELL_CAST_OK; + } + + void Register() + { + OnCheckCast += SpellCheckCastFn(spell_gen_summon_tournament_mount_SpellScript::CheckIfLanceEquiped); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_gen_summon_tournament_mount_SpellScript(); + } +}; + +enum TournamentPennantSpells +{ + SPELL_PENNANT_STORMWIND_ASPIRANT = 62595, + SPELL_PENNANT_STORMWIND_VALIANT = 62596, + SPELL_PENNANT_STORMWIND_CHAMPION = 62594, + SPELL_PENNANT_GNOMEREGAN_ASPIRANT = 63394, + SPELL_PENNANT_GNOMEREGAN_VALIANT = 63395, + SPELL_PENNANT_GNOMEREGAN_CHAMPION = 63396, + SPELL_PENNANT_SEN_JIN_ASPIRANT = 63397, + SPELL_PENNANT_SEN_JIN_VALIANT = 63398, + SPELL_PENNANT_SEN_JIN_CHAMPION = 63399, + SPELL_PENNANT_SILVERMOON_ASPIRANT = 63401, + SPELL_PENNANT_SILVERMOON_VALIANT = 63402, + SPELL_PENNANT_SILVERMOON_CHAMPION = 63403, + SPELL_PENNANT_DARNASSUS_ASPIRANT = 63404, + SPELL_PENNANT_DARNASSUS_VALIANT = 63405, + SPELL_PENNANT_DARNASSUS_CHAMPION = 63406, + SPELL_PENNANT_EXODAR_ASPIRANT = 63421, + SPELL_PENNANT_EXODAR_VALIANT = 63422, + SPELL_PENNANT_EXODAR_CHAMPION = 63423, + SPELL_PENNANT_IRONFORGE_ASPIRANT = 63425, + SPELL_PENNANT_IRONFORGE_VALIANT = 63426, + SPELL_PENNANT_IRONFORGE_CHAMPION = 63427, + SPELL_PENNANT_UNDERCITY_ASPIRANT = 63428, + SPELL_PENNANT_UNDERCITY_VALIANT = 63429, + SPELL_PENNANT_UNDERCITY_CHAMPION = 63430, + SPELL_PENNANT_ORGRIMMAR_ASPIRANT = 63431, + SPELL_PENNANT_ORGRIMMAR_VALIANT = 63432, + SPELL_PENNANT_ORGRIMMAR_CHAMPION = 63433, + SPELL_PENNANT_THUNDER_BLUFF_ASPIRANT = 63434, + SPELL_PENNANT_THUNDER_BLUFF_VALIANT = 63435, + SPELL_PENNANT_THUNDER_BLUFF_CHAMPION = 63436, + SPELL_PENNANT_ARGENT_CRUSADE_ASPIRANT = 63606, + SPELL_PENNANT_ARGENT_CRUSADE_VALIANT = 63500, + SPELL_PENNANT_ARGENT_CRUSADE_CHAMPION = 63501, + SPELL_PENNANT_EBON_BLADE_ASPIRANT = 63607, + SPELL_PENNANT_EBON_BLADE_VALIANT = 63608, + SPELL_PENNANT_EBON_BLADE_CHAMPION = 63609, +}; + +enum TournamentMounts +{ + NPC_STORMWIND_STEED = 33217, + NPC_IRONFORGE_RAM = 33316, + NPC_GNOMEREGAN_MECHANOSTRIDER = 33317, + NPC_EXODAR_ELEKK = 33318, + NPC_DARNASSIAN_NIGHTSABER = 33319, + NPC_ORGRIMMAR_WOLF = 33320, + NPC_DARK_SPEAR_RAPTOR = 33321, + NPC_THUNDER_BLUFF_KODO = 33322, + NPC_SILVERMOON_HAWKSTRIDER = 33323, + NPC_FORSAKEN_WARHORSE = 33324, + NPC_ARGENT_WARHORSE = 33782, + NPC_ARGENT_STEED_ASPIRANT = 33845, + NPC_ARGENT_HAWKSTRIDER_ASPIRANT = 33844, +}; + +enum TournamentQuestsAchievements +{ + ACHIEVEMENT_CHAMPION_STORMWIND = 2781, + ACHIEVEMENT_CHAMPION_DARNASSUS = 2777, + ACHIEVEMENT_CHAMPION_IRONFORGE = 2780, + ACHIEVEMENT_CHAMPION_GNOMEREGAN = 2779, + ACHIEVEMENT_CHAMPION_THE_EXODAR = 2778, + ACHIEVEMENT_CHAMPION_ORGRIMMAR = 2783, + ACHIEVEMENT_CHAMPION_SEN_JIN = 2784, + ACHIEVEMENT_CHAMPION_THUNDER_BLUFF = 2786, + ACHIEVEMENT_CHAMPION_UNDERCITY = 2787, + ACHIEVEMENT_CHAMPION_SILVERMOON = 2785, + ACHIEVEMENT_ARGENT_VALOR = 2758, + ACHIEVEMENT_CHAMPION_ALLIANCE = 2782, + ACHIEVEMENT_CHAMPION_HORDE = 2788, + + QUEST_VALIANT_OF_STORMWIND = 13593, + QUEST_A_VALIANT_OF_STORMWIND = 13684, + QUEST_VALIANT_OF_DARNASSUS = 13706, + QUEST_A_VALIANT_OF_DARNASSUS = 13689, + QUEST_VALIANT_OF_IRONFORGE = 13703, + QUEST_A_VALIANT_OF_IRONFORGE = 13685, + QUEST_VALIANT_OF_GNOMEREGAN = 13704, + QUEST_A_VALIANT_OF_GNOMEREGAN = 13688, + QUEST_VALIANT_OF_THE_EXODAR = 13705, + QUEST_A_VALIANT_OF_THE_EXODAR = 13690, + QUEST_VALIANT_OF_ORGRIMMAR = 13707, + QUEST_A_VALIANT_OF_ORGRIMMAR = 13691, + QUEST_VALIANT_OF_SEN_JIN = 13708, + QUEST_A_VALIANT_OF_SEN_JIN = 13693, + QUEST_VALIANT_OF_THUNDER_BLUFF = 13709, + QUEST_A_VALIANT_OF_THUNDER_BLUFF = 13694, + QUEST_VALIANT_OF_UNDERCITY = 13710, + QUEST_A_VALIANT_OF_UNDERCITY = 13695, + QUEST_VALIANT_OF_SILVERMOON = 13711, + QUEST_A_VALIANT_OF_SILVERMOON = 13696, +}; + +class spell_gen_on_tournament_mount : public SpellScriptLoader +{ + public: + spell_gen_on_tournament_mount() : SpellScriptLoader("spell_gen_on_tournament_mount") { } + + class spell_gen_on_tournament_mountAuraScript : public AuraScript + { + PrepareAuraScript(spell_gen_on_tournament_mountAuraScript); + + uint32 _pennantSpellId; + + bool Load() + { + _pennantSpellId = 0; + return (GetCaster()->GetTypeId() == TYPEID_PLAYER); + } + + void HandleApplyEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* caster = GetCaster(); + + if (caster && caster->GetVehicleBase()) + { + _pennantSpellId = GetPennatSpellId(caster->ToPlayer(), caster->GetVehicleBase()); + caster->CastSpell(caster, _pennantSpellId,true); + } + } + + void HandleRemoveEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* caster = GetCaster(); + + if (caster) + caster->RemoveAurasDueToSpell(_pennantSpellId); + } + + uint32 GetPennatSpellId(Player* player, Unit* mount) + { + switch (mount->GetEntry()) + { + case NPC_ARGENT_STEED_ASPIRANT: + case NPC_STORMWIND_STEED: + { + if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_STORMWIND)) + return SPELL_PENNANT_STORMWIND_CHAMPION; + else if (player->GetQuestRewardStatus(QUEST_VALIANT_OF_STORMWIND) || player->GetQuestRewardStatus(QUEST_A_VALIANT_OF_STORMWIND)) + return SPELL_PENNANT_STORMWIND_VALIANT; + else + return SPELL_PENNANT_STORMWIND_ASPIRANT; + } + case NPC_GNOMEREGAN_MECHANOSTRIDER: + { + if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_GNOMEREGAN)) + return SPELL_PENNANT_GNOMEREGAN_CHAMPION; + else if (player->GetQuestRewardStatus(QUEST_VALIANT_OF_GNOMEREGAN) || player->GetQuestRewardStatus(QUEST_A_VALIANT_OF_GNOMEREGAN)) + return SPELL_PENNANT_GNOMEREGAN_VALIANT; + else + return SPELL_PENNANT_GNOMEREGAN_ASPIRANT; + } + case NPC_DARK_SPEAR_RAPTOR: + { + if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_SEN_JIN)) + return SPELL_PENNANT_SEN_JIN_CHAMPION; + else if (player->GetQuestRewardStatus(QUEST_VALIANT_OF_SEN_JIN) || player->GetQuestRewardStatus(QUEST_A_VALIANT_OF_SEN_JIN)) + return SPELL_PENNANT_SEN_JIN_VALIANT; + else + return SPELL_PENNANT_SEN_JIN_ASPIRANT; + } + case NPC_ARGENT_HAWKSTRIDER_ASPIRANT: + case NPC_SILVERMOON_HAWKSTRIDER: + { + if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_SILVERMOON)) + return SPELL_PENNANT_SILVERMOON_CHAMPION; + else if (player->GetQuestRewardStatus(QUEST_VALIANT_OF_SILVERMOON) || player->GetQuestRewardStatus(QUEST_A_VALIANT_OF_SILVERMOON)) + return SPELL_PENNANT_SILVERMOON_VALIANT; + else + return SPELL_PENNANT_SILVERMOON_ASPIRANT; + } + case NPC_DARNASSIAN_NIGHTSABER: + { + if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_DARNASSUS)) + return SPELL_PENNANT_DARNASSUS_CHAMPION; + else if (player->GetQuestRewardStatus(QUEST_VALIANT_OF_DARNASSUS) || player->GetQuestRewardStatus(QUEST_A_VALIANT_OF_DARNASSUS)) + return SPELL_PENNANT_DARNASSUS_VALIANT; + else + return SPELL_PENNANT_DARNASSUS_ASPIRANT; + } + case NPC_EXODAR_ELEKK: + { + if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_THE_EXODAR)) + return SPELL_PENNANT_EXODAR_CHAMPION; + else if (player->GetQuestRewardStatus(QUEST_VALIANT_OF_THE_EXODAR) || player->GetQuestRewardStatus(QUEST_A_VALIANT_OF_THE_EXODAR)) + return SPELL_PENNANT_EXODAR_VALIANT; + else + return SPELL_PENNANT_EXODAR_ASPIRANT; + } + case NPC_IRONFORGE_RAM: + { + if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_IRONFORGE)) + return SPELL_PENNANT_IRONFORGE_CHAMPION; + else if (player->GetQuestRewardStatus(QUEST_VALIANT_OF_IRONFORGE) || player->GetQuestRewardStatus(QUEST_A_VALIANT_OF_IRONFORGE)) + return SPELL_PENNANT_IRONFORGE_VALIANT; + else + return SPELL_PENNANT_IRONFORGE_ASPIRANT; + } + case NPC_FORSAKEN_WARHORSE: + { + if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_UNDERCITY)) + return SPELL_PENNANT_UNDERCITY_CHAMPION; + else if (player->GetQuestRewardStatus(QUEST_VALIANT_OF_UNDERCITY) || player->GetQuestRewardStatus(QUEST_A_VALIANT_OF_UNDERCITY)) + return SPELL_PENNANT_UNDERCITY_VALIANT; + else + return SPELL_PENNANT_UNDERCITY_ASPIRANT; + } + case NPC_ORGRIMMAR_WOLF: + { + if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_ORGRIMMAR)) + return SPELL_PENNANT_ORGRIMMAR_CHAMPION; + else if (player->GetQuestRewardStatus(QUEST_VALIANT_OF_ORGRIMMAR) || player->GetQuestRewardStatus(QUEST_A_VALIANT_OF_ORGRIMMAR)) + return SPELL_PENNANT_ORGRIMMAR_VALIANT; + else + return SPELL_PENNANT_ORGRIMMAR_ASPIRANT; + } + case NPC_THUNDER_BLUFF_KODO: + { + if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_THUNDER_BLUFF)) + return SPELL_PENNANT_THUNDER_BLUFF_CHAMPION; + else if (player->GetQuestRewardStatus(QUEST_VALIANT_OF_THUNDER_BLUFF) || player->GetQuestRewardStatus(QUEST_A_VALIANT_OF_THUNDER_BLUFF)) + return SPELL_PENNANT_THUNDER_BLUFF_VALIANT; + else + return SPELL_PENNANT_THUNDER_BLUFF_ASPIRANT; + } + case NPC_ARGENT_WARHORSE: + { + if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_ALLIANCE) || player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_HORDE)) + return player->getClass() == CLASS_DEATH_KNIGHT ? SPELL_PENNANT_EBON_BLADE_CHAMPION : SPELL_PENNANT_ARGENT_CRUSADE_CHAMPION; + else if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_ARGENT_VALOR)) + return player->getClass() == CLASS_DEATH_KNIGHT ? SPELL_PENNANT_EBON_BLADE_VALIANT : SPELL_PENNANT_ARGENT_CRUSADE_VALIANT; + else + return player->getClass() == CLASS_DEATH_KNIGHT ? SPELL_PENNANT_EBON_BLADE_ASPIRANT : SPELL_PENNANT_ARGENT_CRUSADE_ASPIRANT; + } + default: + return 0; + } + } + + void Register() + { + AfterEffectApply += AuraEffectApplyFn(spell_gen_on_tournament_mountAuraScript::HandleApplyEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + OnEffectRemove += AuraEffectRemoveFn(spell_gen_on_tournament_mountAuraScript::HandleRemoveEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_gen_on_tournament_mountAuraScript(); + } +}; + +class spell_gen_tournament_pennant : public SpellScriptLoader +{ + public: + spell_gen_tournament_pennant() : SpellScriptLoader("spell_gen_tournament_pennant") { } + + class spell_gen_tournament_pennantAuraScript : public AuraScript + { + PrepareAuraScript(spell_gen_tournament_pennantAuraScript); + + void HandleApplyEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* caster = GetCaster(); + + if (caster && caster->GetTypeId() == TYPEID_PLAYER && !caster->GetVehicleBase()) + caster->RemoveAurasDueToSpell(GetId()); + } + + void Register() + { + OnEffectApply += AuraEffectApplyFn(spell_gen_tournament_pennantAuraScript::HandleApplyEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_gen_tournament_pennantAuraScript(); + } +}; + void AddSC_generic_spell_scripts() { new spell_gen_absorb0_hitlimit1(); @@ -1662,4 +2404,11 @@ void AddSC_generic_spell_scripts() new spell_gen_dalaran_disguise("spell_gen_sunreaver_disguise"); new spell_gen_dalaran_disguise("spell_gen_silver_covenant_disguise"); new spell_gen_elune_candle(); + new spell_gen_break_shield(); + new spell_gen_mounted_charge(); + new spell_gen_defend(); + new spell_gen_tournament_duel(); + new spell_gen_summon_tournament_mount(); + new spell_gen_on_tournament_mount(); + new spell_gen_tournament_pennant(); } diff --git a/src/server/scripts/World/achievement_scripts.cpp b/src/server/scripts/World/achievement_scripts.cpp index 8ce06685893..135f22e0a01 100755 --- a/src/server/scripts/World/achievement_scripts.cpp +++ b/src/server/scripts/World/achievement_scripts.cpp @@ -285,6 +285,17 @@ class achievement_bg_sa_defense_of_ancients : public AchievementCriteriaScript } }; +class achievement_tilted : public AchievementCriteriaScript +{ + public: + achievement_tilted() : AchievementCriteriaScript("achievement_tilted") {} + + bool OnCheck(Player* player, Unit* /*target*/) + { + return player && player->duel && player->duel->isMounted; + } +}; + void AddSC_achievement_scripts() { new achievement_resilient_victory(); @@ -302,4 +313,5 @@ void AddSC_achievement_scripts() new achievement_arena_kills("achievement_arena_3v3_kills", ARENA_TYPE_3v3); new achievement_arena_kills("achievement_arena_5v5_kills", ARENA_TYPE_5v5); new achievement_bg_sa_defense_of_ancients(); + new achievement_tilted(); } -- cgit v1.2.3