Merge branch 'master' into 4.3.4
Conflicts: src/server/game/Server/WorldSocket.cpp src/server/game/Spells/SpellEffects.cpp src/server/scripts/Kalimdor/zone_darkshore.cpp src/server/scripts/Kalimdor/zone_feralas.cpp src/server/scripts/Spells/spell_dk.cpp src/server/scripts/Spells/spell_generic.cpp
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
SET @OGUID := 100499;
|
||||
|
||||
DELETE FROM `gameobject` WHERE `guid` BETWEEN @OGUID+0 AND @OGUID+7;
|
||||
INSERT INTO `gameobject` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`) VALUES
|
||||
(@OGUID+0, 195624, 0, 1, 1, 1483.641, 187.9667, -62.29154, -1.178734, 0, 0, -0.004363404, 0.9999905, 120, 255, 1), -- 195624 (Area: 0)
|
||||
(@OGUID+1, 195626, 0, 1, 1, 1547.33, 276.8282, -62.28028, -1.626545, 0, 0, -0.004363404, 0.9999905, 120, 255, 1), -- 195626 (Area: 0)
|
||||
(@OGUID+2, 195628, 0, 1, 1, 1644.318, 204.0325, -62.27996, -0.1478646, 0, 0, -0.004363404, 0.9999905, 120, 255, 1), -- 195628 (Area: 0)
|
||||
(@OGUID+3, 195627, 0, 1, 1, 1644.843, 276.1801, -62.2799, 0.8283948, 0, 0, -0.004363404, 0.9999905, 120, 255, 1), -- 195627 (Area: 0)
|
||||
(@OGUID+4, 195625, 0, 1, 1, 1547.062, 204.5494, -62.28075, 0.7760351, 0, 0, -0.004363404, 0.9999905, 120, 255, 1), -- 195625 (Area: 0)
|
||||
(@OGUID+5, 195629, 0, 1, 1, 1554.973, 235.1078, -43.20095, 0.2524359, 0, 0, -0.004363404, 0.9999905, 120, 255, 1), -- 195629 (Area: 0)
|
||||
(@OGUID+6, 195618, 0, 1, 1, -8572.362, 552.6837, 102.0039, -2.617989, 0, 0, 0.944089, -0.3296907, 120, 255, 1), -- 195618 (Area: 0)
|
||||
(@OGUID+7, 195610, 0, 1, 1, -9003.499, 860.5499, 105.8766, -1.213004, 0, 0, 0.944089, -0.3296907, 120, 255, 1); -- 195610 (Area: 0)
|
||||
@@ -0,0 +1,3 @@
|
||||
UPDATE `spell_script_names` SET `ScriptName`='spell_ioc_gunship_portal' WHERE `ScriptName`='spell_gen_gunship_portal';
|
||||
UPDATE `spell_script_names` SET `ScriptName`='spell_ioc_parachute_ic' WHERE `ScriptName`='spell_gen_parachute_ic';
|
||||
UPDATE `spell_script_names` SET `ScriptName`='spell_ioc_launch' WHERE `ScriptName`='spell_gen_launch';
|
||||
@@ -0,0 +1 @@
|
||||
UPDATE `creature` SET `modelid`=14515 WHERE `id`=21060; -- Enraged Air Spirit
|
||||
@@ -0,0 +1,2 @@
|
||||
--
|
||||
UPDATE `gossip_menu_option` SET `action_menu_id`=1221 WHERE `menu_id`=1297 AND `id`=3 OR `menu_id`=1294 AND `id`=2;
|
||||
@@ -0,0 +1,4 @@
|
||||
-- Update conditions for Gart Mistrunner gossip
|
||||
UPDATE `conditions` SET `ConditionValue1`=511 WHERE `SourceTypeOrReferenceId`=14 AND `SourceGroup`=4644 AND `SourceEntry`=5717;
|
||||
UPDATE `conditions` SET `ConditionValue1`=1024 WHERE `SourceTypeOrReferenceId`=14 AND `SourceGroup`=4644 AND `SourceEntry`=5716;
|
||||
UPDATE `conditions` SET `ConditionValue1`=1024 WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=4644;
|
||||
@@ -0,0 +1,3 @@
|
||||
DELETE FROM spell_script_names WHERE spell_id=-43265;
|
||||
INSERT INTO spell_script_names VALUES
|
||||
(-43265, 'spell_dk_death_and_decay');
|
||||
@@ -0,0 +1,12 @@
|
||||
-- Argus Shadow Mage SAI
|
||||
SET @ENTRY := 2318;
|
||||
UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=@ENTRY;
|
||||
DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY 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
|
||||
(@ENTRY,0,0,0,4,0,100,0,0,0,0,0,22,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Argus Shadow Mage - On Aggro - Set Event Phase 1"),
|
||||
(@ENTRY,0,1,0,0,1,100,0,0,0,3500,4900,11,20816,64,0,0,0,0,2,0,0,0,0,0,0,0,"Argus Shadow Mage - In Combat CMC - Cast 'Shadow Bolt' (Phase 1)"),
|
||||
(@ENTRY,0,2,0,2,0,100,1,0,30,0,0,22,2,0,0,0,0,0,1,0,0,0,0,0,0,0,"Argus Shadow Mage - Between 0-30% Health - Set Event Phase 2"),
|
||||
(@ENTRY,0,3,4,0,2,100,1,0,0,0,0,11,4063,1,0,0,0,0,1,0,0,0,0,0,0,0,"Argus Shadow Mage - In Combat - Cast 'Argus Shadow Mage Transform' (Phase 2) (No Repeat)"),
|
||||
(@ENTRY,0,4,5,61,2,100,0,0,0,0,0,21,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Argus Shadow Mage - In Combat - Enable Combat Movement"),
|
||||
(@ENTRY,0,5,0,61,2,100,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,"Argus Shadow Mage - In Combat - Say Line 0"),
|
||||
(@ENTRY,0,6,0,23,2,100,0,4063,0,0,0,22,1,0,0,0,0,0,1,0,0,0,0,0,0,0,"Argus Shadow Mage - Missing Aura - Set Event Phase 1");
|
||||
@@ -0,0 +1,6 @@
|
||||
-- Fallen Ranger SAI
|
||||
SET @ENTRY := 16314;
|
||||
UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=@ENTRY;
|
||||
DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY 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
|
||||
(@ENTRY,0,0,0,0,0,100,0,0,0,3400,4800,11,28993,64,0,0,0,0,2,0,0,0,0,0,0,0,"Fallen Ranger - In Combat CMC - Cast 'Banshee Wail'");
|
||||
@@ -0,0 +1,4 @@
|
||||
--
|
||||
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=22 AND `SourceGroup`=2 AND `SourceEntry`=6550 AND `SourceId`=0;
|
||||
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
|
||||
(22,2,6550,0,0,29,1,6550,100,0,1,0,0,'','Execute SAI if only there is no Mana Surge in vicinity');
|
||||
@@ -0,0 +1,14 @@
|
||||
SET @ENTRY := 8612;
|
||||
|
||||
-- Add missing gossip (by Malcrom)
|
||||
DELETE FROM `gossip_menu` WHERE `entry`=1405;
|
||||
INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES (1405,2039);
|
||||
UPDATE `creature_template` SET `gossip_menu_id`=1405 WHERE entry=@ENTRY;
|
||||
|
||||
-- SAI (by Rushor)
|
||||
UPDATE `creature_template` SET `AIName`='SmartAI', `ScriptName`='' WHERE `entry`=@ENTRY;
|
||||
DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY 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
|
||||
(@ENTRY,0,0,1,64,0,100,0,0,0,0,0,33,8612,0,0,0,0,0,7,0,0,0,0,0,0,0,"Screecher Spirit - On Gossip Hello - Quest Credit 'Screecher Spirits'"),
|
||||
(@ENTRY,0,1,2,61,0,100,0,0,0,0,0,18,33554432,0,0,0,0,0,1,0,0,0,0,0,0,0,"Screecher Spirit - On Gossip Hello - Set Flag Not Selectable"),
|
||||
(@ENTRY,0,2,0,61,0,100,0,0,0,0,0,41,3000,0,0,0,0,0,1,0,0,0,0,0,0,0,"Screecher Spirit - On Gossip Hello - Despawn In 3000 ms");
|
||||
@@ -710,10 +710,21 @@ void Battleground::RewardHonorToTeam(uint32 Honor, uint32 TeamID)
|
||||
|
||||
void Battleground::RewardReputationToTeam(uint32 faction_id, uint32 Reputation, uint32 TeamID)
|
||||
{
|
||||
if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction_id))
|
||||
for (BattlegroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
if (Player* player = _GetPlayerForTeam(TeamID, itr, "RewardReputationToTeam"))
|
||||
player->GetReputationMgr().ModifyReputation(factionEntry, Reputation);
|
||||
FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction_id);
|
||||
if (!factionEntry)
|
||||
return;
|
||||
|
||||
for (BattlegroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
{
|
||||
Player* player = _GetPlayerForTeam(TeamID, itr, "RewardReputationToTeam");
|
||||
if (!player)
|
||||
continue;
|
||||
|
||||
uint32 repGain = Reputation;
|
||||
AddPct(repGain, player->GetTotalAuraModifier(SPELL_AURA_MOD_REPUTATION_GAIN));
|
||||
AddPct(repGain, player->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_FACTION_REPUTATION_GAIN, faction_id));
|
||||
player->GetReputationMgr().ModifyReputation(factionEntry, repGain);
|
||||
}
|
||||
}
|
||||
|
||||
void Battleground::UpdateWorldState(uint32 Field, uint32 Value)
|
||||
|
||||
@@ -2852,27 +2852,26 @@ bool Unit::IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled, bool skipAu
|
||||
// We don't do loop here to explicitly show that melee spell is excluded.
|
||||
// Maybe later some special spells will be excluded too.
|
||||
|
||||
// if skipInstant then instant spells shouldn't count as being cast
|
||||
if (skipInstant && m_currentSpells[CURRENT_GENERIC_SPELL] && !m_currentSpells[CURRENT_GENERIC_SPELL]->GetCastTime())
|
||||
return false;
|
||||
|
||||
// generic spells are cast when they are not finished and not delayed
|
||||
if (m_currentSpells[CURRENT_GENERIC_SPELL] &&
|
||||
(m_currentSpells[CURRENT_GENERIC_SPELL]->getState() != SPELL_STATE_FINISHED) &&
|
||||
(withDelayed || m_currentSpells[CURRENT_GENERIC_SPELL]->getState() != SPELL_STATE_DELAYED))
|
||||
{
|
||||
if (!isAutoshoot || !(m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->AttributesEx2 & SPELL_ATTR2_NOT_RESET_AUTO_ACTIONS))
|
||||
return true;
|
||||
if (!skipInstant || m_currentSpells[CURRENT_GENERIC_SPELL]->GetCastTime())
|
||||
{
|
||||
if (!isAutoshoot || !(m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->AttributesEx2 & SPELL_ATTR2_NOT_RESET_AUTO_ACTIONS))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// channeled spells may be delayed, but they are still considered cast
|
||||
else if (!skipChanneled && m_currentSpells[CURRENT_CHANNELED_SPELL] &&
|
||||
if (!skipChanneled && m_currentSpells[CURRENT_CHANNELED_SPELL] &&
|
||||
(m_currentSpells[CURRENT_CHANNELED_SPELL]->getState() != SPELL_STATE_FINISHED))
|
||||
{
|
||||
if (!isAutoshoot || !(m_currentSpells[CURRENT_CHANNELED_SPELL]->m_spellInfo->AttributesEx2 & SPELL_ATTR2_NOT_RESET_AUTO_ACTIONS))
|
||||
return true;
|
||||
}
|
||||
// autorepeat spells may be finished or delayed, but they are still considered cast
|
||||
else if (!skipAutorepeat && m_currentSpells[CURRENT_AUTOREPEAT_SPELL])
|
||||
if (!skipAutorepeat && m_currentSpells[CURRENT_AUTOREPEAT_SPELL])
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@@ -3286,7 +3285,7 @@ void Unit::_RemoveNoStackAurasDueToAura(Aura* aura)
|
||||
Spell::SendCastResult(caster->ToPlayer(), aura->GetSpellInfo(), 1, SPELL_FAILED_AURA_BOUNCED);
|
||||
}
|
||||
|
||||
RemoveAura(aura);
|
||||
aura->Remove();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
#include "Log.h"
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
struct ServerPktHeader
|
||||
{
|
||||
/**
|
||||
@@ -56,4 +58,6 @@ struct ServerPktHeader
|
||||
uint8 header[5];
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -212,28 +212,40 @@ void WorldSocket::AsyncWrite(WorldPacket const& packet)
|
||||
TC_LOG_TRACE("network.opcode", "S->C: %s %s", (_worldSession ? _worldSession->GetPlayerInfo() : GetRemoteIpAddress()).c_str(), GetOpcodeNameForLogging(pkt->GetOpcode()).c_str());
|
||||
|
||||
ServerPktHeader header(pkt->size() + 2, pkt->GetOpcode());
|
||||
_authCrypt.EncryptSend((uint8*)header.header, header.getHeaderLength());
|
||||
|
||||
auto data = new char[header.getHeaderLength() + pkt->size()];
|
||||
std::memcpy(data, (char*)header.header, header.getHeaderLength());
|
||||
std::vector<uint8> data(header.getHeaderLength() + pkt->size());
|
||||
std::memcpy(data.data(), header.header, header.getHeaderLength());
|
||||
|
||||
if (!pkt->empty())
|
||||
std::memcpy(data + header.getHeaderLength(), (char const*)pkt->contents(), pkt->size());
|
||||
std::memcpy(&data[header.getHeaderLength()], pkt->contents(), pkt->size());
|
||||
|
||||
// Use a shared_ptr here to prevent leaking memory after the async operation has completed
|
||||
std::shared_ptr<char> buffer(data, [=](char* _b)
|
||||
{
|
||||
delete[] _b; // Ensure that the data is deleted as an array
|
||||
});
|
||||
std::lock_guard<std::mutex> guard(_writeLock);
|
||||
|
||||
bool needsWriteStart = _writeQueue.empty();
|
||||
_authCrypt.EncryptSend(data.data(), header.getHeaderLength());
|
||||
|
||||
_writeQueue.push(std::move(data));
|
||||
|
||||
if (needsWriteStart)
|
||||
AsyncWrite(_writeQueue.front());
|
||||
}
|
||||
|
||||
void WorldSocket::AsyncWrite(std::vector<uint8> const& data)
|
||||
{
|
||||
auto self(shared_from_this());
|
||||
|
||||
boost::asio::async_write(_socket, boost::asio::buffer(buffer.get(), header.getHeaderLength() + pkt->size()), [this, self, buffer](boost::system::error_code error, std::size_t /*length*/)
|
||||
boost::asio::async_write(_socket, boost::asio::buffer(data), [this, self](boost::system::error_code error, std::size_t /*length*/)
|
||||
{
|
||||
if (error)
|
||||
if (!error)
|
||||
{
|
||||
_socket.close();
|
||||
std::lock_guard<std::mutex> deleteGuard(_writeLock);
|
||||
|
||||
_writeQueue.pop();
|
||||
|
||||
if (!_writeQueue.empty())
|
||||
AsyncWrite(_writeQueue.front());
|
||||
}
|
||||
else
|
||||
_socket.close();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -19,15 +19,16 @@
|
||||
#ifndef __WORLDSOCKET_H__
|
||||
#define __WORLDSOCKET_H__
|
||||
|
||||
#include <memory>
|
||||
#include <chrono>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/streambuf.hpp>
|
||||
#include "Common.h"
|
||||
#include "WorldPacketCrypt.h"
|
||||
#include "Util.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include <memory>
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/streambuf.hpp>
|
||||
|
||||
using boost::asio::ip::tcp;
|
||||
|
||||
@@ -68,10 +69,13 @@ private:
|
||||
|
||||
void AsyncReadHeader();
|
||||
void AsyncReadData(size_t dataSize);
|
||||
void AsyncWrite(std::vector<uint8> const& data);
|
||||
|
||||
tcp::socket _socket;
|
||||
|
||||
char _readBuffer[4096];
|
||||
std::mutex _writeLock;
|
||||
std::queue<std::vector<uint8> > _writeQueue;
|
||||
|
||||
uint32 _authSeed;
|
||||
WorldPacketCrypt _authCrypt;
|
||||
|
||||
@@ -5465,13 +5465,6 @@ void AuraEffect::HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const
|
||||
target->DealDamage(target, damage, NULL, NODAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
|
||||
break;
|
||||
}
|
||||
// Death and Decay
|
||||
if (GetSpellInfo()->SpellFamilyFlags[0] & 0x20)
|
||||
{
|
||||
if (caster)
|
||||
target->CastCustomSpell(target, 52212, &m_amount, NULL, NULL, true, 0, this, caster->GetGUID());
|
||||
break;
|
||||
}
|
||||
// Blood of the North
|
||||
// Reaping
|
||||
// Death Rune Mastery
|
||||
|
||||
@@ -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,28 +15,34 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Maiden_of_Virtue
|
||||
SD%Complete: 100
|
||||
SDComment:
|
||||
SDCategory: Karazhan
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "karazhan.h"
|
||||
|
||||
enum MaidenOfVirtue
|
||||
enum Spells
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_REPENTANCE = 2,
|
||||
SAY_DEATH = 3,
|
||||
SPELL_REPENTANCE = 29511,
|
||||
SPELL_HOLYFIRE = 29522,
|
||||
SPELL_HOLYWRATH = 32445,
|
||||
SPELL_HOLYGROUND = 29512,
|
||||
SPELL_BERSERK = 26662
|
||||
};
|
||||
|
||||
SPELL_REPENTANCE = 29511,
|
||||
SPELL_HOLYFIRE = 29522,
|
||||
SPELL_HOLYWRATH = 32445,
|
||||
SPELL_HOLYGROUND = 29512,
|
||||
SPELL_BERSERK = 26662,
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_REPENTANCE = 2,
|
||||
SAY_DEATH = 3
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_REPENTANCE = 1,
|
||||
EVENT_HOLYFIRE = 2,
|
||||
EVENT_HOLYWRATH = 3,
|
||||
EVENT_HOLYGROUND = 4,
|
||||
EVENT_ENRAGE = 5
|
||||
};
|
||||
|
||||
class boss_maiden_of_virtue : public CreatureScript
|
||||
@@ -50,27 +55,13 @@ public:
|
||||
return new boss_maiden_of_virtueAI(creature);
|
||||
}
|
||||
|
||||
struct boss_maiden_of_virtueAI : public ScriptedAI
|
||||
struct boss_maiden_of_virtueAI : public BossAI
|
||||
{
|
||||
boss_maiden_of_virtueAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
uint32 Repentance_Timer;
|
||||
uint32 Holyfire_Timer;
|
||||
uint32 Holywrath_Timer;
|
||||
uint32 Holyground_Timer;
|
||||
uint32 Enrage_Timer;
|
||||
|
||||
bool Enraged;
|
||||
boss_maiden_of_virtueAI(Creature* creature) : BossAI(creature, TYPE_MAIDEN) { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Repentance_Timer = 25000 + (rand32() % 15000);
|
||||
Holyfire_Timer = 8000 + (rand32() % 17000);
|
||||
Holywrath_Timer = 15000 + (rand32() % 10000);
|
||||
Holyground_Timer = 3000;
|
||||
Enrage_Timer = 600000;
|
||||
|
||||
Enraged = false;
|
||||
_Reset();
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*Victim*/) override
|
||||
@@ -82,11 +73,19 @@ public:
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
_JustDied();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
_EnterCombat();
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
events.ScheduleEvent(EVENT_REPENTANCE, urand(33, 45) * IN_MILLISECONDS);
|
||||
events.ScheduleEvent(EVENT_HOLYFIRE, 12 * IN_MILLISECONDS);
|
||||
events.ScheduleEvent(EVENT_HOLYWRATH, urand(15, 25) * IN_MILLISECONDS);
|
||||
events.ScheduleEvent(EVENT_HOLYGROUND, 3 * IN_MILLISECONDS);
|
||||
events.ScheduleEvent(EVENT_ENRAGE, 600 * IN_MILLISECONDS);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
@@ -94,41 +93,41 @@ public:
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (Enrage_Timer < diff && !Enraged)
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
DoCast(me, SPELL_BERSERK, true);
|
||||
Enraged = true;
|
||||
} else Enrage_Timer -= diff;
|
||||
|
||||
if (Holyground_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_HOLYGROUND, true); //Triggered so it doesn't interrupt her at all
|
||||
Holyground_Timer = 3000;
|
||||
} else Holyground_Timer -= diff;
|
||||
|
||||
if (Repentance_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_REPENTANCE);
|
||||
Talk(SAY_REPENTANCE);
|
||||
|
||||
Repentance_Timer = urand(25000, 35000); //A little randomness on that spell
|
||||
} else Repentance_Timer -= diff;
|
||||
|
||||
if (Holyfire_Timer <= diff)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
DoCast(target, SPELL_HOLYFIRE);
|
||||
|
||||
Holyfire_Timer = urand(8000, 23000); //Anywhere from 8 to 23 seconds, good luck having several of those in a row!
|
||||
} else Holyfire_Timer -= diff;
|
||||
|
||||
if (Holywrath_Timer <= diff)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
DoCast(target, SPELL_HOLYWRATH);
|
||||
|
||||
Holywrath_Timer = urand(20000, 25000); //20-30 secs sounds nice
|
||||
} else Holywrath_Timer -= diff;
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_REPENTANCE:
|
||||
DoCastVictim(SPELL_REPENTANCE);
|
||||
Talk(SAY_REPENTANCE);
|
||||
events.ScheduleEvent(EVENT_REPENTANCE, urand(33, 45) * IN_MILLISECONDS);
|
||||
break;
|
||||
case EVENT_HOLYFIRE:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50, true))
|
||||
DoCast(target, SPELL_HOLYFIRE);
|
||||
events.ScheduleEvent(EVENT_HOLYFIRE, 12 * IN_MILLISECONDS);
|
||||
break;
|
||||
case EVENT_HOLYWRATH:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 80, true))
|
||||
DoCast(target, SPELL_HOLYWRATH);
|
||||
events.ScheduleEvent(EVENT_HOLYWRATH, urand(15, 25) * IN_MILLISECONDS);
|
||||
break;
|
||||
case EVENT_HOLYGROUND:
|
||||
DoCast(me, SPELL_HOLYGROUND, true);
|
||||
events.ScheduleEvent(EVENT_HOLYGROUND, 3 * IN_MILLISECONDS);
|
||||
break;
|
||||
case EVENT_ENRAGE:
|
||||
DoCast(me, SPELL_BERSERK, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
@@ -354,7 +354,7 @@ public:
|
||||
|
||||
if (caster)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 45.0f))
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 45.0f, true))
|
||||
DoCast(target, SPELL_PRIMARY(id));
|
||||
}
|
||||
else
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
#include "PassiveAI.h"
|
||||
#include "BattlegroundIC.h"
|
||||
#include "Player.h"
|
||||
#include "Vehicle.h"
|
||||
#include "SpellScript.h"
|
||||
#include "SpellInfo.h"
|
||||
|
||||
// TO-DO: This should be done with SmartAI, but yet it does not correctly support vehicles's AIs.
|
||||
// Even adding ReactState Passive we still have issues using SmartAI.
|
||||
@@ -70,7 +73,129 @@ class npc_four_car_garage : public CreatureScript
|
||||
}
|
||||
};
|
||||
|
||||
class spell_ioc_gunship_portal : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_ioc_gunship_portal() : SpellScriptLoader("spell_ioc_gunship_portal") { }
|
||||
|
||||
class spell_ioc_gunship_portal_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_ioc_gunship_portal_SpellScript);
|
||||
|
||||
bool Load() override
|
||||
{
|
||||
return GetCaster()->GetTypeId() == TYPEID_PLAYER;
|
||||
}
|
||||
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
Player* caster = GetCaster()->ToPlayer();
|
||||
if (Battleground* bg = caster->GetBattleground())
|
||||
if (bg->GetTypeID(true) == BATTLEGROUND_IC)
|
||||
bg->DoAction(1, caster->GetGUID());
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_ioc_gunship_portal_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_ioc_gunship_portal_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
enum ParachuteIC
|
||||
{
|
||||
SPELL_PARACHUTE_IC = 66657
|
||||
};
|
||||
|
||||
class spell_ioc_parachute_ic : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_ioc_parachute_ic() : SpellScriptLoader("spell_ioc_parachute_ic") { }
|
||||
|
||||
class spell_ioc_parachute_ic_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_ioc_parachute_ic_AuraScript);
|
||||
|
||||
void HandleTriggerSpell(AuraEffect const* /*aurEff*/)
|
||||
{
|
||||
if (Player* target = GetTarget()->ToPlayer())
|
||||
if (target->m_movementInfo.fallTime > 2000)
|
||||
target->CastSpell(target, SPELL_PARACHUTE_IC, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_ioc_parachute_ic_AuraScript::HandleTriggerSpell, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_ioc_parachute_ic_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
enum Launch
|
||||
{
|
||||
SPELL_LAUNCH_NO_FALLING_DAMAGE = 66251
|
||||
};
|
||||
|
||||
class spell_ioc_launch : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_ioc_launch() : SpellScriptLoader("spell_ioc_launch") { }
|
||||
|
||||
class spell_ioc_launch_SpellScript : public SpellScript
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_ioc_launch_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_FORCE_CAST);
|
||||
AfterHit += SpellHitFn(spell_ioc_launch_SpellScript::Launch);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_ioc_launch_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_isle_of_conquest()
|
||||
{
|
||||
new npc_four_car_garage();
|
||||
new spell_ioc_gunship_portal();
|
||||
new spell_ioc_parachute_ic();
|
||||
new spell_ioc_launch();
|
||||
}
|
||||
|
||||
@@ -158,7 +158,7 @@ class npc_minigob_manabonk : public CreatureScript
|
||||
me->setActive(true);
|
||||
}
|
||||
|
||||
void Reset()
|
||||
void Reset() override
|
||||
{
|
||||
me->SetVisible(false);
|
||||
events.ScheduleEvent(EVENT_SELECT_TARGET, IN_MILLISECONDS);
|
||||
@@ -188,7 +188,7 @@ class npc_minigob_manabonk : public CreatureScript
|
||||
CharacterDatabase.CommitTransaction(trans);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
events.Update(diff);
|
||||
|
||||
@@ -232,7 +232,7 @@ class npc_minigob_manabonk : public CreatureScript
|
||||
EventMap events;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return new npc_minigob_manabonkAI(creature);
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ enum DeathKnightSpells
|
||||
SPELL_DK_BLOOD_SHIELD_ABSORB = 77535,
|
||||
SPELL_DK_BUTCHERY = 50163,
|
||||
SPELL_DK_CORPSE_EXPLOSION_TRIGGERED = 43999,
|
||||
SPELL_DK_DEATH_AND_DECAY_DAMAGE = 52212,
|
||||
SPELL_DK_DEATH_COIL_DAMAGE = 47632,
|
||||
SPELL_DK_DEATH_COIL_HEAL = 47633,
|
||||
SPELL_DK_DEATH_STRIKE_HEAL = 45470,
|
||||
@@ -349,7 +350,33 @@ class spell_dk_butchery : public SpellScriptLoader
|
||||
}
|
||||
};
|
||||
|
||||
// 47541, 52375, 59134, -62900 - Death Coil
|
||||
class spell_dk_death_and_decay : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_dk_death_and_decay() : SpellScriptLoader("spell_dk_death_and_decay") { }
|
||||
|
||||
class spell_dk_death_and_decay_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_dk_death_and_decay_AuraScript);
|
||||
|
||||
void HandleDummyTick(AuraEffect const* aurEff)
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
caster->CastCustomSpell(SPELL_DK_DEATH_AND_DECAY_DAMAGE, SPELLVALUE_BASE_POINT0, aurEff->GetAmount(), GetTarget(), true, NULL, aurEff);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_dk_death_and_decay_AuraScript::HandleDummyTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_dk_death_and_decay_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_dk_death_coil : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
@@ -1490,6 +1517,7 @@ void AddSC_deathknight_spell_scripts()
|
||||
new spell_dk_blood_boil();
|
||||
new spell_dk_blood_gorged();
|
||||
new spell_dk_butchery();
|
||||
new spell_dk_death_and_decay();
|
||||
new spell_dk_death_coil();
|
||||
new spell_dk_death_gate();
|
||||
new spell_dk_death_grip();
|
||||
|
||||
@@ -1657,40 +1657,6 @@ class spell_gen_gnomish_transporter : public SpellScriptLoader
|
||||
}
|
||||
};
|
||||
|
||||
class spell_gen_gunship_portal : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_gen_gunship_portal() : SpellScriptLoader("spell_gen_gunship_portal") { }
|
||||
|
||||
class spell_gen_gunship_portal_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_gen_gunship_portal_SpellScript);
|
||||
|
||||
bool Load() override
|
||||
{
|
||||
return GetCaster()->GetTypeId() == TYPEID_PLAYER;
|
||||
}
|
||||
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
Player* caster = GetCaster()->ToPlayer();
|
||||
if (Battleground* bg = caster->GetBattleground())
|
||||
if (bg->GetTypeID(true) == BATTLEGROUND_IC)
|
||||
bg->DoAction(1, caster->GetGUID());
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_gen_gunship_portal_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_gen_gunship_portal_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
enum Interrupt
|
||||
{
|
||||
@@ -1733,58 +1699,6 @@ class spell_gen_interrupt : public SpellScriptLoader
|
||||
}
|
||||
};
|
||||
|
||||
enum Launch
|
||||
{
|
||||
SPELL_LAUNCH_NO_FALLING_DAMAGE = 66251
|
||||
};
|
||||
|
||||
class spell_gen_launch : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_gen_launch() : SpellScriptLoader("spell_gen_launch") { }
|
||||
|
||||
class spell_gen_launch_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_gen_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);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_gen_launch_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_FORCE_CAST);
|
||||
AfterHit += SpellHitFn(spell_gen_launch_SpellScript::Launch);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_gen_launch_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_gen_increase_stats_buff : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
@@ -2616,39 +2530,6 @@ class spell_gen_parachute : public SpellScriptLoader
|
||||
}
|
||||
};
|
||||
|
||||
enum ParachuteIC
|
||||
{
|
||||
SPELL_PARACHUTE_IC = 66657
|
||||
};
|
||||
|
||||
class spell_gen_parachute_ic : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_gen_parachute_ic() : SpellScriptLoader("spell_gen_parachute_ic") { }
|
||||
|
||||
class spell_gen_parachute_ic_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_gen_parachute_ic_AuraScript);
|
||||
|
||||
void HandleTriggerSpell(AuraEffect const* /*aurEff*/)
|
||||
{
|
||||
if (Player* target = GetTarget()->ToPlayer())
|
||||
if (target->m_movementInfo.jump.fallTime > 2000)
|
||||
target->CastSpell(target, SPELL_PARACHUTE_IC, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_gen_parachute_ic_AuraScript::HandleTriggerSpell, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_gen_parachute_ic_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
enum PetSummoned
|
||||
{
|
||||
NPC_DOOMGUARD = 11859,
|
||||
@@ -3753,7 +3634,6 @@ void AddSC_generic_spell_scripts()
|
||||
new spell_gen_gadgetzan_transporter_backfire();
|
||||
new spell_gen_gift_of_naaru();
|
||||
new spell_gen_gnomish_transporter();
|
||||
new spell_gen_gunship_portal();
|
||||
new spell_gen_increase_stats_buff("spell_pal_blessing_of_kings");
|
||||
new spell_gen_increase_stats_buff("spell_pal_blessing_of_might");
|
||||
new spell_gen_increase_stats_buff("spell_dru_mark_of_the_wild");
|
||||
@@ -3762,7 +3642,6 @@ void AddSC_generic_spell_scripts()
|
||||
new spell_gen_increase_stats_buff("spell_mage_arcane_brilliance");
|
||||
new spell_gen_increase_stats_buff("spell_mage_dalaran_brilliance");
|
||||
new spell_gen_interrupt();
|
||||
new spell_gen_launch();
|
||||
new spell_gen_lifebloom("spell_hexlord_lifebloom", SPELL_HEXLORD_MALACRASS_LIFEBLOOM_FINAL_HEAL);
|
||||
new spell_gen_lifebloom("spell_tur_ragepaw_lifebloom", SPELL_TUR_RAGEPAW_LIFEBLOOM_FINAL_HEAL);
|
||||
new spell_gen_lifebloom("spell_cenarion_scout_lifebloom", SPELL_CENARION_SCOUT_LIFEBLOOM_FINAL_HEAL);
|
||||
@@ -3775,7 +3654,6 @@ void AddSC_generic_spell_scripts()
|
||||
new spell_gen_oracle_wolvar_reputation();
|
||||
new spell_gen_orc_disguise();
|
||||
new spell_gen_parachute();
|
||||
new spell_gen_parachute_ic();
|
||||
new spell_gen_pet_summoned();
|
||||
new spell_gen_profession_research();
|
||||
new spell_gen_remove_flight_auras();
|
||||
|
||||
@@ -506,7 +506,7 @@ class spell_warr_overpower : public SpellScriptLoader
|
||||
return;
|
||||
|
||||
if (Player* target = GetHitPlayer())
|
||||
if (target->HasUnitState(UNIT_STATE_CASTING))
|
||||
if (target->IsNonMeleeSpellCast(false, false, true)) // UNIT_STATE_CASTING should not be used here, it's present during a tick for instant casts
|
||||
target->CastSpell(target, spellId, true);
|
||||
}
|
||||
|
||||
|
||||
@@ -236,11 +236,11 @@ class AreaTrigger_at_sholazar_waygate : public AreaTriggerScript
|
||||
switch (trigger->id)
|
||||
{
|
||||
case AT_SHOLAZAR:
|
||||
player->CastSpell(player, SPELL_SHOLAZAR_TO_UNGORO_TELEPORT, false);
|
||||
player->CastSpell(player, SPELL_SHOLAZAR_TO_UNGORO_TELEPORT, true);
|
||||
break;
|
||||
|
||||
case AT_UNGORO:
|
||||
player->CastSpell(player, SPELL_UNGORO_TO_SHOLAZAR_TELEPORT, false);
|
||||
player->CastSpell(player, SPELL_UNGORO_TO_SHOLAZAR_TELEPORT, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user