void MapCell::LoadObjects(CellSpawns * sp) { //we still have mobs loaded on cell. There is no point of loading them again if (_loaded == true) return; _loaded = true; Instance * pInstance = _mapmgr->pInstance; InstanceBossInfoMap *bossInfoMap = objmgr.m_InstanceBossInfoMap[_mapmgr->GetMapId()]; if (sp->CreatureSpawns.size())//got creatures { for (CreatureSpawnList::iterator i = sp->CreatureSpawns.begin(); i != sp->CreatureSpawns.end(); i++) { uint32 respawnTimeOverride = 0; if (pInstance) { if (bossInfoMap != NULL && IS_PERSISTENT_INSTANCE(pInstance)) { bool skip = false; for (std::set<uint32>::iterator killedNpc = pInstance->m_killedNpcs.begin(); killedNpc != pInstance->m_killedNpcs.end(); ++killedNpc) { // Do not spawn the killed boss. if ((*killedNpc) == (*i)->entry) { skip = true; break; } // Do not spawn the killed boss' trash. InstanceBossInfoMap::const_iterator bossInfo = bossInfoMap->find((*killedNpc)); if (bossInfo != bossInfoMap->end() && bossInfo->second->trash.find((*i)->id) != bossInfo->second->trash.end()) { skip = true; break; } } if (skip) continue; for (InstanceBossInfoMap::iterator bossInfo = bossInfoMap->begin(); bossInfo != bossInfoMap->end(); ++bossInfo) { if (pInstance->m_killedNpcs.find(bossInfo->second->creatureid) == pInstance->m_killedNpcs.end() && bossInfo->second->trash.find((*i)->id) != bossInfo->second->trash.end()) { respawnTimeOverride = bossInfo->second->trashRespawnOverride; } } } else { // No boss information available ... fallback ... if (pInstance->m_killedNpcs.find((*i)->id) != pInstance->m_killedNpcs.end()) continue; } } Creature * c = _mapmgr->CreateCreature((*i)->entry); c->SetMapId(_mapmgr->GetMapId()); c->SetInstanceID(_mapmgr->GetInstanceID()); c->m_loadedFromDB = true; if (respawnTimeOverride > 0) c->m_respawnTimeOverride = respawnTimeOverride; if (c->Load(*i, _mapmgr->iInstanceMode, _mapmgr->GetMapInfo()) && c->CanAddToWorld()) { c->PushToWorld(_mapmgr); } else delete c;//missing proto or smth of that kind } } if (sp->GOSpawns.size())//got GOs { for (GOSpawnList::iterator i = sp->GOSpawns.begin(); i != sp->GOSpawns.end(); i++) { GameObject * go = _mapmgr->CreateGameObject((*i)->entry); go->SetInstanceID(_mapmgr->GetInstanceID()); if (go->Load(*i)) { //uint32 state = go->GetUInt32Value(GAMEOBJECT_STATE); // FIXME - burlex /* if(pInstance && pInstance->FindObject((*i)->stateNpcLink)) { go->SetUInt32Value(GAMEOBJECT_STATE, (state ? 0 : 1)); }*/ go->m_loadedFromDB = true; go->PushToWorld(_mapmgr); } else delete go;//missing proto or smth of that kind } } }
void Creature::OnRespawn(MapMgr * m) { if(m_noRespawn) return; InstanceBossInfoMap *bossInfoMap = objmgr.m_InstanceBossInfoMap[m->GetMapId()]; if(bossInfoMap != NULL) { bool skip = false; Instance *pInstance = m->pInstance; for(std::set<uint32>::iterator killedNpc = pInstance->m_killedNpcs.begin(); killedNpc != pInstance->m_killedNpcs.end(); ++killedNpc) { // Is killed boss? if((*killedNpc) == this->creature_info->Id) { skip = true; break; } // Is add from killed boss? InstanceBossInfoMap::const_iterator bossInfo = bossInfoMap->find((*killedNpc)); if(bossInfo != bossInfoMap->end() && bossInfo->second->trash.find(this->spawnid) != bossInfo->second->trash.end()) { skip = true; break; } } if(skip) { this->m_noRespawn = true; this->DeleteMe(); return; } } sLog.outDetail("Respawning "I64FMT"...", GetGUID()); SetUInt32Value(UNIT_FIELD_HEALTH, GetUInt32Value(UNIT_FIELD_MAXHEALTH)); SetUInt32Value(UNIT_DYNAMIC_FLAGS, 0); // not tagging shiat if(proto && m_spawn) { SetUInt32Value(UNIT_NPC_FLAGS, proto->NPCFLags); SetUInt32Value(UNIT_NPC_EMOTESTATE, m_spawn->emote_state); } RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); Skinned = false; Tagged = false; TaggerGuid = 0; m_lootMethod = -1; /* creature death state */ if(proto && proto->death_state == 1) { uint32 newhealth = m_uint32Values[UNIT_FIELD_HEALTH] / 100; if(!newhealth) newhealth = 1; SetUInt32Value(UNIT_FIELD_HEALTH, 1); m_limbostate = true; bInvincible = true; SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_DEAD); SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, 35); } //empty loot loot.items.clear(); setDeathState(ALIVE); GetAIInterface()->StopMovement(0); // after respawn monster can move GetAIInterface()->m_canMove = true; m_PickPocketed = false; PushToWorld(m); }