diff options
Diffstat (limited to 'src/server/scripts')
-rw-r--r-- | src/server/scripts/Commands/cs_instance.cpp | 144 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_misc.cpp | 66 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_quest.cpp | 11 | ||||
-rw-r--r-- | src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_shazzrah.cpp | 112 | ||||
-rw-r--r-- | src/server/scripts/Northrend/isle_of_conquest.cpp | 151 | ||||
-rw-r--r-- | src/server/scripts/Spells/spell_generic.cpp | 309 | ||||
-rw-r--r-- | src/server/scripts/Spells/spell_quest.cpp | 28 |
7 files changed, 749 insertions, 72 deletions
diff --git a/src/server/scripts/Commands/cs_instance.cpp b/src/server/scripts/Commands/cs_instance.cpp index a426c49a5f7..0bc352be842 100644 --- a/src/server/scripts/Commands/cs_instance.cpp +++ b/src/server/scripts/Commands/cs_instance.cpp @@ -40,11 +40,13 @@ public: { static ChatCommand instanceCommandTable[] = { - { "listbinds", rbac::RBAC_PERM_COMMAND_INSTANCE_LISTBINDS, false, &HandleInstanceListBindsCommand, "", NULL }, - { "unbind", rbac::RBAC_PERM_COMMAND_INSTANCE_UNBIND, false, &HandleInstanceUnbindCommand, "", NULL }, - { "stats", rbac::RBAC_PERM_COMMAND_INSTANCE_STATS, true, &HandleInstanceStatsCommand, "", NULL }, - { "savedata", rbac::RBAC_PERM_COMMAND_INSTANCE_SAVEDATA, false, &HandleInstanceSaveDataCommand, "", NULL }, - { NULL, 0, false, NULL, "", NULL } + { "listbinds", rbac::RBAC_PERM_COMMAND_INSTANCE_LISTBINDS, false, &HandleInstanceListBindsCommand, "", NULL }, + { "unbind", rbac::RBAC_PERM_COMMAND_INSTANCE_UNBIND, false, &HandleInstanceUnbindCommand, "", NULL }, + { "stats", rbac::RBAC_PERM_COMMAND_INSTANCE_STATS, true, &HandleInstanceStatsCommand, "", NULL }, + { "savedata", rbac::RBAC_PERM_COMMAND_INSTANCE_SAVEDATA, false, &HandleInstanceSaveDataCommand, "", NULL }, + { "setbossstate", rbac::RBAC_PERM_COMMAND_INSTANCE_SET_BOSS_STATE, true, &HandleInstanceSetBossStateCommand, "", NULL }, + { "getbossstate", rbac::RBAC_PERM_COMMAND_INSTANCE_GET_BOSS_STATE, true, &HandleInstanceGetBossStateCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } }; static ChatCommand commandTable[] = @@ -187,6 +189,138 @@ public: return true; } + + static bool HandleInstanceSetBossStateCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + char* param1 = strtok((char*)args, " "); + char* param2 = strtok(nullptr, " "); + char* param3 = strtok(nullptr, " "); + uint32 encounterId = 0; + int32 state = 0; + Player* player = nullptr; + std::string playerName; + + // Character name must be provided when using this from console. + if (!param2 || (!param3 && !handler->GetSession())) + { + handler->PSendSysMessage(LANG_CMD_SYNTAX); + handler->SetSentErrorMessage(true); + return false; + } + + if (!param3) + player = handler->GetSession()->GetPlayer(); + else + { + playerName = param3; + if (normalizePlayerName(playerName)) + player = sObjectAccessor->FindPlayerByName(playerName); + } + + if (!player) + { + handler->PSendSysMessage(LANG_PLAYER_NOT_FOUND); + handler->SetSentErrorMessage(true); + return false; + } + + Map* map = player->GetMap(); + if (!map->IsDungeon()) + { + handler->PSendSysMessage(LANG_NOT_DUNGEON); + handler->SetSentErrorMessage(true); + return false; + } + + if (!map->ToInstanceMap()->GetInstanceScript()) + { + handler->PSendSysMessage(LANG_NO_INSTANCE_DATA); + handler->SetSentErrorMessage(true); + return false; + } + + encounterId = atoi(param1); + state = atoi(param2); + + // Reject improper values. + if (state > TO_BE_DECIDED || encounterId > map->ToInstanceMap()->GetInstanceScript()->GetEncounterCount()) + { + handler->PSendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + map->ToInstanceMap()->GetInstanceScript()->SetBossState(encounterId, (EncounterState)state); + handler->PSendSysMessage(LANG_COMMAND_INST_SET_BOSS_STATE, encounterId, state); + return true; + } + + static bool HandleInstanceGetBossStateCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + char* param1 = strtok((char*)args, " "); + char* param2 = strtok(nullptr, " "); + uint32 encounterId = 0; + Player* player = nullptr; + std::string playerName; + + // Character name must be provided when using this from console. + if (!param1 || (!param2 && !handler->GetSession())) + { + handler->PSendSysMessage(LANG_CMD_SYNTAX); + handler->SetSentErrorMessage(true); + return false; + } + + if (!param2) + player = handler->GetSession()->GetPlayer(); + else + { + playerName = param2; + if (normalizePlayerName(playerName)) + player = sObjectAccessor->FindPlayerByName(playerName); + } + + if (!player) + { + handler->PSendSysMessage(LANG_PLAYER_NOT_FOUND); + handler->SetSentErrorMessage(true); + return false; + } + + Map* map = player->GetMap(); + if (!map->IsDungeon()) + { + handler->PSendSysMessage(LANG_NOT_DUNGEON); + handler->SetSentErrorMessage(true); + return false; + } + + if (!map->ToInstanceMap()->GetInstanceScript()) + { + handler->PSendSysMessage(LANG_NO_INSTANCE_DATA); + handler->SetSentErrorMessage(true); + return false; + } + + encounterId = atoi(param1); + + if (encounterId > map->ToInstanceMap()->GetInstanceScript()->GetEncounterCount()) + { + handler->PSendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + uint8 state = map->ToInstanceMap()->GetInstanceScript()->GetBossState(encounterId); + handler->PSendSysMessage(LANG_COMMAND_INST_GET_BOSS_STATE, encounterId, state); + return true; + } }; void AddSC_instance_commandscript() diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 75dbf975857..c34e32b134f 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -73,6 +73,7 @@ public: { "maxskill", rbac::RBAC_PERM_COMMAND_MAXSKILL, false, &HandleMaxSkillCommand, "", NULL }, { "movegens", rbac::RBAC_PERM_COMMAND_MOVEGENS, false, &HandleMovegensCommand, "", NULL }, { "mute", rbac::RBAC_PERM_COMMAND_MUTE, true, &HandleMuteCommand, "", NULL }, + { "mutehistory", rbac::RBAC_PERM_COMMAND_MUTEHISTORY, true, &HandleMuteInfoCommand, "", NULL }, { "neargrave", rbac::RBAC_PERM_COMMAND_NEARGRAVE, false, &HandleNearGraveCommand, "", NULL }, { "pinfo", rbac::RBAC_PERM_COMMAND_PINFO, true, &HandlePInfoCommand, "", NULL }, { "playall", rbac::RBAC_PERM_COMMAND_PLAYALL, false, &HandlePlayAllCommand, "", NULL }, @@ -1850,6 +1851,12 @@ public: stmt->setString(2, muteBy.c_str()); stmt->setUInt32(3, accountId); LoginDatabase.Execute(stmt); + stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_ACCOUNT_MUTE); + stmt->setUInt32(0, accountId); + stmt->setUInt32(1, notSpeakTime); + stmt->setString(2, muteBy.c_str()); + stmt->setString(3, muteReasonStr.c_str()); + LoginDatabase.Execute(stmt); std::string nameLink = handler->playerLink(targetName); if (sWorld->getBoolConfig(CONFIG_SHOW_MUTE_IN_WORLD) && !target) @@ -1909,6 +1916,65 @@ public: return true; } + // mutehistory command + static bool HandleMuteInfoCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + char *nameStr = strtok((char*)args, ""); + if (!nameStr) + return false; + + std::string accountName = nameStr; + if (!AccountMgr::normalizeString(accountName)) + { + handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 accountId = AccountMgr::GetId(accountName); + if (!accountId) + { + handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); + return false; + } + + return HandleMuteInfoHelper(accountId, accountName.c_str(), handler); + } + + // helper for mutehistory + static bool HandleMuteInfoHelper(uint32 accountId, char const* accountName, ChatHandler *handler) + { + PreparedStatement *stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_MUTE_INFO); + stmt->setUInt16(0, accountId); + PreparedQueryResult result = LoginDatabase.Query(stmt); + + if (!result) + { + handler->PSendSysMessage(LANG_COMMAND_MUTEHISTORY_EMPTY, accountName); + return true; + } + + handler->PSendSysMessage(LANG_COMMAND_MUTEHISTORY, accountName); + do + { + Field* fields = result->Fetch(); + + // we have to manually set the string for mutedate + time_t sqlTime = fields[0].GetUInt32(); + tm timeinfo; + char buffer[80]; + + // set it to string + localtime_r(&sqlTime, &timeinfo); + strftime(buffer, sizeof(buffer),"%Y-%m-%d %I:%M%p", &timeinfo); + + handler->PSendSysMessage(LANG_COMMAND_MUTEHISTORY_OUTPUT, buffer, fields[1].GetUInt32(), fields[2].GetCString(), fields[3].GetCString()); + } while (result->NextRow()); + return true; + } static bool HandleMovegensCommand(ChatHandler* handler, char const* /*args*/) { diff --git a/src/server/scripts/Commands/cs_quest.cpp b/src/server/scripts/Commands/cs_quest.cpp index dc75e0aedab..fb486128049 100644 --- a/src/server/scripts/Commands/cs_quest.cpp +++ b/src/server/scripts/Commands/cs_quest.cpp @@ -238,6 +238,17 @@ public: if (ReqOrRewMoney < 0) player->ModifyMoney(-ReqOrRewMoney); + if (sWorld->getBoolConfig(CONFIG_QUEST_ENABLE_QUEST_TRACKER)) // check if Quest Tracker is enabled + { + // prepare Quest Tracker datas + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_QUEST_TRACK_GM_COMPLETE); + stmt->setUInt32(0, quest->GetQuestId()); + stmt->setUInt32(1, player->GetGUIDLow()); + + // add to Quest Tracker + CharacterDatabase.Execute(stmt); + } + player->CompleteQuest(entry); return true; } diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_shazzrah.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_shazzrah.cpp index fcabf3d1b18..44c41a6be0f 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_shazzrah.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_shazzrah.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -16,33 +15,29 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Shazzrah -SD%Complete: 75 -SDComment: Teleport NYI -SDCategory: Molten Core -EndScriptData */ - -#include "ObjectMgr.h" #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "SpellScript.h" #include "molten_core.h" enum Spells { - SPELL_ARCANE_EXPLOSION = 19712, - SPELL_SHAZZRAH_CURSE = 19713, - SPELL_MAGIC_GROUNDING = 19714, - SPELL_COUNTERSPELL = 19715, + SPELL_ARCANE_EXPLOSION = 19712, + SPELL_SHAZZRAH_CURSE = 19713, + SPELL_MAGIC_GROUNDING = 19714, + SPELL_COUNTERSPELL = 19715, + SPELL_SHAZZRAH_GATE_DUMMY = 23138, // Teleports to and attacks a random target. + SPELL_SHAZZRAH_GATE = 23139, }; enum Events { - EVENT_ARCANE_EXPLOSION = 1, - EVENT_SHAZZRAH_CURSE = 2, - EVENT_MAGIC_GROUNDING = 3, - EVENT_COUNTERSPELL = 4, - EVENT_BLINK = 5, + EVENT_ARCANE_EXPLOSION = 1, + EVENT_ARCANE_EXPLOSION_TRIGGERED = 2, + EVENT_SHAZZRAH_CURSE = 3, + EVENT_MAGIC_GROUNDING = 4, + EVENT_COUNTERSPELL = 5, + EVENT_SHAZZRAH_GATE = 6, }; class boss_shazzrah : public CreatureScript @@ -52,9 +47,7 @@ class boss_shazzrah : public CreatureScript struct boss_shazzrahAI : public BossAI { - boss_shazzrahAI(Creature* creature) : BossAI(creature, BOSS_SHAZZRAH) - { - } + boss_shazzrahAI(Creature* creature) : BossAI(creature, BOSS_SHAZZRAH) { } void EnterCombat(Unit* target) override { @@ -63,7 +56,7 @@ class boss_shazzrah : public CreatureScript events.ScheduleEvent(EVENT_SHAZZRAH_CURSE, 10000); events.ScheduleEvent(EVENT_MAGIC_GROUNDING, 24000); events.ScheduleEvent(EVENT_COUNTERSPELL, 15000); - events.ScheduleEvent(EVENT_BLINK, 30000); + events.ScheduleEvent(EVENT_SHAZZRAH_GATE, 45000); } void UpdateAI(uint32 diff) override @@ -82,10 +75,14 @@ class boss_shazzrah : public CreatureScript { case EVENT_ARCANE_EXPLOSION: DoCastVictim(SPELL_ARCANE_EXPLOSION); - events.ScheduleEvent(EVENT_ARCANE_EXPLOSION, urand(5000, 9000)); + events.ScheduleEvent(EVENT_ARCANE_EXPLOSION, urand(4000, 7000)); + break; + // Triggered subsequent to using "Gate of Shazzrah". + case EVENT_ARCANE_EXPLOSION_TRIGGERED: + DoCastVictim(SPELL_ARCANE_EXPLOSION); break; case EVENT_SHAZZRAH_CURSE: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, -EVENT_SHAZZRAH_CURSE)) + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, -SPELL_SHAZZRAH_CURSE)) DoCast(target, SPELL_SHAZZRAH_CURSE); events.ScheduleEvent(EVENT_SHAZZRAH_CURSE, urand(25000, 30000)); break; @@ -97,16 +94,12 @@ class boss_shazzrah : public CreatureScript DoCastVictim(SPELL_COUNTERSPELL); events.ScheduleEvent(EVENT_COUNTERSPELL, urand(16000, 20000)); break; - case EVENT_BLINK: - // Teleporting him to a random player and casting Arcane Explosion after that. - // Blink is not working cause of LoS System we need to do this hardcoded. - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100.0f, true)) - { - DoTeleportTo(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()); - DoCast(target, SPELL_ARCANE_EXPLOSION); - DoResetThreat(); - } - events.ScheduleEvent(EVENT_BLINK, 45000); + case EVENT_SHAZZRAH_GATE: + DoResetThreat(); + DoCastAOE(SPELL_SHAZZRAH_GATE_DUMMY); + events.ScheduleEvent(EVENT_ARCANE_EXPLOSION_TRIGGERED, 2000); + events.RescheduleEvent(EVENT_ARCANE_EXPLOSION, urand(3000, 6000)); + events.ScheduleEvent(EVENT_SHAZZRAH_GATE, 45000); break; default: break; @@ -123,7 +116,58 @@ class boss_shazzrah : public CreatureScript } }; +// 23138 - Gate of Shazzrah +class spell_shazzrah_gate_dummy : public SpellScriptLoader +{ + public: + spell_shazzrah_gate_dummy() : SpellScriptLoader("spell_shazzrah_gate_dummy") { } + + class spell_shazzrah_gate_dummy_SpellScript : public SpellScript + { + PrepareSpellScript(spell_shazzrah_gate_dummy_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_SHAZZRAH_GATE)) + return false; + return true; + } + + void FilterTargets(std::list<WorldObject*>& targets) + { + if (targets.empty()) + return; + + WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); + targets.clear(); + targets.push_back(target); + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (Unit* target = GetHitUnit()) + { + target->CastSpell(GetCaster(), SPELL_SHAZZRAH_GATE, true); + if (Creature* creature = GetCaster()->ToCreature()) + creature->AI()->AttackStart(target); // Attack the target which caster will teleport to. + } + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_shazzrah_gate_dummy_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + OnEffectHitTarget += SpellEffectFn(spell_shazzrah_gate_dummy_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_shazzrah_gate_dummy_SpellScript(); + } +}; + void AddSC_boss_shazzrah() { new boss_shazzrah(); + new spell_shazzrah_gate_dummy(); } diff --git a/src/server/scripts/Northrend/isle_of_conquest.cpp b/src/server/scripts/Northrend/isle_of_conquest.cpp index 84541eb7b99..7d4c396f29e 100644 --- a/src/server/scripts/Northrend/isle_of_conquest.cpp +++ b/src/server/scripts/Northrend/isle_of_conquest.cpp @@ -73,6 +73,68 @@ class npc_four_car_garage : public CreatureScript } }; +enum Events +{ + EVENT_TALK = 1, + EVENT_DESPAWN +}; + +enum Texts +{ + SAY_ONBOARD = 0 +}; + +class npc_ioc_gunship_captain : public CreatureScript +{ + public: + npc_ioc_gunship_captain() : CreatureScript("npc_ioc_gunship_captain") { } + + struct npc_ioc_gunship_captainAI : public ScriptedAI + { + npc_ioc_gunship_captainAI(Creature* creature) : ScriptedAI(creature) { } + + void DoAction(int32 action) override + { + if (action == ACTION_GUNSHIP_READY) + { + DoCast(me, SPELL_SIMPLE_TELEPORT); + _events.ScheduleEvent(EVENT_TALK, 3000); + } + } + + void UpdateAI(uint32 diff) override + { + _events.Update(diff); + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_TALK: + _events.ScheduleEvent(EVENT_DESPAWN, 1000); + Talk(SAY_ONBOARD); + DoCast(me, SPELL_TELEPORT_VISUAL_ONLY); + break; + case EVENT_DESPAWN: + if (me->GetMap()->ToBattlegroundMap()) + if (Battleground* bgIoC = me->GetMap()->ToBattlegroundMap()->GetBG()) + bgIoC->DelCreature(BG_IC_NPC_GUNSHIP_CAPTAIN_1); + break; + default: + break; + } + } + } + + private: + EventMap _events; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return new npc_ioc_gunship_captainAI(creature); + } +}; + class spell_ioc_gunship_portal : public SpellScriptLoader { public: @@ -90,9 +152,28 @@ class spell_ioc_gunship_portal : public SpellScriptLoader void HandleScript(SpellEffIndex /*effIndex*/) { Player* caster = GetCaster()->ToPlayer(); - if (Battleground* bg = caster->GetBattleground()) - if (bg->GetTypeID(true) == BATTLEGROUND_IC) - bg->DoAction(1, caster->GetGUID()); + /* + * HACK: GetWorldLocation() returns real position and not transportposition. + * ServertoClient: SMSG_MOVE_TELEPORT (0x0B39) + * counter: 45 + * Tranpsort Guid: Full: xxxx Type: MOTransport Low: xxx + * Transport Position X: 0 Y: 0 Z: 0 O: 0 + * Position: X: 7.305609 Y: -0.095246 Z: 34.51022 O: 0 + */ + caster->TeleportTo(GetHitCreature()->GetWorldLocation(), TELE_TO_NOT_LEAVE_TRANSPORT); + /* + * HACK: This aura should be added by 20212 and 20213 but can't find any SMSG_SPELL_GO. Could't find their position. + * ServerToClient: SMSG_AURA_UPDATE (0x0072) + * [0] CasterGUID: Full: xxxxx Type: Unit Entry: 20212 Low: xxx + * [0] Flags: None (0) + * [0] Caster Level: 60 + * [0] Spell ID: 66656 + * [0] Charges: 0 + * [0] Effect Mask: 1 + * [0] Slot: 37 + * Guid: Full: xxxxx Type: Player2 Low: xxxxx + */ + caster->AddAura(SPELL_PARACHUTE, caster); } void Register() override @@ -107,11 +188,6 @@ class spell_ioc_gunship_portal : public SpellScriptLoader } }; -enum ParachuteIC -{ - SPELL_PARACHUTE_IC = 66657 -}; - class spell_ioc_parachute_ic : public SpellScriptLoader { public: @@ -124,7 +200,7 @@ class spell_ioc_parachute_ic : public SpellScriptLoader void HandleTriggerSpell(AuraEffect const* /*aurEff*/) { if (Player* target = GetTarget()->ToPlayer()) - if (target->m_movementInfo.GetFallTime() > 2000) + if (target->m_movementInfo.GetFallTime() > 2000 && !target->GetTransport()) target->CastSpell(target, SPELL_PARACHUTE_IC, true); } @@ -140,9 +216,31 @@ class spell_ioc_parachute_ic : public SpellScriptLoader } }; -enum Launch +class StartLaunchEvent : public BasicEvent { - SPELL_LAUNCH_NO_FALLING_DAMAGE = 66251 + public: + StartLaunchEvent(float x, float y, float z, uint32 lowGuid) : _x(x), _y(y), _z(z), _lowGuid(lowGuid) + { + } + + bool Execute(uint64 /*time*/, uint32 /*diff*/) + { + Player* player = sObjectMgr->GetPlayerByLowGUID(_lowGuid); + if (!player || !player->GetVehicle()) + return true; + + player->AddAura(SPELL_LAUNCH_NO_FALLING_DAMAGE, player); // prevents falling damage + float speedZ = 10.0f; + float dist = player->GetExactDist2d(_x, _y); + + player->ExitVehicle(); + player->GetMotionMaster()->MoveJump(_x, _y, _z, dist, speedZ); + return true; + } + + private: + float _x, _y, _z; + uint32 _lowGuid; }; class spell_ioc_launch : public SpellScriptLoader @@ -154,34 +252,20 @@ class spell_ioc_launch : public SpellScriptLoader { PrepareSpellScript(spell_ioc_launch_SpellScript); - void HandleScript(SpellEffIndex /*effIndex*/) - { - if (Player* player = GetHitPlayer()) - player->AddAura(SPELL_LAUNCH_NO_FALLING_DAMAGE, player); // prevents falling damage - } - void Launch() { - WorldLocation const* const position = GetExplTargetDest(); - - if (Player* player = GetHitPlayer()) - { - player->ExitVehicle(); - - // A better research is needed - // There is no spell for this, the following calculation was based on void Spell::CalculateJumpSpeeds - - float speedZ = 10.0f; - float dist = position->GetExactDist2d(player->GetPositionX(), player->GetPositionY()); - float speedXY = dist; - - player->GetMotionMaster()->MoveJump(position->GetPositionX(), position->GetPositionY(), position->GetPositionZ(), speedXY, speedZ); - } + if (!GetCaster()->ToCreature() || !GetExplTargetDest()) + return; + + float x, y, z; + x = GetExplTargetDest()->GetPositionX(); + y = GetExplTargetDest()->GetPositionY(); + z = GetExplTargetDest()->GetPositionZ(); + GetCaster()->ToCreature()->m_Events.AddEvent(new StartLaunchEvent(x, y, z, GetHitPlayer()->GetGUIDLow()), GetCaster()->ToCreature()->m_Events.CalculateTime(2500)); } void Register() override { - OnEffectHitTarget += SpellEffectFn(spell_ioc_launch_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_FORCE_CAST); AfterHit += SpellHitFn(spell_ioc_launch_SpellScript::Launch); } }; @@ -195,6 +279,7 @@ class spell_ioc_launch : public SpellScriptLoader void AddSC_isle_of_conquest() { new npc_four_car_garage(); + new npc_ioc_gunship_captain(); new spell_ioc_gunship_portal(); new spell_ioc_parachute_ic(); new spell_ioc_launch(); diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 225920aa2dc..a774a8a7db7 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -3721,6 +3721,314 @@ public: } }; +enum RequiredMixologySpells +{ + SPELL_MIXOLOGY = 53042, + // Flasks + SPELL_FLASK_OF_THE_FROST_WYRM = 53755, + SPELL_FLASK_OF_STONEBLOOD = 53758, + SPELL_FLASK_OF_ENDLESS_RAGE = 53760, + SPELL_FLASK_OF_PURE_MOJO = 54212, + SPELL_LESSER_FLASK_OF_RESISTANCE = 62380, + SPELL_LESSER_FLASK_OF_TOUGHNESS = 53752, + SPELL_FLASK_OF_BLINDING_LIGHT = 28521, + SPELL_FLASK_OF_CHROMATIC_WONDER = 42735, + SPELL_FLASK_OF_FORTIFICATION = 28518, + SPELL_FLASK_OF_MIGHTY_RESTORATION = 28519, + SPELL_FLASK_OF_PURE_DEATH = 28540, + SPELL_FLASK_OF_RELENTLESS_ASSAULT = 28520, + SPELL_FLASK_OF_CHROMATIC_RESISTANCE = 17629, + SPELL_FLASK_OF_DISTILLED_WISDOM = 17627, + SPELL_FLASK_OF_SUPREME_POWER = 17628, + SPELL_FLASK_OF_THE_TITANS = 17626, + // Elixirs + SPELL_ELIXIR_OF_MIGHTY_AGILITY = 28497, + SPELL_ELIXIR_OF_ACCURACY = 60340, + SPELL_ELIXIR_OF_DEADLY_STRIKES = 60341, + SPELL_ELIXIR_OF_MIGHTY_DEFENSE = 60343, + SPELL_ELIXIR_OF_EXPERTISE = 60344, + SPELL_ELIXIR_OF_ARMOR_PIERCING = 60345, + SPELL_ELIXIR_OF_LIGHTNING_SPEED = 60346, + SPELL_ELIXIR_OF_MIGHTY_FORTITUDE = 53751, + SPELL_ELIXIR_OF_MIGHTY_MAGEBLOOD = 53764, + SPELL_ELIXIR_OF_MIGHTY_STRENGTH = 53748, + SPELL_ELIXIR_OF_MIGHTY_TOUGHTS = 60347, + SPELL_ELIXIR_OF_PROTECTION = 53763, + SPELL_ELIXIR_OF_SPIRIT = 53747, + SPELL_GURUS_ELIXIR = 53749, + SPELL_SHADOWPOWER_ELIXIR = 33721, + SPELL_WRATH_ELIXIR = 53746, + SPELL_ELIXIR_OF_EMPOWERMENT = 28514, + SPELL_ELIXIR_OF_MAJOR_MAGEBLOOD = 28509, + SPELL_ELIXIR_OF_MAJOR_SHADOW_POWER = 28503, + SPELL_ELIXIR_OF_MAJOR_DEFENSE = 28502, + SPELL_FEL_STRENGTH_ELIXIR = 38954, + SPELL_ELIXIR_OF_IRONSKIN = 39628, + SPELL_ELIXIR_OF_MAJOR_AGILITY = 54494, + SPELL_ELIXIR_OF_DRAENIC_WISDOM = 39627, + SPELL_ELIXIR_OF_MAJOR_FIREPOWER = 28501, + SPELL_ELIXIR_OF_MAJOR_FROST_POWER = 28493, + SPELL_EARTHEN_ELIXIR = 39626, + SPELL_ELIXIR_OF_MASTERY = 33726, + SPELL_ELIXIR_OF_HEALING_POWER = 28491, + SPELL_ELIXIR_OF_MAJOR_FORTITUDE = 39625, + SPELL_ELIXIR_OF_MAJOR_STRENGTH = 28490, + SPELL_ADEPTS_ELIXIR = 54452, + SPELL_ONSLAUGHT_ELIXIR = 33720, + SPELL_MIGHTY_TROLLS_BLOOD_ELIXIR = 24361, + SPELL_GREATER_ARCANE_ELIXIR = 17539, + SPELL_ELIXIR_OF_THE_MONGOOSE = 17538, + SPELL_ELIXIR_OF_BRUTE_FORCE = 17537, + SPELL_ELIXIR_OF_SAGES = 17535, + SPELL_ELIXIR_OF_SUPERIOR_DEFENSE = 11348, + SPELL_ELIXIR_OF_DEMONSLAYING = 11406, + SPELL_ELIXIR_OF_GREATER_FIREPOWER = 26276, + SPELL_ELIXIR_OF_SHADOW_POWER = 11474, + SPELL_MAGEBLOOD_ELIXIR = 24363, + SPELL_ELIXIR_OF_GIANTS = 11405, + SPELL_ELIXIR_OF_GREATER_AGILITY = 11334, + SPELL_ARCANE_ELIXIR = 11390, + SPELL_ELIXIR_OF_GREATER_INTELLECT = 11396, + SPELL_ELIXIR_OF_GREATER_DEFENSE = 11349, + SPELL_ELIXIR_OF_FROST_POWER = 21920, + SPELL_ELIXIR_OF_AGILITY = 11328, + SPELL_MAJOR_TROLLS_BLLOOD_ELIXIR = 3223, + SPELL_ELIXIR_OF_FORTITUDE = 3593, + SPELL_ELIXIR_OF_OGRES_STRENGTH = 3164, + SPELL_ELIXIR_OF_FIREPOWER = 7844, + SPELL_ELIXIR_OF_LESSER_AGILITY = 3160, + SPELL_ELIXIR_OF_DEFENSE = 3220, + SPELL_STRONG_TROLLS_BLOOD_ELIXIR = 3222, + SPELL_ELIXIR_OF_MINOR_ACCURACY = 63729, + SPELL_ELIXIR_OF_WISDOM = 3166, + SPELL_ELIXIR_OF_GIANTH_GROWTH = 8212, + SPELL_ELIXIR_OF_MINOR_AGILITY = 2374, + SPELL_ELIXIR_OF_MINOR_FORTITUDE = 2378, + SPELL_WEAK_TROLLS_BLOOD_ELIXIR = 3219, + SPELL_ELIXIR_OF_LIONS_STRENGTH = 2367, + SPELL_ELIXIR_OF_MINOR_DEFENSE = 673 +}; + +class spell_gen_mixology_bonus : public SpellScriptLoader +{ +public: + spell_gen_mixology_bonus() : SpellScriptLoader("spell_gen_mixology_bonus") { } + + class spell_gen_mixology_bonus_AuraScript : public AuraScript + { + PrepareAuraScript(spell_gen_mixology_bonus_AuraScript); + + public: + spell_gen_mixology_bonus_AuraScript() + { + bonus = 0; + } + + private: + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_MIXOLOGY)) + return false; + return true; + } + + bool Load() override + { + return GetCaster() && GetCaster()->GetTypeId() == TYPEID_PLAYER; + } + + void SetBonusValueForEffect(SpellEffIndex effIndex, int32 value, AuraEffect const* aurEff) + { + if (aurEff->GetEffIndex() == uint32(effIndex)) + bonus = value; + } + + void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/) + { + if (GetCaster()->HasAura(SPELL_MIXOLOGY) && GetCaster()->HasSpell(GetSpellInfo()->Effects[EFFECT_0].TriggerSpell)) + { + switch (GetId()) + { + case SPELL_WEAK_TROLLS_BLOOD_ELIXIR: + case SPELL_MAGEBLOOD_ELIXIR: + bonus = amount; + break; + case SPELL_ELIXIR_OF_FROST_POWER: + case SPELL_LESSER_FLASK_OF_TOUGHNESS: + case SPELL_LESSER_FLASK_OF_RESISTANCE: + bonus = CalculatePct(amount, 80); + break; + case SPELL_ELIXIR_OF_MINOR_DEFENSE: + case SPELL_ELIXIR_OF_LIONS_STRENGTH: + case SPELL_ELIXIR_OF_MINOR_AGILITY: + case SPELL_MAJOR_TROLLS_BLLOOD_ELIXIR: + case SPELL_ELIXIR_OF_SHADOW_POWER: + case SPELL_ELIXIR_OF_BRUTE_FORCE: + case SPELL_MIGHTY_TROLLS_BLOOD_ELIXIR: + case SPELL_ELIXIR_OF_GREATER_FIREPOWER: + case SPELL_ONSLAUGHT_ELIXIR: + case SPELL_EARTHEN_ELIXIR: + case SPELL_ELIXIR_OF_MAJOR_AGILITY: + case SPELL_FLASK_OF_THE_TITANS: + case SPELL_FLASK_OF_RELENTLESS_ASSAULT: + case SPELL_FLASK_OF_STONEBLOOD: + case SPELL_ELIXIR_OF_MINOR_ACCURACY: + bonus = CalculatePct(amount, 50); + break; + case SPELL_ELIXIR_OF_PROTECTION: + bonus = 280; + break; + case SPELL_ELIXIR_OF_MAJOR_DEFENSE: + bonus = 200; + break; + case SPELL_ELIXIR_OF_GREATER_DEFENSE: + case SPELL_ELIXIR_OF_SUPERIOR_DEFENSE: + bonus = 140; + break; + case SPELL_ELIXIR_OF_FORTITUDE: + bonus = 100; + break; + case SPELL_FLASK_OF_ENDLESS_RAGE: + bonus = 82; + break; + case SPELL_ELIXIR_OF_DEFENSE: + bonus = 70; + break; + case SPELL_ELIXIR_OF_DEMONSLAYING: + bonus = 50; + break; + case SPELL_FLASK_OF_THE_FROST_WYRM: + bonus = 47; + break; + case SPELL_WRATH_ELIXIR: + bonus = 32; + break; + case SPELL_ELIXIR_OF_MAJOR_FROST_POWER: + case SPELL_ELIXIR_OF_MAJOR_FIREPOWER: + case SPELL_ELIXIR_OF_MAJOR_SHADOW_POWER: + bonus = 29; + break; + case SPELL_ELIXIR_OF_MIGHTY_TOUGHTS: + bonus = 27; + break; + case SPELL_FLASK_OF_SUPREME_POWER: + case SPELL_FLASK_OF_BLINDING_LIGHT: + case SPELL_FLASK_OF_PURE_DEATH: + case SPELL_SHADOWPOWER_ELIXIR: + bonus = 23; + break; + case SPELL_ELIXIR_OF_MIGHTY_AGILITY: + case SPELL_FLASK_OF_DISTILLED_WISDOM: + case SPELL_ELIXIR_OF_SPIRIT: + case SPELL_ELIXIR_OF_MIGHTY_STRENGTH: + case SPELL_FLASK_OF_PURE_MOJO: + case SPELL_ELIXIR_OF_ACCURACY: + case SPELL_ELIXIR_OF_DEADLY_STRIKES: + case SPELL_ELIXIR_OF_MIGHTY_DEFENSE: + case SPELL_ELIXIR_OF_EXPERTISE: + case SPELL_ELIXIR_OF_ARMOR_PIERCING: + case SPELL_ELIXIR_OF_LIGHTNING_SPEED: + bonus = 20; + break; + case SPELL_FLASK_OF_CHROMATIC_RESISTANCE: + bonus = 17; + break; + case SPELL_ELIXIR_OF_MINOR_FORTITUDE: + case SPELL_ELIXIR_OF_MAJOR_STRENGTH: + bonus = 15; + break; + case SPELL_FLASK_OF_MIGHTY_RESTORATION: + bonus = 13; + break; + case SPELL_ARCANE_ELIXIR: + bonus = 12; + break; + case SPELL_ELIXIR_OF_GREATER_AGILITY: + case SPELL_ELIXIR_OF_GIANTS: + bonus = 11; + break; + case SPELL_ELIXIR_OF_AGILITY: + case SPELL_ELIXIR_OF_GREATER_INTELLECT: + case SPELL_ELIXIR_OF_SAGES: + case SPELL_ELIXIR_OF_IRONSKIN: + case SPELL_ELIXIR_OF_MIGHTY_MAGEBLOOD: + bonus = 10; + break; + case SPELL_ELIXIR_OF_HEALING_POWER: + bonus = 9; + break; + case SPELL_ELIXIR_OF_DRAENIC_WISDOM: + case SPELL_GURUS_ELIXIR: + bonus = 8; + break; + case SPELL_ELIXIR_OF_FIREPOWER: + case SPELL_ELIXIR_OF_MAJOR_MAGEBLOOD: + case SPELL_ELIXIR_OF_MASTERY: + bonus = 6; + break; + case SPELL_ELIXIR_OF_LESSER_AGILITY: + case SPELL_ELIXIR_OF_OGRES_STRENGTH: + case SPELL_ELIXIR_OF_WISDOM: + case SPELL_ELIXIR_OF_THE_MONGOOSE: + bonus = 5; + break; + case SPELL_STRONG_TROLLS_BLOOD_ELIXIR: + case SPELL_FLASK_OF_CHROMATIC_WONDER: + bonus = 4; + break; + case SPELL_ELIXIR_OF_EMPOWERMENT: + bonus = -10; + break; + case SPELL_ADEPTS_ELIXIR: + SetBonusValueForEffect(EFFECT_0, 13, aurEff); + SetBonusValueForEffect(EFFECT_1, 13, aurEff); + SetBonusValueForEffect(EFFECT_2, 8, aurEff); + break; + case SPELL_ELIXIR_OF_MIGHTY_FORTITUDE: + SetBonusValueForEffect(EFFECT_0, 160, aurEff); + break; + case SPELL_ELIXIR_OF_MAJOR_FORTITUDE: + SetBonusValueForEffect(EFFECT_0, 116, aurEff); + SetBonusValueForEffect(EFFECT_1, 6, aurEff); + break; + case SPELL_FEL_STRENGTH_ELIXIR: + SetBonusValueForEffect(EFFECT_0, 40, aurEff); + SetBonusValueForEffect(EFFECT_1, 40, aurEff); + break; + case SPELL_FLASK_OF_FORTIFICATION: + SetBonusValueForEffect(EFFECT_0, 210, aurEff); + SetBonusValueForEffect(EFFECT_1, 5, aurEff); + break; + case SPELL_GREATER_ARCANE_ELIXIR: + SetBonusValueForEffect(EFFECT_0, 19, aurEff); + SetBonusValueForEffect(EFFECT_1, 19, aurEff); + SetBonusValueForEffect(EFFECT_2, 5, aurEff); + break; + case SPELL_ELIXIR_OF_GIANTH_GROWTH: + SetBonusValueForEffect(EFFECT_0, 5, aurEff); + break; + default: + TC_LOG_ERROR("spells", "SpellId %u couldn't be processed in spell_gen_mixology_bonus", GetId()); + break; + } + amount += bonus; + } + } + + int32 bonus; + + void Register() override + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_mixology_bonus_AuraScript::CalculateAmount, EFFECT_ALL, SPELL_AURA_ANY); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_gen_mixology_bonus_AuraScript(); + } +}; + void AddSC_generic_spell_scripts() { new spell_gen_absorb0_hitlimit1(); @@ -3805,4 +4113,5 @@ void AddSC_generic_spell_scripts() new spell_gen_eject_all_passengers(); new spell_gen_gm_freeze(); new spell_gen_stand(); + new spell_gen_mixology_bonus(); } diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp index 93828865a16..311c37e085f 100644 --- a/src/server/scripts/Spells/spell_quest.cpp +++ b/src/server/scripts/Spells/spell_quest.cpp @@ -2446,6 +2446,33 @@ public: } }; +class spell_q28813_set_health_random : public SpellScriptLoader +{ +public: + spell_q28813_set_health_random() : SpellScriptLoader("spell_q28813_set_health_random") { } + + class spell_q28813_set_health_random_SpellScript : public SpellScript + { + PrepareSpellScript(spell_q28813_set_health_random_SpellScript); + + void HandleDummyEffect() + { + Unit* caster = GetCaster(); + caster->SetHealth(caster->CountPctFromMaxHealth(urand(3, 5)*10)); + } + + void Register() override + { + OnCast += SpellCastFn(spell_q28813_set_health_random_SpellScript::HandleDummyEffect); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_q28813_set_health_random_SpellScript(); + } +}; + void AddSC_quest_spell_scripts() { new spell_q55_sacred_cleansing(); @@ -2505,4 +2532,5 @@ void AddSC_quest_spell_scripts() new spell_q14100_q14111_make_player_destroy_totems(); new spell_q10929_fumping(); new spell_q28813_get_our_boys_back_dummy(); + new spell_q28813_set_health_random(); } |