/** * NeedGroupBuff() * return boolean Returns true if more than two targets in the bot's group need the group buff. * * params:groupBuffSpellId uint32 the spell ID of the group buff like Arcane Brillance * params:singleBuffSpellId uint32 the spell ID of the single target buff equivalent of the group buff like Arcane Intellect for group buff Arcane Brillance * return false if false is returned, the bot is expected to perform a buff check for the single target buff of the group buff. * */ bool PlayerbotClassAI::NeedGroupBuff(uint32 groupBuffSpellId, uint32 singleBuffSpellId) { if (!m_bot) return false; uint8 numberOfGroupTargets = 0; // Check group players to avoid using regeant and mana with an expensive group buff // when only two players or less need it if (m_bot->GetGroup()) { Group::MemberSlotList const& groupSlot = m_bot->GetGroup()->GetMemberSlots(); for (Group::member_citerator itr = groupSlot.begin(); itr != groupSlot.end(); itr++) { Player *groupMember = sObjectMgr.GetPlayer(itr->guid); if (!groupMember || !groupMember->isAlive()) continue; // Check if group member needs buff if (!groupMember->HasAura(groupBuffSpellId, EFFECT_INDEX_0) && !groupMember->HasAura(singleBuffSpellId, EFFECT_INDEX_0)) numberOfGroupTargets++; // Don't forget about pet Pet * pet = groupMember->GetPet(); if (pet && !pet->HasAuraType(SPELL_AURA_MOD_UNATTACKABLE) && (pet->HasAura(groupBuffSpellId, EFFECT_INDEX_0) || pet->HasAura(singleBuffSpellId, EFFECT_INDEX_0))) numberOfGroupTargets++; } // treshold set to 2 targets because beyond that value, the group buff cost is cheaper in mana if (numberOfGroupTargets < 3) return false; // In doubt, buff everyone return true; } else return false; // no group, no group buff }
void BattleGroundIC::HandleBuffs() { for (BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr) { Player *plr = sObjectMgr.GetPlayer(itr->first); if (plr) { // quarry / refinery buffs for (uint8 node = BG_IC_NODE_QUARRY; node <= BG_IC_NODE_REFINERY; node++) { if (m_Nodes[node] >= BG_IC_NODE_TYPE_OCCUPIED) { if ((node == BG_IC_NODE_QUARRY) && (!plr->HasAura(SPELL_QUARRY)) && (plr->GetTeam() == (m_Nodes[node] - BG_IC_NODE_TYPE_OCCUPIED == 0 ? ALLIANCE : HORDE))) plr->CastSpell(plr, SPELL_QUARRY, true); else if ((node == BG_IC_NODE_REFINERY) && (!plr->HasAura(SPELL_REFINERY)) && (plr->GetTeam() == (m_Nodes[node] - BG_IC_NODE_TYPE_OCCUPIED == 0 ? ALLIANCE : HORDE))) plr->CastSpell(plr, SPELL_REFINERY, true); } else { if (node == BG_IC_NODE_QUARRY) plr->RemoveAurasDueToSpell(SPELL_QUARRY); else plr->RemoveAurasDueToSpell(SPELL_REFINERY); } } // parachute handling float height = plr->GetPositionZ(); if (height >= 180) continue; if (height < 180 && height > 140 && (!plr->HasAura(SPELL_PARACHUTE))) plr->CastSpell(plr, SPELL_PARACHUTE, true); } } }
void UpdatePortals() // Here we handle the beams' behavior { for (int j=0; j<3; ++j) // j = color if (Creature *portal = Unit::GetCreature(*me, PortalGUID[j])) { // the one who's been casted upon before Unit *current = Unit::GetUnit(*portal, BeamTarget[j]); // temporary store for the best suitable beam reciever Unit *pTarget = me; if (Map* map = me->GetMap()) { Map::PlayerList const& players = map->GetPlayers(); // get the best suitable target for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i) { Player* p = i->getSource(); if (p && p->isAlive() // alive && (!pTarget || pTarget->GetDistance2d(portal)>p->GetDistance2d(portal)) // closer than current best && !p->HasAura(PlayerDebuff[j],0) // not exhausted && !p->HasAura(PlayerBuff[(j+1)%3],0) // not on another beam && !p->HasAura(PlayerBuff[(j+2)%3],0) && IsBetween(me, p, portal)) // on the beam pTarget = p; } } // buff the target if (pTarget->GetTypeId() == TYPEID_PLAYER) pTarget->AddAura(PlayerBuff[j], pTarget); else pTarget->AddAura(NetherBuff[j], pTarget); // cast visual beam on the chosen target if switched // simple target switching isn't working -> using BeamerGUID to cast (workaround) if (!current || pTarget != current) { BeamTarget[j] = pTarget->GetGUID(); // remove currently beaming portal if (Creature *beamer = Unit::GetCreature(*portal, BeamerGUID[j])) { beamer->CastSpell(pTarget, PortalBeam[j], false); beamer->SetVisibility(VISIBILITY_OFF); beamer->DealDamage(beamer, beamer->GetMaxHealth()); beamer->RemoveFromWorld(); BeamerGUID[j] = 0; } // create new one and start beaming on the target if (Creature *beamer = portal->SummonCreature(PortalID[j],portal->GetPositionX(),portal->GetPositionY(),portal->GetPositionZ(),portal->GetOrientation(),TEMPSUMMON_TIMED_DESPAWN,60000)) { beamer->CastSpell(pTarget, PortalBeam[j], false); BeamerGUID[j] = beamer->GetGUID(); } } // aggro target if Red Beam if (j == RED_PORTAL && me->getVictim() != pTarget && pTarget->GetTypeId() == TYPEID_PLAYER) me->getThreatManager().addThreat(pTarget, 100000.0f+DoGetThreat(me->getVictim())); } }
//Enable\Disable Invisible mode static bool HandleGMVisibleCommand(ChatHandler* handler, const char* args) { if(!*args) { handler->PSendSysMessage(LANG_YOU_ARE, handler->GetSession()->GetPlayer()->isGMVisible() ? handler->GetTrinityString(LANG_VISIBLE) : handler->GetTrinityString(LANG_INVISIBLE)); return true; } std::string argstr = (char*)args; Player* pPlayer = handler->GetSession()->GetPlayer(); if(argstr == "on") { if(pPlayer->HasAura(37800, 0)) pPlayer->RemoveAurasDueToSpell(37800); handler->GetSession()->GetPlayer()->SetGMVisible(true); handler->GetSession()->SendNotification(LANG_INVISIBLE_VISIBLE); return true; } else if(argstr == "off") { handler->GetSession()->GetPlayer()->SetGMVisible(false); handler->GetSession()->SendNotification(LANG_INVISIBLE_INVISIBLE); pPlayer->AddAura(37800, pPlayer); return true; } handler->SendSysMessage(LANG_USE_BOL); handler->SetSentErrorMessage(true); return false; }
bool GOUse_go_gauntlet_gate(Player* pPlayer, GameObject* pGo) { ScriptedInstance* pInstance = (ScriptedInstance*)pGo->GetInstanceData(); if (!pInstance) return false; if (pInstance->GetData(TYPE_BARON_RUN) != NOT_STARTED) return false; if (Group* pGroup = pPlayer->GetGroup()) { for (GroupReference* itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* pGroupie = itr->getSource(); if (!pGroupie) continue; if (!pGroupie->HasAura(SPELL_BARON_ULTIMATUM)) pGroupie->CastSpell(pGroupie, SPELL_BARON_ULTIMATUM, TRIGGERED_OLD_TRIGGERED); } } else { if (!pPlayer->HasAura(SPELL_BARON_ULTIMATUM)) pPlayer->CastSpell(pPlayer, SPELL_BARON_ULTIMATUM, TRIGGERED_OLD_TRIGGERED); } pInstance->SetData(TYPE_BARON_RUN, IN_PROGRESS); return false; }
bool GossipHello(Player* player) override { if (instance->GetData(TYPE_BARON_RUN) != NOT_STARTED) return false; if (Group* group = player->GetGroup()) { for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* pGroupie = itr->GetSource(); if (!pGroupie || !pGroupie->IsInMap(player)) continue; if (pGroupie->GetQuestStatus(QUEST_DEAD_MAN_PLEA) == QUEST_STATUS_INCOMPLETE && !pGroupie->HasAura(SPELL_BARON_ULTIMATUM) && pGroupie->GetMap() == me->GetMap()) pGroupie->CastSpell(pGroupie, SPELL_BARON_ULTIMATUM, true); } } else if (player->GetQuestStatus(QUEST_DEAD_MAN_PLEA) == QUEST_STATUS_INCOMPLETE && !player->HasAura(SPELL_BARON_ULTIMATUM) && player->GetMap() == me->GetMap()) player->CastSpell(player, SPELL_BARON_ULTIMATUM, true); instance->SetData(TYPE_BARON_RUN, IN_PROGRESS); return false; }
void WorldSession::HandleChatMessageDNDOpcode(WorldPackets::Chat::ChatMessageDND& chatMessageDND) { Player* sender = GetPlayer(); if (sender->IsInCombat()) return; if (sender->HasAura(GM_SILENCE_AURA)) { SendNotification(GetTrinityString(LANG_GM_SILENCE), sender->GetName().c_str()); return; } if (sender->isDND()) // Already DND { if (chatMessageDND.Text.empty()) sender->ToggleDND(); // Remove DND else sender->autoReplyMsg = chatMessageDND.Text; // Update message } else // New DND mode { sender->autoReplyMsg = chatMessageDND.Text.empty() ? GetTrinityString(LANG_PLAYER_DND_DEFAULT) : chatMessageDND.Text; if (sender->isAFK()) sender->ToggleAFK(); sender->ToggleDND(); } sScriptMgr->OnPlayerChat(sender, CHAT_MSG_DND, LANG_UNIVERSAL, chatMessageDND.Text); }
bool OnGossipHello(Player* player, GameObject* go) { InstanceScript* instance = go->GetInstanceScript(); if (!instance) return false; if (instance->GetData(TYPE_BARON_RUN) != NOT_STARTED) return false; if (Group* group = player->GetGroup()) { for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* pGroupie = itr->getSource(); if (!pGroupie) continue; if (pGroupie->GetQuestStatus(QUEST_DEAD_MAN_PLEA) == QUEST_STATUS_INCOMPLETE && !pGroupie->HasAura(SPELL_BARON_ULTIMATUM) && pGroupie->GetMap() == go->GetMap()) pGroupie->CastSpell(pGroupie, SPELL_BARON_ULTIMATUM, true); } } else if (player->GetQuestStatus(QUEST_DEAD_MAN_PLEA) == QUEST_STATUS_INCOMPLETE && !player->HasAura(SPELL_BARON_ULTIMATUM) && player->GetMap() == go->GetMap()) player->CastSpell(player, SPELL_BARON_ULTIMATUM, true); instance->SetData(TYPE_BARON_RUN, IN_PROGRESS); return false; }
void VortexHandling() { if(Creature* malygos = instance->GetCreature(malygosGUID)) { std::list<HostileReference*> m_threatlist = malygos->getThreatManager().getThreatList(); for(std::list<uint64>::const_iterator itr_vortex = vortexTriggers.begin(); itr_vortex != vortexTriggers.end(); ++itr_vortex) { if(m_threatlist.empty()) return; uint8 counter = 0; Creature* pCreature = instance->GetCreature(*itr_vortex); if(pCreature) { // each trigger have to cast the spell to 5 players. for(std::list<HostileReference*>::const_iterator itr = m_threatlist.begin(); itr!= m_threatlist.end(); ++itr) { if(counter > 5) break; if(Unit* pTarget = (*itr)->getTarget()) { Player* pPlayer = pTarget->ToPlayer(); if(!pPlayer || pPlayer->isGameMaster() || pPlayer->HasAura(SPELL_VORTEX_4)) continue; pPlayer->CastSpell(pCreature, SPELL_VORTEX_4, true); counter++; } } } } } }
bool GOHello_go_gauntlet_gate(Player* pPlayer, GameObject* pGo) { ScriptedInstance* pInstance = (ScriptedInstance*)pGo->GetInstanceData(); if (!pInstance) return false; if (pInstance->GetData(TYPE_BARON_RUN) != NOT_STARTED) return false; if (Group* pGroup = pPlayer->GetGroup()) { for (GroupReference* itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* pGroupie = itr->GetSource(); if (!pGroupie) continue; if (pGroupie->GetQuestStatus(QUEST_DEAD_MAN_PLEA) == QUEST_STATUS_INCOMPLETE && !pGroupie->HasAura(SPELL_BARON_ULTIMATUM, 0) && pGroupie->GetMap() == pGo->GetMap()) pGroupie->CastSpell(pGroupie, SPELL_BARON_ULTIMATUM, true); } } else if (pPlayer->GetQuestStatus(QUEST_DEAD_MAN_PLEA) == QUEST_STATUS_INCOMPLETE && !pPlayer->HasAura(SPELL_BARON_ULTIMATUM, 0) && pPlayer->GetMap() == pGo->GetMap()) pPlayer->CastSpell(pPlayer, SPELL_BARON_ULTIMATUM, true); pInstance->SetData(TYPE_BARON_RUN, IN_PROGRESS); return false; }
void MoveInLineOfSight(Unit* who) override { if (!who || !who->IsInWorld() || who->GetZoneId() != 4395) return; if (!me->IsWithinDist(who, 65.0f, false)) return; Player* player = who->GetCharmerOrOwnerPlayerOrPlayerItself(); if (!player || player->IsGameMaster() || player->IsBeingTeleported() || // If player has Disguise aura for quest A Meeting With The Magister or An Audience With The Arcanist, do not teleport it away but let it pass player->HasAura(SPELL_SUNREAVER_DISGUISE_FEMALE) || player->HasAura(SPELL_SUNREAVER_DISGUISE_MALE) || player->HasAura(SPELL_SILVER_COVENANT_DISGUISE_FEMALE) || player->HasAura(SPELL_SILVER_COVENANT_DISGUISE_MALE)) return; switch (me->GetEntry()) { case NPC_SILVER_COVENANT_GUARDIAN_MAGE: if (player->GetTeam() == HORDE) // Horde unit found in Alliance area { if (GetClosestCreatureWithEntry(me, NPC_APPLEBOUGH_A, 32.0f)) { if (me->isInBackInMap(who, 12.0f)) // In my line of sight, "outdoors", and behind me DoCast(who, SPELL_TRESPASSER_A); // Teleport the Horde unit out } else // In my line of sight, and "indoors" DoCast(who, SPELL_TRESPASSER_A); // Teleport the Horde unit out } break; case NPC_SUNREAVER_GUARDIAN_MAGE: if (player->GetTeam() == ALLIANCE) // Alliance unit found in Horde area { if (GetClosestCreatureWithEntry(me, NPC_SWEETBERRY_H, 32.0f)) { if (me->isInBackInMap(who, 12.0f)) // In my line of sight, "outdoors", and behind me DoCast(who, SPELL_TRESPASSER_H); // Teleport the Alliance unit out } else // In my line of sight, and "indoors" DoCast(who, SPELL_TRESPASSER_H); // Teleport the Alliance unit out } break; } me->SetOrientation(me->GetHomePosition().GetOrientation()); return; }
void AIUpdate() { Player* plr = _gameobject->GetMapMgr()->GetInterface()->GetPlayerNearestCoords( _gameobject->GetPositionX(), _gameobject->GetPositionY(), _gameobject->GetPositionZ() ); if( !plr ) return; if( _gameobject->CalcDistance( _gameobject, plr ) <= 1.050000f && !plr->HasAura( 26274 ) ) // aura given by the PX-238 Winter Wondervolt { plr->CastSpell( plr, 26275 , true ); // Spell that change into random gnome dispalyid (respect male & female) } }
void HandleResidue() { Player* player = GetUnitOwner()->ToPlayer(); if (!player) return; if (player->HasAura(SPELL_ORANGE_BLIGHT_RESIDUE)) return; player->CastSpell(player, SPELL_ORANGE_BLIGHT_RESIDUE, TRIGGERED_FULL_MASK); }
Unit* PlayerWithDarkEssence() { Map::PlayerList const &PlayerList = m_creature->GetMap()->GetPlayers(); for (Map::PlayerList::const_iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr) { Player* pPlayer = itr->getSource(); if (pPlayer && pPlayer->HasAura(SPELL_DARK_ESSENCE)) return pPlayer; } return NULL; }
void HandleResidue() { Player* target = GetHitPlayer(); if (!target) return; if (target->HasAura(SPELL_GREEN_BLIGHT_RESIDUE)) return; uint32 questId = target->GetMap()->Is25ManRaid() ? QUEST_RESIDUE_RENDEZVOUS_25 : QUEST_RESIDUE_RENDEZVOUS_10; if (target->GetQuestStatus(questId) != QUEST_STATUS_INCOMPLETE) return; target->CastSpell(target, SPELL_GREEN_BLIGHT_RESIDUE, TRIGGERED_FULL_MASK); }
void HandleDummy(SpellEffIndex /*effIndex*/) { if (GetCaster()->GetTypeId() != TYPEID_PLAYER) return; int32 chargeBasePoints0 = GetEffectValue(); Player* caster = GetCaster()->ToPlayer(); caster->CastCustomSpell(caster, SPELL_CHARGE, &chargeBasePoints0, NULL, NULL, true); //Juggernaut crit bonus if (caster->HasAura(SPELL_JUGGERNAUT_CRIT_BONUS_TALENT)) { caster->CastSpell(caster, SPELL_JUGGERNAUT_CRIT_BONUS_BUFF, true); caster->AddSpellCooldown(SPELL_INTERCEPT, 0, time(NULL) + 30); } }
Player* GetPlayerInMap() { Map::PlayerList const& players = instance->GetPlayers(); if (!players.isEmpty()) { for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) { Player* plr = itr->getSource(); if (plr && !plr->HasAura(45839,0)) return plr; } } debug_log("TSCR: Instance Sunwell Plateau: GetPlayerInMap, but PlayerList is empty!"); return NULL; }
Player const* GetPlayerInMap() const { Map::PlayerList const& players = instance->GetPlayers(); if (!players.isEmpty()) { for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) { Player* player = itr->GetSource(); if (player && !player->HasAura(45839, 0)) return player; } } //else // TC_LOG_DEBUG("scripts", "Instance Sunwell Plateau: GetPlayerInMap, but PlayerList is empty!"); return NULL; }
void MindControlGhost() { /************************************************************************/ /** NOTE FOR FUTURE DEVELOPER: PROPERLY IMPLEMENT THE GHOST PORTION *****/ /** ONLY AFTER MaNGOS FULLY IMPLEMENTS MIND CONTROL ABILITIES *****/ /** THE CURRENT CODE IN THIS FUNCTION IS ONLY THE BEGINNING OF *****/ /** WHAT IS FULLY NECESSARY FOR GOREFIEND TO BE 100% COMPLETE *****/ /************************************************************************/ Player* pGhost = NULL; if (m_ghostGuid) pGhost = m_creature->GetMap()->GetPlayer(m_ghostGuid); if (pGhost && pGhost->isAlive() && pGhost->HasAura(SPELL_SHADOW_OF_DEATH, EFFECT_INDEX_0)) { /*float x,y,z; pGhost->GetPosition(x,y,z); Creature* control = m_creature->SummonCreature(CREATURE_GHOST, x, y, z, 0, TEMPSUMMON_TIMED_DESAWN, 30000); if (control) { ((Player*)pGhost)->Possess(control); pGhost->DealDamage(pGhost, pGhost->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); }*/ for(uint8 i = 0; i < 4; ++i) { float fX = CalculateRandomLocation(pGhost->GetPositionX(), 10); float fY = CalculateRandomLocation(pGhost->GetPositionY(), 10); if (Creature* pConstruct = m_creature->SummonCreature(NPC_SHADOWY_CONSTRUCT, fX, fY, pGhost->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 45000)) { pConstruct->CastSpell(pConstruct, SPELL_PASSIVE_SHADOWFORM, true); SetThreatList(pConstruct); // Use same function as Doom Blossom to set Threat List. if (mob_shadowy_constructAI* pConstructAI = dynamic_cast<mob_shadowy_constructAI*>(pConstruct->AI())) pConstructAI->m_ghostGuid = m_ghostGuid; Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1); pConstruct->GetMotionMaster()->MoveChase(pTarget ? pTarget : m_creature->getVictim()); } } } }
void CorpseRemoved(uint32&) override { // TODO: would be better to cast a dummy spell Map* pMap = m_creature->GetMap(); if (!pMap || !pMap->IsBattleGround()) return; Map::PlayerList const& PlayerList = pMap->GetPlayers(); for (Map::PlayerList::const_iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr) { Player* pPlayer = itr->getSource(); if (!pPlayer || !pPlayer->IsWithinDistInMap(m_creature, 20.0f) || !pPlayer->HasAura(SPELL_WAITING_TO_RESURRECT)) continue; // repop player again - now this node won't be counted and another node is searched pPlayer->RepopAtGraveyard(); } }
void JustDied(Unit* Killer) { Map *map = m_creature->GetMap(); if(!map->IsDungeon()) return; Map::PlayerList const &players = map->GetPlayers(); if(players.getSize()==0) return; for(Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) { Player* plr = itr->getSource(); if (!plr->GetSession() || !plr->isAlive()) continue; if (plr->HasAura(SCALDING_WATER,0)) plr->RemoveAurasDueToSpell(SCALDING_WATER); } if (pInstance) pInstance->SetData(DATA_THELURKERBELOWEVENT, DONE); }
void CorpseRemoved(uint32&) override { // TODO: would be better to cast a dummy spell Map* pMap = m_creature->GetMap(); if (!pMap || !pMap->IsBattleGround()) return; std::list<Player*> nearPlayers; MaNGOS::AnyPlayerInObjectRangeCheck rangeChecker(m_creature, 20.0f); MaNGOS::PlayerListSearcher<MaNGOS::AnyPlayerInObjectRangeCheck> searcher(nearPlayers, rangeChecker); Cell::VisitGridObjects(m_creature, searcher, 20.0f); for (auto& i : nearPlayers) { Player* pPlayer = i; if (!pPlayer || !pPlayer->HasAura(SPELL_WAITING_TO_RESURRECT)) continue; // repop player again - now this node won't be counted and another node is searched pPlayer->RepopAtGraveyard(); } }
void HandleEnergize(SpellEffIndex effIndex) { Player* caster = GetCaster()->ToPlayer(); // No boomy, no deal. if (caster->GetPrimaryTalentTree(caster->GetActiveSpec()) != TALENT_TREE_DRUID_BALANCE) return; switch (GetSpellInfo()->Id) { case SPELL_DRUID_WRATH: { energizeAmount = -GetSpellInfo()->Effects[effIndex].BasePoints; // -13 // If we are set to fill the lunar side or we've just logged in with 0 power.. if ((!caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE_MARKER) && caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE_MARKER)) || caster->GetPower(POWER_ECLIPSE) == 0) { caster->CastCustomSpell(caster, SPELL_DRUID_ECLIPSE_GENERAL_ENERGIZE, &energizeAmount, 0, 0, true); // If the energize was due to 0 power, cast the eclipse marker aura if (!caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE_MARKER)) caster->CastSpell(caster, SPELL_DRUID_LUNAR_ECLIPSE_MARKER, true); } // The energizing effect brought us out of the solar eclipse, remove the aura if (caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE) && caster->GetPower(POWER_ECLIPSE) <= 0) caster->RemoveAurasDueToSpell(SPELL_DRUID_SOLAR_ECLIPSE); break; } case SPELL_DRUID_STARFIRE: { energizeAmount = GetSpellInfo()->Effects[effIndex].BasePoints; // 20 // If we are set to fill the solar side or we've just logged in with 0 power.. if ((!caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE_MARKER) && caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE_MARKER)) || caster->GetPower(POWER_ECLIPSE) == 0) { caster->CastCustomSpell(caster, SPELL_DRUID_ECLIPSE_GENERAL_ENERGIZE, &energizeAmount, 0, 0, true); // If the energize was due to 0 power, cast the eclipse marker aura if (!caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE_MARKER)) caster->CastSpell(caster, SPELL_DRUID_SOLAR_ECLIPSE_MARKER, true); } // The energizing effect brought us out of the lunar eclipse, remove the aura if (caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE) && caster->GetPower(POWER_ECLIPSE) >= 0) caster->RemoveAura(SPELL_DRUID_LUNAR_ECLIPSE); break; } case SPELL_DRUID_STARSURGE: { // If we are set to fill the solar side or we've just logged in with 0 power (confirmed with sniffs) if ((!caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE_MARKER) && caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE_MARKER)) || caster->GetPower(POWER_ECLIPSE) == 0) { energizeAmount = GetSpellInfo()->Effects[effIndex].BasePoints; // 15 caster->CastCustomSpell(caster, SPELL_DRUID_STARSURGE_ENERGIZE, &energizeAmount, 0, 0, true); // If the energize was due to 0 power, cast the eclipse marker aura if (!caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE_MARKER)) caster->CastSpell(caster, SPELL_DRUID_SOLAR_ECLIPSE_MARKER, true); } else if (!caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE_MARKER) && caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE_MARKER)) { energizeAmount = -GetSpellInfo()->Effects[effIndex].BasePoints; // -15 caster->CastCustomSpell(caster, SPELL_DRUID_STARSURGE_ENERGIZE, &energizeAmount, 0, 0, true); } // The energizing effect brought us out of the lunar eclipse, remove the aura if (caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE) && caster->GetPower(POWER_ECLIPSE) >= 0) caster->RemoveAura(SPELL_DRUID_LUNAR_ECLIPSE); // The energizing effect brought us out of the solar eclipse, remove the aura else if (caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE) && caster->GetPower(POWER_ECLIPSE) <= 0) caster->RemoveAura(SPELL_DRUID_SOLAR_ECLIPSE); break; } } }
void WorldSession::HandleSendMail(WorldPacket& recvData) { ObjectGuid mailbox; uint64 money, COD; std::string receiver, subject, body; uint32 bodyLength, subjectLength, receiverLength; uint32 unk1, unk2; uint8 itemCount; recvData >> unk1 >> unk2; // both unknown recvData >> COD >> money; // money and cod mailbox[0] = recvData.ReadBit(); mailbox[6] = recvData.ReadBit(); mailbox[4] = recvData.ReadBit(); mailbox[1] = recvData.ReadBit(); bodyLength = recvData.ReadBits(11); mailbox[3] = recvData.ReadBit(); receiverLength = recvData.ReadBits(9); mailbox[7] = recvData.ReadBit(); mailbox[5] = recvData.ReadBit(); itemCount = recvData.ReadBits(5); // attached items count if (itemCount > MAX_MAIL_ITEMS) // client limit { GetPlayer()->SendMailResult(0, MAIL_SEND, MAIL_ERR_TOO_MANY_ATTACHMENTS); recvData.rfinish(); // set to end to avoid warnings spam return; } ObjectGuid itemGuids[MAX_MAIL_ITEMS]; uint8 bitOrder[8] = {1, 7, 2, 5, 0, 6, 3, 4}; for (uint8 i = 0; i < itemCount; ++i) recvData.ReadBitInOrder(itemGuids[i], bitOrder); subjectLength = recvData.ReadBits(9); mailbox[2] = recvData.ReadBit(); for (uint8 i = 0; i < itemCount; ++i) { recvData.read_skip<uint8>(); // item slot in mail, not used recvData.ReadByteSeq(itemGuids[i][3]); recvData.ReadByteSeq(itemGuids[i][0]); recvData.ReadByteSeq(itemGuids[i][2]); recvData.ReadByteSeq(itemGuids[i][1]); recvData.ReadByteSeq(itemGuids[i][6]); recvData.ReadByteSeq(itemGuids[i][5]); recvData.ReadByteSeq(itemGuids[i][7]); recvData.ReadByteSeq(itemGuids[i][4]); } recvData.ReadByteSeq(mailbox[1]); body = recvData.ReadString(bodyLength); recvData.ReadByteSeq(mailbox[0]); subject = recvData.ReadString(subjectLength); recvData.ReadByteSeq(mailbox[2]); recvData.ReadByteSeq(mailbox[6]); recvData.ReadByteSeq(mailbox[5]); recvData.ReadByteSeq(mailbox[7]); recvData.ReadByteSeq(mailbox[3]); recvData.ReadByteSeq(mailbox[4]); receiver = recvData.ReadString(receiverLength); // packet read complete, now do check if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) return; if (receiver.empty()) return; Player* player = _player; if (player->getLevel() < sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ)) { SendNotification(GetTrinityString(LANG_MAIL_SENDER_REQ), sWorld->getIntConfig(CONFIG_MAIL_LEVEL_REQ)); return; } uint64 rc = 0; if (normalizePlayerName(receiver)) rc = sObjectMgr->GetPlayerGUIDByName(receiver); if (!rc) { sLog->outInfo(LOG_FILTER_NETWORKIO, "Player %u is sending mail to %s (GUID: not existed!) with subject %s and body %s includes %u items, " UI64FMTD " copper and " UI64FMTD " COD copper with unk1 = %u, unk2 = %u", player->GetGUIDLow(), receiver.c_str(), subject.c_str(), body.c_str(), itemCount, money, COD, unk1, unk2); player->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_NOT_FOUND); return; } sLog->outInfo(LOG_FILTER_NETWORKIO, "Player %u is sending mail to %s (GUID: %u) with subject %s and body %s includes %u items, " UI64FMTD " copper and " UI64FMTD " COD copper with unk1 = %u, unk2 = %u", player->GetGUIDLow(), receiver.c_str(), GUID_LOPART(rc), subject.c_str(), body.c_str(), itemCount, money, COD, unk1, unk2); if (player->GetGUID() == rc) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANNOT_SEND_TO_SELF); return; } uint32 cost = itemCount ? 30 * itemCount : 30; // price hardcoded in client uint64 reqmoney = cost + money; if (!player->HasEnoughMoney(reqmoney) && !player->isGameMaster()) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_ENOUGH_MONEY); return; } Player* receive = ObjectAccessor::FindPlayer(rc); uint32 rc_team = 0; uint8 mails_count = 0; //do not allow to send to one player more than 100 mails if (receive) { rc_team = receive->GetTeam(); mails_count = receive->GetMailSize(); } //do not allow to have more than 100 mails in mailbox.. mails count is in opcode uint8!!! - so max can be 255.. if (mails_count > 100) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_CAP_REACHED); return; } // test the receiver's Faction... or all items are account bound bool accountBound = itemCount ? true : false; for (uint8 i = 0; i < itemCount; ++i) { Item* item = player->GetItemByGuid(itemGuids[i]); if (item) { ItemTemplate const* itemProto = item->GetTemplate(); if (!itemProto || !(itemProto->Flags & ITEM_PROTO_FLAG_BIND_TO_ACCOUNT)) { accountBound = false; break; } } } if (!accountBound && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL) && player->GetTeam() != rc_team && AccountMgr::IsPlayerAccount(GetSecurity())) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_YOUR_TEAM); return; } uint32 rc_account = receive ? receive->GetSession()->GetAccountId() : sObjectMgr->GetPlayerAccountIdByGUID(rc); Item* items[MAX_MAIL_ITEMS]; for (uint8 i = 0; i < itemCount; ++i) { if (!itemGuids[i]) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID); return; } Item* item = player->GetItemByGuid(itemGuids[i]); // prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to mail) if (!item) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID); return; } if (!item->CanBeTraded(true)) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_MAIL_BOUND_ITEM); return; } if (item->IsBoundAccountWide() && item->IsSoulBound() && player->GetSession()->GetAccountId() != rc_account) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_NOT_SAME_ACCOUNT); return; } if (item->GetTemplate()->Flags & ITEM_PROTO_FLAG_CONJURED || item->GetUInt32Value(ITEM_FIELD_DURATION)) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_MAIL_BOUND_ITEM); return; } if (COD && item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED)) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANT_SEND_WRAPPED_COD); return; } if (item->IsNotEmptyBag()) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_DESTROY_NONEMPTY_BAG); return; } items[i] = item; } // Check for spamming if (!UpdateAntispamCount()) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_INTERNAL_ERROR); SendNotification(GetTrinityString(LANG_ANTISPAM_ERROR)); return; } // Check for special symbols if (!checkMailText(subject) || !checkMailText(body)) { player->SendMailResult(0, MAIL_SEND, MAIL_ERR_INTERNAL_ERROR); return; } player->SendMailResult(0, MAIL_SEND, MAIL_OK); player->ModifyMoney(-int64(reqmoney)); player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL, cost); bool needItemDelay = false; MailDraft draft(subject, body); SQLTransaction trans = CharacterDatabase.BeginTransaction(); if (itemCount > 0 || money > 0) { if (itemCount > 0) { for (uint8 i = 0; i < itemCount; ++i) { Item* item = items[i]; if (!AccountMgr::IsPlayerAccount(GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) { sLog->outCommand(GetAccountId(), "", GetPlayer()->GetGUIDLow(), GetPlayer()->GetName(), rc_account, "", 0, receiver.c_str(), "GM %s (Account: %u) mail item: %s (Entry: %u Count: %u) to player: %s (Account: %u)", GetPlayerName().c_str(), GetAccountId(), item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetCount(), receiver.c_str(), rc_account); } item->SetNotRefundable(GetPlayer()); // makes the item no longer refundable player->MoveItemFromInventory(items[i]->GetBagSlot(), item->GetSlot(), true); item->DeleteFromInventoryDB(trans); // deletes item from character's inventory item->SetOwnerGUID(rc); item->SaveToDB(trans); // recursive and not have transaction guard into self, item not in inventory and can be save standalone draft.AddItem(item); } // if item send to character at another account, then apply item delivery delay needItemDelay = player->GetSession()->GetAccountId() != rc_account; } if (money > 0 && !AccountMgr::IsPlayerAccount(GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) { //TODO: character guid sLog->outCommand(GetAccountId(), "", GetPlayer()->GetGUIDLow(), GetPlayer()->GetName(), rc_account, "", 0, receiver.c_str(), "GM %s (Account: %u) mail money: %u to player: %s (Account: %u)", GetPlayerName().c_str(), GetAccountId(), money, receiver.c_str(), rc_account); } } // Guild Mail if (receive && receive->GetGuildId() && player->GetGuildId()) if (player->HasAura(83951) && (player->GetGuildId() == receive->GetGuildId())) needItemDelay = false; // If theres is an item, there is a one hour delivery delay if sent to another account's character. uint32 deliver_delay = needItemDelay ? sWorld->getIntConfig(CONFIG_MAIL_DELIVERY_DELAY) : 0; // will delete item or place to receiver mail list draft .AddMoney(money) .AddCOD(COD) .SendMailTo(trans, MailReceiver(receive, GUID_LOPART(rc)), MailSender(player), body.empty() ? MAIL_CHECK_MASK_COPIED : MAIL_CHECK_MASK_HAS_BODY, deliver_delay); player->SaveInventoryAndGoldToDB(trans); CharacterDatabase.CommitTransaction(trans); }
void WorldSession::HandleChatMessage(ChatMsg type, uint32 lang, std::string msg, std::string target /*= ""*/) { Player* sender = GetPlayer(); if (lang == LANG_UNIVERSAL && type != CHAT_MSG_EMOTE) { TC_LOG_ERROR("entities.player.cheat", "CMSG_MESSAGECHAT: Possible hacking-attempt: %s tried to send a message in universal language", GetPlayerInfo().c_str()); SendNotification(LANG_UNKNOWN_LANGUAGE); return; } // prevent talking at unknown language (cheating) LanguageDesc const* langDesc = GetLanguageDescByID(lang); if (!langDesc) { SendNotification(LANG_UNKNOWN_LANGUAGE); return; } if (langDesc->skill_id != 0 && !sender->HasSkill(langDesc->skill_id)) { // also check SPELL_AURA_COMPREHEND_LANGUAGE (client offers option to speak in that language) Unit::AuraEffectList const& langAuras = sender->GetAuraEffectsByType(SPELL_AURA_COMPREHEND_LANGUAGE); bool foundAura = false; for (Unit::AuraEffectList::const_iterator i = langAuras.begin(); i != langAuras.end(); ++i) { if ((*i)->GetMiscValue() == int32(lang)) { foundAura = true; break; } } if (!foundAura) { SendNotification(LANG_NOT_LEARNED_LANGUAGE); return; } } // send in universal language if player in .gm on mode (ignore spell effects) if (sender->IsGameMaster()) lang = LANG_UNIVERSAL; else { // send in universal language in two side iteration allowed mode if (HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT)) lang = LANG_UNIVERSAL; else { switch (type) { case CHAT_MSG_PARTY: case CHAT_MSG_RAID: case CHAT_MSG_RAID_WARNING: // allow two side chat at group channel if two side group allowed if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP)) lang = LANG_UNIVERSAL; break; case CHAT_MSG_GUILD: case CHAT_MSG_OFFICER: // allow two side chat at guild channel if two side guild allowed if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD)) lang = LANG_UNIVERSAL; break; default: break; } } // but overwrite it by SPELL_AURA_MOD_LANGUAGE auras (only single case used) Unit::AuraEffectList const& ModLangAuras = sender->GetAuraEffectsByType(SPELL_AURA_MOD_LANGUAGE); if (!ModLangAuras.empty()) lang = ModLangAuras.front()->GetMiscValue(); } if (!sender->CanSpeak()) { std::string timeStr = secsToTimeString(m_muteTime - time(NULL)); SendNotification(GetTrinityString(LANG_WAIT_BEFORE_SPEAKING), timeStr.c_str()); return; } if (sender->HasAura(GM_SILENCE_AURA) && type != CHAT_MSG_WHISPER) { SendNotification(GetTrinityString(LANG_GM_SILENCE), sender->GetName().c_str()); return; } if (msg.empty()) return; if (ChatHandler(this).ParseCommands(msg.c_str())) return; // Strip invisible characters for non-addon messages if (sWorld->getBoolConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING)) stripLineInvisibleChars(msg); if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY) && !ChatHandler(this).isValidChatMessage(msg.c_str())) { TC_LOG_ERROR("network", "Player %s (%s) sent a chatmessage with an invalid link: %s", GetPlayer()->GetName().c_str(), GetPlayer()->GetGUID().ToString().c_str(), msg.c_str()); if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_KICK)) KickPlayer(); return; } switch (type) { case CHAT_MSG_SAY: { // Prevent cheating if (!sender->IsAlive()) return; if (sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_SAY_LEVEL_REQ)) { SendNotification(GetTrinityString(LANG_SAY_REQ), sWorld->getIntConfig(CONFIG_CHAT_SAY_LEVEL_REQ)); return; } sender->Say(msg, Language(lang)); break; } case CHAT_MSG_EMOTE: { // Prevent cheating if (!sender->IsAlive()) return; if (sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_EMOTE_LEVEL_REQ)) { SendNotification(GetTrinityString(LANG_SAY_REQ), sWorld->getIntConfig(CONFIG_CHAT_EMOTE_LEVEL_REQ)); return; } sender->TextEmote(msg); break; } case CHAT_MSG_YELL: { // Prevent cheating if (!sender->IsAlive()) return; if (sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_YELL_LEVEL_REQ)) { SendNotification(GetTrinityString(LANG_SAY_REQ), sWorld->getIntConfig(CONFIG_CHAT_YELL_LEVEL_REQ)); return; } sender->Yell(msg, Language(lang)); break; } case CHAT_MSG_WHISPER: { /// @todo implement cross realm whispers (someday) ExtendedPlayerName extName = ExtractExtendedPlayerName(target); if (!normalizePlayerName(extName.Name)) { SendChatPlayerNotfoundNotice(target); break; } Player* receiver = ObjectAccessor::FindConnectedPlayerByName(extName.Name); if (!receiver || (lang != LANG_ADDON && !receiver->isAcceptWhispers() && receiver->GetSession()->HasPermission(rbac::RBAC_PERM_CAN_FILTER_WHISPERS) && !receiver->IsInWhisperWhiteList(sender->GetGUID()))) { SendChatPlayerNotfoundNotice(target); return; } if (!sender->IsGameMaster() && sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ) && !receiver->IsInWhisperWhiteList(sender->GetGUID())) { SendNotification(GetTrinityString(LANG_WHISPER_REQ), sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ)); return; } if (GetPlayer()->GetTeam() != receiver->GetTeam() && !HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT) && !receiver->IsInWhisperWhiteList(sender->GetGUID())) { SendChatPlayerNotfoundNotice(target); return; } if (GetPlayer()->HasAura(1852) && !receiver->IsGameMaster()) { SendNotification(GetTrinityString(LANG_GM_SILENCE), GetPlayer()->GetName().c_str()); return; } // If player is a Gamemaster and doesn't accept whisper, we auto-whitelist every player that the Gamemaster is talking to // We also do that if a player is under the required level for whispers. if (receiver->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ) || (HasPermission(rbac::RBAC_PERM_CAN_FILTER_WHISPERS) && !sender->isAcceptWhispers() && !sender->IsInWhisperWhiteList(receiver->GetGUID()))) sender->AddWhisperWhiteList(receiver->GetGUID()); GetPlayer()->Whisper(msg, Language(lang), receiver); break; } case CHAT_MSG_PARTY: { // if player is in battleground, he cannot say to battleground members by /p Group* group = GetPlayer()->GetOriginalGroup(); if (!group) { group = sender->GetGroup(); if (!group || group->isBGGroup()) return; } if (group->IsLeader(GetPlayer()->GetGUID())) type = CHAT_MSG_PARTY_LEADER; sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPackets::Chat::Chat packet; packet.Initialize(ChatMsg(type), Language(lang), sender, nullptr, msg); group->BroadcastPacket(packet.Write(), false, group->GetMemberGroup(GetPlayer()->GetGUID())); break; } case CHAT_MSG_GUILD: { if (GetPlayer()->GetGuildId()) { if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId())) { sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, guild); guild->BroadcastToGuild(this, false, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL); } } break; } case CHAT_MSG_OFFICER: { if (GetPlayer()->GetGuildId()) { if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId())) { sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, guild); guild->BroadcastToGuild(this, true, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL); } } break; } case CHAT_MSG_RAID: { Group* group = GetPlayer()->GetGroup(); if (!group || !group->isRaidGroup() || group->isBGGroup()) return; if (group->IsLeader(GetPlayer()->GetGUID())) type = CHAT_MSG_RAID_LEADER; sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPackets::Chat::Chat packet; packet.Initialize(ChatMsg(type), Language(lang), sender, nullptr, msg); group->BroadcastPacket(packet.Write(), false); break; } case CHAT_MSG_RAID_WARNING: { Group* group = GetPlayer()->GetGroup(); if (!group || !(group->isRaidGroup() || sWorld->getBoolConfig(CONFIG_CHAT_PARTY_RAID_WARNINGS)) || !(group->IsLeader(GetPlayer()->GetGUID()) || group->IsAssistant(GetPlayer()->GetGUID())) || group->isBGGroup()) return; sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPackets::Chat::Chat packet; //in battleground, raid warning is sent only to players in battleground - code is ok packet.Initialize(CHAT_MSG_RAID_WARNING, Language(lang), sender, NULL, msg); group->BroadcastPacket(packet.Write(), false); break; } case CHAT_MSG_CHANNEL: { if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHAT_CHANNEL_REQ)) { if (sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ)) { SendNotification(GetTrinityString(LANG_CHANNEL_REQ), sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ)); return; } } if (Channel* chn = ChannelMgr::GetChannelForPlayerByNamePart(target, sender)) { sScriptMgr->OnPlayerChat(sender, type, lang, msg, chn); chn->Say(sender->GetGUID(), msg.c_str(), lang); } break; } case CHAT_MSG_INSTANCE_CHAT: { Group* group = GetPlayer()->GetGroup(); if (!group) return; if (group->IsLeader(GetPlayer()->GetGUID())) type = CHAT_MSG_INSTANCE_CHAT_LEADER; sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPackets::Chat::Chat packet; packet.Initialize(ChatMsg(type), Language(lang), sender, nullptr, msg); group->BroadcastPacket(packet.Write(), false); break; } default: TC_LOG_ERROR("network", "CHAT: unknown message type %u, lang: %u", type, lang); break; } }
void UpdateAI(const uint32 diff) { if (WaterTimer < diff) // every 1000ms { Map *map = m_creature->GetMap(); if(!map->IsDungeon()) return; Map::PlayerList const &players = map->GetPlayers(); if(players.getSize()==0) return; for(Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) { Player* plr = itr->getSource(); if (!plr) continue; if (!(plr)->GetSession() || !(plr)->isAlive()) continue; if (!InCombat && plr->GetDistance(m_creature) < 2.25 && (plr->HasAura(33095, 2))) { if (TimeToSpawn%40 == 0) { DoYell(EMOTE_STOPFISHING, LANG_UNIVERSAL, NULL); } if (FirstVictim == 0) FirstVictim = plr; // Remember the first player who started fishing // the player is trying to catch fish TimeToSpawn--; // Time to spawn reduced for every fishing player by 1 per second } // --> more fishermen(and-women): faster spawn if (!InCombat && (TimeToSpawn<=1)) // effective up to TimeToSpawn seconds of fishing { if (pInstance) pInstance->SetData(DATA_THELURKERBELOWEVENT, IN_PROGRESS); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_creature->RemoveFlag(UNIT_NPC_EMOTESTATE, EMOTE_STATE_SUBMERGED); DoCast(m_creature, SPELL_EMERGE); m_creature->setFaction(14); InCombat = true; if (FirstVictim) { if (FirstVictim->GetSession() && FirstVictim->isAlive()) m_creature->AddThreat(FirstVictim, 1.0f); // guarantee, that first fisher is first in ThreatList } Aggro(NULL); // Put anybody else into the fight (with 0.0 aggro) } if(plr && plr->GetDistance(m_creature ) > 5625) { if (plr->HasAura(SCALDING_WATER,0)) plr->RemoveAurasDueToSpell(SCALDING_WATER); if (plr->IsInWater() && !plr->isGameMaster() && !InCombat) { Fishy = plr->SummonCreature(MOB_COILFANG_FRENZY,plr->GetPositionX(),plr->GetPositionY(),plr->GetPositionZ(),plr->GetOrientation(),TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,15000); if (Fishy) Fishy->AI()->AttackStart(plr); } }else{ if (plr->IsInWater()) { if (!plr->HasAura(SCALDING_WATER,0)) plr->CastSpell(plr,SCALDING_WATER,true); }else{ if (plr->HasAura(SCALDING_WATER,0)) plr->RemoveAurasDueToSpell(SCALDING_WATER); } } } WaterTimer = 1000; }else WaterTimer -= diff; //Return since we have no target if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() ) return; if(!Submerged) { if(SpoutTimer < diff) { //Turning while spouting ;) bit fuzzy but working if (OrientationUpdated == -1) { OrientationUpdated = 0; Unit* target = NULL; target = SelectUnit(SELECT_TARGET_TOPAGGRO,0); m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0); //DoTextEmote(EMOTE_SPOUT,NULL); SpoutTimer = 5000; switch(rand()%2) { case 0: Clockwise = true; break; case 1: Clockwise = false; break; } guids.clear(); //clear targets return; } else { if(Clockwise) SpoutAngle += PI/100; else SpoutAngle -= PI/100; if(SpoutAngle > 2*PI) SpoutAngle -= 2*PI; if(SpoutAngle < 0) SpoutAngle += 2*PI; //So spin around ya evil fish m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0); m_creature->SetOrientation(SpoutAngle); m_creature->StopMoving(); //Spout part if(SVTimer < diff) { DoCast(m_creature, SPELL_SPOUT); SVTimer = 850; } SVTimer -= diff; OrientationUpdated++; SpoutTimer = 100; if (OrientationUpdated == 200) { SpoutTimer = 45000; OrientationUpdated = -1; WhirlTimer = 5000; Unit *victim = m_creature->getVictim(); if(victim) { m_creature->SetUInt64Value(UNIT_FIELD_TARGET, victim->GetGUID()); } } } }else SpoutTimer -= diff; if(PhaseTimer >= diff) PhaseTimer -= diff; //need to count the phase timer while spouting too if(OrientationUpdated != -1) return; //Whirl directly after a Spout and at random times if(WhirlTimer < diff) { WhirlTimer = rand()%5000 + 15000; DoCast(m_creature,SPELL_WHIRL); }else WhirlTimer -= diff; if(PhaseTimer < diff) { DoCast(m_creature,SPELL_SUBMERGE); PhaseTimer = 60000; Submerged = true; }else PhaseTimer -= diff; if(GeyserTimer < diff) { Unit* target = NULL; target = SelectUnit(SELECT_TARGET_RANDOM,1); GeyserTimer = rand()%15000 + 10000; if(target) DoCast(target,SPELL_GEYSER); }else GeyserTimer -= diff; if(WaterboltTimer < diff) { Unit* target = NULL; int i = 0; bool meleeTarget = false; target = SelectUnit(SELECT_TARGET_TOPAGGRO,0); if (!target) target = m_creature->getVictim(); while (target) { if( m_creature->IsWithinDistInMap(target, 6)) { meleeTarget = true; break; } target = SelectUnit(SELECT_TARGET_TOPAGGRO,i); i++; } if(!meleeTarget) { DoCast(m_creature->getVictim(),SPELL_WATERBOLT); WaterboltTimer = 3000; } else DoMeleeAttackIfReady(); // WTF ? (1) }else WaterboltTimer -= diff; DoMeleeAttackIfReady(); //(1) } else { if(PhaseTimer < diff) { Submerged = false; m_creature->RemoveAllAuras(); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_creature->RemoveFlag(UNIT_NPC_EMOTESTATE, EMOTE_STATE_SUBMERGED); m_creature->RemoveFlag(UNIT_FIELD_BYTES_1,9); DoCast(m_creature, SPELL_EMERGE); Spawned = false; SpoutTimer = 5000; PhaseTimer = 120000; return; } else { /*if(!m_creature->isInCombat()) m_creature->SetInCombat();*/ PhaseTimer -= diff; } if(!Spawned) { m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); SummonAdd(MOBID_COILFANG_AMBUSHER,AddPos[0][0],AddPos[0][1],AddPos[0][2]); SummonAdd(MOBID_COILFANG_AMBUSHER,AddPos[1][0],AddPos[1][1],AddPos[1][2]); SummonAdd(MOBID_COILFANG_AMBUSHER,AddPos[2][0],AddPos[2][1],AddPos[2][2]); SummonAdd(MOBID_COILFANG_AMBUSHER,AddPos[3][0],AddPos[3][1],AddPos[3][2]); SummonAdd(MOBID_COILFANG_AMBUSHER,AddPos[4][0],AddPos[4][1],AddPos[4][2]); SummonAdd(MOBID_COILFANG_AMBUSHER,AddPos[5][0],AddPos[5][1],AddPos[5][2]); SummonAdd(MOBID_COILFANG_GUARDIAN,AddPos[6][0],AddPos[6][1],AddPos[6][2]); SummonAdd(MOBID_COILFANG_GUARDIAN,AddPos[7][0],AddPos[7][1],AddPos[7][2]); SummonAdd(MOBID_COILFANG_GUARDIAN,AddPos[8][0],AddPos[8][1],AddPos[8][2]); Spawned = true; } } }
void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) { uint32 type; uint32 lang; recvData >> type; recvData >> lang; if (type >= MAX_CHAT_MSG_TYPE) { TC_LOG_ERROR("network", "CHAT: Wrong message type received: %u", type); recvData.rfinish(); return; } if (lang == LANG_UNIVERSAL && type != CHAT_MSG_AFK && type != CHAT_MSG_DND) { TC_LOG_ERROR("network", "CMSG_MESSAGECHAT: Possible hacking-attempt: %s tried to send a message in universal language", GetPlayerInfo().c_str()); SendNotification(LANG_UNKNOWN_LANGUAGE); recvData.rfinish(); return; } Player* sender = GetPlayer(); //TC_LOG_DEBUG("CHAT: packet received. type %u, lang %u", type, lang); // prevent talking at unknown language (cheating) LanguageDesc const* langDesc = GetLanguageDescByID(lang); if (!langDesc) { SendNotification(LANG_UNKNOWN_LANGUAGE); recvData.rfinish(); return; } if (langDesc->skill_id != 0 && !sender->HasSkill(langDesc->skill_id)) { // also check SPELL_AURA_COMPREHEND_LANGUAGE (client offers option to speak in that language) Unit::AuraEffectList const& langAuras = sender->GetAuraEffectsByType(SPELL_AURA_COMPREHEND_LANGUAGE); bool foundAura = false; for (Unit::AuraEffectList::const_iterator i = langAuras.begin(); i != langAuras.end(); ++i) { if ((*i)->GetMiscValue() == int32(lang)) { foundAura = true; break; } } if (!foundAura) { SendNotification(LANG_NOT_LEARNED_LANGUAGE); recvData.rfinish(); return; } } if (lang == LANG_ADDON) { // LANG_ADDON is only valid for the following message types switch (type) { case CHAT_MSG_PARTY: case CHAT_MSG_RAID: case CHAT_MSG_GUILD: case CHAT_MSG_BATTLEGROUND: case CHAT_MSG_WHISPER: // check if addon messages are disabled if (!sWorld->getBoolConfig(CONFIG_ADDON_CHANNEL)) { recvData.rfinish(); return; } break; default: TC_LOG_ERROR("network", "Player %s (GUID: %u) sent a chatmessage with an invalid language/message type combination", GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow()); recvData.rfinish(); return; } } // LANG_ADDON should not be changed nor be affected by flood control else { // send in universal language if player in .gmon mode (ignore spell effects) if (sender->IsGameMaster()) lang = LANG_UNIVERSAL; else { Unit::AuraEffectList const& ModLangAuras = sender->GetAuraEffectsByType(SPELL_AURA_MOD_LANGUAGE); if (!ModLangAuras.empty()) lang = ModLangAuras.front()->GetMiscValue(); else if (HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT)) lang = LANG_UNIVERSAL; else { switch (type) { case CHAT_MSG_PARTY: case CHAT_MSG_PARTY_LEADER: case CHAT_MSG_RAID: case CHAT_MSG_RAID_LEADER: case CHAT_MSG_RAID_WARNING: // allow two side chat at group channel if two side group allowed if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP)) lang = LANG_UNIVERSAL; break; case CHAT_MSG_GUILD: case CHAT_MSG_OFFICER: // allow two side chat at guild channel if two side guild allowed if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD)) lang = LANG_UNIVERSAL; break; } } } if (!sender->CanSpeak()) { std::string timeStr = secsToTimeString(m_muteTime - time(NULL)); SendNotification(GetTrinityString(LANG_WAIT_BEFORE_SPEAKING), timeStr.c_str()); recvData.rfinish(); // Prevent warnings return; } if (type != CHAT_MSG_AFK && type != CHAT_MSG_DND) sender->UpdateSpeakTime(); } if (sender->HasAura(1852) && type != CHAT_MSG_WHISPER) { SendNotification(GetTrinityString(LANG_GM_SILENCE), sender->GetName().c_str()); recvData.rfinish(); return; } std::string to, channel, msg; bool ignoreChecks = false; switch (type) { case CHAT_MSG_SAY: case CHAT_MSG_EMOTE: case CHAT_MSG_YELL: case CHAT_MSG_PARTY: case CHAT_MSG_PARTY_LEADER: case CHAT_MSG_GUILD: case CHAT_MSG_OFFICER: case CHAT_MSG_RAID: case CHAT_MSG_RAID_LEADER: case CHAT_MSG_RAID_WARNING: case CHAT_MSG_BATTLEGROUND: case CHAT_MSG_BATTLEGROUND_LEADER: recvData >> msg; break; case CHAT_MSG_WHISPER: recvData >> to; recvData >> msg; break; case CHAT_MSG_CHANNEL: recvData >> channel; recvData >> msg; break; case CHAT_MSG_AFK: case CHAT_MSG_DND: recvData >> msg; ignoreChecks = true; break; } if (!ignoreChecks) { if (msg.empty()) return; if (ChatHandler(this).ParseCommands(msg.c_str())) return; if (lang != LANG_ADDON) { // Strip invisible characters for non-addon messages if (sWorld->getBoolConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING)) stripLineInvisibleChars(msg); if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY) && !ChatHandler(this).isValidChatMessage(msg.c_str())) { TC_LOG_ERROR("network", "Player %s (GUID: %u) sent a chatmessage with an invalid link: %s", GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow(), msg.c_str()); if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_KICK)) KickPlayer(); return; } } } switch (type) { case CHAT_MSG_SAY: case CHAT_MSG_EMOTE: case CHAT_MSG_YELL: { // Prevent cheating if (!sender->IsAlive()) return; if (sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_SAY_LEVEL_REQ)) { SendNotification(GetTrinityString(LANG_SAY_REQ), sWorld->getIntConfig(CONFIG_CHAT_SAY_LEVEL_REQ)); return; } if (type == CHAT_MSG_SAY) { #ifdef ELUNA if (!sEluna->OnChat(sender, type, lang, msg)) return; #endif sender->Say(msg, Language(lang)); } else if (type == CHAT_MSG_EMOTE) { #ifdef ELUNA if (!sEluna->OnChat(sender, type, LANG_UNIVERSAL, msg)) return; #endif sender->TextEmote(msg); } else if (type == CHAT_MSG_YELL) { #ifdef ELUNA if (!sEluna->OnChat(sender, type, lang, msg)) return; #endif sender->Yell(msg, Language(lang)); } } break; case CHAT_MSG_WHISPER: { if (!normalizePlayerName(to)) { SendPlayerNotFoundNotice(to); break; } Player* receiver = ObjectAccessor::FindConnectedPlayerByName(to); if (!receiver || (lang != LANG_ADDON && !receiver->isAcceptWhispers() && receiver->GetSession()->HasPermission(rbac::RBAC_PERM_CAN_FILTER_WHISPERS) && !receiver->IsInWhisperWhiteList(sender->GetGUID()))) { SendPlayerNotFoundNotice(to); return; } if (!sender->IsGameMaster() && sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ) && !receiver->IsInWhisperWhiteList(sender->GetGUID())) { SendNotification(GetTrinityString(LANG_WHISPER_REQ), sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ)); return; } if (GetPlayer()->GetTeam() != receiver->GetTeam() && !HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT) && !receiver->IsInWhisperWhiteList(sender->GetGUID())) { SendWrongFactionNotice(); return; } if (GetPlayer()->HasAura(1852) && !receiver->IsGameMaster()) { SendNotification(GetTrinityString(LANG_GM_SILENCE), GetPlayer()->GetName().c_str()); return; } // If player is a Gamemaster and doesn't accept whisper, we auto-whitelist every player that the Gamemaster is talking to // We also do that if a player is under the required level for whispers. if (receiver->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ) || (HasPermission(rbac::RBAC_PERM_CAN_FILTER_WHISPERS) && !sender->isAcceptWhispers() && !sender->IsInWhisperWhiteList(receiver->GetGUID()))) sender->AddWhisperWhiteList(receiver->GetGUID()); #ifdef ELUNA if (!sEluna->OnChat(GetPlayer(), type, lang, msg, receiver)) return; #endif GetPlayer()->Whisper(msg, Language(lang), receiver); } break; case CHAT_MSG_PARTY: case CHAT_MSG_PARTY_LEADER: { // if player is in battleground, he cannot say to battleground members by /p Group* group = GetPlayer()->GetOriginalGroup(); if (!group) { group = sender->GetGroup(); if (!group || group->isBGGroup()) return; } if (type == CHAT_MSG_PARTY_LEADER && !group->IsLeader(sender->GetGUID())) return; sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); #ifdef ELUNA if(!sEluna->OnChat(sender, type, lang, msg, group)) return; #endif WorldPacket data; ChatHandler::BuildChatPacket(data, ChatMsg(type), Language(lang), sender, NULL, msg); group->BroadcastPacket(&data, false, group->GetMemberGroup(GetPlayer()->GetGUID())); } break; case CHAT_MSG_GUILD: { if (GetPlayer()->GetGuildId()) { if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId())) { sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, guild); #ifdef ELUNA if(!sEluna->OnChat(sender, type, lang, msg, guild)) return; #endif guild->BroadcastToGuild(this, false, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL); } } } break; case CHAT_MSG_OFFICER: { if (GetPlayer()->GetGuildId()) { if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId())) { sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, guild); #ifdef ELUNA if(!sEluna->OnChat(sender, type, lang, msg, guild)) return; #endif guild->BroadcastToGuild(this, true, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL); } } } break; case CHAT_MSG_RAID: { // if player is in battleground, he cannot say to battleground members by /ra Group* group = GetPlayer()->GetOriginalGroup(); if (!group) { group = GetPlayer()->GetGroup(); if (!group || group->isBGGroup() || !group->isRaidGroup()) return; } sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); #ifdef ELUNA if(!sEluna->OnChat(sender, type, lang, msg, group)) return; #endif WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID, Language(lang), sender, NULL, msg); group->BroadcastPacket(&data, false); } break; case CHAT_MSG_RAID_LEADER: { // if player is in battleground, he cannot say to battleground members by /ra Group* group = GetPlayer()->GetOriginalGroup(); if (!group) { group = GetPlayer()->GetGroup(); if (!group || group->isBGGroup() || !group->isRaidGroup() || !group->IsLeader(sender->GetGUID())) return; } sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); #ifdef ELUNA if(!sEluna->OnChat(sender, type, lang, msg, group)) return; #endif WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_LEADER, Language(lang), sender, NULL, msg); group->BroadcastPacket(&data, false); } break; case CHAT_MSG_RAID_WARNING: { Group* group = GetPlayer()->GetGroup(); if (!group || !group->isRaidGroup() || !(group->IsLeader(GetPlayer()->GetGUID()) || group->IsAssistant(GetPlayer()->GetGUID())) || group->isBGGroup()) return; sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); #ifdef ELUNA if(!sEluna->OnChat(sender, type, lang, msg, group)) return; #endif WorldPacket data; //in battleground, raid warning is sent only to players in battleground - code is ok ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_WARNING, Language(lang), sender, NULL, msg); group->BroadcastPacket(&data, false); } break; case CHAT_MSG_BATTLEGROUND: { //battleground raid is always in Player->GetGroup(), never in GetOriginalGroup() Group* group = GetPlayer()->GetGroup(); if (!group || !group->isBGGroup()) return; sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); #ifdef ELUNA if(!sEluna->OnChat(sender, type, lang, msg, group)) return; #endif WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND, Language(lang), sender, NULL, msg); group->BroadcastPacket(&data, false); } break; case CHAT_MSG_BATTLEGROUND_LEADER: { // battleground raid is always in Player->GetGroup(), never in GetOriginalGroup() Group* group = GetPlayer()->GetGroup(); if (!group || !group->isBGGroup() || !group->IsLeader(GetPlayer()->GetGUID())) return; sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); #ifdef ELUNA if(!sEluna->OnChat(sender, type, lang, msg, group)) return; #endif WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND_LEADER, Language(lang), sender, NULL, msg);; group->BroadcastPacket(&data, false); } break; case CHAT_MSG_CHANNEL: { if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHAT_CHANNEL_REQ)) { if (sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ)) { SendNotification(GetTrinityString(LANG_CHANNEL_REQ), sWorld->getIntConfig(CONFIG_CHAT_CHANNEL_LEVEL_REQ)); return; } } if (ChannelMgr* cMgr = ChannelMgr::forTeam(sender->GetTeam())) { if (Channel* chn = cMgr->GetChannel(channel, sender)) { sScriptMgr->OnPlayerChat(sender, type, lang, msg, chn); #ifdef ELUNA if(!sEluna->OnChat(sender, type, lang, msg, chn)) return; #endif chn->Say(sender->GetGUID(), msg.c_str(), lang); } } } break; case CHAT_MSG_AFK: { if (!sender->IsInCombat()) { if (sender->isAFK()) // Already AFK { if (msg.empty()) sender->ToggleAFK(); // Remove AFK else sender->autoReplyMsg = msg; // Update message } else // New AFK mode { sender->autoReplyMsg = msg.empty() ? GetTrinityString(LANG_PLAYER_AFK_DEFAULT) : msg; if (sender->isDND()) sender->ToggleDND(); sender->ToggleAFK(); } sScriptMgr->OnPlayerChat(sender, type, lang, msg); #ifdef ELUNA if(!sEluna->OnChat(sender, type, lang, msg)) return; #endif } break; } case CHAT_MSG_DND: { if (sender->isDND()) // Already DND { if (msg.empty()) sender->ToggleDND(); // Remove DND else sender->autoReplyMsg = msg; // Update message } else // New DND mode { sender->autoReplyMsg = msg.empty() ? GetTrinityString(LANG_PLAYER_DND_DEFAULT) : msg; if (sender->isAFK()) sender->ToggleAFK(); sender->ToggleDND(); } sScriptMgr->OnPlayerChat(sender, type, lang, msg); #ifdef ELUNA if(!sEluna->OnChat(sender, type, lang, msg)) return; #endif break; } default: TC_LOG_ERROR("network", "CHAT: unknown message type %u, lang: %u", type, lang); break; } }
void PlayerbotWarlockAI::DoNonCombatActions() { if (!m_ai) return; if (!m_bot) return; //uint32 spec = m_bot->GetSpec(); Pet *pet = m_bot->GetPet(); // Initialize pet spells if (pet && pet->GetEntry() != m_lastDemon) { switch (pet->GetEntry()) { case DEMON_IMP: BLOOD_PACT = m_ai->initPetSpell(BLOOD_PACT_ICON); FIREBOLT = m_ai->initPetSpell(FIREBOLT_ICON); FIRE_SHIELD = m_ai->initPetSpell(FIRE_SHIELD_ICON); break; case DEMON_VOIDWALKER: CONSUME_SHADOWS = m_ai->initPetSpell(CONSUME_SHADOWS_ICON); SACRIFICE = m_ai->initPetSpell(SACRIFICE_ICON); SUFFERING = m_ai->initPetSpell(SUFFERING_ICON); TORMENT = m_ai->initPetSpell(TORMENT_ICON); break; case DEMON_SUCCUBUS: LASH_OF_PAIN = m_ai->initPetSpell(LASH_OF_PAIN_ICON); SEDUCTION = m_ai->initPetSpell(SEDUCTION_ICON); SOOTHING_KISS = m_ai->initPetSpell(SOOTHING_KISS_ICON); break; case DEMON_FELHUNTER: DEVOUR_MAGIC = m_ai->initPetSpell(DEVOUR_MAGIC_ICON); SPELL_LOCK = m_ai->initPetSpell(SPELL_LOCK_ICON); break; } m_lastDemon = pet->GetEntry(); } // Destroy extra soul shards uint8 shardCount = m_bot->GetItemCount(SOUL_SHARD, false, nullptr); uint8 freeSpace = m_ai->GetFreeBagSpace(); if (shardCount > MAX_SHARD_COUNT || (freeSpace == 0 && shardCount > 1)) m_bot->DestroyItemCount(SOUL_SHARD, shardCount > MAX_SHARD_COUNT ? shardCount - MAX_SHARD_COUNT : 1, true, false); // buff myself DEMON_SKIN, DEMON_ARMOR, FEL_ARMOR - Strongest one available is chosen if (DEMON_ARMOR) { if (m_ai->SelfBuff(DEMON_ARMOR)) return; } else if (DEMON_SKIN) if (m_ai->SelfBuff(DEMON_SKIN)) return; // healthstone creation if (CREATE_HEALTHSTONE && shardCount > 0) { Item* const healthStone = m_ai->FindConsumable(HEALTHSTONE_DISPLAYID); if (!healthStone && m_ai->CastSpell(CREATE_HEALTHSTONE)) return; } // soulstone creation and use if (CREATE_SOULSTONE) { Item* soulStone = m_ai->FindConsumable(SOULSTONE_DISPLAYID); if (!soulStone) { if (shardCount > 0 && m_bot->IsSpellReady(CREATE_SOULSTONE) && m_ai->CastSpell(CREATE_SOULSTONE)) return; } else { uint32 soulStoneSpell = soulStone->GetProto()->Spells[0].SpellId; Player* master = GetMaster(); if (!master->HasAura(soulStoneSpell) && m_bot->IsSpellReady(soulStoneSpell)) { // TODO: first choice: healer. Second choice: anyone else with revive spell. Third choice: self or master. m_ai->UseItem(soulStone, master); return; } } } // hp/mana check if (pet && DARK_PACT && (100 * pet->GetPower(POWER_MANA) / pet->GetMaxPower(POWER_MANA)) > 40 && m_ai->GetManaPercent() <= 60) if (m_ai->CastSpell(DARK_PACT, *m_bot)) return; if (LIFE_TAP && m_ai->GetManaPercent() <= 80 && m_ai->GetHealthPercent() > 50) if (m_ai->CastSpell(LIFE_TAP, *m_bot)) return; // Do not waste time/soul shards to create spellstone or firestone // if two-handed weapon (staff) or off-hand item are already equiped // Spellstone creation and use (Spellstone dominates firestone completely as I understand it) Item* const weapon = m_bot->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND); Item* const offweapon = m_bot->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND); if (weapon && !offweapon && weapon->GetProto()->SubClass != ITEM_SUBCLASS_WEAPON_STAFF && weapon->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT) == 0) { Item* const stone = m_ai->FindConsumable(SPELLSTONE_DISPLAYID); Item* const stone2 = m_ai->FindConsumable(FIRESTONE_DISPLAYID); uint8 spellstone_count = m_bot->GetItemCount(SPELLSTONE, false, nullptr); if (spellstone_count == 0) spellstone_count = m_bot->GetItemCount(GREATER_SPELLSTONE, false, nullptr); if (spellstone_count == 0) spellstone_count = m_bot->GetItemCount(MAJOR_SPELLSTONE, false, nullptr); uint8 firestone_count = m_bot->GetItemCount(LESSER_FIRESTONE, false, nullptr); if (firestone_count == 0) firestone_count = m_bot->GetItemCount(FIRESTONE, false, nullptr); if (firestone_count == 0) firestone_count = m_bot->GetItemCount(GREATER_FIRESTONE, false, nullptr); if (firestone_count == 0) firestone_count = m_bot->GetItemCount(MAJOR_FIRESTONE, false, nullptr); if (spellstone_count == 0 && firestone_count == 0) { if (CREATE_SPELLSTONE && shardCount > 0 && m_ai->CastSpell(CREATE_SPELLSTONE)) return; else if (CREATE_SPELLSTONE == 0 && CREATE_FIRESTONE > 0 && shardCount > 0 && m_ai->CastSpell(CREATE_FIRESTONE)) return; } else if (stone) { m_ai->UseItem(stone, EQUIPMENT_SLOT_OFFHAND); return; } else { m_ai->UseItem(stone2, EQUIPMENT_SLOT_OFFHAND); return; } } if (EatDrinkBandage()) return; //Heal Voidwalker if (pet && pet->GetEntry() == DEMON_VOIDWALKER && CONSUME_SHADOWS && pet->GetHealthPercent() < 75 && !pet->HasAura(CONSUME_SHADOWS)) m_ai->CastPetSpell(CONSUME_SHADOWS); CheckDemon(); // Soul link demon if (pet && SOUL_LINK && !m_bot->HasAura(SOUL_LINK_AURA) && m_ai->CastSpell(SOUL_LINK, *m_bot)) return; // Check demon buffs if (pet && pet->GetEntry() == DEMON_IMP && BLOOD_PACT && !m_bot->HasAura(BLOOD_PACT) && m_ai->CastPetSpell(BLOOD_PACT)) return; } // end DoNonCombatActions
void FocusMagic(uint32 diff) { if (!FOCUSMAGIC || fmCheckTimer > diff || GC_Timer > diff || me->getLevel() < 20 || Rand() < 50 || IsCasting()) return; if (Unit* target = FindAffectedTarget(FOCUSMAGIC, me->GetGUID(), 70, 2)) { fmCheckTimer = 15000; return; } else { Group* pGroup = master->GetGroup(); if (!pGroup) { if (master->getPowerType() == POWER_MANA && me->GetExactDist(master) < 30 && !master->HasAura(FOCUSMAGIC)) target = master; } else { for (GroupReference* itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* pPlayer = itr->GetSource(); if (!pPlayer || pPlayer->IsInWorld() || pPlayer->IsDead()) continue; if (me->GetMapId() != pPlayer->GetMapId()) continue; if (pPlayer->getPowerType() == POWER_MANA && me->GetExactDist(pPlayer) < 30 && !pPlayer->HasAura(FOCUSMAGIC)) { target = pPlayer; break; } } if (!target) { for (GroupReference* itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) { Player* pPlayer = itr->GetSource(); if (!pPlayer || !pPlayer->IsInWorld() || !pPlayer->HaveBot()) continue; if (me->GetMapId() != pPlayer->GetMapId()) continue; for (uint8 i = 0; i != pPlayer->GetMaxNpcBots(); ++i) { Creature* cre = pPlayer->GetBotMap(i)->_Cre(); if (!cre || !cre->IsInWorld() || cre == me || cre->IsDead()) continue; if (cre->getPowerType() == POWER_MANA && me->GetExactDist(cre) < 30 && !cre->HasAura(FOCUSMAGIC)) { target = cre; break; } } } } } if (target && doCast(target, FOCUSMAGIC)) { GC_Timer = 500; fmCheckTimer = 30000; return; } } fmCheckTimer = 5000; }
void BattleGroundWS::Update(uint32 diff) { BattleGround::Update(diff); if (GetStatus() == STATUS_IN_PROGRESS) { if (m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_WAIT_RESPAWN) { m_FlagsTimer[BG_TEAM_ALLIANCE] -= diff; if (m_FlagsTimer[BG_TEAM_ALLIANCE] < 0) { m_FlagsTimer[BG_TEAM_ALLIANCE] = 0; RespawnFlag(ALLIANCE, true); } } if (m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_GROUND) { m_FlagsDropTimer[BG_TEAM_ALLIANCE] -= diff; if (m_FlagsDropTimer[BG_TEAM_ALLIANCE] < 0) { m_FlagsDropTimer[BG_TEAM_ALLIANCE] = 0; RespawnFlagAfterDrop(ALLIANCE); } } if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_WAIT_RESPAWN) { m_FlagsTimer[BG_TEAM_HORDE] -= diff; if (m_FlagsTimer[BG_TEAM_HORDE] < 0) { m_FlagsTimer[BG_TEAM_HORDE] = 0; RespawnFlag(HORDE, true); } } if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_ON_GROUND) { m_FlagsDropTimer[BG_TEAM_HORDE] -= diff; if (m_FlagsDropTimer[BG_TEAM_HORDE] < 0) { m_FlagsDropTimer[BG_TEAM_HORDE] = 0; RespawnFlagAfterDrop(HORDE); } } if (m_FlagState[BG_TEAM_ALLIANCE] >= BG_WS_FLAG_STATE_ON_PLAYER && m_FlagState[BG_TEAM_HORDE] >= BG_WS_FLAG_STATE_ON_PLAYER) { if (m_FocusedAssault < BG_WS_FIVE_MINUTES) { for(uint8 i = 0; i < BG_TEAMS_COUNT; i++) { Player* carrier = sObjectMgr.GetPlayer(m_FlagKeepers[i]); if(!carrier) continue; if((!carrier->HasAura(BG_WS_SPELL_FOCUSED_ASSAULT) && !carrier->HasAura(BG_WS_SPELL_BRUTAL_ASSAULT)) || (m_FocusedAssaultExtra && m_FocusedAssault < diff)) carrier->CastSpell(carrier, (m_FocusedAssault < diff) ? BG_WS_SPELL_BRUTAL_ASSAULT : BG_WS_SPELL_FOCUSED_ASSAULT, true); } if(m_FocusedAssault < BG_WS_FIVE_MINUTES && m_FocusedAssaultExtra) m_FocusedAssaultExtra = false; }else m_FocusedAssault -= diff; }else { m_FocusedAssault = BG_WS_CARRIER_DEBUFF; m_FocusedAssaultExtra = true; } if (m_EndTimer <= diff) { uint32 allianceScore = GetTeamScore(ALLIANCE); uint32 hordeScore = GetTeamScore(HORDE); if (allianceScore > hordeScore) EndBattleGround(ALLIANCE); else if (allianceScore < hordeScore) EndBattleGround(HORDE); else { // if 0 => tie EndBattleGround(m_LastCapturedFlagTeam); } } else { uint32 minutesLeftPrev = GetRemainingTimeInMinutes(); m_EndTimer -= diff; uint32 minutesLeft = GetRemainingTimeInMinutes(); if (minutesLeft != minutesLeftPrev) UpdateWorldState(BG_WS_TIME_REMAINING, minutesLeft); } } }