Merge branch 'master' into Playerbot

This commit is contained in:
Yunfan Li
2025-01-15 20:49:11 +08:00
45 changed files with 1025 additions and 84 deletions

View File

@@ -2334,6 +2334,12 @@ void Player::ProcessSpellQueue()
{
PendingSpellCastRequest& request = SpellQueue.front(); // Peek at the first spell
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(request.spellId);
if (!spellInfo)
{
LOG_ERROR("entities.player", "Player::ProcessSpellQueue: Invalid spell {}", request.spellId);
SpellQueue.clear();
break;
}
if (CanExecutePendingSpellCastRequest(spellInfo))
{
ExecuteOrCancelSpellCastRequest(&request);

View File

@@ -9673,8 +9673,6 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
return false;
}
// Cast positive spell on enemy target
case 7099: // Curse of Mending
case 39703: // Curse of Mending
case 20233: // Improved Lay on Hands (cast on target)
{
target = victim;

View File

@@ -184,6 +184,9 @@ public:
//Called when a player successfully enters the instance.
virtual void OnPlayerEnter(Player* /*player*/) {}
//Called when a player successfully leaves the instance.
virtual void OnPlayerLeave(Player* /*player*/) {}
virtual void OnPlayerAreaUpdate(Player* /*player*/, uint32 /*oldArea*/, uint32 /*newArea*/) {}
//Called when a player enters/leaves water bodies.

View File

@@ -3046,6 +3046,8 @@ void InstanceMap::Update(const uint32 t_diff, const uint32 s_diff, bool /*thread
void InstanceMap::RemovePlayerFromMap(Player* player, bool remove)
{
if (instance_data)
instance_data->OnPlayerLeave(player);
// pussywizard: moved m_unloadTimer to InstanceMap::AfterPlayerUnlinkFromMap(), in this function if 2 players run out at the same time the instance won't close
//if (!m_unloadTimer && m_mapRefMgr.getSize() == 1)
// m_unloadTimer = m_unloadWhenEmpty ? MIN_UNLOAD_DELAY : std::max(sWorld->getIntConfig(CONFIG_INSTANCE_UNLOAD_DELAY), (uint32)MIN_UNLOAD_DELAY);

View File

@@ -1145,7 +1145,10 @@ enum AcoreStrings
LANG_CMD_GO_RESPAWN = 5085,
// Room for more strings 5086-9999
LANG_CMD_NO_DOOR_FOUND = 5086,
LANG_CMD_DOOR_OPENED = 5087,
// Room for more strings 5088-9999
// Level requirement notifications
LANG_SAY_REQ = 6604,

View File

@@ -2892,27 +2892,27 @@ void World::UpdateRealmCharCount(uint32 accountId)
{
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_COUNT);
stmt->SetData(0, accountId);
_queryProcessor.AddCallback(CharacterDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&World::_UpdateRealmCharCount, this, std::placeholders::_1)));
_queryProcessor.AddCallback(CharacterDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&World::_UpdateRealmCharCount, this, std::placeholders::_1,accountId)));
}
void World::_UpdateRealmCharCount(PreparedQueryResult resultCharCount)
void World::_UpdateRealmCharCount(PreparedQueryResult resultCharCount,uint32 accountId)
{
uint8 charCount{0};
if (resultCharCount)
{
Field* fields = resultCharCount->Fetch();
uint32 accountId = fields[0].Get<uint32>();
uint8 charCount = uint8(fields[1].Get<uint64>());
LoginDatabaseTransaction trans = LoginDatabase.BeginTransaction();
LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_REP_REALM_CHARACTERS);
stmt->SetData(0, charCount);
stmt->SetData(1, accountId);
stmt->SetData(2, realm.Id.Realm);
trans->Append(stmt);
LoginDatabase.CommitTransaction(trans);
charCount = uint8(fields[1].Get<uint64>());
}
LoginDatabaseTransaction trans = LoginDatabase.BeginTransaction();
LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_REP_REALM_CHARACTERS);
stmt->SetData(0, charCount);
stmt->SetData(1, accountId);
stmt->SetData(2, realm.Id.Realm);
trans->Append(stmt);
LoginDatabase.CommitTransaction(trans);
}
void World::InitWeeklyQuestResetTime()

View File

@@ -350,7 +350,7 @@ public:
protected:
void _UpdateGameTime();
// callback for UpdateRealmCharacters
void _UpdateRealmCharCount(PreparedQueryResult resultCharCount);
void _UpdateRealmCharCount(PreparedQueryResult resultCharCount,uint32 accountId);
void InitDailyQuestResetTime();
void InitWeeklyQuestResetTime();

View File

@@ -206,7 +206,7 @@ public:
return true;
}
static bool HandleInstanceGetBossStateCommand(ChatHandler* handler, uint32 encounterId, Optional<PlayerIdentifier> player)
static bool HandleInstanceGetBossStateCommand(ChatHandler* handler, Optional<PlayerIdentifier> player)
{
// Character name must be provided when using this from console.
if (!player && !handler->GetSession())
@@ -237,15 +237,13 @@ public:
return false;
}
if (encounterId > map->GetInstanceScript()->GetEncounterCount())
for (uint8 i = 0; i < map->GetInstanceScript()->GetEncounterCount(); ++i)
{
handler->SendErrorMessage(LANG_BAD_VALUE);
return false;
uint32 state = map->GetInstanceScript()->GetBossState(i);
std::string stateName = InstanceScript::GetBossStateName(state);
handler->PSendSysMessage(LANG_COMMAND_INST_GET_BOSS_STATE, i, state, stateName);
}
uint32 state = map->GetInstanceScript()->GetBossState(encounterId);
std::string stateName = InstanceScript::GetBossStateName(state);
handler->PSendSysMessage(LANG_COMMAND_INST_GET_BOSS_STATE, encounterId, state, stateName);
return true;
}
};

View File

@@ -146,7 +146,8 @@ public:
{ "playall", HandlePlayAllCommand, SEC_GAMEMASTER, Console::No },
{ "skirmish", HandleSkirmishCommand, SEC_ADMINISTRATOR, Console::No },
{ "mailbox", HandleMailBoxCommand, SEC_MODERATOR, Console::No },
{ "string", HandleStringCommand, SEC_GAMEMASTER, Console::No }
{ "string", HandleStringCommand, SEC_GAMEMASTER, Console::No },
{ "opendoor", HandleOpenDoorCommand, SEC_GAMEMASTER, Console::No }
};
return commandTable;
@@ -3034,6 +3035,19 @@ public:
return true;
}
}
static bool HandleOpenDoorCommand(ChatHandler* handler, Optional<float> range)
{
if (GameObject* go = handler->GetPlayer()->FindNearestGameObjectOfType(GAMEOBJECT_TYPE_DOOR, range ? *range : 5.0f))
{
go->SetGoState(GO_STATE_ACTIVE);
handler->PSendSysMessage(LANG_CMD_DOOR_OPENED, go->GetName(), go->GetEntry());
return true;
}
handler->SendErrorMessage(LANG_CMD_NO_DOOR_FOUND, range ? *range : 5.0f);
return false;
}
};
void AddSC_misc_commandscript()

View File

@@ -385,19 +385,13 @@ struct npc_zuljin_vortex : public ScriptedAI
ChangeToNewPlayer();
}
void SpellHit(Unit* caster, SpellInfo const* spell) override
{
if (spell->Id == SPELL_ZAP_INFORM)
DoCast(caster, SPELL_ZAP_DAMAGE, true);
}
void ChangeToNewPlayer()
{
DoResetThreatList();
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true))
{
me->AddThreat(target, 10000000.0f);
}
if (WorldObject* summoner = GetSummoner())
if (Creature* zuljin = summoner->ToCreature())
if (Unit* target = zuljin->AI()->SelectTarget(SelectTargetMethod::Random, 0, 80.0f, true))
me->AddThreat(target, 10000000.0f);
}
void UpdateAI(uint32 /*diff*/) override
@@ -442,9 +436,33 @@ class spell_claw_rage_aura : public AuraScript
}
};
// 42577 - Zap
class spell_zuljin_zap : public SpellScript
{
PrepareSpellScript(spell_zuljin_zap);
bool Validate(SpellInfo const* /*spell*/) override
{
return ValidateSpellInfo({ SPELL_ZAP_DAMAGE });
}
void HandleScript(SpellEffIndex effIndex)
{
PreventHitDefaultEffect(effIndex);
if (Unit* victim = GetHitUnit())
victim->CastSpell(GetCaster(), SPELL_ZAP_DAMAGE, true);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_zuljin_zap::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
void AddSC_boss_zuljin()
{
RegisterZulAmanCreatureAI(boss_zuljin);
RegisterZulAmanCreatureAI(npc_zuljin_vortex);
RegisterSpellScript(spell_claw_rage_aura);
RegisterSpellScript(spell_zuljin_zap);
}

View File

@@ -112,7 +112,6 @@ public:
LoadBossBoundaries(boundaries);
LoadDoorData(doorData);
LoadSummonData(summonData);
_chestLooted = 0;
for (uint8 i = 0; i < RAND_VENDOR; ++i)
RandVendor[i] = NOT_STARTED;
@@ -149,10 +148,10 @@ public:
void OnGameObjectCreate(GameObject* go) override
{
if (go->GetEntry() == GO_GATE_HEXLORD)
CheckInstanceStatus();
InstanceScript::OnGameObjectCreate(go);
if (go->GetEntry() == GO_GATE_HEXLORD)
CheckInstanceStatus(go);
}
void SummonHostage(uint8 num)
@@ -189,10 +188,10 @@ public:
}
}
void CheckInstanceStatus()
void CheckInstanceStatus(GameObject* gate = nullptr)
{
if (AllBossesDone({ DATA_NALORAKK, DATA_AKILZON, DATA_JANALAI, DATA_HALAZZI }))
HandleGameObject(ObjectGuid::Empty, true, GetGameObject(DATA_HEXLORD_GATE));
HandleGameObject(ObjectGuid::Empty, true, gate ? gate : GetGameObject(DATA_HEXLORD_GATE));
}
void SetData(uint32 type, uint32 data) override
@@ -211,7 +210,10 @@ public:
_akilzonGauntlet = DONE;
}
else if (type == DATA_CHEST_LOOTED)
++_chestLooted;
{
uint8 chestCount = GetPersistentData(DATA_CHEST_COUNT);
StorePersistentData(DATA_CHEST_COUNT, ++chestCount);
}
}
void StartAkilzonGauntlet()
@@ -249,6 +251,23 @@ public:
creature->Respawn(true);
}
void OnUnitDeath(Unit* unit) override
{
Creature* creature = unit->ToCreature();
if (!creature)
return;
switch (creature->GetEntry())
{
case NPC_AMINISHI_PROTECTOR:
case NPC_AMANISHI_WIND_WALKER:
if (_akilzonGauntlet == NOT_STARTED && AkilzonTrash.contains(creature->GetGUID()))
creature->DespawnOrUnsummon(30s, 1s);
default:
break;
}
}
void OnCreatureEvade(Creature* creature) override
{
switch (creature->GetEntry())
@@ -337,7 +356,7 @@ public:
else if (type == TYPE_AKILZON_GAUNTLET)
return _akilzonGauntlet;
else if (type == DATA_CHEST_LOOTED)
return _chestLooted;
return GetPersistentData(DATA_CHEST_COUNT);
return 0;
}
@@ -348,7 +367,6 @@ public:
}
private:
uint16 _chestLooted;
uint32 RandVendor[RAND_VENDOR];
GuidSet AkilzonTrash;
EncounterState _akilzonGauntlet = NOT_STARTED;

View File

@@ -561,7 +561,7 @@ struct npc_amanishi_lookout : public NullCreatureAI
void MoveInLineOfSight(Unit* who) override
{
if (!me->IsWithinDist(who, 25.0f, false)) // distance not confirmed
if (!me->IsWithinDist(who, me->GetAggroRange(who), false))
return;
Player* player = who->GetCharmerOrOwnerPlayerOrPlayerItself();
@@ -596,6 +596,29 @@ private:
InstanceScript* _instance;
};
struct npc_eagle_trash_aggro_trigger : public ScriptedAI
{
npc_eagle_trash_aggro_trigger(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) {}
void MoveInLineOfSight(Unit* who) override
{
if (who->GetLevel() > 70)
return;
if (!me->IsWithinDist(who, me->GetAggroRange(who), false))
return;
Player* player = who->GetCharmerOrOwnerPlayerOrPlayerItself();
if (!player || player->IsGameMaster())
return;
if (_instance->GetData(TYPE_AKILZON_GAUNTLET) == NOT_STARTED)
_instance->SetData(TYPE_AKILZON_GAUNTLET, IN_PROGRESS);
}
private:
InstanceScript* _instance;
};
enum AmanishiTempest
{
GROUP_AKILZON_GAUNTLET = 1,
@@ -845,6 +868,7 @@ void AddSC_zulaman()
RegisterZulAmanCreatureAI(npc_harrison_jones);
RegisterSpellScript(spell_ritual_of_power);
RegisterZulAmanCreatureAI(npc_amanishi_lookout);
RegisterZulAmanCreatureAI(npc_eagle_trash_aggro_trigger);
RegisterZulAmanCreatureAI(npc_amanishi_tempest);
RegisterZulAmanCreatureAI(npc_amanishi_scout);
RegisterSpellScript(spell_alert_drums);

View File

@@ -90,14 +90,17 @@ enum GameobjectIds
enum MiscIds
{
// Persistent data
DATA_TIMED_RUN = 0,
DATA_CHEST_COUNT = 1,
ACTION_START_TIMED_RUN = 0,
ACTION_START_AKILZON_GAUNTLET = 1,
ACTION_RESET_AKILZON_GAUNTLET = 2,
GROUP_TIMED_RUN = 1
};
uint32 constexpr PersistentDataCount = 1;
uint32 constexpr PersistentDataCount = 2;
template <class AI, class T>
inline AI* GetZulAmanAI(T* obj)

View File

@@ -114,7 +114,17 @@ public:
Map::PlayerList const& players = instance->GetPlayers();
if (!players.IsEmpty())
if (Player* pPlayer = players.begin()->GetSource())
TeamIdInInstance = pPlayer->GetTeamId();
{
if (Group* group = pPlayer->GetGroup())
{
if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()))
TeamIdInInstance = Player::TeamIdForRace(gLeader->getRace());
else
TeamIdInInstance = pPlayer->GetTeamId();
}
else
TeamIdInInstance = pPlayer->GetTeamId();
}
}
switch (creature->GetEntry())
@@ -271,9 +281,25 @@ public:
// EVENT STUFF BELOW:
void OnPlayerEnter(Player* plr) override
void OnPlayerEnter(Player* player) override
{
if (DoNeedCleanup(plr))
if (TeamIdInInstance == TEAM_NEUTRAL)
{
if (Group* group = player->GetGroup())
{
if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()))
TeamIdInInstance = Player::TeamIdForRace(gLeader->getRace());
else
TeamIdInInstance = player->GetTeamId();
}
else
TeamIdInInstance = player->GetTeamId();
}
if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP))
player->SetFaction((TeamIdInInstance == TEAM_HORDE) ? 1610 : 1);
if (DoNeedCleanup(player))
{
InstanceCleanup();
}
@@ -281,6 +307,12 @@ public:
events.RescheduleEvent(EVENT_CHECK_PLAYERS, CLEANUP_CHECK_INTERVAL);
}
void OnPlayerLeave(Player* player) override
{
if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP))
player->SetFactionForRace(player->getRace());
}
bool DoNeedCleanup(Player* ignoredPlayer = nullptr)
{
uint8 aliveCount = 0;

View File

@@ -1203,8 +1203,24 @@ public:
if (Player* plr = itr->GetSource())
if (!plr->IsGameMaster())
{
TeamIdInInstance = plr->GetTeamId();
break;
if (Group* group = plr->GetGroup())
{
if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()))
{
TeamIdInInstance = Player::TeamIdForRace(gLeader->getRace());
break;
}
else
{
TeamIdInInstance = plr->GetTeamId();
break;
}
}
else
{
TeamIdInInstance = plr->GetTeamId();
break;
}
}
}
if (Creature* c = instance->GetCreature(TeamIdInInstance == TEAM_ALLIANCE ? NPC_VarianGUID : NPC_GarroshGUID))
@@ -1397,6 +1413,22 @@ public:
void OnPlayerEnter(Player* plr) override
{
if (TeamIdInInstance == TEAM_NEUTRAL)
{
if (Group* group = plr->GetGroup())
{
if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()))
TeamIdInInstance = Player::TeamIdForRace(gLeader->getRace());
else
TeamIdInInstance = plr->GetTeamId();
}
else
TeamIdInInstance = plr->GetTeamId();
}
if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP))
plr->SetFaction((TeamIdInInstance == TEAM_HORDE) ? 1610 : 1);
if (instance->IsHeroic())
{
plr->SendUpdateWorldState(UPDATE_STATE_UI_SHOW, 1);
@@ -1416,6 +1448,12 @@ public:
events.RescheduleEvent(EVENT_CHECK_PLAYERS, 5s);
}
void OnPlayerLeave(Player* player) override
{
if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP))
player->SetFactionForRace(player->getRace());
}
bool DoNeedCleanup(Player* ignoredPlayer = nullptr)
{
uint8 aliveCount = 0;

View File

@@ -19,6 +19,7 @@
#include "Player.h"
#include "ScriptedCreature.h"
#include "forge_of_souls.h"
#include "Group.h"
BossBoundaryData const boundaries =
{
@@ -69,8 +70,24 @@ public:
return false;
}
void OnPlayerEnter(Player* /*plr*/) override
void OnPlayerEnter(Player* player) override
{
if (teamIdInInstance == TEAM_NEUTRAL)
{
if (Group* group = player->GetGroup())
{
if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()))
teamIdInInstance = Player::TeamIdForRace(gLeader->getRace());
else
teamIdInInstance = player->GetTeamId();
}
else
teamIdInInstance = player->GetTeamId();
}
if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP))
player->SetFaction((teamIdInInstance == TEAM_HORDE) ? 1610 : 1);
// this will happen only after crash and loading the instance from db
if (m_auiEncounter[0] == DONE && m_auiEncounter[1] == DONE && (!NPC_LeaderSecondGUID || !instance->GetCreature(NPC_LeaderSecondGUID)))
{
@@ -79,6 +96,12 @@ public:
}
}
void OnPlayerLeave(Player* player) override
{
if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP))
player->SetFactionForRace(player->getRace());
}
void OnCreatureCreate(Creature* creature) override
{
if (teamIdInInstance == TEAM_NEUTRAL)
@@ -86,7 +109,17 @@ public:
Map::PlayerList const& players = instance->GetPlayers();
if (!players.IsEmpty())
if (Player* player = players.begin()->GetSource())
teamIdInInstance = player->GetTeamId();
{
if (Group* group = player->GetGroup())
{
if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()))
teamIdInInstance = Player::TeamIdForRace(gLeader->getRace());
else
teamIdInInstance = player->GetTeamId();
}
else
teamIdInInstance = player->GetTeamId();
}
}
switch (creature->GetEntry())

View File

@@ -20,6 +20,7 @@
#include "Transport.h"
#include "halls_of_reflection.h"
#include "InstanceScript.h"
#include "Group.h"
class UtherBatteredHiltEvent : public BasicEvent
{
@@ -213,6 +214,31 @@ public:
return (instance->HavePlayers() && WaveNumber) || IsDuringLKFight; // during LK fight npcs are active and will unset this variable
}
void OnPlayerEnter(Player* player) override
{
if (TeamIdInInstance == TEAM_NEUTRAL)
{
if (Group* group = player->GetGroup())
{
if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()))
TeamIdInInstance = Player::TeamIdForRace(gLeader->getRace());
else
TeamIdInInstance = player->GetTeamId();
}
else
TeamIdInInstance = player->GetTeamId();
}
if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP))
player->SetFaction((TeamIdInInstance == TEAM_HORDE) ? 1610 : 1);
}
void OnPlayerLeave(Player* player) override
{
if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP))
player->SetFactionForRace(player->getRace());
}
void OnCreatureCreate(Creature* creature) override
{
if (TeamIdInInstance == TEAM_NEUTRAL)
@@ -223,8 +249,24 @@ public:
if (Player* p = itr->GetSource())
if (!p->IsGameMaster())
{
TeamIdInInstance = p->GetTeamId();
break;
if (Group* group = p->GetGroup())
{
if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()))
{
TeamIdInInstance = Player::TeamIdForRace(gLeader->getRace());
break;
}
else
{
TeamIdInInstance = p->GetTeamId();
break;
}
}
else
{
TeamIdInInstance = p->GetTeamId();
break;
}
}
}

View File

@@ -20,6 +20,7 @@
#include "Player.h"
#include "ScriptedCreature.h"
#include "pit_of_saron.h"
#include "Group.h"
class instance_pit_of_saron : public InstanceMapScript
{
@@ -75,13 +76,35 @@ public:
return false;
}
void OnPlayerEnter(Player* /*plr*/) override
void OnPlayerEnter(Player* player) override
{
if (teamIdInInstance == TEAM_NEUTRAL)
{
if (Group* group = player->GetGroup())
{
if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()))
teamIdInInstance = Player::TeamIdForRace(gLeader->getRace());
else
teamIdInInstance = player->GetTeamId();
}
else
teamIdInInstance = player->GetTeamId();
}
if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP))
player->SetFaction((teamIdInInstance == TEAM_HORDE) ? 1610 : 1);
instance->LoadGrid(LeaderIntroPos.GetPositionX(), LeaderIntroPos.GetPositionY());
if (Creature* c = instance->GetCreature(GetGuidData(DATA_LEADER_FIRST_GUID)))
c->AI()->SetData(DATA_START_INTRO, 0);
}
void OnPlayerLeave(Player* player) override
{
if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP))
player->SetFactionForRace(player->getRace());
}
uint32 GetCreatureEntry(ObjectGuid::LowType /*guidLow*/, CreatureData const* data) override
{
if (teamIdInInstance == TEAM_NEUTRAL)
@@ -89,7 +112,17 @@ public:
Map::PlayerList const& players = instance->GetPlayers();
if (!players.IsEmpty())
if (Player* player = players.begin()->GetSource())
teamIdInInstance = player->GetTeamId();
{
if (Group* group = player->GetGroup())
{
if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()))
teamIdInInstance = Player::TeamIdForRace(gLeader->getRace());
else
teamIdInInstance = player->GetTeamId();
}
else
teamIdInInstance = player->GetTeamId();
}
}
uint32 entry = data->id1;
@@ -115,7 +148,17 @@ public:
Map::PlayerList const& players = instance->GetPlayers();
if (!players.IsEmpty())
if (Player* player = players.begin()->GetSource())
teamIdInInstance = player->GetTeamId();
{
if (Group* group = player->GetGroup())
{
if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()))
teamIdInInstance = Player::TeamIdForRace(gLeader->getRace());
else
teamIdInInstance = player->GetTeamId();
}
else
teamIdInInstance = player->GetTeamId();
}
}
switch (creature->GetEntry())

View File

@@ -262,7 +262,20 @@ public:
void OnPlayerEnter(Player* player) override
{
if (TeamIdInInstance == TEAM_NEUTRAL)
TeamIdInInstance = player->GetTeamId();
{
if (Group* group = player->GetGroup())
{
if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()))
TeamIdInInstance = Player::TeamIdForRace(gLeader->getRace());
else
TeamIdInInstance = player->GetTeamId();
}
else
TeamIdInInstance = player->GetTeamId();
}
if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP))
player->SetFaction((TeamIdInInstance == TEAM_HORDE) ? 1610 : 1);
// for professor putricide hc
DoRemoveAurasDueToSpellOnPlayers(SPELL_GAS_VARIABLE);
@@ -293,6 +306,12 @@ public:
}
}
void OnPlayerLeave(Player* player) override
{
if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP))
player->SetFactionForRace(player->getRace());
}
void OnCreatureCreate(Creature* creature) override
{
if (TeamIdInInstance == TEAM_NEUTRAL)
@@ -300,7 +319,17 @@ public:
Map::PlayerList const& players = instance->GetPlayers();
if (!players.IsEmpty())
if (Player* player = players.begin()->GetSource())
TeamIdInInstance = player->GetTeamId();
{
if (Group* group = player->GetGroup())
{
if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()))
TeamIdInInstance = Player::TeamIdForRace(gLeader->getRace());
else
TeamIdInInstance = player->GetTeamId();
}
else
TeamIdInInstance = player->GetTeamId();
}
}
// apply ICC buff to pets/summons
@@ -537,6 +566,7 @@ public:
}
InstanceScript::OnCreatureCreate(creature);
}
void OnCreatureRemove(Creature* creature) override
@@ -554,7 +584,17 @@ public:
Map::PlayerList const& players = instance->GetPlayers();
if (!players.IsEmpty())
if (Player* player = players.begin()->GetSource())
TeamIdInInstance = player->GetTeamId();
{
if (Group* group = player->GetGroup())
{
if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()))
TeamIdInInstance = Player::TeamIdForRace(gLeader->getRace());
else
TeamIdInInstance = player->GetTeamId();
}
else
TeamIdInInstance = player->GetTeamId();
}
}
uint32 entry = data->id1;
@@ -599,7 +639,17 @@ public:
Map::PlayerList const& players = instance->GetPlayers();
if (!players.IsEmpty())
if (Player* player = players.begin()->GetSource())
TeamIdInInstance = player->GetTeamId();
{
if (Group* group = player->GetGroup())
{
if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()))
TeamIdInInstance = Player::TeamIdForRace(gLeader->getRace());
else
TeamIdInInstance = player->GetTeamId();
}
else
TeamIdInInstance = player->GetTeamId();
}
}
switch (entry)
@@ -703,7 +753,17 @@ public:
Map::PlayerList const& players = instance->GetPlayers();
if (!players.IsEmpty())
if (Player* player = players.begin()->GetSource())
TeamIdInInstance = player->GetTeamId();
{
if (Group* group = player->GetGroup())
{
if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()))
TeamIdInInstance = Player::TeamIdForRace(gLeader->getRace());
else
TeamIdInInstance = player->GetTeamId();
}
else
TeamIdInInstance = player->GetTeamId();
}
}
switch (go->GetEntry())

View File

@@ -20,6 +20,7 @@
#include "ScriptedCreature.h"
#include "nexus.h"
#include "Player.h"
#include "Group.h"
DoorData const doorData[] =
{
@@ -48,15 +49,29 @@ public:
SetHeaders(DataHeader);
SetBossNumber(MAX_ENCOUNTERS);
LoadDoorData(doorData);
TeamIdInInstance = TEAM_NEUTRAL;
}
void OnCreatureCreate(Creature* creature) override
{
Map::PlayerList const& players = instance->GetPlayers();
TeamId TeamIdInInstance = TEAM_NEUTRAL;
if (!players.IsEmpty())
if (Player* pPlayer = players.begin()->GetSource())
TeamIdInInstance = pPlayer->GetTeamId();
if (TeamIdInInstance == TEAM_NEUTRAL)
{
Map::PlayerList const& players = instance->GetPlayers();
if (!players.IsEmpty())
if (Player* pPlayer = players.begin()->GetSource())
{
if (Group* group = pPlayer->GetGroup())
{
if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()))
TeamIdInInstance = Player::TeamIdForRace(gLeader->getRace());
else
TeamIdInInstance = pPlayer->GetTeamId();
}
else
TeamIdInInstance = pPlayer->GetTeamId();
}
}
switch (creature->GetEntry())
{
@@ -88,6 +103,31 @@ public:
}
}
void OnPlayerEnter(Player* player) override
{
if (TeamIdInInstance == TEAM_NEUTRAL)
{
if (Group* group = player->GetGroup())
{
if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()))
TeamIdInInstance = Player::TeamIdForRace(gLeader->getRace());
else
TeamIdInInstance = player->GetTeamId();
}
else
TeamIdInInstance = player->GetTeamId();
}
if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP))
player->SetFaction((TeamIdInInstance == TEAM_HORDE) ? 1610 : 1);
}
void OnPlayerLeave(Player* player) override
{
if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP))
player->SetFactionForRace(player->getRace());
}
void OnGameObjectCreate(GameObject* gameObject) override
{
switch (gameObject->GetEntry())
@@ -154,6 +194,8 @@ public:
(*i)->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE);
return true;
}
protected:
TeamId TeamIdInInstance;
};
};

View File

@@ -21,6 +21,7 @@
#include "InstanceMapScript.h"
#include "InstanceScript.h"
#include "shattered_halls.h"
#include "Group.h"
ObjectData const creatureData[] =
{
@@ -66,7 +67,26 @@ public:
void OnPlayerEnter(Player* player) override
{
if (TeamIdInInstance == TEAM_NEUTRAL)
TeamIdInInstance = player->GetTeamId();
{
if (Group* group = player->GetGroup())
{
if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()))
TeamIdInInstance = Player::TeamIdForRace(gLeader->getRace());
else
TeamIdInInstance = player->GetTeamId();
}
else
TeamIdInInstance = player->GetTeamId();
}
if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP))
player->SetFaction((TeamIdInInstance == TEAM_HORDE) ? 1610 : 1);
}
void OnPlayerLeave(Player* player) override
{
if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP))
player->SetFactionForRace(player->getRace());
}
void OnCreatureCreate(Creature* creature) override
@@ -76,7 +96,17 @@ public:
Map::PlayerList const& players = instance->GetPlayers();
if (!players.IsEmpty())
if (Player* player = players.begin()->GetSource())
TeamIdInInstance = player->GetTeamId();
{
if (Group* group = player->GetGroup())
{
if (Player* gLeader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()))
TeamIdInInstance = Player::TeamIdForRace(gLeader->getRace());
else
TeamIdInInstance = player->GetTeamId();
}
else
TeamIdInInstance = player->GetTeamId();
}
}
switch (creature->GetEntry())
@@ -84,22 +114,26 @@ public:
case NPC_SHATTERED_EXECUTIONER:
if (RescueTimer > 25 * MINUTE * IN_MILLISECONDS)
creature->AddLootMode(2);
executionerGUID = creature->GetGUID();
ExecutionerGUID = creature->GetGUID();
break;
case NPC_RIFLEMAN_BROWNBEARD:
if (TeamIdInInstance == TEAM_HORDE)
creature->UpdateEntry(NPC_KORAG_PROUDMANE);
prisonerGUID[0] = creature->GetGUID();
PrisonerGUID[0] = creature->GetGUID();
break;
case NPC_CAPTAIN_ALINA:
if (TeamIdInInstance == TEAM_HORDE)
creature->UpdateEntry(NPC_CAPTAIN_BONESHATTER);
prisonerGUID[1] = creature->GetGUID();
PrisonerGUID[1] = creature->GetGUID();
break;
case NPC_PRIVATE_JACINT:
if (TeamIdInInstance == TEAM_HORDE)
creature->UpdateEntry(NPC_SCOUT_ORGARR);
prisonerGUID[2] = creature->GetGUID();
PrisonerGUID[2] = creature->GetGUID();
break;
case NPC_RANDY_WHIZZLESPROCKET:
if (TeamIdInInstance == TEAM_HORDE)
creature->UpdateEntry(NPC_DRISELLA);
break;
}
InstanceScript::OnCreatureCreate(creature);
@@ -126,9 +160,9 @@ public:
case DATA_PRISONER_1:
case DATA_PRISONER_2:
case DATA_PRISONER_3:
return prisonerGUID[data - DATA_PRISONER_1];
return PrisonerGUID[data - DATA_PRISONER_1];
case DATA_EXECUTIONER:
return executionerGUID;
return ExecutionerGUID;
}
return ObjectGuid::Empty;
@@ -144,22 +178,22 @@ public:
{
DoRemoveAurasDueToSpellOnPlayers(SPELL_KARGATHS_EXECUTIONER_1);
DoCastSpellOnPlayers(SPELL_KARGATHS_EXECUTIONER_2);
if (Creature* prisoner = instance->GetCreature(prisonerGUID[0]))
if (Creature* prisoner = instance->GetCreature(PrisonerGUID[0]))
Unit::Kill(prisoner, prisoner);
if (Creature* executioner = instance->GetCreature(executionerGUID))
if (Creature* executioner = instance->GetCreature(ExecutionerGUID))
executioner->RemoveLootMode(2);
}
else if ((RescueTimer / IN_MILLISECONDS) == 15 * MINUTE)
{
DoRemoveAurasDueToSpellOnPlayers(SPELL_KARGATHS_EXECUTIONER_2);
DoCastSpellOnPlayers(SPELL_KARGATHS_EXECUTIONER_3);
if (Creature* prisoner = instance->GetCreature(prisonerGUID[1]))
if (Creature* prisoner = instance->GetCreature(PrisonerGUID[1]))
Unit::Kill(prisoner, prisoner);
}
else if ((RescueTimer / IN_MILLISECONDS) == 0)
{
DoRemoveAurasDueToSpellOnPlayers(SPELL_KARGATHS_EXECUTIONER_3);
if (Creature* prisoner = instance->GetCreature(prisonerGUID[2]))
if (Creature* prisoner = instance->GetCreature(PrisonerGUID[2]))
Unit::Kill(prisoner, prisoner);
}
}
@@ -176,8 +210,8 @@ public:
}
protected:
ObjectGuid executionerGUID;
ObjectGuid prisonerGUID[3];
ObjectGuid ExecutionerGUID;
ObjectGuid PrisonerGUID[3];
uint32 RescueTimer;
TeamId TeamIdInInstance;
};

View File

@@ -66,6 +66,11 @@ enum CreatureIds
NPC_KORAG_PROUDMANE = 17295,
NPC_CAPTAIN_BONESHATTER = 17296,
NPC_SCOUT_ORGARR = 17297,
//Drisella
NPC_DRISELLA = 17294,
// Randy Whizzlesprocket
NPC_RANDY_WHIZZLESPROCKET = 17288,
};
enum GameobjectIds

View File

@@ -340,7 +340,8 @@ private:
/* 55640 - Lightweave Embroidery
67698 - Item - Coliseum 25 Normal Healer Trinket
67752 - Item - Coliseum 25 Heroic Healer Trinket
69762 - Unchained Magic */
69762 - Unchained Magic
43983 - Energy Storm */
class spell_gen_allow_proc_from_spells_with_cost : public AuraScript
{
PrepareAuraScript(spell_gen_allow_proc_from_spells_with_cost);
@@ -5379,6 +5380,26 @@ class spell_pet_spellhit_expertise_spellpen_scaling : public AuraScript
}
};
// 7098 - Curse of Mending
// 39647 - Curse of Mending
class spell_gen_proc_on_victim : public AuraScript
{
PrepareAuraScript(spell_gen_proc_on_victim);
void OnProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo)
{
PreventDefaultAction();
if (Unit* target = eventInfo.GetActionTarget())
GetUnitOwner()->CastSpell(target, GetSpellInfo()->Effects[EFFECT_0].TriggerSpell, true);
}
void Register() override
{
OnEffectProc += AuraEffectProcFn(spell_gen_proc_on_victim::OnProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL);
}
};
void AddSC_generic_spell_scripts()
{
RegisterSpellScript(spell_silithyst);
@@ -5538,4 +5559,5 @@ void AddSC_generic_spell_scripts()
RegisterSpellScript(spell_gen_steal_weapon);
RegisterSpellScript(spell_gen_set_health);
RegisterSpellScript(spell_pet_spellhit_expertise_spellpen_scaling);
RegisterSpellScript(spell_gen_proc_on_victim);
}