diff options
24 files changed, 532 insertions, 143 deletions
diff --git a/sql/updates/world/2011_09_02_00_world_misc.sql b/sql/updates/world/2011_09_02_00_world_misc.sql new file mode 100644 index 00000000000..fa5c2a7ba7b --- /dev/null +++ b/sql/updates/world/2011_09_02_00_world_misc.sql @@ -0,0 +1,17 @@ +-- Add spell Magma Totem TEST to disables table +DELETE FROM `disables` WHERE `sourceType`=0 AND `entry`=61904; +INSERT INTO `disables` (`sourceType`, `entry`, `flags`, `comment`) VALUES +(0, 61904, 8, 'Magma Totem TEST - can crash client by spawning too many totems'); + +-- Move a high guid to a lower one (Vyragosa) +SET @oldguid = 250006; +SET @newguid = 202602; +UPDATE `creature` SET `guid`=@newguid WHERE `guid`=@oldguid; +UPDATE `creature_addon` SET `guid`=@newguid, `path_id`=@newguid*100 WHERE `guid`=@oldguid; +UPDATE `waypoint_data` SET `id`=@newguid*100 WHERE `id`=@oldguid*100; + +-- By Aokromes: +-- Orientation fix for portal from ghostlands to eastern plagelands. +UPDATE `areatrigger_teleport` SET `target_orientation`=2.255664 WHERE `id`=4386; +-- Spawn Arcane Container also on heroic mode SLab +UPDATE `gameobject` SET `spawnMask`=3 WHERE `guid`=22674; diff --git a/sql/updates/world/2011_09_02_02_world_spell_script_names.sql b/sql/updates/world/2011_09_02_02_world_spell_script_names.sql new file mode 100644 index 00000000000..b95cd2c17d6 --- /dev/null +++ b/sql/updates/world/2011_09_02_02_world_spell_script_names.sql @@ -0,0 +1,6 @@ +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_rotface_mutated_infection'; +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(69674,'spell_rotface_mutated_infection'), +(71224,'spell_rotface_mutated_infection'), +(73022,'spell_rotface_mutated_infection'), +(73023,'spell_rotface_mutated_infection'); diff --git a/sql/updates/world/2011_09_03_00_world_spell_script_names.sql b/sql/updates/world/2011_09_03_00_world_spell_script_names.sql new file mode 100644 index 00000000000..6cec12b63fd --- /dev/null +++ b/sql/updates/world/2011_09_03_00_world_spell_script_names.sql @@ -0,0 +1,15 @@ +DELETE FROM `spell_script_names` WHERE `spell_id` IN (67590,67602,67603,67604,65684,67176,67177,67178,65686,67222,67223,67224); +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) +VALUES +(67590, 'spell_powering_up'), +(67602, 'spell_powering_up'), +(67603, 'spell_powering_up'), +(67604, 'spell_powering_up'), +(65684, 'spell_valkyr_essences'), +(67176, 'spell_valkyr_essences'), +(67177, 'spell_valkyr_essences'), +(67178, 'spell_valkyr_essences'), +(67222, 'spell_valkyr_essences'), +(65686, 'spell_valkyr_essences'), +(67223, 'spell_valkyr_essences'), +(67224, 'spell_valkyr_essences');
\ No newline at end of file diff --git a/sql/updates/world/2011_09_03_01_world_conditions.sql b/sql/updates/world/2011_09_03_01_world_conditions.sql new file mode 100644 index 00000000000..c830d3ad18e --- /dev/null +++ b/sql/updates/world/2011_09_03_01_world_conditions.sql @@ -0,0 +1,10 @@ +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 13 AND `ConditionTypeOrReference` = 18 AND `SourceEntry` IN (65875,67303,67304,67305,65876,67306,67307,67308) ; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(13, 0, 65875, 0, 18, 1, 34497, 2, 0, '', 'Twins Pact - Dark'), +(13, 0, 67303, 0, 18, 1, 34497, 2, 0, '', 'Twins Pact - Dark'), +(13, 0, 67304, 0, 18, 1, 34497, 2, 0, '', 'Twins Pact - Dark'), +(13, 0, 67305, 0, 18, 1, 34497, 2, 0, '', 'Twins Pact - Dark'), +(13, 0, 65876, 0, 18, 1, 34496, 2, 0, '', 'Twins Pact - Light'), +(13, 0, 67306, 0, 18, 1, 34496, 2, 0, '', 'Twins Pact - Light'), +(13, 0, 67307, 0, 18, 1, 34496, 2, 0, '', 'Twins Pact - Light'), +(13, 0, 67308, 0, 18, 1, 34496, 2, 0, '', 'Twins Pact - Light'); diff --git a/sql/updates/world/2011_09_03_02_spell_script_names.sql b/sql/updates/world/2011_09_03_02_spell_script_names.sql new file mode 100644 index 00000000000..b7b6907b7f1 --- /dev/null +++ b/sql/updates/world/2011_09_03_02_spell_script_names.sql @@ -0,0 +1,10 @@ +DELETE FROM `spell_script_names` WHERE `spell_id` IN (65879,65916,67244,67245,67246,67248,67249,67250); +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(65879, 'spell_power_of_the_twins'), +(65916, 'spell_power_of_the_twins'), +(67244, 'spell_power_of_the_twins'), +(67245, 'spell_power_of_the_twins'), +(67246, 'spell_power_of_the_twins'), +(67248, 'spell_power_of_the_twins'), +(67249, 'spell_power_of_the_twins'), +(67250, 'spell_power_of_the_twins'); diff --git a/sql/updates/world/2011_09_03_03_world_creature_template.sql b/sql/updates/world/2011_09_03_03_world_creature_template.sql new file mode 100644 index 00000000000..73bd1687ef6 --- /dev/null +++ b/sql/updates/world/2011_09_03_03_world_creature_template.sql @@ -0,0 +1 @@ +UPDATE `creature_template` SET `ScriptName`='npc_vereth_the_cunning' WHERE `entry`=30944;
\ No newline at end of file diff --git a/sql/updates/world/2011_09_03_04_world_misc.sql b/sql/updates/world/2011_09_03_04_world_misc.sql new file mode 100644 index 00000000000..f35cebe2014 --- /dev/null +++ b/sql/updates/world/2011_09_03_04_world_misc.sql @@ -0,0 +1,14 @@ +UPDATE `creature_template` SET `npcflag`=`npcflag`|0x1000000 WHERE `entry` in(31770,31736); +UPDATE `creature_template` SET `minlevel`=80,`maxlevel`=80,`exp`=2,`npcflag`=`npcflag`|0x1000000,`VehicleId`=282,`spell1`=59643,`spell2`=4342,`spell3`=4336 WHERE `entry`=31785; +UPDATE `creature_template` SET `minlevel`=80,`maxlevel`=80,`exp`=2,`npcflag`=`npcflag`|0x1000000,`VehicleId`=282,`spell1`=4338,`spell2`=4342,`spell3`=4336 WHERE `entry`=31784; +DELETE FROM `npc_spellclick_spells` WHERE `npc_entry` in (31785,31770,31736,31784); +INSERT INTO `npc_spellclick_spells` VALUES +(31785,59656,13283,1,13283,1,0,0,0), +(31770,59654,0,0,0,1,0,0,0), +(31736,59592,13280,1,13280,1,0,0,0), +(31784,59593,0,0,0,1,0,0,0); + +DELETE FROM `spell_script_names` WHERE `spell_id` IN (59643,4338); +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(59643, 'spell_q13280_13283_plant_battle_standard'), +(4338, 'spell_q13280_13283_plant_battle_standard');
\ No newline at end of file diff --git a/sql/updates/world/2011_09_03_05_world_gossip_menu_option.sql b/sql/updates/world/2011_09_03_05_world_gossip_menu_option.sql new file mode 100644 index 00000000000..53bc3104c50 --- /dev/null +++ b/sql/updates/world/2011_09_03_05_world_gossip_menu_option.sql @@ -0,0 +1,5 @@ +DELETE FROM `gossip_menu_option` WHERE `menu_id`=1293 AND `id`=1; +DELETE FROM `gossip_menu_option` WHERE `menu_id`=1293 AND `id`=2; +INSERT INTO `gossip_menu_option` (`menu_id`, `id`, `option_icon`, `option_text`, `option_id`, `npc_option_npcflag`, `action_menu_id`, `action_poi_id`, `box_coded`, `box_money`, `box_text`) VALUES +(1293,1,0, 'Make this inn my home!',8,66179,0,0,0,0,NULL), +(1293,2,1, 'I want to browse your goods!',3,66179,0,0,0,0,NULL);
\ No newline at end of file diff --git a/src/server/game/Battlegrounds/ArenaTeamMgr.cpp b/src/server/game/Battlegrounds/ArenaTeamMgr.cpp index 70be3b52238..59f31e36971 100644 --- a/src/server/game/Battlegrounds/ArenaTeamMgr.cpp +++ b/src/server/game/Battlegrounds/ArenaTeamMgr.cpp @@ -146,18 +146,20 @@ void ArenaTeamMgr::DistributeArenaPoints() if (ArenaTeam * at = teamItr->second) at->UpdateArenaPointsHelper(PlayerPoints); + SQLTransaction trans = CharacterDatabase.BeginTransaction(); + // Cycle that gives points to all players for (std::map<uint32, uint32>::iterator playerItr = PlayerPoints.begin(); playerItr != PlayerPoints.end(); ++playerItr) { - // Update database - CharacterDatabase.PExecute("UPDATE characters SET arenaPoints = arenaPoints + '%u' WHERE guid = '%u'", playerItr->second, playerItr->first); - // Add points to player if online - Player* pl = ObjectAccessor::FindPlayer(playerItr->first); - if (pl) - pl->ModifyArenaPoints(playerItr->second); + if (Player* player = HashMapHolder<Player>::Find(playerItr->first)) + player->ModifyArenaPoints(playerItr->second, &trans); + else // Update database + trans->PAppend("UPDATE characters SET arenaPoints=arenaPoints+%u WHERE guid=%u", playerItr->second, playerItr->first); } + CharacterDatabase.CommitTransaction(trans); + PlayerPoints.clear(); sWorld->SendWorldText(LANG_DIST_ARENA_POINTS_ONLINE_END); diff --git a/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp b/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp index 45d4414d9ed..3978d582e84 100755 --- a/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp @@ -424,12 +424,8 @@ void WorldSession::HandleCancelAuraOpcode(WorldPacket& recvPacket) if (!spellInfo) return; - // not allow remove non positive spells and spells with attr SPELL_ATTR0_CANT_CANCEL - if (!spellInfo->IsPositive() || (spellInfo->Attributes & SPELL_ATTR0_CANT_CANCEL)) - return; - - // don't allow cancelling passive auras (some of them are visible) - if (spellInfo->IsPassive()) + // not allow remove spells with attr SPELL_ATTR0_CANT_CANCEL + if (spellInfo->Attributes & SPELL_ATTR0_CANT_CANCEL) return; // channeled spell case (it currently casted then) @@ -441,7 +437,12 @@ void WorldSession::HandleCancelAuraOpcode(WorldPacket& recvPacket) return; } - // non channeled case + // non channeled case: + // don't allow remove non positive spells + // don't allow cancelling passive auras (some of them are visible) + if (!spellInfo->IsPositive() || spellInfo->IsPassive()) + return; + // maybe should only remove one buff when there are multiple? _player->RemoveOwnedAura(spellId, 0, 0, AURA_REMOVE_BY_CANCEL); } diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index f58bd72914d..ed36a4ae208 100755 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -2030,8 +2030,9 @@ void Spell::SelectEffectTargets(uint32 i, SpellImplicitTargetInfo const& cur) float min_dis = m_spellInfo->GetMinRange(true); float max_dis = m_spellInfo->GetMaxRange(true); float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis; - float x, y, z; - m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dis); + float x, y, z, angle; + angle = (float)rand_norm() * static_cast<float>(M_PI * 70.0f / 180.0f) - static_cast<float>(M_PI * 35.0f / 180.0f); + m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dis, angle); m_targets.SetDst(x, y, z, m_caster->GetOrientation()); break; } @@ -3303,6 +3304,11 @@ void Spell::handle_immediate() // Remove used for cast item if need (it can be already NULL after TakeReagents call TakeCastItem(); + // handle ammo consumption for Hunter's volley spell + if (m_spellInfo->IsRangedWeaponSpell() && m_spellInfo->IsChanneled()) + TakeAmmo(); + + if (m_spellState != SPELL_STATE_CASTING) finish(true); // successfully finish spell cast (not last in case autorepeat or channel spell) } @@ -6605,6 +6611,10 @@ void Spell::CalculateDamageDoneForAllTargets() if (!unit) // || !unit->isAlive()) do we need to check alive here? continue; + // do not consume ammo anymore for Hunter's volley spell + if (IsTriggered() && m_spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && m_spellInfo->IsAOE()) + usesAmmo = false; + if (usesAmmo) { bool ammoTaken = false; diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp index cf1e8e9ab62..75fa999825d 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp @@ -32,12 +32,12 @@ EndScriptData */ #define SAY_WATCH -1309018 #define SAY_WATCH_WHISPER -1309019 //is this text for real? easter egg? -#define SPELL_CHARGE 24315 -#define SPELL_CLEAVE 20691 +#define SPELL_CHARGE 24408 +#define SPELL_CLEAVE 7160 #define SPELL_FEAR 29321 -#define SPELL_WHIRLWIND 24236 -#define SPELL_MORTAL_STRIKE 24573 -#define SPELL_ENRAGE 23537 +#define SPELL_WHIRLWIND 15589 +#define SPELL_MORTAL_STRIKE 16856 +#define SPELL_ENRAGE 24318 #define SPELL_WATCH 24314 #define SPELL_LEVEL_UP 24312 diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp index 12540d6d7fb..b99cd3b180f 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp @@ -32,25 +32,25 @@ EndScriptData */ enum eSpells { SPELL_MORTALCLEAVE = 22859, - SPELL_SILENCE = 23207, - SPELL_FRENZY = 23342, + SPELL_SILENCE = 22666, + SPELL_FRENZY = 8269, SPELL_FORCEPUNCH = 24189, - SPELL_CHARGE = 24408, - SPELL_ENRAGE = 23537, + SPELL_CHARGE = 24193, + SPELL_ENRAGE = 8269, SPELL_SUMMONTIGERS = 24183, SPELL_TIGER_FORM = 24169, SPELL_RESURRECT = 24173, //We will not use this spell. //Zealot Lor'Khan Spells - SPELL_SHIELD = 25020, + SPELL_SHIELD = 25045, SPELL_BLOODLUST = 24185, SPELL_GREATERHEAL = 24208, - SPELL_DISARM = 22691, + SPELL_DISARM = 6713, -//Zealot Lor'Khan Spells +//Zealot Zath Spells SPELL_SWEEPINGSTRIKES = 18765, - SPELL_SINISTERSTRIKE = 15667, - SPELL_GOUGE = 24698, + SPELL_SINISTERSTRIKE = 15581, + SPELL_GOUGE = 12540, SPELL_KICK = 15614, SPELL_BLIND = 21060, }; diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp index 44385ea83e2..6d1c2b5d991 100755 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp @@ -25,8 +25,7 @@ EndScriptData */ // Known bugs: // - They should be floating but they aren't respecting the floor =( -// - Lacks the powering up effect that leads to Empowering -// - There's a workaround for the shared life effect +// - Hardcoded bullets spawner #include "ScriptPCH.h" #include "trial_of_the_crusader.h" @@ -48,26 +47,26 @@ enum Yells enum Equipment { - EQUIP_MAIN_1 = 49303, - EQUIP_OFFHAND_1 = 47146, - EQUIP_RANGED_1 = 47267, - EQUIP_MAIN_2 = 45990, - EQUIP_OFFHAND_2 = 47470, - EQUIP_RANGED_2 = 47267, - EQUIP_DONE = EQUIP_NO_CHANGE, + EQUIP_MAIN_1 = 9423, + EQUIP_MAIN_2 = 37377, }; enum Summons { - NPC_DARK_ESSENCE = 34567, - NPC_LIGHT_ESSENCE = 34568, - NPC_UNLEASHED_DARK = 34628, NPC_UNLEASHED_LIGHT = 34630, + + // Future Development + NPC_BULLET_CONTROLLER = 34743, // Npc controller for all bullets + + NPC_BULLET_STALKER_DARK = 34704, // Npc spawner for dark bullets + NPC_BULLET_STALKER_LIGHT = 34720, // Npc spawner for light bullets }; enum BossSpells { + SPELL_CONTROLLER_PERIODIC = 66149, // Future Development + SPELL_LIGHT_TWIN_SPIKE = 66075, SPELL_LIGHT_SURGE = 65766, SPELL_LIGHT_SHIELD = 65858, @@ -79,6 +78,7 @@ enum BossSpells SPELL_DARK_SURGE = 65768, SPELL_DARK_SHIELD = 65874, SPELL_DARK_TWIN_PACT = 65875, + SPELL_POWER_TWINS = 65879, SPELL_DARK_VORTEX = 66058, SPELL_DARK_TOUCH = 67282, @@ -93,12 +93,19 @@ enum BossSpells SPELL_UNLEASHED_DARK = 65808, SPELL_UNLEASHED_LIGHT = 65795, - //PowerUp 67604 + + SPELL_TWIN_EMPATHY_1 = 66132, + SPELL_TWIN_EMPATHY_2 = 66133, + + SPELL_POWERING_UP = 67590, + SPELL_SURGE_OF_SPEED = 65828, }; #define SPELL_DARK_ESSENCE_HELPER RAID_MODE<uint32>(65684, 67176, 67177, 67178) #define SPELL_LIGHT_ESSENCE_HELPER RAID_MODE<uint32>(65686, 67222, 67223, 67224) +#define SPELL_POWERING_UP_HELPER RAID_MODE(67590, 67602, 67603, 67604) + #define SPELL_EMPOWERED_DARK_HELPER RAID_MODE<uint32>(65724,67213,67214,67215) #define SPELL_EMPOWERED_LIGHT_HELPER RAID_MODE<uint32>(65748, 67216, 67217, 67218) @@ -122,9 +129,12 @@ struct boss_twin_baseAI : public ScriptedAI InstanceScript* m_pInstance; SummonList Summons; + AuraStateType m_uiAuraState; + uint8 m_uiStage; bool m_bIsBerserk; uint8 m_uiWaveCount; + uint32 m_uiWeapon; uint32 m_uiColorballsTimer; uint32 m_uiSpecialAbilityTimer; uint32 m_uiSpikeTimer; @@ -135,6 +145,7 @@ struct boss_twin_baseAI : public ScriptedAI int32 m_uiVortexEmote; uint32 m_uiSisterNpcId; uint32 m_uiColorballNpcId; + uint32 m_uiMyEmphatySpellId; uint32 m_uiEssenceNpcId; uint32 m_uiMyEssenceSpellId; uint32 m_uiOtherEssenceSpellId; @@ -152,6 +163,7 @@ struct boss_twin_baseAI : public ScriptedAI void Reset() { me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); me->SetReactState(REACT_PASSIVE); + me->ModifyAuraState(m_uiAuraState, true); /* Uncomment this once that they are flying above the ground me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING); me->SetFlying(true); */ @@ -172,7 +184,6 @@ struct boss_twin_baseAI : public ScriptedAI if (m_pInstance) { m_pInstance->SetData(TYPE_VALKIRIES, FAIL); - m_pInstance->SetData(DATA_HEALTH_TWIN_SHARED, me->GetMaxHealth()); } me->DespawnOrUnsummon(); } @@ -190,7 +201,6 @@ struct boss_twin_baseAI : public ScriptedAI case 1: me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); me->SetReactState(REACT_AGGRESSIVE); - me->SetInCombatWithZone(); break; } } @@ -223,45 +233,16 @@ struct boss_twin_baseAI : public ScriptedAI { case NPC_LIGHT_ESSENCE: m_pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_LIGHT_ESSENCE_HELPER); + m_pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_POWERING_UP_HELPER); break; case NPC_DARK_ESSENCE: m_pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_DARK_ESSENCE_HELPER); + m_pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_POWERING_UP_HELPER); break; } Summons.Despawn(summoned); } - void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) - { - if (!me || !me->isAlive()) - return; - - if (pDoneBy->GetGUID() == me->GetGUID()) - return; - - if (pDoneBy->GetTypeId() == TYPEID_PLAYER) - { - if (pDoneBy->HasAura(m_uiOtherEssenceSpellId)) - uiDamage += uiDamage/2; - if (pDoneBy->HasAura(m_uiEmpoweredWeaknessSpellId)) - uiDamage += uiDamage; - else - if (pDoneBy->HasAura(m_uiMyEssenceSpellId)) - uiDamage /= 2; - } - - if (m_pInstance) - m_pInstance->SetData(DATA_HEALTH_TWIN_SHARED, me->GetHealth() >= uiDamage ? me->GetHealth() - uiDamage : 0); - } - - void SpellHit(Unit* caster, const SpellInfo* spell) - { - if (caster->ToCreature() == me) - if (spell->Effects[0].Effect == 136) //Effect Heal - if (m_pInstance) - m_pInstance->SetData(DATA_HEALTH_TWIN_SHARED, me->GetHealth() + me->CountPctFromMaxHealth(spell->Effects[EFFECT_0].CalcValue())); - } - void SummonColorballs(uint8 quantity) { float x0 = ToCCommonLoc[1].GetPositionX(), y0 = ToCCommonLoc[1].GetPositionY(), r = 47.0f; @@ -282,7 +263,6 @@ struct boss_twin_baseAI : public ScriptedAI DoScriptText(SAY_DEATH, me); if (m_pInstance) { - m_pInstance->SetData(DATA_HEALTH_TWIN_SHARED, 0); if (Creature* pSister = GetSister()) { if (!pSister->isAlive()) @@ -307,8 +287,10 @@ struct boss_twin_baseAI : public ScriptedAI me->SetInCombatWithZone(); if (m_pInstance) { + if (Creature* pSister = GetSister()) + me->AddAura(m_uiMyEmphatySpellId, pSister); + m_pInstance->SetData(TYPE_VALKIRIES, IN_PROGRESS); - m_pInstance->SetData(DATA_HEALTH_TWIN_SHARED, me->GetMaxHealth()); } if (me->isAlive()) { @@ -333,16 +315,18 @@ struct boss_twin_baseAI : public ScriptedAI } } + void EnableDualWield(bool mode) + { + SetEquipmentSlots(false, m_uiWeapon, mode ? m_uiWeapon : EQUIP_UNEQUIP, EQUIP_UNEQUIP); + me->SetCanDualWield(mode); + me->UpdateDamagePhysical(mode ? OFF_ATTACK : BASE_ATTACK); + } + void UpdateAI(const uint32 uiDiff) { if (!m_pInstance || !UpdateVictim()) return; - if (m_pInstance->GetData(DATA_HEALTH_TWIN_SHARED) != 0) - me->SetHealth(m_pInstance->GetData(DATA_HEALTH_TWIN_SHARED)); - else - me->SetHealth(1); - switch (m_uiStage) { case 0: @@ -364,10 +348,13 @@ struct boss_twin_baseAI : public ScriptedAI case 2: // Shield+Pact if (m_uiSpecialAbilityTimer <= uiDiff) { - if (Creature* pSister = GetSister()) - pSister->AI()->DoAction(ACTION_PACT); DoScriptText(EMOTE_SHIELD, me); DoScriptText(SAY_SHIELD, me); + if (Creature* pSister = GetSister()) + { + pSister->AI()->DoAction(ACTION_PACT); + pSister->CastSpell(pSister, SPELL_POWER_TWINS, false); + } DoCast(me, m_uiShieldSpellId); DoCast(me, m_uiTwinPactSpellId); m_uiStage = 0; @@ -447,13 +434,16 @@ public: void Reset() { boss_twin_baseAI::Reset(); - SetEquipmentSlots(false, EQUIP_MAIN_1, EQUIP_OFFHAND_1, EQUIP_RANGED_1); + SetEquipmentSlots(false, EQUIP_MAIN_1, EQUIP_UNEQUIP, EQUIP_NO_CHANGE); m_uiStage = 0; + m_uiWeapon = EQUIP_MAIN_1; + m_uiAuraState = AURA_STATE_UNKNOWN22; m_uiVortexEmote = EMOTE_LIGHT_VORTEX; m_uiVortexSay = SAY_LIGHT_VORTEX; m_uiSisterNpcId = NPC_DARKBANE; m_uiColorballNpcId = NPC_UNLEASHED_LIGHT; m_uiEssenceNpcId = NPC_LIGHT_ESSENCE; + m_uiMyEmphatySpellId = SPELL_TWIN_EMPATHY_1; m_uiMyEssenceSpellId = SPELL_LIGHT_ESSENCE_HELPER; m_uiOtherEssenceSpellId = SPELL_DARK_ESSENCE_HELPER; m_uiEmpoweredWeaknessSpellId = SPELL_EMPOWERED_DARK_HELPER; @@ -506,13 +496,16 @@ public: void Reset() { boss_twin_baseAI::Reset(); - SetEquipmentSlots(false, EQUIP_MAIN_2, EQUIP_OFFHAND_2, EQUIP_RANGED_2); + SetEquipmentSlots(false, EQUIP_MAIN_2, EQUIP_UNEQUIP, EQUIP_NO_CHANGE); m_uiStage = 1; + m_uiWeapon = EQUIP_MAIN_2; + m_uiAuraState = AURA_STATE_UNKNOWN19; m_uiVortexEmote = EMOTE_DARK_VORTEX; m_uiVortexSay = SAY_DARK_VORTEX; m_uiSisterNpcId = NPC_LIGHTBANE; m_uiColorballNpcId = NPC_UNLEASHED_DARK; m_uiEssenceNpcId = NPC_DARK_ESSENCE; + m_uiMyEmphatySpellId = SPELL_TWIN_EMPATHY_2; m_uiMyEssenceSpellId = SPELL_DARK_ESSENCE_HELPER; m_uiOtherEssenceSpellId = SPELL_LIGHT_ESSENCE_HELPER; m_uiEmpoweredWeaknessSpellId = SPELL_EMPOWERED_LIGHT_HELPER; @@ -654,6 +647,12 @@ public: } else m_uiRangeCheckTimer -= uiDiff; } + + void SpellHitTarget(Unit* who, const SpellInfo* spell) + { + if (who->HasAura(SPELL_DARK_ESSENCE_HELPER)) + who->CastSpell(who, SPELL_POWERING_UP, true); + } }; }; @@ -687,10 +686,173 @@ public: } else m_uiRangeCheckTimer -= uiDiff; } + + void SpellHitTarget(Unit* who, const SpellInfo* spell) + { + if (who->HasAura(SPELL_LIGHT_ESSENCE_HELPER)) + who->CastSpell(who, SPELL_POWERING_UP, true); + } }; }; +class spell_powering_up : public SpellScriptLoader +{ + public: + spell_powering_up() : SpellScriptLoader("spell_powering_up") { } + + class spell_powering_up_AuraScript : public AuraScript + { + PrepareAuraScript(spell_powering_up_AuraScript); + + void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Unit* target = GetTarget()) + { + if (Aura* pAura = target->GetAura(GetId())) + { + if (pAura->GetStackAmount() == 100) + { + if(target->GetDummyAuraEffect(SPELLFAMILY_GENERIC, 2206, EFFECT_1)) + target->CastSpell(target, SPELL_EMPOWERED_DARK, true); + + if(target->GetDummyAuraEffect(SPELLFAMILY_GENERIC, 2845, EFFECT_1)) + target->CastSpell(target, SPELL_EMPOWERED_LIGHT, true); + + target->RemoveAurasDueToSpell(GetId()); + } + } + } + } + + void Register() + { + OnEffectApply += AuraEffectApplyFn(spell_powering_up_AuraScript::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_powering_up_AuraScript(); + } + + class spell_powering_up_SpellScript : public SpellScript + { + public: + PrepareSpellScript(spell_powering_up_SpellScript) + + uint32 spellId; + + bool Validate(SpellEntry const * /*spellEntry*/) + { + spellId = sSpellMgr->GetSpellIdForDifficulty(SPELL_SURGE_OF_SPEED, GetCaster()); + if (!sSpellMgr->GetSpellInfo(spellId)) + return false; + return true; + } + + void HandleScriptEffect(SpellEffIndex /*effIndex*/) + { + if (Unit* target = GetTargetUnit()) + if (urand(0, 99) < 15) + target->CastSpell(target, spellId, true); + } + + void Register() + { + OnEffect += SpellEffectFn(spell_powering_up_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_powering_up_SpellScript(); + } +}; + +class spell_valkyr_essences : public SpellScriptLoader +{ + public: + spell_valkyr_essences() : SpellScriptLoader("spell_valkyr_essences") { } + + class spell_valkyr_essences_AuraScript : public AuraScript + { + PrepareAuraScript(spell_valkyr_essences_AuraScript); + + uint32 spellId; + + bool Load() + { + spellId = sSpellMgr->GetSpellIdForDifficulty(SPELL_SURGE_OF_SPEED, GetCaster()); + if (!sSpellMgr->GetSpellInfo(spellId)) + return false; + return true; + } + + void Absorb(AuraEffect * /*aurEff*/, DamageInfo & /*dmgInfo*/, uint32 & /*absorbAmount*/) + { + if (urand(0, 99) < 5) + GetTarget()->CastSpell(GetTarget(), spellId, true); + } + + void Register() + { + OnEffectAbsorb += AuraEffectAbsorbFn(spell_valkyr_essences_AuraScript::Absorb, EFFECT_0); + } + }; + + AuraScript *GetAuraScript() const + { + return new spell_valkyr_essences_AuraScript(); + } +}; + +class spell_power_of_the_twins : public SpellScriptLoader +{ + public: + spell_power_of_the_twins() : SpellScriptLoader("spell_power_of_the_twins") { } + + class spell_power_of_the_twins_AuraScript : public AuraScript + { + PrepareAuraScript(spell_power_of_the_twins_AuraScript); + + bool Load() + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + void HandleEffectApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + if (InstanceScript* instance = GetCaster()->GetInstanceScript()) + { + if (Creature* Valk = ObjectAccessor::GetCreature(*GetCaster(), instance->GetData64(GetCaster()->GetEntry()))) + CAST_AI(boss_twin_baseAI, Valk->AI())->EnableDualWield(true); + } + } + + void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (InstanceScript* instance = GetCaster()->GetInstanceScript()) + { + if (Creature* Valk = ObjectAccessor::GetCreature(*GetCaster(), instance->GetData64(GetCaster()->GetEntry()))) + CAST_AI(boss_twin_baseAI, Valk->AI())->EnableDualWield(false); + } + } + + void Register() + { + AfterEffectApply += AuraEffectApplyFn(spell_power_of_the_twins_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_power_of_the_twins_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + + } + }; + + AuraScript *GetAuraScript() const + { + return new spell_power_of_the_twins_AuraScript(); + } +}; + void AddSC_boss_twin_valkyr() { new boss_fjola(); @@ -698,4 +860,7 @@ void AddSC_boss_twin_valkyr() new mob_unleashed_light(); new mob_unleashed_dark(); new mob_essence_of_twin(); + new spell_powering_up(); + new spell_valkyr_essences(); + new spell_power_of_the_twins(); } diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp index e4d7d051676..91cd8dee55c 100755 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp @@ -44,10 +44,6 @@ class instance_trial_of_the_crusader : public InstanceMapScript std::string SaveDataBuffer; bool NeedSave; - uint32 DataDamageTwin; - uint32 FjolaCasting; - uint32 EydisCasting; - uint64 BarrentGUID; uint64 TirionGUID; uint64 FizzlebangGUID; @@ -368,11 +364,6 @@ class instance_trial_of_the_crusader : public InstanceMapScript break; } break; - case DATA_HEALTH_TWIN_SHARED: - DataDamageTwin = data; - data = NOT_STARTED; - break; - //Achievements case DATA_SNOBOLD_COUNT: if (data == INCREASE) @@ -584,8 +575,6 @@ class instance_trial_of_the_crusader : public InstanceMapScript break; }; return EventNPCId; - case DATA_HEALTH_TWIN_SHARED: - return DataDamageTwin; default: break; } diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp index bdccc540bb6..34c065f5649 100755 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp @@ -745,24 +745,36 @@ class npc_tirion_toc : public CreatureScript break; case 4010: DoScriptText(SAY_STAGE_3_02, me); - m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR)); + if(Creature* pTemp = me->SummonCreature(NPC_LIGHTBANE, ToCCommonLoc[3].GetPositionX(), ToCCommonLoc[3].GetPositionY(), ToCCommonLoc[3].GetPositionZ(), 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME)) + { + pTemp->SetVisible(false); + pTemp->SetReactState(REACT_PASSIVE); + pTemp->SummonCreature(NPC_LIGHT_ESSENCE, TwinValkyrsLoc[0].GetPositionX(), TwinValkyrsLoc[0].GetPositionY(), TwinValkyrsLoc[0].GetPositionZ()); + pTemp->SummonCreature(NPC_LIGHT_ESSENCE, TwinValkyrsLoc[1].GetPositionX(), TwinValkyrsLoc[1].GetPositionY(), TwinValkyrsLoc[1].GetPositionZ()); + } + if(Creature* pTemp = me->SummonCreature(NPC_DARKBANE, ToCCommonLoc[4].GetPositionX(), ToCCommonLoc[4].GetPositionY(), ToCCommonLoc[4].GetPositionZ(), 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME)) + { + pTemp->SetVisible(false); + pTemp->SetReactState(REACT_PASSIVE); + pTemp->SummonCreature(NPC_DARK_ESSENCE, TwinValkyrsLoc[2].GetPositionX(), TwinValkyrsLoc[2].GetPositionY(), TwinValkyrsLoc[2].GetPositionZ()); + pTemp->SummonCreature(NPC_DARK_ESSENCE, TwinValkyrsLoc[3].GetPositionX(), TwinValkyrsLoc[3].GetPositionY(), TwinValkyrsLoc[3].GetPositionZ()); + } m_uiUpdateTimer = 3000; m_pInstance->SetData(TYPE_EVENT, 4015); break; case 4015: - me->SummonCreature(NPC_LIGHTBANE, ToCCommonLoc[3].GetPositionX(), ToCCommonLoc[3].GetPositionY(), ToCCommonLoc[3].GetPositionZ(), 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR)); if (Creature* pTemp = Unit::GetCreature((*me), m_pInstance->GetData64(NPC_LIGHTBANE))) { pTemp->GetMotionMaster()->MovePoint(0, ToCCommonLoc[6].GetPositionX(), ToCCommonLoc[6].GetPositionY(), ToCCommonLoc[6].GetPositionZ()); pTemp->AddUnitMovementFlag(MOVEMENTFLAG_WALKING); - me->SetReactState(REACT_PASSIVE); + pTemp->SetVisible(true); } - me->SummonCreature(NPC_DARKBANE, ToCCommonLoc[4].GetPositionX(), ToCCommonLoc[4].GetPositionY(), ToCCommonLoc[4].GetPositionZ(), 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); if (Creature* pTemp = Unit::GetCreature((*me), m_pInstance->GetData64(NPC_DARKBANE))) { pTemp->GetMotionMaster()->MovePoint(0, ToCCommonLoc[7].GetPositionX(), ToCCommonLoc[7].GetPositionY(), ToCCommonLoc[7].GetPositionZ()); pTemp->AddUnitMovementFlag(MOVEMENTFLAG_WALKING); - me->SetReactState(REACT_PASSIVE); + pTemp->SetVisible(true); } m_uiUpdateTimer = 5000; m_pInstance->SetData(TYPE_EVENT, 4016); diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h index ab9087c0ca8..a0ee721a26a 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h @@ -22,8 +22,6 @@ enum TYPE_EVENT_NPC = 102, TYPE_NORTHREND_BEASTS = 103, - DATA_HEALTH_TWIN_SHARED = 201, - DATA_SNOBOLD_COUNT = 301, DATA_MISTRESS_OF_PAIN_COUNT = 302, DATA_TRIBUTE_TO_IMMORTALITY_ELEGIBLE = 303, @@ -210,6 +208,9 @@ enum eCreature NPC_LIGHTBANE = 34497, NPC_DARKBANE = 34496, + NPC_DARK_ESSENCE = 34567, + NPC_LIGHT_ESSENCE = 34568, + NPC_ANUBARAK = 34564, }; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp index 40f465c9ccd..35c2d40494a 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp @@ -425,6 +425,9 @@ class boss_prince_keleseth_icc : public CreatureScript void JustDied(Unit* /*killer*/) { + events.Reset(); + summons.DespawnAll(); + Talk(SAY_KELESETH_DEATH); instance->SendEncounterUnit(ENCOUNTER_FRAME_REMOVE, me); } @@ -646,6 +649,9 @@ class boss_prince_taldaram_icc : public CreatureScript void JustDied(Unit* /*killer*/) { + events.Reset(); + summons.DespawnAll(); + Talk(EMOTE_TALDARAM_DEATH); instance->SendEncounterUnit(ENCOUNTER_FRAME_REMOVE, me); } @@ -866,6 +872,9 @@ class boss_prince_valanar_icc : public CreatureScript void JustDied(Unit* /*killer*/) { + events.Reset(); + summons.DespawnAll(); + Talk(SAY_VALANAR_DEATH); instance->SendEncounterUnit(ENCOUNTER_FRAME_REMOVE, me); } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp index ac820162a8b..25c804f2eed 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp @@ -81,6 +81,7 @@ uint32 const vampireAuras[3][MAX_DIFFICULTY] = #define ESSENCE_OF_BLOOD_QUEEN RAID_MODE<uint32>(70867, 71473, 71532, 71533) #define ESSENCE_OF_BLOOD_QUEEN_PLR RAID_MODE<uint32>(70879, 71525, 71530, 71531) #define FRENZIED_BLOODTHIRST RAID_MODE<uint32>(70877, 71474, 70877, 71474) +#define DELIRIOUS_SLASH RAID_MODE<uint32>(71623, 71624, 71625, 71626) enum Events { @@ -185,7 +186,7 @@ class boss_blood_queen_lana_thel : public CreatureScript instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_BLOOD_MIRROR_DAMAGE); instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_BLOOD_MIRROR_VISUAL); instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_BLOOD_MIRROR_DUMMY); - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_DELIRIOUS_SLASH); + instance->DoRemoveAurasDueToSpellOnPlayers(DELIRIOUS_SLASH); instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_PACT_OF_THE_DARKFALLEN); // Blah, credit the quest if (_creditBloodQuickening) @@ -355,6 +356,7 @@ class boss_blood_queen_lana_thel : public CreatureScript _offtank = newOfftank; if (_offtank) { + // both spells have SPELL_ATTR5_SINGLE_TARGET_SPELL, no manual removal needed _offtank->CastSpell(me->getVictim(), SPELL_BLOOD_MIRROR_DAMAGE, true); me->getVictim()->CastSpell(_offtank, SPELL_BLOOD_MIRROR_DUMMY, true); DoCastVictim(SPELL_BLOOD_MIRROR_VISUAL); @@ -416,7 +418,7 @@ class boss_blood_queen_lana_thel : public CreatureScript case EVENT_AIR_PHASE: DoStopAttack(); me->SetReactState(REACT_PASSIVE); - events.DelayEvents(7000, EVENT_GROUP_NORMAL); + events.DelayEvents(10000, EVENT_GROUP_NORMAL); events.CancelEventGroup(EVENT_GROUP_CANCELLABLE); me->GetMotionMaster()->MovePoint(POINT_CENTER, centerPos); break; @@ -682,20 +684,6 @@ class spell_blood_queen_bloodbolt : public SpellScriptLoader } }; -class PactOfTheDarkfallenCheck -{ - public: - PactOfTheDarkfallenCheck(bool hasPact) : _hasPact(hasPact) { } - - bool operator() (Unit* unit) - { - return unit->HasAura(SPELL_PACT_OF_THE_DARKFALLEN) == _hasPact; - } - - private: - bool _hasPact; -}; - class spell_blood_queen_pact_of_the_darkfallen : public SpellScriptLoader { public: @@ -707,7 +695,7 @@ class spell_blood_queen_pact_of_the_darkfallen : public SpellScriptLoader void FilterTargets(std::list<Unit*>& unitList) { - unitList.remove_if(PactOfTheDarkfallenCheck(false)); + unitList.remove_if(Trinity::UnitAuraCheck(false, SPELL_PACT_OF_THE_DARKFALLEN)); bool remove = true; std::list<Unit*>::const_iterator itrEnd = unitList.end(), itr, itr2; @@ -793,7 +781,7 @@ class spell_blood_queen_pact_of_the_darkfallen_dmg_target : public SpellScriptLo void FilterTargets(std::list<Unit*>& unitList) { - unitList.remove_if(PactOfTheDarkfallenCheck(true)); + unitList.remove_if(Trinity::UnitAuraCheck(true, SPELL_PACT_OF_THE_DARKFALLEN)); unitList.push_back(GetCaster()); } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp index ab16458f8b1..dd645562501 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp @@ -125,6 +125,7 @@ class boss_rotface : public CreatureScript { _JustDied(); Talk(SAY_DEATH); + instance->DoRemoveAurasDueToSpellOnPlayers(MUTATED_INFECTION); if (Creature* professor = Unit::GetCreature(*me, instance->GetData64(DATA_PROFESSOR_PUTRICIDE))) professor->AI()->DoAction(ACTION_ROTFACE_DEATH); } @@ -191,18 +192,9 @@ class boss_rotface : public CreatureScript } break; case EVENT_MUTATED_INFECTION: - { - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true, -MUTATED_INFECTION); - if (!target) - target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, -MUTATED_INFECTION); - if (target) - { - me->CastCustomSpell(SPELL_MUTATED_INFECTION, SPELLVALUE_MAX_TARGETS, 1, target, false); - Talk(EMOTE_MUTATED_INFECTION, target->GetGUID()); - } + me->CastCustomSpell(SPELL_MUTATED_INFECTION, SPELLVALUE_MAX_TARGETS, 1, NULL, false); events.ScheduleEvent(EVENT_MUTATED_INFECTION, infectionCooldown); break; - } default: break; } @@ -478,6 +470,68 @@ class spell_rotface_ooze_flood : public SpellScriptLoader } }; +class spell_rotface_mutated_infection : public SpellScriptLoader +{ + public: + spell_rotface_mutated_infection() : SpellScriptLoader("spell_rotface_mutated_infection") { } + + class spell_rotface_mutated_infection_SpellScript : public SpellScript + { + PrepareSpellScript(spell_rotface_mutated_infection_SpellScript); + + bool Load() + { + _target = NULL; + return true; + } + + void FilterTargets(std::list<Unit*>& targets) + { + // remove targets with this aura already + // tank is not on this list + targets.remove_if(Trinity::UnitAuraCheck(true, GetSpellInfo()->Id)); + if (targets.empty()) + return; + + std::list<Unit*>::iterator itr = targets.begin(); + std::advance(itr, urand(0, targets.size() - 1)); + Unit* target = *itr; + targets.clear(); + targets.push_back(target); + _target = target; + } + + void ReplaceTargets(std::list<Unit*>& targets) + { + targets.clear(); + if (_target) + targets.push_back(_target); + } + + void NotifyTargets() + { + if (Creature* caster = GetCaster()->ToCreature()) + if (Unit* target = GetHitUnit()) + caster->AI()->Talk(EMOTE_MUTATED_INFECTION, target->GetGUID()); + } + + void Register() + { + OnUnitTargetSelect += SpellUnitTargetFn(spell_rotface_mutated_infection_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + OnUnitTargetSelect += SpellUnitTargetFn(spell_rotface_mutated_infection_SpellScript::ReplaceTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY); + OnUnitTargetSelect += SpellUnitTargetFn(spell_rotface_mutated_infection_SpellScript::ReplaceTargets, EFFECT_2, TARGET_UNIT_SRC_AREA_ENEMY); + AfterHit += SpellHitFn(spell_rotface_mutated_infection_SpellScript::NotifyTargets); + } + + Unit* _target; + }; + + SpellScript* GetSpellScript() const + { + return new spell_rotface_mutated_infection_SpellScript(); + } +}; + class spell_rotface_little_ooze_combine : public SpellScriptLoader { public: @@ -724,6 +778,7 @@ void AddSC_boss_rotface() new npc_big_ooze(); new npc_precious_icc(); new spell_rotface_ooze_flood(); + new spell_rotface_mutated_infection(); new spell_rotface_little_ooze_combine(); new spell_rotface_large_ooze_combine(); new spell_rotface_large_ooze_buff_combine(); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp index b5d3eb947c0..c167dfc8e95 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp @@ -212,15 +212,6 @@ class AuraRemoveEvent : public BasicEvent uint32 _spellId; }; -class SummonTargetSelector -{ - public: - bool operator()(Unit* unit) const - { - return unit->HasAura(SPELL_RECENTLY_SPAWNED); - } -}; - class ValithriaDespawner : public BasicEvent { public: @@ -249,6 +240,7 @@ class ValithriaDespawner : public BasicEvent case NPC_GLUTTONOUS_ABOMINATION: case NPC_MANA_VOID: case NPC_COLUMN_OF_FROST: + case NPC_ROT_WORM: creature->DespawnOrUnsummon(); return; case NPC_RISEN_ARCHMAGE: @@ -1186,7 +1178,7 @@ class spell_dreamwalker_summoner : public SpellScriptLoader void FilterTargets(std::list<Unit*>& targets) { - targets.remove_if(SummonTargetSelector()); + targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_RECENTLY_SPAWNED)); if (targets.empty()) return; @@ -1227,7 +1219,7 @@ class spell_dreamwalker_summon_suppresser : public SpellScriptLoader std::list<Creature*> summoners; GetCreatureListWithEntryInGrid(summoners, caster, 22515, 100.0f); - summoners.remove_if(SummonTargetSelector()); + summoners.remove_if(Trinity::UnitAuraCheck(true, SPELL_RECENTLY_SPAWNED)); Trinity::RandomResizeList(summoners, 2); if (summoners.empty()) return; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h index 7a1ab3e4f19..f5973fc0c8c 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h @@ -228,6 +228,7 @@ enum CreaturesIds NPC_GLUTTONOUS_ABOMINATION = 37886, NPC_MANA_VOID = 38068, NPC_COLUMN_OF_FROST = 37918, + NPC_ROT_WORM = 37907, NPC_THE_LICH_KING_VALITHRIA = 16980, NPC_DREAM_PORTAL_PRE_EFFECT = 38186, NPC_NIGHTMARE_PORTAL_PRE_EFFECT = 38429, diff --git a/src/server/scripts/Northrend/icecrown.cpp b/src/server/scripts/Northrend/icecrown.cpp index 86b375fc274..dc55c2f6ad3 100644 --- a/src/server/scripts/Northrend/icecrown.cpp +++ b/src/server/scripts/Northrend/icecrown.cpp @@ -381,6 +381,51 @@ public: } }; +/*###### +## npc_vereth_the_cunning +######*/ + +enum eVerethTheCunning +{ + NPC_GEIST_RETURN_BUNNY_KC = 31049, + NPC_LITHE_STALKER = 30894, + SPELL_SUBDUED_LITHE_STALKER = 58151, +}; + +class npc_vereth_the_cunning : public CreatureScript +{ +public: + npc_vereth_the_cunning() : CreatureScript("npc_vereth_the_cunning") { } + + struct npc_vereth_the_cunningAI : public ScriptedAI + { + npc_vereth_the_cunningAI(Creature* pCreature) : ScriptedAI(pCreature) {} + + void MoveInLineOfSight(Unit* who) + { + ScriptedAI::MoveInLineOfSight(who); + + if (who->GetEntry() == NPC_LITHE_STALKER && me->IsWithinDistInMap(who, 10.0f)) + { + if (Unit* owner = who->GetCharmer()) + { + if (who->HasAura(SPELL_SUBDUED_LITHE_STALKER)) + { + owner->ToPlayer()->KilledMonsterCredit(NPC_GEIST_RETURN_BUNNY_KC, 0); + who->ToCreature()->DisappearAndDie(); + + } + } + } + } + }; + + CreatureAI *GetAI(Creature *creature) const + { + return new npc_vereth_the_cunningAI(creature); + } +}; + void AddSC_icecrown() { new npc_arete; @@ -389,4 +434,5 @@ void AddSC_icecrown() new npc_argent_valiant; new npc_alorah_and_grimmin; new npc_guardian_pavilion; + new npc_vereth_the_cunning; } diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp index ae8069747e3..a9ffe2e0f47 100644 --- a/src/server/scripts/Spells/spell_quest.cpp +++ b/src/server/scripts/Spells/spell_quest.cpp @@ -22,6 +22,7 @@ */ #include "ScriptPCH.h" +#include "Vehicle.h" class spell_generic_quest_update_entry_SpellScript : public SpellScript { @@ -939,6 +940,44 @@ class spell_q12805_lifeblood_dummy : public SpellScriptLoader }; }; +/* + http://www.wowhead.com/quest=13283 King of the Mountain + http://www.wowhead.com/quest=13280 King of the Mountain + 59643 Plant Horde Battle Standard + 4338 Plant Alliance Battle Standard + */ +enum eBattleStandard +{ + NPC_KING_OF_THE_MOUNTAINT_KC = 31766, +}; +class spell_q13280_13283_plant_battle_standard: public SpellScriptLoader +{ +public: + spell_q13280_13283_plant_battle_standard() : SpellScriptLoader("spell_q13280_13283_plant_battle_standard") { } + + class spell_q13280_13283_plant_battle_standard_SpellScript : public SpellScript + { + PrepareSpellScript(spell_q13280_13283_plant_battle_standard_SpellScript) + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + if (caster->IsVehicle()) + if (Unit* player = caster->GetVehicleKit()->GetPassenger(0)) + player->ToPlayer()->KilledMonsterCredit(NPC_KING_OF_THE_MOUNTAINT_KC,0); + } + + void Register() + { + OnEffect += SpellEffectFn(spell_q13280_13283_plant_battle_standard_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_q13280_13283_plant_battle_standard_SpellScript(); + } +}; + void AddSC_quest_spell_scripts() { new spell_q55_sacred_cleansing(); @@ -961,4 +1000,5 @@ void AddSC_quest_spell_scripts() new spell_q12659_ahunaes_knife(); new spell_q9874_liquid_fire(); new spell_q12805_lifeblood_dummy(); + new spell_q13280_13283_plant_battle_standard(); } |