Merge branch 'azerothcore:master' into Playerbot

This commit is contained in:
ZhengPeiRu21
2022-04-04 07:53:51 -06:00
committed by GitHub
35 changed files with 8418 additions and 82 deletions

View File

@@ -219,6 +219,12 @@ void CreatureAI::EnterEvadeMode()
}
}
Reset();
if (me->IsVehicle()) // use the same sequence of addtoworld, aireset may remove all summons!
{
me->GetVehicleKit()->Reset(true);
}
// despawn bosses at reset - only verified tbc/woltk bosses with this reset type - add bosses in last line respectively (dungeon/raid) and increase array limit
CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(me->GetEntry());
if (cInfo && cInfo->HasFlagsExtra(CREATURE_FLAG_EXTRA_HARD_RESET))
@@ -226,14 +232,6 @@ void CreatureAI::EnterEvadeMode()
me->DespawnOnEvade();
me->m_Events.AddEvent(new PhasedRespawn(*me), me->m_Events.CalculateTime(20000));
}
else // bosses will run back to the spawnpoint at reset
{
Reset();
if (me->IsVehicle()) // use the same sequence of addtoworld, aireset may remove all summons!
{
me->GetVehicleKit()->Reset(true);
}
}
}
/*void CreatureAI::AttackedBy(Unit* attacker)

View File

@@ -2013,18 +2013,6 @@ void Creature::DespawnOnEvade()
{
SetVisible(false);
AI()->SummonedCreatureDespawnAll();
RemoveEvadeAuras();
float x, y, z, o;
GetRespawnPosition(x, y, z, &o);
SetHomePosition(x, y, z, o);
SetPosition(x, y, z, o);
if (IsFalling())
{
RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING);
}
StopMoving();
}
void Creature::RespawnOnEvade()

View File

@@ -2272,8 +2272,8 @@ void WorldObject::SetZoneScript()
{
if (Map* map = FindMap())
{
if (map->IsDungeon())
m_zoneScript = (ZoneScript*)map->ToInstanceMap()->GetInstanceScript();
if (InstanceMap* instanceMap = map->ToInstanceMap())
m_zoneScript = reinterpret_cast<ZoneScript*>(instanceMap->GetInstanceScript());
else if (!map->IsBattlegroundOrArena())
{
uint32 zoneId = GetZoneId();

View File

@@ -2009,13 +2009,8 @@ void WorldSession::HandleCharFactionOrRaceChangeCallback(std::shared_ptr<Charact
return;
}
// xinef: check money
bool valid = Player::TeamIdForRace(oldRace) == Player::TeamIdForRace(factionChangeInfo->Race);
if ((level < 10 && money <= 0) || (level > 10 && level <= 30 && money <= 3000000) || (level > 30 && level <= 50 && money <= 10000000) ||
(level > 50 && level <= 70 && money <= 50000000) || (level > 70 && money <= 200000000))
valid = true;
if (!valid)
uint32 maxMoney = sWorld->getIntConfig(CONFIG_CHANGE_FACTION_MAX_MONEY);
if (maxMoney && money > maxMoney)
{
SendCharFactionChange(CHAR_CREATE_CHARACTER_GOLD_LIMIT, factionChangeInfo.get());
return;

View File

@@ -227,7 +227,7 @@ void WorldSession::HandleActivateTaxiOpcode(WorldPacket& recvData)
ObjectGuid guid;
std::vector<uint32> nodes;
nodes.resize(2);
GetPlayer()->SetCanTeleport(true);
recvData >> guid >> nodes[0] >> nodes[1];
LOG_DEBUG("network", "WORLD: Received CMSG_ACTIVATETAXI from {} to {}", nodes[0], nodes[1]);
Creature* npc = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_FLIGHTMASTER);
@@ -251,6 +251,7 @@ void WorldSession::HandleActivateTaxiOpcode(WorldPacket& recvData)
void WorldSession::SendActivateTaxiReply(ActivateTaxiReply reply)
{
GetPlayer()->SetCanTeleport(true);
WorldPacket data(SMSG_ACTIVATETAXIREPLY, 4);
data << uint32(reply);
SendPacket(&data);

View File

@@ -4474,10 +4474,22 @@ void Spell::SendSpellStart()
if (m_spellInfo->HasAttribute(SPELL_ATTR0_USES_RANGED_SLOT) || m_spellInfo->HasAttribute(SPELL_ATTR0_CU_NEEDS_AMMO_DATA))
castFlags |= CAST_FLAG_PROJECTILE;
if ((m_caster->GetTypeId() == TYPEID_PLAYER || (m_caster->GetTypeId() == TYPEID_UNIT && m_caster->IsPet()))
&& m_spellInfo->PowerType != POWER_HEALTH && m_powerCost != 0)
if (m_caster->GetTypeId() == TYPEID_PLAYER || m_caster->IsPet())
{
castFlags |= CAST_FLAG_POWER_LEFT_SELF;
switch (m_spellInfo->PowerType)
{
case POWER_HEALTH:
break;
case POWER_RUNE:
castFlags |= CAST_FLAG_POWER_LEFT_SELF;
break;
default:
if (m_powerCost != 0)
{
castFlags |= CAST_FLAG_POWER_LEFT_SELF;
}
break;
}
}
if (m_spellInfo->RuneCostID && m_spellInfo->PowerType == POWER_RUNE)
@@ -4532,10 +4544,23 @@ void Spell::SendSpellGo()
if (m_spellInfo->HasAttribute(SPELL_ATTR0_USES_RANGED_SLOT) || m_spellInfo->HasAttribute(SPELL_ATTR0_CU_NEEDS_AMMO_DATA))
castFlags |= CAST_FLAG_PROJECTILE; // arrows/bullets visual
if ((m_caster->GetTypeId() == TYPEID_PLAYER || (m_caster->GetTypeId() == TYPEID_UNIT && m_caster->IsPet()))
&& m_spellInfo->PowerType != POWER_HEALTH && m_powerCost != 0) // should only be sent to self, but the current messaging doesn't make that possible
// should only be sent to self, but the current messaging doesn't make that possible
if (m_caster->GetTypeId() == TYPEID_PLAYER || m_caster->IsPet())
{
castFlags |= CAST_FLAG_POWER_LEFT_SELF;
switch (m_spellInfo->PowerType)
{
case POWER_HEALTH:
break;
case POWER_RUNE:
castFlags |= CAST_FLAG_POWER_LEFT_SELF;
break;
default:
if (m_powerCost != 0)
{
castFlags |= CAST_FLAG_POWER_LEFT_SELF;
}
break;
}
}
if ((m_caster->GetTypeId() == TYPEID_PLAYER)

View File

@@ -398,6 +398,7 @@ enum WorldIntConfigs
CONFIG_LOOT_NEED_BEFORE_GREED_ILVL_RESTRICTION,
CONFIG_LFG_MAX_KICK_COUNT,
CONFIG_LFG_KICK_PREVENTION_TIMER,
CONFIG_CHANGE_FACTION_MAX_MONEY,
INT_CONFIG_VALUE_COUNT
};

View File

@@ -1264,6 +1264,8 @@ void World::LoadConfigSettings(bool reload)
m_bool_configs[CONFIG_ALLOW_JOIN_BG_AND_LFG] = sConfigMgr->GetOption<bool>("JoinBGAndLFG.Enable", false);
m_int_configs[CONFIG_CHANGE_FACTION_MAX_MONEY] = sConfigMgr->GetOption<uint32>("ChangeFaction.MaxMoney", 0);
///- Read the "Data" directory from the config file
std::string dataPath = sConfigMgr->GetOption<std::string>("DataDir", "./");
if (dataPath.empty() || (dataPath.at(dataPath.length() - 1) != '/' && dataPath.at(dataPath.length() - 1) != '\\'))

View File

@@ -119,6 +119,7 @@ public:
{ "setskill", HandleSetSkillCommand, SEC_GAMEMASTER, Console::No },
{ "pinfo", HandlePInfoCommand, SEC_GAMEMASTER, Console::Yes },
{ "respawn", HandleRespawnCommand, SEC_GAMEMASTER, Console::No },
{ "respawn all", HandleRespawnAllCommand, SEC_GAMEMASTER, Console::No },
{ "mute", HandleMuteCommand, SEC_GAMEMASTER, Console::Yes },
{ "mutehistory", HandleMuteInfoCommand, SEC_GAMEMASTER, Console::Yes },
{ "unmute", HandleUnmuteCommand, SEC_GAMEMASTER, Console::Yes },
@@ -2333,7 +2334,6 @@ public:
{
Player* player = handler->GetSession()->GetPlayer();
// accept only explicitly selected target (not implicitly self targeting case)
Unit* target = handler->getSelectedUnit();
if (player->GetTarget() && target)
{
@@ -2351,6 +2351,15 @@ public:
return true;
}
handler->SendSysMessage(LANG_SELECT_CREATURE);
handler->SetSentErrorMessage(true);
return false;
}
static bool HandleRespawnAllCommand(ChatHandler* handler)
{
Player* player = handler->GetSession()->GetPlayer();
CellCoord p(Acore::ComputeCellCoord(player->GetPositionX(), player->GetPositionY()));
Cell cell(p);
cell.SetNoCreate();

View File

@@ -221,7 +221,7 @@ class go_suppression_device : public GameObjectScript
me->SetGoState(GO_STATE_READY);
me->SetLootState(GO_READY);
me->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
_events.ScheduleEvent(EVENT_SUPPRESSION_CAST, 1000);
_events.ScheduleEvent(EVENT_SUPPRESSION_CAST, 5000);
me->Respawn();
}

View File

@@ -215,6 +215,11 @@ public:
events.ScheduleEvent(EVENT_FRENZY, 15000);
}
bool CanAIAttack(Unit const* victim) const override
{
return !victim->HasAura(SPELL_TIMELAPSE);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
@@ -248,21 +253,32 @@ public:
case EVENT_AFFLICTION:
{
uint32 afflictionSpellID = RAND(SPELL_BROODAF_BLUE, SPELL_BROODAF_BLACK, SPELL_BROODAF_RED, SPELL_BROODAF_BRONZE, SPELL_BROODAF_GREEN);
std::vector<Player*> playerTargets;
Map::PlayerList const& players = me->GetMap()->GetPlayers();
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
{
if (Player* player = itr->GetSource()->ToPlayer())
{
DoCast(player, afflictionSpellID, true);
if (!player->IsGameMaster() && !player->IsSpectator() && player->IsAlive())
{
playerTargets.push_back(player);
}
}
}
if (player->HasAura(SPELL_BROODAF_BLUE) &&
player->HasAura(SPELL_BROODAF_BLACK) &&
player->HasAura(SPELL_BROODAF_RED) &&
player->HasAura(SPELL_BROODAF_BRONZE) &&
player->HasAura(SPELL_BROODAF_GREEN))
{
DoCast(player, SPELL_CHROMATIC_MUT_1);
}
if (playerTargets.size() > 12)
{
Acore::Containers::RandomResize(playerTargets, 12);
}
for (Player* player : playerTargets)
{
DoCast(player, afflictionSpellID, true);
if (player->HasAura(SPELL_BROODAF_BLUE) && player->HasAura(SPELL_BROODAF_BLACK) && player->HasAura(SPELL_BROODAF_RED) &&
player->HasAura(SPELL_BROODAF_BRONZE) && player->HasAura(SPELL_BROODAF_GREEN))
{
DoCast(player, SPELL_CHROMATIC_MUT_1);
}
}
}

View File

@@ -53,10 +53,14 @@ enum Events
EVENT_SUCCESS_1,
EVENT_SUCCESS_2,
EVENT_SUCCESS_3,
// Drakonid Spawner
EVENT_SPAWN_CHROMATIC_DRAKONID,
// EVENT_SPAWN_ADDS, // placeholder, already defined above.
ACTION_RESET = 0,
ACTION_KILLED = 1,
ACTION_ADD_KILLED = 2
ACTION_ADD_KILLED = 2,
ACTION_SPAWNER_STOP = 3
};
enum Says
@@ -140,6 +144,7 @@ enum Spells
SPELL_SPAWN_BRONZE_DRAKONID = 22657,
SPELL_SPAWN_BLUE_DRAKONID = 22658,
SPELL_SPAWN_CHROMATIC_DRAKONID = 22680,
SPELL_SPAWN_DRAKONID_GEN = 22653,
// Nefarian
SPELL_SHADOWFLAME_INITIAL = 22992,
@@ -437,9 +442,11 @@ public:
events.CancelEvent(EVENT_SILENCE);
DoCastSelf(SPELL_ROOT_SELF, true);
me->SetVisible(false);
// Despawn the spawners.
summons.DespawnEntry(_nefarianLeftTunnel);
summons.DespawnEntry(_nefarianRightTunnel);
// Stop spawning adds
EntryCheckPredicate pred(_nefarianRightTunnel);
summons.DoAction(ACTION_SPAWNER_STOP, pred);
EntryCheckPredicate pred2(_nefarianLeftTunnel);
summons.DoAction(ACTION_SPAWNER_STOP, pred2);
return;
}
events.ScheduleEvent(EVENT_CHECK_PHASE_2, 1000);
@@ -624,7 +631,7 @@ struct boss_nefarian : public BossAI
break;
case EVENT_TAILLASH:
// Cast NYI since we need a better check for behind target
DoCastVictim(SPELL_TAILLASH);
DoCastAOE(SPELL_TAILLASH);
events.ScheduleEvent(EVENT_TAILLASH, 10000);
break;
case EVENT_CLASSCALL:
@@ -883,6 +890,37 @@ struct npc_corrupted_totem : public ScriptedAI
bool _auraAdded;
};
struct npc_drakonid_spawner : public ScriptedAI
{
npc_drakonid_spawner(Creature* creature) : ScriptedAI(creature) { }
void DoAction(int32 action) override
{
if (action == ACTION_SPAWNER_STOP)
{
me->RemoveAurasDueToSpell(SPELL_SPAWN_DRAKONID_GEN);
_scheduler.CancelAll();
}
}
void IsSummonedBy(Unit* /*summoner*/) override
{
DoCastSelf(SPELL_SPAWN_DRAKONID_GEN);
_scheduler.Schedule(10s, 60s, [this](TaskContext /*context*/)
{
DoCastSelf(SPELL_SPAWN_CHROMATIC_DRAKONID);
});
}
void UpdateAI(uint32 diff) override
{
_scheduler.Update(diff);
}
protected:
TaskScheduler _scheduler;
};
std::unordered_map<uint32, uint8> const classCallSpells =
{
{ SPELL_MAGE, CLASS_MAGE },
@@ -1211,6 +1249,7 @@ void AddSC_boss_nefarian()
new boss_victor_nefarius();
RegisterCreatureAI(boss_nefarian);
RegisterCreatureAI(npc_corrupted_totem);
RegisterCreatureAI(npc_drakonid_spawner);
RegisterSpellScript(spell_class_call_handler);
RegisterSpellScript(aura_class_call_wild_magic);
RegisterSpellScript(aura_class_call_siphon_blessing);

View File

@@ -393,8 +393,9 @@ public:
case NPC_CHROMATIC_DRAKONID:
case NPC_GREEN_DRAKONID:
case NPC_RED_DRAKONID:
if (Creature* summon = unit->ToCreature())
if (Creature* summon = unit->ToTempSummon())
{
summon->SetCorpseDelay(DAY * IN_MILLISECONDS);
summon->UpdateEntry(NPC_BONE_CONSTRUCT);
summon->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
summon->SetReactState(REACT_PASSIVE);
@@ -407,6 +408,18 @@ public:
nefarius->AI()->DoAction(ACTION_NEFARIUS_ADD_KILLED);
}
}
else // Something happened, try another way
{
if (Creature* nefarius = summon->FindNearestCreature(NPC_VICTOR_NEFARIUS, 500.f, true))
{
victorNefariusGUID = nefarius->GetGUID();
if (nefarius->AI())
{
nefarius->AI()->DoAction(ACTION_NEFARIUS_ADD_KILLED);
}
}
}
}
break;
}

View File

@@ -3709,6 +3709,15 @@ EnablePlayerSettings = 0
JoinBGAndLFG.Enable = 0
#
# ChangeFaction.MaxMoney
# Description: Maximum amount of gold allowed on the character to perform a faction change.
# Default: 0 - Disabled
# > 0 - Enabled (money in copper)
# Example: If set to 10000, the maximum amount of money allowed on the character would be 1 gold.
ChangeFaction.MaxMoney = 0
#
###################################################################################################