void CNodeDefManager::removeNode(const std::string &name) { // Pre-condition assert(name != ""); // Erase name from name ID mapping content_t id = CONTENT_IGNORE; if (m_name_id_mapping.getId(name, id)) { m_name_id_mapping.eraseName(name); m_name_id_mapping_with_aliases.erase(name); } // Erase node content from all groups it belongs to for (UNORDERED_MAP<std::string, GroupItems>::iterator iter_groups = m_group_to_items.begin(); iter_groups != m_group_to_items.end();) { GroupItems &items = iter_groups->second; for (GroupItems::iterator iter_groupitems = items.begin(); iter_groupitems != items.end();) { if (iter_groupitems->first == id) items.erase(iter_groupitems++); else iter_groupitems++; } // Check if group is empty if (items.size() == 0) m_group_to_items.erase(iter_groups++); else iter_groups++; } }
Unit* SelectRandomNotStomach() { if (Stomach_Map.empty()) return NULL; UNORDERED_MAP<uint64, bool>::const_iterator i = Stomach_Map.begin(); std::list<Unit*> temp; std::list<Unit*>::const_iterator j; //Get all players in map while (i != Stomach_Map.end()) { //Check for valid player Unit* pUnit = Unit::GetUnit(*me, i->first); //Only units out of stomach if (pUnit && i->second == false) temp.push_back(pUnit); ++i; } if (temp.empty()) return NULL; j = temp.begin(); //Get random but only if we have more than one unit on threat list if (temp.size() > 1) advance (j , rand() % (temp.size() - 1)); return (*j); }
void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_uiMorphTimer) { if (m_uiMorphTimer <= uiDiff) { if (DoCastSpellIfCan(m_creature, SPELL_POLYMORPH_BACKFIRE, CAST_TRIGGERED) == CAST_OK) { m_uiMorphTimer = 0; m_creature->ForcedDespawn(); } } else m_uiMorphTimer -= uiDiff; } for (UNORDERED_MAP<uint8, uint32>::iterator itr = m_mSpellTimers.begin(); itr != m_mSpellTimers.end(); ++itr) { if (itr->second < uiDiff) { if (CanUseSpecialAbility(itr->first)) { itr->second = m_aSpitelashAbility[itr->first].m_uiCooldown; break; } } else itr->second -= uiDiff; } DoMeleeAttackIfReady(); }
void Reset() { m_uiMorphTimer = 0; for (UNORDERED_MAP<uint8, uint32>::iterator itr = m_mSpellTimers.begin(); itr != m_mSpellTimers.end(); ++itr) itr->second = m_aSpitelashAbility[itr->first].m_uiInitialTimer; }
void UpdateAI(const uint32 uiDiff) { //Return since we have no target if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; for (UNORDERED_MAP<uint8, uint32>::iterator itr = m_mSpellTimers.begin(); itr != m_mSpellTimers.end(); ++itr) { if (itr->second < uiDiff) { if (CanUseSpecialAbility(itr->first)) { itr->second = m_aSilverHandAbility[itr->first].m_uiCooldown; break; } } else itr->second -= uiDiff; } DoMeleeAttackIfReady(); }
bool bot_ai::HasAuraName (Unit *unit, std::string spell, uint64 casterGuid) { if (spell.length()==0) return false; int loc = master->GetSession()->GetSessionDbcLocale();; if(unit == NULL) return false; Unit *target = unit; if(target->isDead()) return false; Unit::AuraMap &vAuras = (Unit::AuraMap&)target->GetOwnedAuras(); //save the map of auras b/c it can crash if an aura goes away while looping UNORDERED_MAP<uint64, Aura*> auraMap; for(Unit::AuraMap::const_iterator iter = vAuras.begin(); iter!= vAuras.end(); ++iter) { Aura *aura = iter->second; (auraMap)[iter->first] = aura; } // now search our new map for(UNORDERED_MAP<uint64, Aura*>::iterator itr = auraMap.begin(); itr!= auraMap.end(); ++itr) { const SpellEntry *spellInfo = itr->second->GetSpellProto(); const std::string name = spellInfo->SpellName[loc]; if(!spell.compare(name)) { if(casterGuid == 0){ //don't care who casted it return true; } else if(casterGuid == itr->second->GetCasterGUID()){ //only if correct caster casted it return true; } } } return false; }
bool bot_ai::HasAuraIcon (Unit *unit, uint32 SpellIconID, uint64 casterGuid) { int loc = master->GetSession()->GetSessionDbcLocale();; if(unit == NULL) return false; Unit *target = unit; if(target->isDead()) return false; Unit::AuraMap &vAuras = (Unit::AuraMap&)target->GetOwnedAuras(); //save the map of auras b/c it can crash if an aura goes away while looping UNORDERED_MAP<uint64, Aura*> auraMap; for(Unit::AuraMap::const_iterator iter = vAuras.begin(); iter!= vAuras.end(); ++iter) { Aura *aura = iter->second; (auraMap)[iter->first] = aura; } // now search our new map for(UNORDERED_MAP<uint64, Aura*>::iterator itr = auraMap.begin(); itr!= auraMap.end(); ++itr) { const SpellEntry *spellInfo = itr->second->GetSpellProto(); uint32 spelliconId = spellInfo->SpellIconID; //error_log ("bot_ai.HasAuraICON: %s has icon %u",spellInfo->SpellName[master->GetSession()->GetSessionDbcLocale()], spellInfo->SpellIconID); if(spelliconId==SpellIconID) { //error_log ("bot_ai.HasAuraICON: %s has icon %u",spellInfo->SpellName[master->GetSession()->GetSessionDbcLocale()], spellInfo->SpellIconID); if(casterGuid == 0){ //don't care who casted it return true; } else if(casterGuid == itr->second->GetCasterGUID()){ //only if correct caster casted it return true; } } } return false; }
void UpdateAI(const uint32 diff) { //Check if we have a target if (!UpdateVictim()) { //No target so we'll use this section to do our random wispers instance wide //WisperTimer if (WisperTimer <= diff) { Map* map = me->GetMap(); if (!map->IsDungeon()) return; //Play random sound to the zone Map::PlayerList const &PlayerList = map->GetPlayers(); if (!PlayerList.isEmpty()) { for (Map::PlayerList::const_iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr) { if (Player* pPlr = itr->getSource()) pPlr->PlayDirectSound(RANDOM_SOUND_WHISPER, pPlr); } } //One random wisper every 90 - 300 seconds WisperTimer = urand(90000, 300000); } else WisperTimer -= diff; return; } me->SetTarget(0); //No instance if (!pInst) return; uint32 currentPhase = pInst->GetData(DATA_CTHUN_PHASE); if (currentPhase == PHASE_CTHUN_STOMACH || currentPhase == PHASE_CTHUN_WEAK) { // EyeTentacleTimer if (EyeTentacleTimer <= diff) { //Spawn the 8 Eye Tentacles in the corret spots SpawnEyeTentacle(0, 20); //south SpawnEyeTentacle(10, 10); //south west SpawnEyeTentacle(20, 0); //west SpawnEyeTentacle(10, -10); //north west SpawnEyeTentacle(0, -20); //north SpawnEyeTentacle(-10, -10); //north east SpawnEyeTentacle(-20, 0); // east SpawnEyeTentacle(-10, 10); // south east EyeTentacleTimer = 30000; // every 30sec in phase 2 } else EyeTentacleTimer -= diff; } switch (currentPhase) { //Transition phase case PHASE_CTHUN_TRANSITION: //PhaseTimer if (PhaseTimer <= diff) { //Switch pInst->SetData(DATA_CTHUN_PHASE, PHASE_CTHUN_STOMACH); //Switch to c'thun model me->InterruptNonMeleeSpells(false); DoCast(me, SPELL_TRANSFORM, false); me->SetFullHealth(); me->SetVisible(true); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE); //Emerging phase //AttackStart(Unit::GetUnit(*me, HoldpPlayer)); DoZoneInCombat(); //Place all units in threat list on outside of stomach Stomach_Map.clear(); std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin(); for (; i != me->getThreatManager().getThreatList().end(); ++i) { //Outside stomach Stomach_Map[(*i)->getUnitGuid()] = false; } //Spawn 2 flesh tentacles FleshTentaclesKilled = 0; //Spawn flesh tentacle for (uint8 i = 0; i < 2; i++) { Creature* spawned = me->SummonCreature(MOB_FLESH_TENTACLE, FleshTentaclePos[i], TEMPSUMMON_CORPSE_DESPAWN); if (!spawned) ++FleshTentaclesKilled; } PhaseTimer = 0; } else PhaseTimer -= diff; break; //Body Phase case PHASE_CTHUN_STOMACH: //Remove Target field me->SetTarget(0); //Weaken if (FleshTentaclesKilled > 1) { pInst->SetData(DATA_CTHUN_PHASE, PHASE_CTHUN_WEAK); DoScriptText(EMOTE_WEAKENED, me); PhaseTimer = 45000; DoCast(me, SPELL_PURPLE_COLORATION, true); UNORDERED_MAP<uint64, bool>::iterator i = Stomach_Map.begin(); //Kick all players out of stomach while (i != Stomach_Map.end()) { //Check for valid player Unit* pUnit = Unit::GetUnit(*me, i->first); //Only move units in stomach if (pUnit && i->second == true) { //Teleport each player out DoTeleportPlayer(pUnit, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()+10, float(rand()%6)); //Cast knockback on them DoCast(pUnit, SPELL_EXIT_STOMACH_KNOCKBACK, true); //Remove the acid debuff pUnit->RemoveAurasDueToSpell(SPELL_DIGESTIVE_ACID); i->second = false; } ++i; } return; } //Stomach acid if (StomachAcidTimer <= diff) { //Apply aura to all players in stomach UNORDERED_MAP<uint64, bool>::iterator i = Stomach_Map.begin(); while (i != Stomach_Map.end()) { //Check for valid player Unit* pUnit = Unit::GetUnit(*me, i->first); //Only apply to units in stomach if (pUnit && i->second == true) { //Cast digestive acid on them DoCast(pUnit, SPELL_DIGESTIVE_ACID, true); //Check if player should be kicked from stomach if (pUnit->IsWithinDist3d(&KickPos, 15.0f)) { //Teleport each player out DoTeleportPlayer(pUnit, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()+10, float(rand()%6)); //Cast knockback on them DoCast(pUnit, SPELL_EXIT_STOMACH_KNOCKBACK, true); //Remove the acid debuff pUnit->RemoveAurasDueToSpell(SPELL_DIGESTIVE_ACID); i->second = false; } } ++i; } StomachAcidTimer = 4000; } else StomachAcidTimer -= diff; //Stomach Enter Timer if (StomachEnterTimer <= diff) { if (Unit* target = SelectRandomNotStomach()) { //Set target in stomach Stomach_Map[target->GetGUID()] = true; target->InterruptNonMeleeSpells(false); target->CastSpell(target, SPELL_MOUTH_TENTACLE, true, NULL, NULL, me->GetGUID()); StomachEnterTarget = target->GetGUID(); StomachEnterVisTimer = 3800; } StomachEnterTimer = 13800; } else StomachEnterTimer -= diff; if (StomachEnterVisTimer && StomachEnterTarget) { if (StomachEnterVisTimer <= diff) { //Check for valid player Unit* pUnit = Unit::GetUnit(*me, StomachEnterTarget); if (pUnit) { DoTeleportPlayer(pUnit, STOMACH_X, STOMACH_Y, STOMACH_Z, STOMACH_O); } StomachEnterTarget = 0; StomachEnterVisTimer = 0; } else StomachEnterVisTimer -= diff; } //GientClawTentacleTimer if (GiantClawTentacleTimer <= diff) { if (Unit* target = SelectRandomNotStomach()) { //Spawn claw tentacle on the random target if (Creature* spawned = me->SummonCreature(MOB_GIANT_CLAW_TENTACLE, *target, TEMPSUMMON_CORPSE_DESPAWN, 500)) if (spawned->AI()) spawned->AI()->AttackStart(target); } //One giant claw tentacle every minute GiantClawTentacleTimer = 60000; } else GiantClawTentacleTimer -= diff; //GiantEyeTentacleTimer if (GiantEyeTentacleTimer <= diff) { if (Unit* target = SelectRandomNotStomach()) { //Spawn claw tentacle on the random target if (Creature* spawned = me->SummonCreature(MOB_GIANT_EYE_TENTACLE, *target, TEMPSUMMON_CORPSE_DESPAWN, 500)) if (spawned->AI()) spawned->AI()->AttackStart(target); } //One giant eye tentacle every minute GiantEyeTentacleTimer = 60000; } else GiantEyeTentacleTimer -= diff; break; //Weakened state case PHASE_CTHUN_WEAK: //PhaseTimer if (PhaseTimer <= diff) { //Switch pInst->SetData(DATA_CTHUN_PHASE, PHASE_CTHUN_STOMACH); //Remove purple coloration me->RemoveAurasDueToSpell(SPELL_PURPLE_COLORATION); //Spawn 2 flesh tentacles FleshTentaclesKilled = 0; //Spawn flesh tentacle for (uint8 i = 0; i < 2; i++) { Creature* spawned = me->SummonCreature(MOB_FLESH_TENTACLE, FleshTentaclePos[i], TEMPSUMMON_CORPSE_DESPAWN); if (!spawned) ++FleshTentaclesKilled; } PhaseTimer = 0; } else PhaseTimer -= diff; break; } }
void UpdateAI(const uint32 diff) { //Check if we have a target if (!UpdateVictim()) { //No target so we'll use this section to do our random wispers instance wide //WisperTimer if (WisperTimer <= diff) { Map *map = me->GetMap(); if (!map->IsDungeon()) return; Map::PlayerList const &PlayerList = map->GetPlayers(); for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if (Player* i_pl = i->getSource()) { //Play random sound to the zone i_pl->SendPlaySound(RANDOM_SOUND_WHISPER, true); } } //One random wisper every 90 - 300 seconds WisperTimer = 90000 + (rand()% 210000); } else WisperTimer -= diff; return; } me->SetUInt64Value(UNIT_FIELD_TARGET, 0); //No instance if (!pInst) return; switch (pInst->GetData(DATA_CTHUN_PHASE)) { //Transition phase case 2: { //PhaseTimer if (PhaseTimer <= diff) { //Switch pInst->SetData(DATA_CTHUN_PHASE, 3); //Switch to c'thun model me->InterruptNonMeleeSpells(false); DoCast(me, SPELL_TRANSFORM, false); me->SetHealth(me->GetMaxHealth()); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE); //Emerging phase //AttackStart(Unit::GetUnit(*me, HoldPlayer)); DoZoneInCombat(); //Place all units in threat list on outside of stomach Stomach_Map.clear(); std::list<HostileReference*>::iterator i = me->getThreatManager().getThreatList().begin(); for (; i != me->getThreatManager().getThreatList().end(); ++i) { //Outside stomach Stomach_Map[(*i)->getUnitGuid()] = false; } //Spawn 2 flesh tentacles FleshTentaclesKilled = 0; Creature* Spawned; //Spawn flesh tentacle Spawned = (Creature*)me->SummonCreature(MOB_FLESH_TENTACLE, TENTACLE_POS1_X, TENTACLE_POS1_Y, TENTACLE_POS1_Z, TENTACLE_POS1_O, TEMPSUMMON_CORPSE_DESPAWN, 0); if (!Spawned) FleshTentaclesKilled++; else ((flesh_tentacleAI*)(Spawned->AI()))->SpawnedByCthun(me->GetGUID()); //Spawn flesh tentacle Spawned = (Creature*)me->SummonCreature(MOB_FLESH_TENTACLE, TENTACLE_POS2_X, TENTACLE_POS2_Y, TENTACLE_POS2_Z, TENTACLE_POS2_O, TEMPSUMMON_CORPSE_DESPAWN, 0); if (!Spawned) FleshTentaclesKilled++; else ((flesh_tentacleAI*)(Spawned->AI()))->SpawnedByCthun(me->GetGUID()); PhaseTimer = 0; } else PhaseTimer -= diff; }break; //Body Phase case 3: { //Remove Target field me->SetUInt64Value(UNIT_FIELD_TARGET, 0); //Weaken if (FleshTentaclesKilled > 1) { pInst->SetData(DATA_CTHUN_PHASE, 4); DoScriptText(EMOTE_WEAKENED, me); PhaseTimer = 45000; DoCast(me, SPELL_RED_COLORATION, true); UNORDERED_MAP<uint64, bool>::iterator i = Stomach_Map.begin(); //Kick all players out of stomach while (i != Stomach_Map.end()) { //Check for valid player Unit* pUnit = Unit::GetUnit(*me, i->first); //Only move units in stomach if (pUnit && i->second == true) { //Teleport each player out DoTeleportPlayer(pUnit, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()+10, float(rand()%6)); //Cast knockback on them DoCast(pUnit, SPELL_EXIT_STOMACH_KNOCKBACK, true); //Remove the acid debuff pUnit->RemoveAurasDueToSpell(SPELL_DIGESTIVE_ACID); i->second = false; } ++i; } return; } //Stomach acid if (StomachAcidTimer <= diff) { //Apply aura to all players in stomach UNORDERED_MAP<uint64, bool>::iterator i = Stomach_Map.begin(); while (i != Stomach_Map.end()) { //Check for valid player Unit* pUnit = Unit::GetUnit(*me, i->first); //Only apply to units in stomach if (pUnit && i->second == true) { //Cast digestive acid on them DoCast(pUnit, SPELL_DIGESTIVE_ACID, true); //Check if player should be kicked from stomach if (pUnit->GetDistance(KICK_X, KICK_Y, KICK_Z) < 15) { //Teleport each player out DoTeleportPlayer(pUnit, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()+10, float(rand()%6)); //Cast knockback on them DoCast(pUnit, SPELL_EXIT_STOMACH_KNOCKBACK, true); //Remove the acid debuff pUnit->RemoveAurasDueToSpell(SPELL_DIGESTIVE_ACID); i->second = false; } } ++i; } StomachAcidTimer = 4000; } else StomachAcidTimer -= diff; //Stomach Enter Timer if (StomachEnterTimer <= diff) { Unit* pTarget = NULL; pTarget = SelectRandomNotStomach(); if (pTarget) { //Set target in stomach Stomach_Map[pTarget->GetGUID()] = true; pTarget->InterruptNonMeleeSpells(false); pTarget->CastSpell(pTarget, SPELL_MOUTH_TENTACLE, true, NULL, NULL, me->GetGUID()); StomachEnterTarget = pTarget->GetGUID(); StomachEnterVisTimer = 3800; } StomachEnterTimer = 13800; } else StomachEnterTimer -= diff; if (StomachEnterVisTimer && StomachEnterTarget) { if (StomachEnterVisTimer <= diff) { //Check for valid player Unit* pUnit = Unit::GetUnit(*me, StomachEnterTarget); if (pUnit) { DoTeleportPlayer(pUnit, STOMACH_X, STOMACH_Y, STOMACH_Z, STOMACH_O); } StomachEnterTarget = 0; StomachEnterVisTimer = 0; } else StomachEnterVisTimer -= diff; } //GientClawTentacleTimer if (GiantClawTentacleTimer <= diff) { Unit* pTarget = NULL; pTarget = SelectRandomNotStomach(); if (pTarget) { Creature* Spawned = NULL; //Spawn claw tentacle on the random target Spawned = (Creature*)me->SummonCreature(MOB_GIANT_CLAW_TENTACLE,pTarget->GetPositionX(),pTarget->GetPositionY(),pTarget->GetPositionZ(),0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,500); if (Spawned) Spawned->AI()->AttackStart(pTarget); } //One giant claw tentacle every minute GiantClawTentacleTimer = 60000; } else GiantClawTentacleTimer -= diff; //GiantEyeTentacleTimer if (GiantEyeTentacleTimer <= diff) { Unit* pTarget = NULL; pTarget = SelectRandomNotStomach(); if (pTarget) { Creature* Spawned = NULL; //Spawn claw tentacle on the random target Spawned = (Creature*)me->SummonCreature(MOB_GIANT_EYE_TENTACLE,pTarget->GetPositionX(),pTarget->GetPositionY(),pTarget->GetPositionZ(),0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,500); if (Spawned) Spawned->AI()->AttackStart(pTarget); } //One giant eye tentacle every minute GiantEyeTentacleTimer = 60000; } else GiantEyeTentacleTimer -= diff; //EyeTentacleTimer if (EyeTentacleTimer <= diff) { //Spawn the 8 Eye Tentacles in the corret spots SpawnEyeTentacle(0, 25); //south SpawnEyeTentacle(12, 12); //south west SpawnEyeTentacle(25, 0); //west SpawnEyeTentacle(12, -12); //north west SpawnEyeTentacle(0, -25); //north SpawnEyeTentacle(-12, -12); //north east SpawnEyeTentacle(-25, 0); // east SpawnEyeTentacle(-12, 12); // south east //These spawn at every 30 seconds EyeTentacleTimer = 30000; } else EyeTentacleTimer -= diff; }break; //Weakened state case 4: { //PhaseTimer if (PhaseTimer <= diff) { //Switch pInst->SetData(DATA_CTHUN_PHASE, 3); //Remove red coloration me->RemoveAurasDueToSpell(SPELL_RED_COLORATION); //Spawn 2 flesh tentacles FleshTentaclesKilled = 0; Creature* Spawned; //Spawn flesh tentacle Spawned = (Creature*)me->SummonCreature(MOB_FLESH_TENTACLE, TENTACLE_POS1_X, TENTACLE_POS1_Y, TENTACLE_POS1_Z, TENTACLE_POS1_O, TEMPSUMMON_CORPSE_DESPAWN, 0); if (!Spawned) FleshTentaclesKilled++; else ((flesh_tentacleAI*)(Spawned->AI()))->SpawnedByCthun(me->GetGUID()); //Spawn flesh tentacle Spawned = (Creature*)me->SummonCreature(MOB_FLESH_TENTACLE, TENTACLE_POS2_X, TENTACLE_POS2_Y, TENTACLE_POS2_Z, TENTACLE_POS2_O, TEMPSUMMON_CORPSE_DESPAWN, 0); if (!Spawned) FleshTentaclesKilled++; else ((flesh_tentacleAI*)(Spawned->AI()))->SpawnedByCthun(me->GetGUID()); PhaseTimer = 0; } else PhaseTimer -= diff; } } }
void Reset() { for (UNORDERED_MAP<uint8, uint32>::iterator itr = m_mSpellTimers.begin(); itr != m_mSpellTimers.end(); ++itr) itr->second = m_aSilverHandAbility[itr->first].m_uiInitialTimer; }