void Creature::AIM_Update(const uint32 &diff) { switch( m_deathState ) { case JUST_DIED: { SetUInt32Value(UNIT_NPC_FLAGS, 0); m_deathState = CORPSE; i_AI->UpdateAI(diff); break; } case DEAD: { if( m_respawnTimer <= diff ) { DEBUG_LOG("Respawning..."); SetUInt32Value(UNIT_FIELD_HEALTH, GetUInt32Value(UNIT_FIELD_MAXHEALTH)); m_deathState = ALIVE; ClearState(ALL_STATE); i_motionMaster.Clear(); MapManager::Instance().GetMap(GetMapId())->Add(this); } else m_respawnTimer -= diff; break; } case CORPSE: { if( m_deathTimer <= diff ) { DEBUG_LOG("Removing corpse..."); ObjectAccessor::Instance().RemoveCreatureCorpseFromPlayerView(this); setDeathState(DEAD); m_respawnTimer = m_respawnDelay; GetRespawnCoord(m_positionX, m_positionY, m_positionZ); } else m_deathTimer -= diff; break; } case ALIVE: { Unit::Update( diff ); i_AI->UpdateAI(diff); i_motionMaster.UpdateMotion(diff); break; } default: break; } }
bool Creature::IsOutOfThreatArea(Unit* pVictim) const { if(!pVictim) return true; if(!pVictim->isTargetableForAttack()) return true; float rx,ry,rz; GetRespawnCoord(rx, ry, rz); float length = pVictim->GetDistanceSq(rx,ry,rz); return ( length > CREATURE_THREAT_RADIUS ); }
void Creature::Update(uint32 diff) { switch( m_deathState ) { case JUST_DIED: // Dont must be called, see Creature::setDeathState JUST_DIED -> CORPSE promoting. sLog.outError("Creature (GUIDLow: %u Entry: %u ) in wrong state: JUST_DEAD (1)",GetGUIDLow(),GetEntry()); break; case DEAD: { if( m_respawnTime <= time(NULL) ) { DEBUG_LOG("Respawning..."); m_respawnTime = 0; CreatureInfo const *cinfo = objmgr.GetCreatureTemplate(this->GetEntry()); SelectLevel(cinfo); SetUInt32Value(UNIT_DYNAMIC_FLAGS, 0); RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); SetUInt32Value(UNIT_NPC_FLAGS, cinfo->npcflag); SetHealth(GetMaxHealth()); setDeathState( ALIVE ); clearUnitState(UNIT_STAT_ALL_STATE); i_motionMaster.Clear(); MapManager::Instance().GetMap(GetMapId(), this)->Add(this); } break; } case CORPSE: { if( m_deathTimer <= diff ) { m_deathTimer = 0; DEBUG_LOG("Removing corpse... %u ", GetUInt32Value(OBJECT_FIELD_ENTRY)); ObjectAccessor::Instance().RemoveCreatureCorpseFromPlayerView(this); lootForPickPocketed = false; lootForBody = false; loot.clear(); setDeathState(DEAD); m_respawnTime = time(NULL) + m_respawnDelay; float x,y,z; GetRespawnCoord(x, y, z); MapManager::Instance().GetMap(GetMapId(), this)->CreatureRelocation(this,x,y,z,GetOrientation()); } else { m_deathTimer -= diff; if (m_groupLootTimer && lootingGroupLeaderGUID) { if(diff <= m_groupLootTimer) { m_groupLootTimer -= diff; } else { Group* group = objmgr.GetGroupByLeader(lootingGroupLeaderGUID); if (group) group->EndRoll(); m_groupLootTimer = 0; lootingGroupLeaderGUID = 0; } } } break; } case ALIVE: { Unit::Update( diff ); i_motionMaster.UpdateMotion(diff); i_AI->UpdateAI(diff); if(m_regenTimer > 0) { if(diff >= m_regenTimer) m_regenTimer = 0; else m_regenTimer -= diff; } if (m_regenTimer != 0) break; if (!isInCombat()) { RegenerateHealth(); RegenerateMana(); } m_regenTimer = 2000; break; } default: break; } }