diff options
Diffstat (limited to 'src/game/Creature.cpp')
-rw-r--r-- | src/game/Creature.cpp | 116 |
1 files changed, 80 insertions, 36 deletions
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 71631e4bdbc..9650c537751 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -404,36 +404,21 @@ void Creature::Update(uint32 diff) { if( m_respawnTime <= time(NULL) ) { - DEBUG_LOG("Respawning..."); - m_respawnTime = 0; - lootForPickPocketed = false; - lootForBody = false; - - if(m_originalEntry != GetEntry()) - UpdateEntry(m_originalEntry); - - CreatureInfo const *cinfo = GetCreatureInfo(); - SelectLevel(cinfo); - - if (m_isDeadByDefault) + if(!GetLinkedCreatureRespawnTime()) // Can respawn + Respawn(); + else // the master is dead { - setDeathState(JUST_DIED); - SetHealth(0); - i_motionMaster.Clear(); - clearUnitState(UNIT_STAT_ALL_STATE); - LoadCreaturesAddon(true); + if(uint32 targetGuid = objmgr.GetLinkedRespawnGuid(m_DBTableGuid)) + { + if(targetGuid == m_DBTableGuid) // if linking self, never respawn (check delayed to next day) + SetRespawnTime(DAY); + else + m_respawnTime = (time(NULL)>GetLinkedCreatureRespawnTime()? time(NULL):GetLinkedCreatureRespawnTime())+urand(5,MINUTE); // else copy time from master and add a little + SaveRespawnTime(); // also save to DB immediately + } + else + Respawn(); } - else - setDeathState( JUST_ALIVED ); - - //Call AI respawn virtual function - AI()->JustRespawned(); - - uint16 poolid = poolhandler.IsPartOfAPool(GetGUIDLow(), GetTypeId()); - if (poolid) - poolhandler.UpdatePool(poolid, GetGUIDLow(), GetTypeId()); - else - GetMap()->Add(this); } break; } @@ -618,7 +603,7 @@ bool Creature::AIM_Initialize(CreatureAI* ai) i_AI = ai ? ai : FactorySelector::selectAI(this); if(oldAI) delete oldAI; IsAIEnabled = true; - i_AI->Reset(); + i_AI->InitializeAI(); return true; } @@ -1444,7 +1429,7 @@ bool Creature::LoadFromDB(uint32 guid, Map *map) m_deathState = m_isDeadByDefault ? DEAD : ALIVE; m_respawnTime = objmgr.GetCreatureRespawnTime(m_DBTableGuid,GetInstanceId()); - if(m_respawnTime > time(NULL)) // not ready to respawn + if(m_respawnTime) // respawn on Update { m_deathState = DEAD; if(canFly()) @@ -1454,11 +1439,6 @@ bool Creature::LoadFromDB(uint32 guid, Map *map) Relocate(data->posX,data->posY,tz); } } - else if(m_respawnTime) // respawn time set but expired - { - m_respawnTime = 0; - objmgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),0); - } uint32 curhealth = data->curhealth; if(curhealth) @@ -1728,7 +1708,37 @@ void Creature::Respawn() { if (m_DBTableGuid) objmgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),0); - m_respawnTime = time(NULL); // respawn at next tick + + DEBUG_LOG("Respawning..."); + m_respawnTime = 0; + lootForPickPocketed = false; + lootForBody = false; + + if(m_originalEntry != GetEntry()) + UpdateEntry(m_originalEntry); + + CreatureInfo const *cinfo = GetCreatureInfo(); + SelectLevel(cinfo); + + if (m_isDeadByDefault) + { + setDeathState(JUST_DIED); + SetHealth(0); + i_motionMaster.Clear(); + clearUnitState(UNIT_STAT_ALL_STATE); + LoadCreaturesAddon(true); + } + else + setDeathState( JUST_ALIVED ); + + //Call AI respawn virtual function + AI()->JustRespawned(); + + uint16 poolid = poolhandler.IsPartOfAPool(GetGUIDLow(), GetTypeId()); + if (poolid) + poolhandler.UpdatePool(poolid, GetGUIDLow(), GetTypeId()); + else + GetMap()->Add(this); } } @@ -2349,3 +2359,37 @@ const char* Creature::GetNameForLocaleIdx(int32 loc_idx) const return GetName(); } + +const CreatureData* Creature::GetLinkedRespawnCreatureData() const +{ + if(!m_DBTableGuid) // only hard-spawned creatures from DB can have a linked master + return NULL; + + if(uint32 targetGuid = objmgr.GetLinkedRespawnGuid(m_DBTableGuid)) + return objmgr.GetCreatureData(targetGuid); + + return NULL; +} + +// returns master's remaining respawn time if any +time_t Creature::GetLinkedCreatureRespawnTime() const +{ + if(!m_DBTableGuid) // only hard-spawned creatures from DB can have a linked master + return 0; + + if(uint32 targetGuid = objmgr.GetLinkedRespawnGuid(m_DBTableGuid)) + { + Map* targetMap = NULL; + if(const CreatureData* data = objmgr.GetCreatureData(targetGuid)) + { + if(data->mapid == GetMapId()) // look up on the same map + targetMap = GetMap(); + else // it shouldn't be instanceable map here + targetMap = MapManager::Instance().FindMap(data->mapid); + } + if(targetMap) + return objmgr.GetCreatureRespawnTime(targetGuid,targetMap->GetInstanceId()); + } + + return 0; +}
\ No newline at end of file |