aboutsummaryrefslogtreecommitdiff
path: root/src/game/Creature.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/Creature.cpp')
-rw-r--r--src/game/Creature.cpp105
1 files changed, 74 insertions, 31 deletions
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp
index 0681dcddd04..f8643543038 100644
--- a/src/game/Creature.cpp
+++ b/src/game/Creature.cpp
@@ -413,32 +413,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 = 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();
-
- GetMap()->Add(this);
}
break;
}
@@ -1424,7 +1413,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())
@@ -1434,11 +1423,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)
@@ -1709,7 +1693,33 @@ 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();
+
+ GetMap()->Add(this);
}
}
@@ -2323,3 +2333,36 @@ 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