Merge branch 'azerothcore:master' into Playerbot
This commit is contained in:
@@ -24,7 +24,7 @@ ExternalProject_Add(
|
||||
GIT_REPOSITORY
|
||||
https://github.com/google/googletest.git
|
||||
GIT_TAG
|
||||
main
|
||||
release-1.12.1
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace Acore
|
||||
static int CreateChildProcess(T waiter, std::string const& executable,
|
||||
std::vector<std::string> const& argsVector,
|
||||
std::string const& logger, std::string const& input,
|
||||
bool secure)
|
||||
bool secure, boost::process::environment envVariables = boost::this_process::environment())
|
||||
{
|
||||
ipstream outStream;
|
||||
ipstream errStream;
|
||||
@@ -97,7 +97,7 @@ namespace Acore
|
||||
return child{
|
||||
exe = std::filesystem::absolute(executable).string(),
|
||||
args = argsVector,
|
||||
env = environment(boost::this_process::environment()),
|
||||
env = environment(envVariables),
|
||||
std_in = inputFile.get(),
|
||||
std_out = outStream,
|
||||
std_err = errStream
|
||||
@@ -109,7 +109,7 @@ namespace Acore
|
||||
return child{
|
||||
exe = std::filesystem::absolute(executable).string(),
|
||||
args = argsVector,
|
||||
env = environment(boost::this_process::environment()),
|
||||
env = environment(envVariables),
|
||||
std_in = boost::process::close,
|
||||
std_out = outStream,
|
||||
std_err = errStream
|
||||
@@ -144,7 +144,7 @@ namespace Acore
|
||||
}
|
||||
|
||||
int StartProcess(std::string const& executable, std::vector<std::string> const& args,
|
||||
std::string const& logger, std::string input_file, bool secure)
|
||||
std::string const& logger, std::string input_file, bool secure, boost::process::environment env)
|
||||
{
|
||||
return CreateChildProcess([](child& c) -> int
|
||||
{
|
||||
@@ -157,7 +157,7 @@ namespace Acore
|
||||
{
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}, executable, args, logger, input_file, secure);
|
||||
}, executable, args, logger, input_file, secure, env);
|
||||
}
|
||||
|
||||
class AsyncProcessResultImplementation
|
||||
@@ -168,6 +168,7 @@ namespace Acore
|
||||
std::string const logger;
|
||||
std::string const input_file;
|
||||
bool const is_secure;
|
||||
boost::process::environment envVariables;
|
||||
|
||||
std::atomic<bool> was_terminated;
|
||||
|
||||
@@ -177,10 +178,10 @@ namespace Acore
|
||||
public:
|
||||
explicit AsyncProcessResultImplementation(std::string executable_, std::vector<std::string> args_,
|
||||
std::string logger_, std::string input_file_,
|
||||
bool secure)
|
||||
bool secure, boost::process::environment env)
|
||||
: executable(std::move(executable_)), args(std::move(args_)),
|
||||
logger(std::move(logger_)), input_file(input_file_),
|
||||
is_secure(secure), was_terminated(false) { }
|
||||
is_secure(secure), envVariables(env), was_terminated(false) { }
|
||||
|
||||
AsyncProcessResultImplementation(AsyncProcessResultImplementation const&) = delete;
|
||||
AsyncProcessResultImplementation& operator= (AsyncProcessResultImplementation const&) = delete;
|
||||
@@ -209,7 +210,7 @@ namespace Acore
|
||||
my_child.reset();
|
||||
return was_terminated ? EXIT_FAILURE : exitCode;
|
||||
|
||||
}, executable, args, logger, input_file, is_secure);
|
||||
}, executable, args, logger, input_file, is_secure, envVariables);
|
||||
}
|
||||
|
||||
void SetFuture(std::future<int> result_)
|
||||
@@ -245,10 +246,10 @@ namespace Acore
|
||||
|
||||
std::shared_ptr<AsyncProcessResult>
|
||||
StartAsyncProcess(std::string executable, std::vector<std::string> args,
|
||||
std::string logger, std::string input_file, bool secure)
|
||||
std::string logger, std::string input_file, bool secure, boost::process::native_environment env)
|
||||
{
|
||||
auto handle = std::make_shared<AsyncProcessResultImplementation>(
|
||||
std::move(executable), std::move(args), std::move(logger), std::move(input_file), secure);
|
||||
std::move(executable), std::move(args), std::move(logger), std::move(input_file), secure, env);
|
||||
|
||||
handle->SetFuture(std::async(std::launch::async, [handle] { return handle->StartProcess(); }));
|
||||
return handle;
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <boost/process/environment.hpp>
|
||||
|
||||
namespace Acore
|
||||
{
|
||||
@@ -34,7 +35,7 @@ namespace Acore
|
||||
/// Note that most executables expect it's name as the first argument.
|
||||
AC_COMMON_API int StartProcess(std::string const& executable, std::vector<std::string> const& args,
|
||||
std::string const& logger, std::string input_file = "",
|
||||
bool secure = false);
|
||||
bool secure = false, boost::process::environment env = boost::this_process::environment());
|
||||
|
||||
/// Platform and library independent representation
|
||||
/// of asynchronous process results
|
||||
@@ -58,7 +59,7 @@ namespace Acore
|
||||
/// Note that most executables expect it's name as the first argument.
|
||||
AC_COMMON_API std::shared_ptr<AsyncProcessResult> StartAsyncProcess(std::string executable, std::vector<std::string> args,
|
||||
std::string logger, std::string input_file = "",
|
||||
bool secure = false);
|
||||
bool secure = false, boost::process::environment env = boost::this_process::environment());
|
||||
|
||||
/// Searches for the given executable in the PATH variable
|
||||
/// and returns a non-empty string when it was found.
|
||||
|
||||
@@ -557,9 +557,12 @@ void DBUpdater<T>::ApplyFile(DatabaseWorkerPool<T>& pool, std::string const& hos
|
||||
if (!database.empty())
|
||||
args.emplace_back(database);
|
||||
|
||||
auto env = boost::process::environment();
|
||||
|
||||
|
||||
// Invokes a mysql process which doesn't leak credentials to logs
|
||||
int const ret = Acore::StartProcess(DBUpdaterUtil::GetCorrectedMySQLExecutable(), args,
|
||||
"sql.updates", "", true);
|
||||
"sql.updates", "", true, env);
|
||||
|
||||
if (ret != EXIT_SUCCESS)
|
||||
{
|
||||
|
||||
@@ -729,8 +729,8 @@ void BattlegroundAV::ChangeMineOwner(uint8 mine, TeamId teamId, bool initial)
|
||||
{
|
||||
m_Mine_Reclaim_Timer[mine] = AV_MINE_RECLAIM_TIMER;
|
||||
char buf[256];
|
||||
sprintf(buf, GetAcoreString(LANG_BG_AV_MINE_TAKEN), GetAcoreString((mine == AV_NORTH_MINE) ? LANG_BG_AV_MINE_NORTH : LANG_BG_AV_MINE_SOUTH),
|
||||
(teamId == TEAM_ALLIANCE) ? GetAcoreString(LANG_BG_AV_ALLY) : GetAcoreString(LANG_BG_AV_HORDE));
|
||||
sprintf(buf, GetAcoreString(LANG_BG_AV_MINE_TAKEN), (teamId == TEAM_ALLIANCE) ? GetAcoreString(LANG_BG_AV_ALLY) : GetAcoreString(LANG_BG_AV_HORDE),
|
||||
GetAcoreString((mine == AV_NORTH_MINE) ? LANG_BG_AV_MINE_NORTH : LANG_BG_AV_MINE_SOUTH));
|
||||
Creature* creature = GetBGCreature(AV_CPLACE_HERALD);
|
||||
if (creature)
|
||||
YellToAll(creature, buf, LANG_UNIVERSAL);
|
||||
|
||||
@@ -62,9 +62,9 @@ void Unit::UpdateDamagePhysical(WeaponAttackType attType)
|
||||
float totalMin = 0.f;
|
||||
float totalMax = 0.f;
|
||||
|
||||
float tmpMin, tmpMax;
|
||||
for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
|
||||
{
|
||||
float tmpMin, tmpMax;
|
||||
CalculateMinMaxDamage(attType, false, true, tmpMin, tmpMax, i);
|
||||
totalMin += tmpMin;
|
||||
totalMax += tmpMax;
|
||||
|
||||
@@ -151,6 +151,7 @@ struct boss_eye_of_cthun : public BossAI
|
||||
boss_eye_of_cthun(Creature* creature) : BossAI(creature, DATA_CTHUN)
|
||||
{
|
||||
SetCombatMovement(false);
|
||||
me->m_SightDistance = 90.f;
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
@@ -199,7 +200,7 @@ struct boss_eye_of_cthun : public BossAI
|
||||
if (who->GetTypeId() == TYPEID_PLAYER && !me->IsInCombat())
|
||||
{
|
||||
// Z checks are necessary here because AQ maps do funky stuff.
|
||||
if (me->IsWithinLOSInMap(who) && me->IsWithinDist2d(who, 50.0f) && who->GetPositionZ() > 100.0f)
|
||||
if (me->IsWithinLOSInMap(who) && me->IsWithinDist2d(who, 90.0f) && who->GetPositionZ() > 100.0f)
|
||||
{
|
||||
AttackStart(who);
|
||||
}
|
||||
@@ -993,7 +994,7 @@ public:
|
||||
|
||||
player->m_Events.AddEventAtOffset([player, cthun]()
|
||||
{
|
||||
if (Creature* trigger = player->FindNearestCreature(NPC_EXIT_TRIGGER, 10.0f))
|
||||
if (player->FindNearestCreature(NPC_EXIT_TRIGGER, 10.0f))
|
||||
{
|
||||
player->JumpTo(0.0f, 80.0f, false);
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@ enum Spells
|
||||
SPELL_ENRAGE = 8269,
|
||||
SPELL_BERSERK = 27680,
|
||||
SPELL_SUNDERING_CLEAVE = 25174,
|
||||
|
||||
// Sartura's Royal Guard
|
||||
SPELL_GUARD_WHIRLWIND = 26038,
|
||||
SPELL_GUARD_KNOCKBACK = 26027
|
||||
@@ -44,20 +43,15 @@ enum events
|
||||
{
|
||||
// Battleguard Sartura
|
||||
EVENT_SARTURA_WHIRLWIND = 1,
|
||||
EVENT_SARTURA_WHIRLWIND_RANDOM = 2,
|
||||
EVENT_SARTURA_WHIRLWIND_END = 3,
|
||||
EVENT_SPELL_BERSERK = 4,
|
||||
EVENT_SARTURA_AGGRO_RESET = 5,
|
||||
EVENT_SARTURA_AGGRO_RESET_END = 6,
|
||||
EVENT_SARTURA_SUNDERING_CLEAVE = 7,
|
||||
|
||||
EVENT_SARTURA_WHIRLWIND_RANDOM,
|
||||
EVENT_SARTURA_WHIRLWIND_END,
|
||||
EVENT_SPELL_BERSERK,
|
||||
EVENT_SARTURA_SUNDERING_CLEAVE,
|
||||
// Sartura's Royal Guard
|
||||
EVENT_GUARD_WHIRLWIND = 8,
|
||||
EVENT_GUARD_WHIRLWIND_RANDOM = 9,
|
||||
EVENT_GUARD_WHIRLWIND_END = 10,
|
||||
EVENT_GUARD_KNOCKBACK = 11,
|
||||
EVENT_GUARD_AGGRO_RESET = 12,
|
||||
EVENT_GUARD_AGGRO_RESET_END = 13
|
||||
EVENT_GUARD_WHIRLWIND,
|
||||
EVENT_GUARD_WHIRLWIND_RANDOM,
|
||||
EVENT_GUARD_WHIRLWIND_END,
|
||||
EVENT_GUARD_KNOCKBACK,
|
||||
};
|
||||
|
||||
struct boss_sartura : public BossAI
|
||||
@@ -74,13 +68,11 @@ struct boss_sartura : public BossAI
|
||||
void Reset() override
|
||||
{
|
||||
_Reset();
|
||||
whirlwind = false;
|
||||
enraged = false;
|
||||
berserked = false;
|
||||
aggroReset = false;
|
||||
MinionReset();
|
||||
_savedTargetGUID.Clear();
|
||||
_savedTargetThreat = 0.f;
|
||||
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
}
|
||||
|
||||
void MinionReset()
|
||||
@@ -98,8 +90,7 @@ struct boss_sartura : public BossAI
|
||||
BossAI::EnterCombat(who);
|
||||
Talk(SAY_AGGRO);
|
||||
events.ScheduleEvent(EVENT_SARTURA_WHIRLWIND, 12s, 22s);
|
||||
events.ScheduleEvent(EVENT_SARTURA_AGGRO_RESET, urand(45000, 55000));
|
||||
events.ScheduleEvent(EVENT_SPELL_BERSERK, 10 * 60000);
|
||||
events.ScheduleEvent(EVENT_SPELL_BERSERK, 10min);
|
||||
events.ScheduleEvent(EVENT_SARTURA_SUNDERING_CLEAVE, 2400ms, 3s);
|
||||
}
|
||||
|
||||
@@ -125,7 +116,7 @@ struct boss_sartura : public BossAI
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
if (!UpdateVictimWithGaze())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
@@ -135,61 +126,26 @@ struct boss_sartura : public BossAI
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_SARTURA_WHIRLWIND:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100.0f, true))
|
||||
{
|
||||
SetGazeOn(target);
|
||||
}
|
||||
DoCastSelf(SPELL_WHIRLWIND, true);
|
||||
whirlwind = true;
|
||||
events.ScheduleEvent(EVENT_SARTURA_WHIRLWIND_RANDOM, urand(3000, 7000));
|
||||
events.ScheduleEvent(EVENT_SARTURA_WHIRLWIND_END, 15000);
|
||||
events.ScheduleEvent(EVENT_SARTURA_WHIRLWIND_RANDOM, 2s, 7s);
|
||||
events.ScheduleEvent(EVENT_SARTURA_WHIRLWIND_END, 15s);
|
||||
break;
|
||||
case EVENT_SARTURA_WHIRLWIND_RANDOM:
|
||||
if (whirlwind == true)
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
|
||||
{
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100.0f, true))
|
||||
{
|
||||
me->AddThreat(target, 1.0f);
|
||||
me->TauntApply(target);
|
||||
AttackStart(target);
|
||||
}
|
||||
events.RepeatEvent(urand(3000, 7000));
|
||||
SetGazeOn(target);
|
||||
}
|
||||
events.Repeat(2s, 7s);
|
||||
break;
|
||||
case EVENT_SARTURA_WHIRLWIND_END:
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
events.CancelEvent(EVENT_SARTURA_WHIRLWIND_RANDOM);
|
||||
whirlwind = false;
|
||||
events.ScheduleEvent(EVENT_SARTURA_WHIRLWIND, 5s, 11s);
|
||||
break;
|
||||
case EVENT_SARTURA_AGGRO_RESET:
|
||||
if (aggroReset == false)
|
||||
{
|
||||
if (Unit* originalTarget = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
{
|
||||
_savedTargetGUID = originalTarget->GetGUID();
|
||||
_savedTargetThreat = me->GetThreatMgr().GetThreat(originalTarget);
|
||||
me->GetThreatMgr().ModifyThreatByPercent(originalTarget, -100);
|
||||
}
|
||||
aggroReset = true;
|
||||
events.ScheduleEvent(EVENT_SARTURA_AGGRO_RESET_END, 5000);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100.0f, true))
|
||||
{
|
||||
me->AddThreat(target, 1.0f);
|
||||
me->TauntApply(target);
|
||||
AttackStart(target);
|
||||
}
|
||||
}
|
||||
events.RepeatEvent(urand(1000, 2000));
|
||||
break;
|
||||
case EVENT_SARTURA_AGGRO_RESET_END:
|
||||
events.CancelEvent(EVENT_SARTURA_AGGRO_RESET);
|
||||
if (Unit* originalTarget = ObjectAccessor::GetUnit(*me, _savedTargetGUID))
|
||||
{
|
||||
me->GetThreatMgr().AddThreat(originalTarget, _savedTargetThreat);
|
||||
_savedTargetGUID.Clear();
|
||||
}
|
||||
aggroReset = false;
|
||||
events.RescheduleEvent(EVENT_SARTURA_AGGRO_RESET, urand(30000, 40000));
|
||||
break;
|
||||
case EVENT_SPELL_BERSERK:
|
||||
if (!berserked)
|
||||
{
|
||||
@@ -198,7 +154,7 @@ struct boss_sartura : public BossAI
|
||||
}
|
||||
break;
|
||||
case EVENT_SARTURA_SUNDERING_CLEAVE:
|
||||
if (whirlwind)
|
||||
if (me->HasReactState(REACT_PASSIVE))
|
||||
{
|
||||
Milliseconds whirlwindTimer = events.GetTimeUntilEvent(EVENT_SARTURA_WHIRLWIND_END);
|
||||
events.RescheduleEvent(EVENT_SARTURA_SUNDERING_CLEAVE, whirlwindTimer + 500ms);
|
||||
@@ -213,15 +169,13 @@ struct boss_sartura : public BossAI
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
};
|
||||
|
||||
private:
|
||||
bool whirlwind;
|
||||
bool enraged;
|
||||
bool berserked;
|
||||
bool aggroReset;
|
||||
ObjectGuid _savedTargetGUID;
|
||||
float _savedTargetThreat;
|
||||
};
|
||||
|
||||
struct npc_sartura_royal_guard : public ScriptedAI
|
||||
@@ -231,22 +185,19 @@ struct npc_sartura_royal_guard : public ScriptedAI
|
||||
void Reset() override
|
||||
{
|
||||
events.Reset();
|
||||
whirlwind = false;
|
||||
aggroReset = false;
|
||||
_savedTargetGUID.Clear();
|
||||
_savedTargetThreat = 0.f;
|
||||
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
events.ScheduleEvent(EVENT_GUARD_WHIRLWIND, 6s, 10s);
|
||||
events.ScheduleEvent(EVENT_GUARD_AGGRO_RESET, urand(45000, 55000));
|
||||
events.ScheduleEvent(EVENT_GUARD_KNOCKBACK, 12s, 16s);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
if (!UpdateVictimWithGaze())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
@@ -256,74 +207,35 @@ struct npc_sartura_royal_guard : public ScriptedAI
|
||||
switch (eventid)
|
||||
{
|
||||
case EVENT_GUARD_WHIRLWIND:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100.0f, true))
|
||||
{
|
||||
SetGazeOn(target);
|
||||
}
|
||||
DoCastSelf(SPELL_GUARD_WHIRLWIND);
|
||||
whirlwind = true;
|
||||
events.ScheduleEvent(EVENT_GUARD_WHIRLWIND_RANDOM, urand(3000, 7000));
|
||||
events.ScheduleEvent(EVENT_GUARD_WHIRLWIND_RANDOM, 2s, 7s);
|
||||
events.ScheduleEvent(EVENT_GUARD_WHIRLWIND_END, 8s);
|
||||
break;
|
||||
case EVENT_GUARD_WHIRLWIND_RANDOM:
|
||||
if (whirlwind == true)
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
|
||||
{
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100.0f, true))
|
||||
{
|
||||
me->AddThreat(target, 1.0f);
|
||||
me->TauntApply(target);
|
||||
AttackStart(target);
|
||||
}
|
||||
events.RepeatEvent(urand(3000, 7000));
|
||||
SetGazeOn(target);
|
||||
}
|
||||
events.Repeat(2s, 7s);
|
||||
break;
|
||||
case EVENT_GUARD_WHIRLWIND_END:
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
events.CancelEvent(EVENT_GUARD_WHIRLWIND_RANDOM);
|
||||
whirlwind = false;
|
||||
events.ScheduleEvent(EVENT_GUARD_WHIRLWIND, 500ms, 9s);
|
||||
break;
|
||||
case EVENT_GUARD_AGGRO_RESET:
|
||||
if (aggroReset == true)
|
||||
{
|
||||
if (Unit* originalTarget = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
{
|
||||
_savedTargetGUID = originalTarget->GetGUID();
|
||||
_savedTargetThreat = me->GetThreatMgr().GetThreat(originalTarget);
|
||||
me->GetThreatMgr().ModifyThreatByPercent(originalTarget, -100);
|
||||
}
|
||||
aggroReset = true;
|
||||
events.ScheduleEvent(EVENT_GUARD_AGGRO_RESET_END, 5000);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100.0f, true))
|
||||
{
|
||||
me->AddThreat(target, 1.0f);
|
||||
me->TauntApply(target);
|
||||
AttackStart(target);
|
||||
}
|
||||
}
|
||||
events.RepeatEvent(urand(1000, 2000));
|
||||
break;
|
||||
case EVENT_GUARD_AGGRO_RESET_END:
|
||||
events.CancelEvent(EVENT_GUARD_AGGRO_RESET);
|
||||
if (Unit* originalTarget = ObjectAccessor::GetUnit(*me, _savedTargetGUID))
|
||||
{
|
||||
me->GetThreatMgr().AddThreat(originalTarget, _savedTargetThreat);
|
||||
_savedTargetGUID.Clear();
|
||||
}
|
||||
aggroReset = false;
|
||||
events.RescheduleEvent(EVENT_GUARD_AGGRO_RESET, urand(30000, 40000));
|
||||
break;
|
||||
case EVENT_GUARD_KNOCKBACK:
|
||||
DoCastVictim(SPELL_GUARD_KNOCKBACK);
|
||||
events.Repeat(21s, 37s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
private:
|
||||
bool whirlwind;
|
||||
bool aggroReset;
|
||||
ObjectGuid _savedTargetGUID;
|
||||
float _savedTargetThreat;
|
||||
};
|
||||
|
||||
void AddSC_boss_sartura()
|
||||
|
||||
@@ -134,6 +134,8 @@ struct boss_skeram : public BossAI
|
||||
{
|
||||
_JustDied();
|
||||
Talk(SAY_DEATH);
|
||||
if (me->GetMap() && me->GetMap()->ToInstanceMap())
|
||||
me->GetMap()->ToInstanceMap()->PermBindAllPlayers();
|
||||
}
|
||||
else
|
||||
me->RemoveCorpse();
|
||||
|
||||
@@ -168,7 +168,7 @@ struct boss_twinemperorsAI : public BossAI
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
if (Unit* victim = me->SelectNearestTarget())
|
||||
{
|
||||
me->AddThreat(victim, 200000.f);
|
||||
me->AddThreat(victim, 2000.f);
|
||||
AttackStart(victim);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -15,22 +15,11 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: npc_anubisath_sentinel
|
||||
SD%Complete: 95
|
||||
SDComment: Shadow storm is not properly implemented in core it should only target ppl outside of melee range.
|
||||
SDCategory: Temple of Ahn'Qiraj
|
||||
EndScriptData */
|
||||
|
||||
#include "Cell.h"
|
||||
#include "CellImpl.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "GridNotifiersImpl.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "Spell.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "SpellScript.h"
|
||||
#include "temple_of_ahnqiraj.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
@@ -316,7 +305,46 @@ public:
|
||||
};
|
||||
};
|
||||
|
||||
// 9347: Mortal Strike
|
||||
class spell_anubisath_mortal_strike : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_anubisath_mortal_strike);
|
||||
|
||||
void OnPeriodic(AuraEffect const* /*aurEff*/)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
|
||||
if (Unit* target = GetUnitOwner()->GetVictim())
|
||||
if (target->IsWithinDist(GetUnitOwner(), 5.f))
|
||||
GetUnitOwner()->CastSpell(target, GetSpellInfo()->Effects[EFFECT_0].TriggerSpell, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_anubisath_mortal_strike::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
||||
}
|
||||
};
|
||||
|
||||
// 26626 (Server-side): Mana Burn Area
|
||||
class spell_mana_burn_area : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_mana_burn_area);
|
||||
|
||||
void HandleDummy(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (Unit* target = GetHitUnit())
|
||||
GetCaster()->CastSpell(target, SPELL_MANAB, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_mana_burn_area::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_npc_anubisath_sentinel()
|
||||
{
|
||||
new npc_anubisath_sentinel();
|
||||
RegisterSpellScript(spell_anubisath_mortal_strike);
|
||||
RegisterSpellScript(spell_mana_burn_area);
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ enum Spells
|
||||
|
||||
// Obsidian Eradicator
|
||||
SPELL_SHOCK_BLAST = 26458,
|
||||
SPELL_DRAIN_MANA = 25671,
|
||||
SPELL_DRAIN_MANA_ERADICATOR = 25755,
|
||||
SPELL_DRAIN_MANA_VISUAL = 26639,
|
||||
|
||||
// Anubisath Warder
|
||||
@@ -59,6 +59,7 @@ enum Spells
|
||||
|
||||
// Obsidian Nullifier
|
||||
SPELL_NULLIFY = 26552,
|
||||
SPELL_DRAIN_MANA_NULLIFIER = 25671,
|
||||
SPELL_CLEAVE = 40504,
|
||||
|
||||
// Qiraji Scorpion
|
||||
@@ -268,7 +269,7 @@ struct npc_obsidian_eradicator : public ScriptedAI
|
||||
|
||||
for (Unit* target : _targets)
|
||||
{
|
||||
DoCast(target, SPELL_DRAIN_MANA, true);
|
||||
DoCast(target, SPELL_DRAIN_MANA_ERADICATOR, true);
|
||||
}
|
||||
|
||||
if (me->GetPowerPct(POWER_MANA) >= 100.f)
|
||||
@@ -401,7 +402,7 @@ struct npc_obsidian_nullifier : public ScriptedAI
|
||||
|
||||
for (Unit* target : _targets)
|
||||
{
|
||||
DoCast(target, SPELL_DRAIN_MANA, true);
|
||||
DoCast(target, SPELL_DRAIN_MANA_NULLIFIER, true);
|
||||
}
|
||||
|
||||
if (me->GetPowerPct(POWER_MANA) >= 100.f)
|
||||
|
||||
@@ -122,7 +122,7 @@ class spell_rog_blade_flurry : public AuraScript
|
||||
DamageInfo* damageInfo = eventInfo.GetDamageInfo();
|
||||
if (procTarget && damageInfo)
|
||||
{
|
||||
int32 damage = damageInfo->GetUnmitigatedDamage();
|
||||
int32 damage = damageInfo->GetDamage();
|
||||
|
||||
CustomSpellValues values;
|
||||
values.AddSpellMod(SPELLVALUE_BASE_POINT0, damage);
|
||||
|
||||
@@ -668,7 +668,7 @@ class spell_warr_sweeping_strikes : public AuraScript
|
||||
}
|
||||
else
|
||||
{
|
||||
int32 damage = damageInfo->GetUnmitigatedDamage();
|
||||
int32 damage = damageInfo->GetDamage();
|
||||
GetTarget()->CastCustomSpell(_procTarget, SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK_1, &damage, 0, 0, true, nullptr, aurEff);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user