bool HatchAllEggs(uint32 uiAction) //1: reset, 2: isHatching all { std::list<Creature*> templist; float x, y, z; m_creature->GetPosition(x, y, z); { CellPair pair(Trinity::ComputeCellPair(x, y)); Cell cell(pair); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); Trinity::AllCreaturesOfEntryInRange check(m_creature, MOB_EGG, 100); Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(m_creature, templist, check); TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange>, GridTypeMapContainer> cSearcher(searcher); CellLock<GridReadGuard> cell_lock(cell, pair); cell_lock->Visit(cell_lock, cSearcher, *(m_creature->GetMap())); } //error_log("Eggs %d at middle", templist.size()); if (!templist.size()) return false; for (std::list<Creature*>::iterator i = templist.begin(); i != templist.end(); ++i) { if (uiAction == 1) (*i)->SetDisplayId(10056); else if (uiAction == 2 &&(*i)->GetDisplayId() != 11686) (*i)->CastSpell(*i, SPELL_HATCH_EGG, false); } return true; }
void WorldSession::HandleTextEmoteOpcode( WorldPacket & recv_data ) { if(!GetPlayer()->isAlive()) return; if (!GetPlayer()->CanSpeak()) { std::string timeStr = secsToTimeString(m_muteTime - time(NULL)); SendNotification(GetMangosString(LANG_WAIT_BEFORE_SPEAKING),timeStr.c_str()); return; } CHECK_PACKET_SIZE(recv_data,4+4+8); uint32 text_emote, emoteNum; uint64 guid; recv_data >> text_emote; recv_data >> emoteNum; recv_data >> guid; EmotesTextEntry const *em = sEmotesTextStore.LookupEntry(text_emote); if (!em) return; uint32 emote_anim = em->textid; switch(emote_anim) { case EMOTE_STATE_SLEEP: case EMOTE_STATE_SIT: case EMOTE_STATE_KNEEL: case EMOTE_ONESHOT_NONE: break; default: GetPlayer()->HandleEmoteCommand(emote_anim); break; } Unit* unit = ObjectAccessor::GetUnit(*_player, guid); CellPair p = MaNGOS::ComputeCellPair(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY()); Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); MaNGOS::EmoteChatBuilder emote_builder(*GetPlayer(), text_emote, emoteNum, unit); MaNGOS::LocalizedPacketDo<MaNGOS::EmoteChatBuilder > emote_do(emote_builder); MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::EmoteChatBuilder > > emote_worker(GetPlayer(),sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE),emote_do); TypeContainerVisitor<MaNGOS::PlayerDistWorker<MaNGOS::LocalizedPacketDo<MaNGOS::EmoteChatBuilder > >, WorldTypeMapContainer > message(emote_worker); CellLock<GridReadGuard> cell_lock(cell, p); cell_lock->Visit(cell_lock, message, *GetPlayer()->GetMap()); GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, unit); //Send scripted event call if (unit && unit->GetTypeId()==TYPEID_UNIT && Script) Script->ReceiveEmote(GetPlayer(),(Creature*)unit,text_emote); }
void Map::MessageBroadcast(Player *player, WorldPacket *msg, bool to_self, bool own_team_only) { //sLog.outDetail("Map::MessageBroadcast Player"); CellPair p = LeGACY::ComputeCellPair(player->GetPositionX(), player->GetPositionY()); if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP ) { sLog.outError("Map::MessageBroadcast: Player '%s' (%u) have invalid coordinates X:%f Y:%f grid cell [%u:%u]", player->GetName(), player->GetAccountId(), player->GetPositionX(), player->GetPositionY(), p.x_coord, p.y_coord); return; } Cell cell(p); cell.data.Part.reserved = CENTER_DISTRICT; if( !loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)) ) { sLog.outDetail("Not loaded"); // return; } LeGACY::MessageDeliverer post_man(*player, msg, to_self, own_team_only); TypeContainerVisitor<LeGACY::MessageDeliverer, WorldTypeMapContainer > message(post_man); CellLock<ReadGuard> cell_lock(cell, p); cell_lock->Visit(cell_lock, message, *this); }
void DespawnSummons(uint32 entry) { std::list<Creature*> templist; float x, y, z; m_creature->GetPosition(x, y, z); { CellPair pair(MaNGOS::ComputeCellPair(x, y)); Cell cell(pair); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); AllCreaturesOfEntryInRange check(m_creature, entry, 100); MaNGOS::CreatureListSearcher<AllCreaturesOfEntryInRange> searcher(templist, check); TypeContainerVisitor<MaNGOS::CreatureListSearcher<AllCreaturesOfEntryInRange>, GridTypeMapContainer> cSearcher(searcher); CellLock<GridReadGuard> cell_lock(cell, pair); cell_lock->Visit(cell_lock, cSearcher, *(m_creature->GetMap())); } for(std::list<Creature*>::iterator i = templist.begin(); i != templist.end(); ++i) { if(entry == MOB_VAPOR_TRAIL && Phase == PHASE_FLIGHT) { float x, y, z; (*i)->GetPosition(x, y, z); m_creature->SummonCreature(MOB_DEAD, x, y, z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); } (*i)->SetVisibility(VISIBILITY_OFF); (*i)->setDeathState(JUST_DIED); if((*i)->getDeathState() == CORPSE) (*i)->RemoveCorpse(); } }
void DespawnSummons(uint32 entry) { std::list<Creature*> templist; float x, y, z; m_creature->GetPosition(x, y, z); { CellPair pair(MaNGOS::ComputeCellPair(x, y)); Cell cell(pair); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); AllCreaturesOfEntryInRange check(m_creature, entry, 100); MaNGOS::CreatureListSearcher<AllCreaturesOfEntryInRange> searcher(templist, check); TypeContainerVisitor<MaNGOS::CreatureListSearcher<AllCreaturesOfEntryInRange>, GridTypeMapContainer> cSearcher(searcher); CellLock<GridReadGuard> cell_lock(cell, pair); cell_lock->Visit(cell_lock, cSearcher, *(m_creature->GetMap())); } for(std::list<Creature*>::iterator i = templist.begin(); i != templist.end(); ++i) { (*i)->SetVisibility(VISIBILITY_OFF); (*i)->setDeathState(JUST_DIED); } }
void Boom() { std::list<Creature*> templist; float x, y, z; m_creature->GetPosition(x, y, z); { CellPair pair(Trinity::ComputeCellPair(x, y)); Cell cell(pair); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); Trinity::AllCreaturesOfEntryInRange check(m_creature, MOB_FIRE_BOMB, 100); Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(m_creature, templist, check); TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange>, GridTypeMapContainer> cSearcher(searcher); CellLock<GridReadGuard> cell_lock(cell, pair); cell_lock->Visit(cell_lock, cSearcher, *(m_creature->GetMap())); } for (std::list<Creature*>::iterator i = templist.begin(); i != templist.end(); ++i) { (*i)->CastSpell(*i, SPELL_FIRE_BOMB_DAMAGE, true); (*i)->RemoveAllAuras(); } }
void cell_send(struct cell *c, int port, void *msg) { cell_lock(c); struct message m = { port, msg }; mq_push(&c->mq, &m); cell_unlock(c); }
Creature *RespawnNearbyBugsAndGetOne() { CellPair p(Trinity::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY())); Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); std::list<Creature*> unitList; AnyBugCheck u_check(m_creature, 150); Trinity::CreatureListSearcher<AnyBugCheck> searcher(unitList, u_check); TypeContainerVisitor<Trinity::CreatureListSearcher<AnyBugCheck>, GridTypeMapContainer > grid_creature_searcher(searcher); CellLock<GridReadGuard> cell_lock(cell, p); cell_lock->Visit(cell_lock, grid_creature_searcher, *(m_creature->GetMap())); Creature *nearb = NULL; for(std::list<Creature*>::iterator iter = unitList.begin(); iter != unitList.end(); ++iter) { Creature *c = (Creature *)(*iter); if (c->isDead()) { c->Respawn(); c->setFaction(7); c->RemoveAllAuras(); } if (c->IsWithinDistInMap(m_creature, ABUSE_BUG_RANGE)) { if (!nearb || (rand()%4)==0) nearb = c; } } return nearb; }
void GameObject::TriggeringLinkedGameObject( uint32 trapEntry, Unit* target) { GameObjectInfo const* trapInfo = sGOStorage.LookupEntry<GameObjectInfo>(trapEntry); if(!trapInfo || trapInfo->type!=GAMEOBJECT_TYPE_TRAP) return; SpellEntry const* trapSpell = sSpellStore.LookupEntry(trapInfo->trap.spellId); if(!trapSpell) // checked at load already return; float range = GetSpellMaxRange(sSpellRangeStore.LookupEntry(trapSpell->rangeIndex)); // search nearest linked GO GameObject* trapGO = NULL; { // using original GO distance CellPair p(MaNGOS::ComputeCellPair(GetPositionX(), GetPositionY())); Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; MaNGOS::NearestGameObjectEntryInObjectRangeCheck go_check(*target,trapEntry,range); MaNGOS::GameObjectLastSearcher<MaNGOS::NearestGameObjectEntryInObjectRangeCheck> checker(trapGO,go_check); TypeContainerVisitor<MaNGOS::GameObjectLastSearcher<MaNGOS::NearestGameObjectEntryInObjectRangeCheck>, GridTypeMapContainer > object_checker(checker); CellLock<GridReadGuard> cell_lock(cell, p); cell_lock->Visit(cell_lock, object_checker, *GetMap()); } // found correct GO // FIXME: when GO casting will be implemented trap must cast spell to target if(trapGO) target->CastSpell(target,trapSpell,true); }
void TotemAI::UpdateAI(const uint32 /*diff*/) { if (i_totem.GetTotemType() != TOTEM_ACTIVE) return; if (!i_totem.isAlive() || i_totem.IsNonMeleeSpellCasted(false)) return; // Search spell SpellEntry const *spellInfo = sSpellStore.LookupEntry(i_totem.GetSpell()); if (!spellInfo) return; // Get spell rangy SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(spellInfo->rangeIndex); float max_range = GetSpellMaxRange(srange); // SPELLMOD_RANGE not applied in this place just because not existence range mods for attacking totems // pointer to appropriate target if found any Unit* victim = i_victimGuid ? ObjectAccessor::GetUnit(i_totem, i_victimGuid) : NULL; // Search victim if no, not attackable, or out of range, or friendly (possible in case duel end) if( !victim || !victim->isTargetableForAttack() || !i_totem.IsWithinDistInMap(victim, max_range) || i_totem.IsFriendlyTo(victim) || !victim->isVisibleForOrDetect(&i_totem,false) ) { CellPair p(MaNGOS::ComputeCellPair(i_totem.GetPositionX(),i_totem.GetPositionY())); Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; victim = NULL; MaNGOS::NearestAttackableUnitInObjectRangeCheck u_check(&i_totem, &i_totem, max_range); MaNGOS::UnitLastSearcher<MaNGOS::NearestAttackableUnitInObjectRangeCheck> checker(victim, u_check); TypeContainerVisitor<MaNGOS::UnitLastSearcher<MaNGOS::NearestAttackableUnitInObjectRangeCheck>, GridTypeMapContainer > grid_object_checker(checker); TypeContainerVisitor<MaNGOS::UnitLastSearcher<MaNGOS::NearestAttackableUnitInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker); CellLock<GridReadGuard> cell_lock(cell, p); cell_lock->Visit(cell_lock, grid_object_checker, *MapManager::Instance().GetMap(i_totem.GetMapId(), &i_totem)); cell_lock->Visit(cell_lock, world_object_checker, *MapManager::Instance().GetMap(i_totem.GetMapId(), &i_totem)); } // If have target if (victim) { // remember i_victimGuid = victim->GetGUID(); // attack i_totem.SetInFront(victim); // client change orientation by self i_totem.CastSpell(victim, i_totem.GetSpell(), false); } else i_victimGuid = 0; }
void cell_close(struct cell *c) { lua_State *L = NULL; cell_lock(c); L = c->L; c->L = NULL; cell_unlock(c); scheduler_deletetask(L); }
void Map::UpdatePlayerVisibility( Player* player, Cell cell, CellPair cellpair ) { cell.data.Part.reserved = CENTER_DISTRICT; LeGACY::PlayerNotifier pl_notifier(*player); TypeContainerVisitor<LeGACY::PlayerNotifier, WorldTypeMapContainer > player_notifier(pl_notifier); CellLock<ReadGuard> cell_lock(cell, cellpair); cell_lock->Visit(cell_lock, player_notifier, *this); }
void ObjectAccessor::_buildChangeObjectForPlayer(WorldObject *obj, UpdateDataMapType &update_players) { CellPair p = MaNGOS::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY()); Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); WorldObjectChangeAccumulator notifier(*obj, update_players); TypeContainerVisitor<WorldObjectChangeAccumulator, WorldTypeMapContainer > player_notifier(notifier); CellLock<GridReadGuard> cell_lock(cell, p); cell_lock->Visit(cell_lock, player_notifier, *obj->GetMap()); }
void Map::PlayerRelocationNotify(Player* player, Cell cell, CellPair cellpair) { CellLock<ReadGuard> cell_lock(cell, cellpair); LeGACY::PlayerRelocationNotifier relocationNotifier(*player); cell.data.Part.reserved = ALL_DISTRICT; TypeContainerVisitor<LeGACY::PlayerRelocationNotifier, GridTypeMapContainer > p2grid_relocation(relocationNotifier); TypeContainerVisitor<LeGACY::PlayerRelocationNotifier, WorldTypeMapContainer > p2world_relocation(relocationNotifier); cell_lock->Visit(cell_lock, p2grid_relocation, *this); cell_lock->Visit(cell_lock, p2world_relocation, *this); }
void GetCreatureListWithEntryInGrid(std::list<Creature*>& lList, WorldObject* pSource, uint32 uiEntry, float fMaxSearchRange) { CellPair pair(MaNGOS::ComputeCellPair(pSource->GetPositionX(), pSource->GetPositionY())); Cell cell(pair); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); AllCreaturesOfEntryInRange check(pSource, uiEntry, fMaxSearchRange); MaNGOS::CreatureListSearcher<AllCreaturesOfEntryInRange> searcher(lList, check); TypeContainerVisitor<MaNGOS::CreatureListSearcher<AllCreaturesOfEntryInRange>, GridTypeMapContainer> visitor(searcher); CellLock<GridReadGuard> cell_lock(cell, pair); cell_lock->Visit(cell_lock, visitor, *(pSource->GetMap()), *pSource, fMaxSearchRange); }
void ObjectAccessor::_buildChangeObjectForPlayer(WorldObject *obj, UpdateDataMapType &update_players) { CellPair p = Trinity::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY()); Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); WorldObjectChangeAccumulator notifier(*obj, update_players); TypeContainerVisitor<WorldObjectChangeAccumulator, WorldTypeMapContainer > player_notifier(notifier); CellLock<GridReadGuard> cell_lock(cell, p); Map& map = *obj->GetMap(); //we must build packets for all visible players cell_lock->Visit(cell_lock, player_notifier, map, *obj, map.GetVisibilityDistance()); }
GameObject* GameObject::LookupFishingHoleAround(float range) { GameObject* ok = NULL; CellPair p(MaNGOS::ComputeCellPair(GetPositionX(),GetPositionY())); Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; MaNGOS::NearestGameObjectFishingHole u_check(*this, range); MaNGOS::GameObjectSearcher<MaNGOS::NearestGameObjectFishingHole> checker(ok, u_check); CellLock<GridReadGuard> cell_lock(cell, p); TypeContainerVisitor<MaNGOS::GameObjectSearcher<MaNGOS::NearestGameObjectFishingHole>, GridTypeMapContainer > grid_object_checker(checker); cell_lock->Visit(cell_lock, grid_object_checker, *GetMap()); return ok; }
Player* ScriptedAI::GetPlayerAtMinimumRange(float fMinimumRange) { Player* pPlayer = NULL; CellPair pair(MaNGOS::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY())); Cell cell(pair); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); PlayerAtMinimumRangeAway check(m_creature, fMinimumRange); MaNGOS::PlayerSearcher<PlayerAtMinimumRangeAway> searcher(m_creature, pPlayer, check); TypeContainerVisitor<MaNGOS::PlayerSearcher<PlayerAtMinimumRangeAway>, GridTypeMapContainer> visitor(searcher); CellLock<GridReadGuard> cell_lock(cell, pair); cell_lock->Visit(cell_lock, visitor, *(m_creature->GetMap())); return pPlayer; }
std::list<Creature*> GetCreaturesByEntry(uint32 entry) { CellPair pair(MaNGOS::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY())); Cell cell(pair); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); std::list<Creature*> creatureList; AllCreaturesOfEntryInRange check(m_creature, entry, 100); MaNGOS::CreatureListSearcher<AllCreaturesOfEntryInRange> searcher(m_creature, creatureList, check); TypeContainerVisitor<MaNGOS::CreatureListSearcher<AllCreaturesOfEntryInRange>, GridTypeMapContainer> visitor(searcher); CellLock<GridReadGuard> cell_lock(cell, pair); cell_lock->Visit(cell_lock, visitor, *(m_creature->GetMap())); return creatureList; }
//return closest GO in grid, with range from pSource GameObject* GetClosestGameObjectWithEntry(WorldObject* pSource, uint32 uiEntry, float fMaxSearchRange) { GameObject* pGo = NULL; CellPair pair(MaNGOS::ComputeCellPair(pSource->GetPositionX(), pSource->GetPositionY())); Cell cell(pair); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); MaNGOS::NearestGameObjectEntryInObjectRangeCheck go_check(*pSource, uiEntry, fMaxSearchRange); MaNGOS::GameObjectLastSearcher<MaNGOS::NearestGameObjectEntryInObjectRangeCheck> searcher(pGo, go_check); TypeContainerVisitor<MaNGOS::GameObjectLastSearcher<MaNGOS::NearestGameObjectEntryInObjectRangeCheck>, GridTypeMapContainer> go_searcher(searcher); CellLock<GridReadGuard> cell_lock(cell, pair); cell_lock->Visit(cell_lock, go_searcher,*(pSource->GetMap()), *pSource, fMaxSearchRange); return pGo; }
std::list<Creature*> ScriptedAI::DoFindFriendlyMissingBuff(float range, uint32 spellid) { CellPair p(MaNGOS::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY())); Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); std::list<Creature*> pList; MaNGOS::FriendlyMissingBuffInRange u_check(m_creature, range, spellid); MaNGOS::CreatureListSearcher<MaNGOS::FriendlyMissingBuffInRange> searcher(m_creature, pList, u_check); TypeContainerVisitor<MaNGOS::CreatureListSearcher<MaNGOS::FriendlyMissingBuffInRange>, GridTypeMapContainer > grid_creature_searcher(searcher); CellLock<GridReadGuard> cell_lock(cell, p); cell_lock->Visit(cell_lock, grid_creature_searcher, *(m_creature->GetMap())); return pList; }
//return closest creature alive in grid, with range from pSource Creature* GetClosestCreatureWithEntry(WorldObject* pSource, uint32 uiEntry, float fMaxSearchRange) { Creature* pCreature = NULL; CellPair pair(MaNGOS::ComputeCellPair(pSource->GetPositionX(), pSource->GetPositionY())); Cell cell(pair); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck creature_check(*pSource, uiEntry, true, fMaxSearchRange); MaNGOS::CreatureLastSearcher<MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(pCreature, creature_check); TypeContainerVisitor<MaNGOS::CreatureLastSearcher<MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck>, GridTypeMapContainer> creature_searcher(searcher); CellLock<GridReadGuard> cell_lock(cell, pair); cell_lock->Visit(cell_lock, creature_searcher,*(pSource->GetMap()), *pSource, fMaxSearchRange); return pCreature; }
Player* ScriptedAI::GetPlayerAtMinimumRange(float fMinimumRange) { Player* pPlayer = NULL; CellPair pair(MaNGOS::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY())); Cell cell(pair); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); PlayerAtMinimumRangeAway check(m_creature, fMinimumRange); MaNGOS::PlayerSearcher<PlayerAtMinimumRangeAway> searcher(pPlayer, check); TypeContainerVisitor<MaNGOS::PlayerSearcher<PlayerAtMinimumRangeAway>, GridTypeMapContainer> visitor(searcher); CellLock<GridReadGuard> cell_lock(cell, pair); Map * map = m_creature->GetMap(); //lets limit the maximum player search distance to speed up calculations... const float fMaxSearchDst = map->GetVisibilityDistance() > MAX_PLAYER_STEALTH_DETECT_RANGE ? MAX_PLAYER_STEALTH_DETECT_RANGE : map->GetVisibilityDistance(); cell_lock->Visit(cell_lock, visitor, *map, *m_creature, fMaxSearchDst); return pPlayer; }
Unit* ScriptedAI::DoSelectLowestHpFriendly(float range, uint32 MinHPDiff) { CellPair p(MaNGOS::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY())); Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); Unit* pUnit = NULL; MaNGOS::MostHPMissingInRange u_check(m_creature, range, MinHPDiff); MaNGOS::UnitLastSearcher<MaNGOS::MostHPMissingInRange> searcher(m_creature, pUnit, u_check); /* typedef TYPELIST_4(GameObject, Creature*except pets*, DynamicObject, Corpse*Bones*) AllGridObjectTypes; This means that if we only search grid then we cannot possibly return pets or players so this is safe */ TypeContainerVisitor<MaNGOS::UnitLastSearcher<MaNGOS::MostHPMissingInRange>, GridTypeMapContainer > grid_unit_searcher(searcher); CellLock<GridReadGuard> cell_lock(cell, p); cell_lock->Visit(cell_lock, grid_unit_searcher, *(m_creature->GetMap())); return pUnit; }
void DynamicObject::Update(uint32 p_time) { // caster can be not in world at time dynamic object update, but dynamic object not yet deleted in Unit destructor Unit* caster = GetCaster(); if(!caster) { Delete(); return; } bool deleteThis = false; if(m_aliveDuration > int32(p_time)) m_aliveDuration -= p_time; else deleteThis = true; // TODO: make a timer and update this in larger intervals CellPair p(MaNGOS::ComputeCellPair(GetPositionX(), GetPositionY())); Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); MaNGOS::DynamicObjectUpdater notifier(*this,caster); TypeContainerVisitor<MaNGOS::DynamicObjectUpdater, WorldTypeMapContainer > world_object_notifier(notifier); TypeContainerVisitor<MaNGOS::DynamicObjectUpdater, GridTypeMapContainer > grid_object_notifier(notifier); CellLock<GridReadGuard> cell_lock(cell, p); cell_lock->Visit(cell_lock, world_object_notifier, *GetMap()); cell_lock->Visit(cell_lock, grid_object_notifier, *GetMap()); if(deleteThis) { caster->RemoveDynObjectWithGUID(GetGUID()); Delete(); } }
int cell_dispatch_message(struct cell *c) { cell_lock(c); if (c->quit) { cell_destroy(c); return CELL_QUIT; } struct message m; int empty = mq_pop(&c->mq, &m); if (empty || c->L == NULL) { cell_unlock(c); return CELL_EMPTY; } cell_grab(c); cell_unlock(c); lua_pushvalue(c->L, 1); // dup callback lua_pushinteger(c->L, m.port); lua_pushlightuserdata(c->L, m.buffer); lua_call(c->L, 2, 0); cell_release(c); return CELL_MESSAGE; }
void Map::MessageBroadcast(WorldObject *obj, WorldPacket *msg) { // sLog.outString("Map::MessageBroadcast WorldObject"); CellPair p = LeGACY::ComputeCellPair(obj->GetPositionX(), obj->GetPositionY()); if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP ) { sLog.outError("Map::MessageBroadcast: Object " I64FMTD " have invalid coordinates X:%f Y:%f grid cell [%u,%u]", obj->GetGUID(), obj->GetPositionX(), obj->GetPositionY(), p.x_coord, p.y_coord); return; } Cell cell(p); cell.data.Part.reserved = CENTER_DISTRICT; cell.SetNoCreate(); if( !loaded(GridPair(cell.data.Part.grid_x, cell.data.Part.grid_y)) ) return; LeGACY::ObjectMessageDeliverer post_man(*obj, msg); TypeContainerVisitor<LeGACY::ObjectMessageDeliverer, WorldTypeMapContainer > message(post_man); CellLock<ReadGuard> cell_lock(cell, p); cell_lock->Visit(cell_lock, message, *this); }
void HandleStormSequence(Unit *Cloud) // 1: begin, 2-9: tick, 10: end { if(StormCount < 10 && StormCount > 1) { // deal damage int32 bp0 = 800; for(uint8 i = 2; i < StormCount; ++i) bp0 *= 2; CellPair p(Ribon::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY())); Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); std::list<Unit *> tempUnitMap; { Ribon::AnyAoETargetUnitInObjectRangeCheck u_check(m_creature, m_creature, 999); Ribon::UnitListSearcher<Ribon::AnyAoETargetUnitInObjectRangeCheck> searcher(m_creature, tempUnitMap, u_check); TypeContainerVisitor<Ribon::UnitListSearcher<Ribon::AnyAoETargetUnitInObjectRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher); TypeContainerVisitor<Ribon::UnitListSearcher<Ribon::AnyAoETargetUnitInObjectRangeCheck>, GridTypeMapContainer > grid_unit_searcher(searcher); CellLock<GridReadGuard> cell_lock(cell, p); cell_lock->Visit(cell_lock, world_unit_searcher, *(m_creature->GetMap())); cell_lock->Visit(cell_lock, grid_unit_searcher, *(m_creature->GetMap())); } //dealdamege for(std::list<Unit*>::iterator i = tempUnitMap.begin(); i != tempUnitMap.end(); ++i) { if(!Cloud->IsWithinDist(*i, 6, false)) { Cloud->CastCustomSpell(*i, 43137, &bp0, NULL, NULL, true, 0, 0, m_creature->GetGUID()); } } // visual float x,y,z; z = m_creature->GetPositionZ(); for(uint8 i = 0; i < 5+rand()%5; ++i) { x = 343+rand()%60; y = 1380+rand()%60; if(Unit *trigger = m_creature->SummonTrigger(x, y, z, 0, 2000)) { trigger->setFaction(35); trigger->SetMaxHealth(100000); trigger->SetHealth(100000); trigger->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); if (Cloud) Cloud->CastCustomSpell(trigger, /*43661*/43137, &bp0, NULL, NULL,true, 0, 0, Cloud->GetGUID()); } } } StormCount++; if(StormCount > 10) { StormCount = 0; // finish SummonEagles_Timer = 5000; m_creature->InterruptNonMeleeSpells(false); CloudGUID = 0; if (Cloud) Cloud->DealDamage(Cloud, Cloud->GetHealth(),NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); SetWeather(WEATHER_STATE_FINE, 0.0f); isRaining = false; } StormSequenceTimer = 1000; }
void GameObject::Update(uint32 /*p_time*/) { if (IS_MO_TRANSPORT(GetGUID())) { //((Transport*)this)->Update(p_time); return; } switch (m_lootState) { case GO_NOT_READY: { switch(GetGoType()) { case GAMEOBJECT_TYPE_TRAP: { // Arming Time for GAMEOBJECT_TYPE_TRAP (6) Unit* owner = GetOwner(); if (owner && ((Player*)owner)->isInCombat()) m_cooldownTime = time(NULL) + GetGOInfo()->trap.startDelay; m_lootState = GO_READY; break; } case GAMEOBJECT_TYPE_FISHINGNODE: { // fishing code (bobber ready) if( time(NULL) > m_respawnTime - FISHING_BOBBER_READY_TIME ) { // splash bobber (bobber ready now) Unit* caster = GetOwner(); if(caster && caster->GetTypeId()==TYPEID_PLAYER) { SetGoState(0); SetUInt32Value(GAMEOBJECT_FLAGS, GO_FLAG_NODESPAWN); UpdateData udata; WorldPacket packet; BuildValuesUpdateBlockForPlayer(&udata,((Player*)caster)); udata.BuildPacket(&packet); ((Player*)caster)->GetSession()->SendPacket(&packet); WorldPacket data(SMSG_GAMEOBJECT_CUSTOM_ANIM,8+4); data << GetGUID(); data << (uint32)(0); ((Player*)caster)->SendMessageToSet(&data,true); } m_lootState = GO_READY; // can be successfully open with some chance } return; } default: m_lootState = GO_READY; // for other GOis same switched without delay to GO_READY break; } // NO BREAK for switch (m_lootState) } case GO_READY: { if (m_respawnTime > 0) // timer on { if (m_respawnTime <= time(NULL)) // timer expired { m_respawnTime = 0; m_SkillupList.clear(); m_usetimes = 0; switch (GetGoType()) { case GAMEOBJECT_TYPE_FISHINGNODE: // can't fish now { Unit* caster = GetOwner(); if(caster && caster->GetTypeId()==TYPEID_PLAYER) { if(caster->m_currentSpells[CURRENT_CHANNELED_SPELL]) { caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->SendChannelUpdate(0); caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->finish(false); } WorldPacket data(SMSG_FISH_NOT_HOOKED,0); ((Player*)caster)->GetSession()->SendPacket(&data); } // can be delete m_lootState = GO_JUST_DEACTIVATED; return; } case GAMEOBJECT_TYPE_DOOR: case GAMEOBJECT_TYPE_BUTTON: //we need to open doors if they are closed (add there another condition if this code breaks some usage, but it need to be here for battlegrounds) if( !GetGoState() ) SwitchDoorOrButton(false); //flags in AB are type_button and we need to add them here so no break! default: if(!m_spawnedByDefault) // despawn timer { // can be despawned or destroyed SetLootState(GO_JUST_DEACTIVATED); return; } // respawn timer GetMap()->Add(this); break; } } } // traps can have time and can not have GameObjectInfo const* goInfo = GetGOInfo(); if(goInfo->type == GAMEOBJECT_TYPE_TRAP) { // traps Unit* owner = GetOwner(); Unit* ok = NULL; // pointer to appropriate target if found any if(m_cooldownTime >= time(NULL)) return; bool IsBattleGroundTrap = false; //FIXME: this is activation radius (in different casting radius that must be selected from spell data) //TODO: move activated state code (cast itself) to GO_ACTIVATED, in this place only check activating and set state float radius = goInfo->trap.radius; if(!radius) { if(goInfo->trap.cooldown != 3) // cast in other case (at some triggering/linked go/etc explicit call) return; else { if(m_respawnTime > 0) break; radius = goInfo->trap.cooldown; // battlegrounds gameobjects has data2 == 0 && data5 == 3 IsBattleGroundTrap = true; } } bool NeedDespawn = (goInfo->trap.charges != 0); CellPair p(MaNGOS::ComputeCellPair(GetPositionX(),GetPositionY())); Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; // Note: this hack with search required until GO casting not implemented // search unfriendly creature if(owner && NeedDespawn) // hunter trap { MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck u_check(this, owner, radius); MaNGOS::UnitSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck> checker(ok, u_check); CellLock<GridReadGuard> cell_lock(cell, p); TypeContainerVisitor<MaNGOS::UnitSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck>, GridTypeMapContainer > grid_object_checker(checker); cell_lock->Visit(cell_lock, grid_object_checker, *GetMap()); // or unfriendly player/pet if(!ok) { TypeContainerVisitor<MaNGOS::UnitSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker); cell_lock->Visit(cell_lock, world_object_checker, *GetMap()); } } else // environmental trap { // environmental damage spells already have around enemies targeting but this not help in case not existed GO casting support // affect only players Player* p_ok = NULL; MaNGOS::AnyPlayerInObjectRangeCheck p_check(this, radius); MaNGOS::PlayerSearcher<MaNGOS::AnyPlayerInObjectRangeCheck> checker(p_ok, p_check); CellLock<GridReadGuard> cell_lock(cell, p); TypeContainerVisitor<MaNGOS::PlayerSearcher<MaNGOS::AnyPlayerInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker); cell_lock->Visit(cell_lock, world_object_checker, *GetMap()); ok = p_ok; } if (ok) { Unit *caster = owner ? owner : ok; caster->CastSpell(ok, goInfo->trap.spellId, true); m_cooldownTime = time(NULL) + 4; // 4 seconds if(NeedDespawn) SetLootState(GO_JUST_DEACTIVATED); // can be despawned or destroyed if(IsBattleGroundTrap && ok->GetTypeId() == TYPEID_PLAYER) { //BattleGround gameobjects case if(((Player*)ok)->InBattleGround()) if(BattleGround *bg = ((Player*)ok)->GetBattleGround()) bg->HandleTriggerBuff(GetGUID()); } } } if (m_charges && m_usetimes >= m_charges) SetLootState(GO_JUST_DEACTIVATED); // can be despawned or destroyed break; } case GO_ACTIVATED: { switch(GetGoType()) { case GAMEOBJECT_TYPE_DOOR: case GAMEOBJECT_TYPE_BUTTON: if(GetAutoCloseTime() && (m_cooldownTime < time(NULL))) { SwitchDoorOrButton(false); SetLootState(GO_JUST_DEACTIVATED); } break; } break; } case GO_JUST_DEACTIVATED: { //if Gameobject should cast spell, then this, but some GOs (type = 10) should be destroyed if (GetGoType() == GAMEOBJECT_TYPE_GOOBER) { uint32 spellId = GetGOInfo()->goober.spellId; if(spellId) { std::set<uint32>::iterator it = m_unique_users.begin(); std::set<uint32>::iterator end = m_unique_users.end(); for (; it != end; it++) { Unit* owner = Unit::GetUnit(*this, uint64(*it)); if (owner) owner->CastSpell(owner, spellId, false); } m_unique_users.clear(); m_usetimes = 0; } //any return here in case battleground traps } if(GetOwnerGUID()) { m_respawnTime = 0; Delete(); return; } //burning flags in some battlegrounds, if you find better condition, just add it if (GetGoAnimProgress() > 0) { SendObjectDeSpawnAnim(GetGUID()); //reset flags SetUInt32Value(GAMEOBJECT_FLAGS, GetGOInfo()->flags); } loot.clear(); SetLootState(GO_READY); if(!m_respawnDelayTime) return; if(!m_spawnedByDefault) { m_respawnTime = 0; return; } m_respawnTime = time(NULL) + m_respawnDelayTime; // if option not set then object will be saved at grid unload if(sWorld.getConfig(CONFIG_SAVE_RESPAWN_TIME_IMMEDIATLY)) SaveRespawnTime(); ObjectAccessor::UpdateObjectVisibility(this); break; } } }
void HandleStormSequence(Unit *Cloud) // 1: begin, 2-9: tick, 10: end { if(StormCount < 10 && StormCount > 1) { // deal damage int32 bp0 = 800; for(uint8 i = 2; i < StormCount; ++i) bp0 *= 2; CellPair p(MaNGOS::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY())); Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); std::list<Unit *> tempUnitMap; { MaNGOS::AnyAoETargetUnitInObjectRangeCheck u_check(m_creature, m_creature, 999); MaNGOS::UnitListSearcher<MaNGOS::AnyAoETargetUnitInObjectRangeCheck> searcher(tempUnitMap, u_check); TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyAoETargetUnitInObjectRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher); TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyAoETargetUnitInObjectRangeCheck>, GridTypeMapContainer > grid_unit_searcher(searcher); CellLock<GridReadGuard> cell_lock(cell, p); cell_lock->Visit(cell_lock, world_unit_searcher, *(m_creature->GetMap())); cell_lock->Visit(cell_lock, grid_unit_searcher, *(m_creature->GetMap())); } for(std::list<Unit*>::iterator i = tempUnitMap.begin(); i != tempUnitMap.end(); ++i) { if(!Cloud->IsWithinDistInMap(*i, 15)) { float x, y, z; (*i)->GetPosition(x, y, z); x = rand()%2 ? x + rand()%5 : x - rand()%5; y = rand()%2 ? y + rand()%5 : y - rand()%5; z = Cloud->GetPositionZ() + 2 - rand()%4; if(Creature *trigger = m_creature->SummonCreature(MOB_TEMP_TRIGGER, x, y, z, 0, TEMPSUMMON_TIMED_DESPAWN, 2000)) { trigger->AddMonsterMoveFlag(MONSTER_MOVE_LEVITATING); trigger->StopMoving(); trigger->CastSpell(trigger, 37248, true); trigger->CastCustomSpell(*i, 43137, &bp0, NULL, NULL, true, 0, 0, m_creature->GetGUID()); } } } // visual float x, y, z; for(uint8 i = 0; i < StormCount; ++i) { Cloud->GetPosition(x, y, z); x = rand()%2 ? x + rand()%10 : x - rand()%10; y = rand()%2 ? y + rand()%10 : y - rand()%10; z = z + 2 - rand()%4; if(Creature *trigger = m_creature->SummonCreature(MOB_TEMP_TRIGGER, x, y, z, 0, TEMPSUMMON_TIMED_DESPAWN, 2000)) { trigger->AddMonsterMoveFlag(MONSTER_MOVE_LEVITATING); trigger->StopMoving(); trigger->CastSpell(trigger, 37248, true); } Cloud->GetPosition(x, y, z); x = rand()%2 ? x + 10 + rand()%10 : x - 10 - rand()%10; y = rand()%2 ? y + 10 + rand()%10 : y - 10 - rand()%10; if(Creature *trigger = m_creature->SummonCreature(MOB_TEMP_TRIGGER, x, y, m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 2000)) { trigger->SetMaxHealth(9999999); trigger->SetHealth(9999999); trigger->CastSpell(trigger, 43661, true); } } } StormCount++; if(StormCount > 10) { StormCount = 0; // finish SummonEagles_Timer = 5000; m_creature->InterruptNonMeleeSpells(false); Cloud->RemoveAurasDueToSpell(45213); CloudGUID = 0; if(Unit* Cyclone = Unit::GetUnit(*m_creature, CycloneGUID)) Cyclone->RemoveAurasDueToSpell(25160); SetWeather(WEATHER_STATE_FINE, 0.0f); isRaining = false; } StormSequenceTimer = 1000; }