--HG--
branch : trunk
This commit is contained in:
megamage
2009-04-15 17:06:38 -05:00
17 changed files with 266 additions and 43 deletions
+2
View File
@@ -408,6 +408,7 @@ ChatCommand * ChatHandler::getCommandTable()
{ "event_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadEventScriptsCommand, "", NULL },
{ "command", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCommandCommand, "", NULL },
{ "creature_involvedrelation", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCreatureQuestInvRelationsCommand,"",NULL },
{ "creature_linked_respawn", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCreatureLinkedRespawnCommand, "", NULL },
{ "creature_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesCreatureCommand, "", NULL },
{ "creature_questrelation", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCreatureQuestRelationsCommand, "", NULL },
//{ "db_script_string", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadDbScriptStringCommand, "", NULL },
@@ -518,6 +519,7 @@ ChatCommand * ChatHandler::getCommandTable()
{
{ "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL },
{ "" , SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCommand, "", NULL },
{ "setlink", SEC_MODERATOR, false, &ChatHandler::HandleNpcSetLinkCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
+2
View File
@@ -279,6 +279,7 @@ class ChatHandler
bool HandleNpcWhisperCommand(const char* args);
bool HandleNpcYellCommand(const char* args);
bool HandleNpcAddFormationCommand(const char* args);
bool HandleNpcSetLinkCommand(const char* args);
//TODO: NpcCommands that needs to be fixed :
bool HandleNpcAddWeaponCommand(const char* args);
@@ -312,6 +313,7 @@ class ChatHandler
bool HandleReloadCommandCommand(const char* args);
bool HandleReloadCreatureQuestRelationsCommand(const char* args);
bool HandleReloadCreatureQuestInvRelationsCommand(const char* args);
bool HandleReloadCreatureLinkedRespawnCommand(const char* args);
bool HandleReloadDbScriptStringCommand(const char* args);
bool HandleReloadGameGraveyardZoneCommand(const char* args);
bool HandleReloadGameObjectScriptsCommand(const char* args);
+79 -35
View File
@@ -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;
}
@@ -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;
}
+4
View File
@@ -645,6 +645,10 @@ class TRINITY_DLL_SPEC Creature : public Unit
float GetRespawnRadius() const { return m_respawnradius; }
void SetRespawnRadius(float dist) { m_respawnradius = dist; }
// Linked Creature Respawning System
time_t GetLinkedCreatureRespawnTime() const;
const CreatureData* GetLinkedRespawnCreatureData() const;
uint32 m_groupLootTimer; // (msecs)timer used for group loot
uint64 lootingGroupLeaderGUID; // used to find group which is looting corpse
+3 -1
View File
@@ -694,7 +694,9 @@ enum TrinityStrings
// LANG_BG_EY_START_TWO_MINUTES = 755, - defined above
// Room for batleground/arena strings 756-799 not used
// Room for BG/ARENA 750-769 not used
// Room for BG/ARENA 751-769 not used
LANG_NPCINFO_LINKGUID = 750,
LANG_ARENA_TESTING = 785,
LANG_AUTO_ANN = 786,
+1
View File
@@ -282,6 +282,7 @@ std::string ChatHandler::PGetParseString(int32 entry, ...)
va_end(ap);
return (std::string)str;
}
bool ChatHandler::HandleGMTicketListCommand(const char* args)
{
SendSysMessage(LANG_COMMAND_TICKETSHOWLIST);
+36 -1
View File
@@ -42,6 +42,7 @@
#include <fstream>
#include <map>
#include "GlobalEvents.h"
#include "TicketMgr.h"
#include "TargetedMovementGenerator.h" // for HandleNpcUnFollowCommand
#include "CreatureGroups.h"
@@ -160,7 +161,7 @@ bool ChatHandler::HandleUnmuteCommand(const char* args)
bool ChatHandler::HandleGoTicketCommand(const char * args)
{
if(!*args)
if(!*args)
return false;
char *cstrticket_id = strtok((char*)args, " ");
@@ -4640,3 +4641,37 @@ bool ChatHandler::HandleNpcAddFormationCommand(const char* args)
return true;
}
bool ChatHandler::HandleNpcSetLinkCommand(const char* args)
{
if (!*args)
return false;
uint32 linkguid = (uint32) atoi((char*)args);
Creature* pCreature = getSelectedCreature();
if(!pCreature)
{
SendSysMessage(LANG_SELECT_CREATURE);
SetSentErrorMessage(true);
return false;
}
if(!pCreature->GetDBTableGUIDLow())
{
PSendSysMessage("Selected creature isn't in `creature` table", pCreature->GetGUIDLow());
SetSentErrorMessage(true);
return false;
}
if(!objmgr.SetCreatureLinkedRespawn(pCreature->GetDBTableGUIDLow(), linkguid))
{
PSendSysMessage("Selected creature can't link with guid '%u'", linkguid);
SetSentErrorMessage(true);
return false;
}
PSendSysMessage("LinkGUID '%u' added to creature with DBTableGUID: '%u'", linkguid, pCreature->GetDBTableGUIDLow());
return true;
}
+11
View File
@@ -714,6 +714,14 @@ bool ChatHandler::HandleReloadCreatureQuestRelationsCommand(const char*)
return true;
}
bool ChatHandler::HandleReloadCreatureLinkedRespawnCommand(const char* args)
{
sLog.outString( "Loading Linked Respawns... (`creature_linked_respawn`)" );
objmgr.LoadCreatureLinkedRespawn();
SendGlobalGMSysMessage("DB table `creature_linked_respawn` (creature linked respawns) reloaded.");
return true;
}
bool ChatHandler::HandleReloadCreatureQuestInvRelationsCommand(const char*)
{
sLog.outString( "Loading Quests Relations... (`creature_involvedrelation`)" );
@@ -4300,6 +4308,9 @@ bool ChatHandler::HandleNpcInfoCommand(const char* /*args*/)
PSendSysMessage(LANG_NPCINFO_LOOT, cInfo->lootid,cInfo->pickpocketLootId,cInfo->SkinLootId);
PSendSysMessage(LANG_NPCINFO_DUNGEON_ID, target->GetInstanceId());
PSendSysMessage(LANG_NPCINFO_POSITION,float(target->GetPositionX()), float(target->GetPositionY()), float(target->GetPositionZ()));
if(const CreatureData* const linked = target->GetLinkedRespawnCreatureData())
if(CreatureInfo const *master = GetCreatureInfo(linked->id))
PSendSysMessage(LANG_NPCINFO_LINKGUID, objmgr.GetLinkedRespawnGuid(target->GetDBTableGUIDLow()), linked->id, master->Name);
if ((npcflags & UNIT_NPC_FLAG_VENDOR) )
{
+88 -3
View File
@@ -940,6 +940,94 @@ void ObjectMgr::LoadCreatureModelInfo()
}
}
bool ObjectMgr::CheckCreatureLinkedRespawn(uint32 guid, uint32 linkedGuid) const
{
const CreatureData* const slave = GetCreatureData(guid);
const CreatureData* const master = GetCreatureData(linkedGuid);
if(!slave || !master) // they must have a corresponding entry in db
{
sLog.outError("LinkedRespawn: Creature '%u' linking to '%u' which doesn't exist",guid,linkedGuid);
return false;
}
const MapEntry* const map = sMapStore.LookupEntry(master->mapid);
if(master->mapid != slave->mapid // link only to same map
&& (!map || map->Instanceable())) // or to unistanced world
{
sLog.outError("LinkedRespawn: Creature '%u' linking to '%u' on an unpermitted map",guid,linkedGuid);
return false;
}
if(!(master->spawnMask & slave->spawnMask) // they must have a possibility to meet (normal/heroic difficulty)
&& (!map || map->Instanceable()))
{
sLog.outError("LinkedRespawn: Creature '%u' linking to '%u' with not corresponding spawnMask",guid,linkedGuid);
return false;
}
return true;
}
void ObjectMgr::LoadCreatureLinkedRespawn()
{
mCreatureLinkedRespawnMap.clear();
QueryResult *result = WorldDatabase.Query("SELECT guid, linkedGuid FROM creature_linked_respawn ORDER BY guid ASC");
if(!result)
{
barGoLink bar(1);
bar.step();
sLog.outString("");
sLog.outErrorDb(">> Loaded 0 linked respawns. DB table `creature_linked_respawn` is empty.");
return;
}
barGoLink bar(result->GetRowCount());
do
{
Field *fields = result->Fetch();
bar.step();
uint32 guid = fields[0].GetUInt32();
uint32 linkedGuid = fields[1].GetUInt32();
if(CheckCreatureLinkedRespawn(guid,linkedGuid))
mCreatureLinkedRespawnMap[guid] = linkedGuid;
} while (result->NextRow());
delete result;
sLog.outString();
sLog.outString( ">> Loaded %u linked respawns", mCreatureLinkedRespawnMap.size() );
}
bool ObjectMgr::SetCreatureLinkedRespawn(uint32 guid, uint32 linkedGuid)
{
if(!guid)
return false;
if(!linkedGuid) // we're removing the linking
{
mCreatureLinkedRespawnMap.erase(guid);
WorldDatabase.DirectPExecute("DELETE FROM `creature_linked_respawn` WHERE `guid` = '%u'",guid);
return true;
}
if(CheckCreatureLinkedRespawn(guid,linkedGuid)) // we add/change linking
{
mCreatureLinkedRespawnMap[guid] = linkedGuid;
WorldDatabase.DirectPExecute("REPLACE INTO `creature_linked_respawn`(`guid`,`linkedGuid`) VALUES ('%u','%u')",guid,linkedGuid);
return true;
}
return false;
}
void ObjectMgr::LoadCreatures()
{
uint32 count = 0;
@@ -1246,9 +1334,6 @@ void ObjectMgr::RemoveGameobjectFromGrid(uint32 guid, GameObjectData const* data
void ObjectMgr::LoadCreatureRespawnTimes()
{
// remove outdated data
WorldDatabase.DirectExecute("DELETE FROM creature_respawn WHERE respawntime <= UNIX_TIMESTAMP(NOW())");
uint32 count = 0;
QueryResult *result = WorldDatabase.Query("SELECT guid,respawntime,instance FROM creature_respawn");
+11
View File
@@ -134,6 +134,7 @@ struct TrinityStringLocale
std::vector<std::string> Content; // 0 -> default, i -> i-1 locale index
};
typedef std::map<uint32,uint32> CreatureLinkedRespawnMap;
typedef UNORDERED_MAP<uint32,CreatureData> CreatureDataMap;
typedef UNORDERED_MAP<uint32,GameObjectData> GameObjectDataMap;
typedef UNORDERED_MAP<uint32,CreatureLocale> CreatureLocaleMap;
@@ -528,6 +529,9 @@ class ObjectMgr
void LoadCreatureLocales();
void LoadCreatureTemplates();
void LoadCreatures();
void LoadCreatureLinkedRespawn();
bool CheckCreatureLinkedRespawn(uint32 guid, uint32 linkedGuid) const;
bool SetCreatureLinkedRespawn(uint32 guid, uint32 linkedGuid);
void LoadCreatureRespawnTimes();
void LoadCreatureAddons();
void LoadCreatureModelInfo();
@@ -635,6 +639,12 @@ class ObjectMgr
}
CreatureData& NewOrExistCreatureData(uint32 guid) { return mCreatureDataMap[guid]; }
void DeleteCreatureData(uint32 guid);
uint32 GetLinkedRespawnGuid(uint32 guid) const
{
CreatureLinkedRespawnMap::const_iterator itr = mCreatureLinkedRespawnMap.find(guid);
if(itr == mCreatureLinkedRespawnMap.end()) return 0;
return itr->second;
}
CreatureLocale const* GetCreatureLocale(uint32 entry) const
{
CreatureLocaleMap::const_iterator itr = mCreatureLocaleMap.find(entry);
@@ -897,6 +907,7 @@ class ObjectMgr
MapObjectGuids mMapObjectGuids;
CreatureDataMap mCreatureDataMap;
CreatureLinkedRespawnMap mCreatureLinkedRespawnMap;
CreatureLocaleMap mCreatureLocaleMap;
GameObjectDataMap mGameObjectDataMap;
GameObjectLocaleMap mGameObjectLocaleMap;
+3
View File
@@ -1254,6 +1254,9 @@ void World::SetInitialWorldSettings()
sLog.outString( "Loading Creature Data..." );
objmgr.LoadCreatures();
sLog.outString( "Loading Creature Linked Respawn..." );
objmgr.LoadCreatureLinkedRespawn(); // must be after LoadCreatures()
sLog.outString( "Loading Creature Addon Data..." );
sLog.outString();
objmgr.LoadCreatureAddons(); // must be after LoadCreatureTemplates() and LoadCreatures()