*Change waypoint data structure. Use creature db guid as path id. If a creature uses waypoint movement as default movement type, the path id should be DBGUID*10. For paths of script use, the path id should be DBGUID*10+1 ~ DBGUID*10+9.

*Two sql queries are included. Converter is used to convert the existing path id to new path id. "...creature_add..." is used to change table structure. You can first run the converter, then run the other one. Or run the other one directly and get the new data from the db team. Because it may take hours to run the converter.
*If you have custom data, you may need to run the converter. We suggest you use console to run it It is extremely slow to run the query. If you have multiple paths for a creature in your db, you need to do more work to convert it. However, if you know how to use multiple paths, you should already have more db knowledge than I do and you should know how to convert it.
*There may be a faster query to convert the db. If you know, please tell us. I am no sql expert.
*Backup your db first!
*Thanks to X-Savior and subhuman_bob.

--HG--
branch : trunk
This commit is contained in:
megamage
2009-05-11 13:27:10 -05:00
parent 91558b8b29
commit 8fc07d443a
11 changed files with 116 additions and 75 deletions

View File

@@ -0,0 +1,2 @@
ALTER TABLE creature_template_addon DROP COLUMN path_id;
ALTER TABLE creature_addon DROP COLUMN path_id;

View File

@@ -0,0 +1,6 @@
ALTER TABLE waypoint_data ADD COLUMN id_old int(10) unsigned NOT NULL default '0' COMMENT 'Creature GUID' AFTER wpguid;
UPDATE waypoint_data SET id_old=id;
UPDATE waypoint_data,creature_addon SET waypoint_data.id=creature_addon.guid*10 WHERE creature_addon.path_id > 0 AND creature_addon.path_id=waypoint_data.id_old;
UPDATE waypoint_data SET id = 1343801 WHERE id_old = 2084;
UPDATE waypoint_scripts SET datalong = 1343801 WHERE id = 515;
ALTER TABLE waypoint_data DROP COLUMN id_old;

View File

@@ -175,7 +175,7 @@ void Creature::AddToWorld()
{
ObjectAccessor::Instance().AddObject(this);
Unit::AddToWorld();
SearchFormation();
SearchFormationAndPath();
AIM_Initialize();
}
}
@@ -194,7 +194,7 @@ void Creature::RemoveFromWorld()
}
}
void Creature::SearchFormation()
void Creature::SearchFormationAndPath()
{
if(isSummon())
return;
@@ -203,9 +203,28 @@ void Creature::SearchFormation()
if(!lowguid)
return;
bool usePath = (GetDefaultMovementType() == WAYPOINT_MOTION_TYPE);
CreatureGroupInfoType::iterator frmdata = CreatureGroupMap.find(lowguid);
if(frmdata != CreatureGroupMap.end())
{
if(usePath && lowguid != frmdata->second->leaderGUID)
{
SetDefaultMovementType(IDLE_MOTION_TYPE);
usePath = false;
}
formation_mgr.AddCreatureToGroup(frmdata->second->leaderGUID, this);
}
if(usePath)
{
if(WaypointMgr.GetPath(lowguid * 10))
SetWaypointPathId(lowguid * 10);
else
{
sLog.outErrorDb("Creature DBGUID %u has waypoint motion type, but it does not have a waypoint path!", lowguid);
SetDefaultMovementType(IDLE_MOTION_TYPE);
}
}
}
void Creature::RemoveCorpse()
@@ -2081,10 +2100,6 @@ bool Creature::LoadCreaturesAddon(bool reload)
if (cainfo->move_flags != 0)
SetUnitMovementFlags(cainfo->move_flags);
//Load Path
if (cainfo->path_id != 0)
m_path_id = cainfo->path_id;
if(cainfo->auras)
{
for (CreatureDataAddonAura const* cAura = cainfo->auras; cAura->spell_id; ++cAura)

View File

@@ -315,7 +315,6 @@ struct CreatureDataAddonAura
struct CreatureDataAddon
{
uint32 guidOrEntry;
uint32 path_id;
uint32 mount;
uint32 bytes0;
uint32 bytes1;
@@ -692,13 +691,13 @@ class TRINITY_DLL_SPEC Creature : public Unit
uint32 GetGlobalCooldown() const { return m_GlobalCooldown; }
uint32 GetWaypointPath(){return m_path_id;}
void LoadPath(uint32 pathid) { m_path_id = pathid; }
uint32 GetWaypointPathId() const { return m_pathId; }
void SetWaypointPathId(uint32 pathid) { m_pathId = pathid; }
uint32 GetCurrentWaypointID(){return m_waypointID;}
void UpdateWaypointID(uint32 wpID){m_waypointID = wpID;}
void SearchFormation();
void SearchFormationAndPath();
CreatureGroup *GetFormation() {return m_formation;}
void SetFormation(CreatureGroup *formation) {m_formation = formation;}
@@ -759,7 +758,7 @@ class TRINITY_DLL_SPEC Creature : public Unit
private:
//WaypointMovementGenerator vars
uint32 m_waypointID;
uint32 m_path_id;
uint32 m_pathId;
//Formation var
CreatureGroup *m_formation;

View File

@@ -1288,7 +1288,7 @@ bool ChatHandler::HandleNpcAddMoveCommand(const char* args)
// update movement type
WorldDatabase.PExecuteLog("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE,lowguid);
if(pCreature && pCreature->GetWaypointPath())
if(pCreature && pCreature->GetWaypointPathId())
{
pCreature->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
pCreature->GetMotionMaster()->Initialize();
@@ -1609,7 +1609,7 @@ bool ChatHandler::HandleNpcSetMoveTypeCommand(const char* args)
{
// update movement type
if(doNotDelete == false)
pCreature->LoadPath(0);
pCreature->SetWaypointPathId(0);
pCreature->SetDefaultMovementType(move_type);
pCreature->GetMotionMaster()->Initialize();
@@ -2639,7 +2639,7 @@ bool ChatHandler::HandleWpAddCommand(const char* args)
if (!path_number)
{
if(target)
pathid = target->GetWaypointPath();
pathid = target->GetWaypointPathId();
else
{
QueryResult *result = WorldDatabase.PQuery( "SELECT MAX(id) FROM waypoint_data");
@@ -2694,7 +2694,6 @@ bool ChatHandler::HandleWpLoadPathCommand(const char *args)
if(*args)
path_number = strtok((char*)args, " ");
uint32 pathid = 0;
uint32 guidlow = 0;
Creature* target = getSelectedCreature();
@@ -2725,6 +2724,7 @@ bool ChatHandler::HandleWpLoadPathCommand(const char *args)
return true;
}
/*
guidlow = target->GetDBTableGUIDLow();
QueryResult *result = WorldDatabase.PQuery( "SELECT guid FROM creature_addon WHERE guid = '%u'",guidlow);
@@ -2735,10 +2735,11 @@ bool ChatHandler::HandleWpLoadPathCommand(const char *args)
}
else
WorldDatabase.PExecute("INSERT INTO creature_addon(guid,path_id) VALUES ('%u','%u')", guidlow, pathid);
*/
WorldDatabase.PExecute("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", WAYPOINT_MOTION_TYPE, guidlow);
target->LoadPath(pathid);
target->SetWaypointPathId(pathid);
target->SetDefaultMovementType(WAYPOINT_MOTION_TYPE);
target->GetMotionMaster()->Initialize();
target->MonsterSay("Path loaded.",0,0);
@@ -2746,20 +2747,19 @@ bool ChatHandler::HandleWpLoadPathCommand(const char *args)
return true;
}
bool ChatHandler::HandleReloadAllPaths(const char* args)
{
if(!*args)
return false;
if(!*args)
return false;
uint32 id = atoi(args);
uint32 id = atoi(args);
if(!id)
return false;
if(!id)
return false;
PSendSysMessage("%s%s|r|cff00ffff%u|r", "|cff00ff00", "Loading Path: ", id);
WaypointMgr.UpdatePath(id);
return true;
return true;
}
bool ChatHandler::HandleWpUnLoadPathCommand(const char *args)
@@ -2773,24 +2773,39 @@ bool ChatHandler::HandleWpUnLoadPathCommand(const char *args)
return true;
}
if(target->GetCreatureAddon())
if(target->GetWaypointPathId())
{
if(target->GetCreatureAddon()->path_id != 0)
uint32 pathId = target->GetDBTableGUIDLow() * 10;
if(target->GetWaypointPathId() == pathId)
{
WorldDatabase.PExecute("DELETE FROM creature_addon WHERE guid = %u", target->GetGUIDLow());
target->UpdateWaypointID(0);
WorldDatabase.PExecute("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", IDLE_MOTION_TYPE, guidlow);
target->LoadPath(0);
target->SetDefaultMovementType(IDLE_MOTION_TYPE);
target->GetMotionMaster()->MoveTargetedHome();
target->GetMotionMaster()->Initialize();
target->MonsterSay("Path unloaded.",0,0);
return true;
for(uint32 i = 1; i < 11; ++i)
{
if(i == 10)
{
PSendSysMessage("%s%s|r", "|cffff33ff", "Target cannot have more than 9 script paths. Unloading failed.");
break;
}
if(WaypointMgr.GetPath(++pathId))
continue;
WorldDatabase.PExecute("UPDATE waypoint_data SET id = %u WHERE id = %u", pathId, target->GetDBTableGUIDLow() * 10);
WorldDatabase.PExecute("UPDATE creature SET MovementType = '%u' WHERE guid = '%u'", IDLE_MOTION_TYPE, guidlow);
target->SetWaypointPathId(0);
target->UpdateWaypointID(0);
target->SetDefaultMovementType(IDLE_MOTION_TYPE);
target->GetMotionMaster()->Initialize();
target->GetMotionMaster()->MoveTargetedHome();
PSendSysMessage("Path unloaded.");
break;
}
}
PSendSysMessage("%s%s|r", "|cffff33ff", "Target have no loaded path.");
return true;
else
PSendSysMessage("%s%s|r", "|cffff33ff", "Target has path but that path is not its default path. Unloading failed.");
}
PSendSysMessage("%s%s|r", "|cffff33ff", "Target have no loaded path.");
else
PSendSysMessage("%s%s|r", "|cffff33ff", "Target has no loaded path.");
return true;
}
@@ -3264,7 +3279,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
return false;
}
pathid = target->GetWaypointPath();
pathid = target->GetWaypointPathId();
}
else
@@ -4629,7 +4644,7 @@ bool ChatHandler::HandleNpcAddFormationCommand(const char* args)
group_member->groupAI = 0;
CreatureGroupMap[lowguid] = group_member;
pCreature->SearchFormation();
pCreature->SearchFormationAndPath();
WorldDatabase.PExecuteLog("INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`) VALUES ('%u','%u','%f', '%f', '%u')",
leaderGUID, lowguid, group_member->follow_dist, group_member->follow_angle, group_member->groupAI);

View File

@@ -2431,31 +2431,32 @@ void SpellMgr::LoadSpellCustomAttr()
case 45976: // Muru Portal Channel
case 39365: // Thundering Storm
case 41071: // Raise Dead (HACK)
case 28542: // Life Drain - Sapphiron
spellInfo->MaxAffectedTargets = 1;
break;
case 41376: // Spite
case 39992: // Needle Spine
case 29576: //Multi-Shot
case 40816: //Saber Lash
case 37790: //Spread Shot
case 46771: //Flame Sear
case 45248: //Shadow Blades
case 29576: // Multi-Shot
case 40816: // Saber Lash
case 37790: // Spread Shot
case 46771: // Flame Sear
case 45248: // Shadow Blades
case 41303: // Soul Drain
case 54172: // Divine Storm (heal)
case 29213: // Curse of the Plaguebringer
case 29213: // Curse of the Plaguebringer - Noth
case 28542: // Life Drain - Sapphiron
spellInfo->MaxAffectedTargets = 3;
break;
case 38310: //Multi-Shot
spellInfo->MaxAffectedTargets = 4;
break;
case 42005: // Bloodboil
case 38296: //Spitfire Totem
case 37676: //Insidious Whisper
case 46009: //Negative Energy
case 45641: //Fire Bloom
case 54937: //Glyph of Holy Light
case 55665: // Life Drain - Sapphiron
case 38296: // Spitfire Totem
case 37676: // Insidious Whisper
case 46009: // Negative Energy
case 45641: // Fire Bloom
case 54937: // Glyph of Holy Light
case 55665: // Life Drain - Sapphiron (H)
case 28796: // Poison Bolt Volly - Faerlina
spellInfo->MaxAffectedTargets = 5;
break;
case 40827: // Sinful Beam
@@ -2463,7 +2464,8 @@ void SpellMgr::LoadSpellCustomAttr()
case 40860: // Vile Beam
case 40861: // Wicked Beam
case 57669: // Replenishment
case 54835: // Curse of the Plaguebringer
case 54835: // Curse of the Plaguebringer - Noth (H)
case 54098: // Poison Bolt Volly - Faerlina (H)
spellInfo->MaxAffectedTargets = 10;
break;
case 8122: case 8124: case 10888: case 10890: // Psychic Scream

View File

@@ -24,12 +24,12 @@
#include "ProgressBar.h"
#include "MapManager.h"
UNORDERED_MAP<uint32, WaypointPath*> waypoint_map;
WaypointPathMap WaypointPathHolder;
WaypointStore WaypointMgr;
void WaypointStore::Free()
{
waypoint_map.clear();
WaypointPathHolder.clear();
}
void WaypointStore::Load()
@@ -37,7 +37,7 @@ void WaypointStore::Load()
QueryResult *result = WorldDatabase.PQuery("SELECT MAX(`id`) FROM `waypoint_data`");
if(!result)
{
sLog.outError(" an error occured while loading the table `waypoint_data` ( maybe it doesn't exist ?)\n");
sLog.outError("an error occured while loading the table `waypoint_data` (maybe it doesn't exist ?)");
exit(1); // Stop server at loading non exited table or not accessable table
}
@@ -47,7 +47,7 @@ void WaypointStore::Load()
result = WorldDatabase.PQuery("SELECT `id`,`point`,`position_x`,`position_y`,`position_z`,`move_flag`,`delay`,`action`,`action_chance` FROM `waypoint_data` ORDER BY `id`, `point`");
if(!result)
{
sLog.outErrorDb("The table `creature_addon` is empty or corrupted");
sLog.outErrorDb("The table `waypoint_data` is empty or corrupted");
return;
}
@@ -87,22 +87,21 @@ void WaypointStore::Load()
path_data->push_back(wp);
if(id != last_id)
waypoint_map[id] = path_data;
if(id != last_id)
WaypointPathHolder[id] = path_data;
last_id = id;
} while(result->NextRow()) ;
delete result;
}
void WaypointStore::UpdatePath(uint32 id)
{
if(waypoint_map.find(id)!= waypoint_map.end())
waypoint_map[id]->clear();
// TODO: this will cause memory leak
if(WaypointPathHolder.find(id) != WaypointPathHolder.end())
WaypointPathHolder[id]->clear();
QueryResult *result;
@@ -145,7 +144,7 @@ void WaypointStore::UpdatePath(uint32 id)
}while (result->NextRow());
waypoint_map[id] = path_data;
WaypointPathHolder[id] = path_data;
delete result;
}

View File

@@ -34,7 +34,9 @@ struct WaypointData
};
typedef std::vector<WaypointData*> WaypointPath;
extern UNORDERED_MAP<uint32, WaypointPath*> waypoint_map;
typedef UNORDERED_MAP<uint32, WaypointPath*> WaypointPathMap;
extern WaypointPathMap WaypointPathHolder;
class WaypointStore
{
@@ -48,9 +50,10 @@ class WaypointStore
WaypointPath* GetPath(uint32 id)
{
if(waypoint_map.find(id) != waypoint_map.end())
return waypoint_map[id];
else return 0;
WaypointPathMap::iterator itr = WaypointPathHolder.find(id);
if(itr != WaypointPathHolder.end())
return itr->second;
return NULL;
}
inline uint32 GetRecordsCount() { return records; }

View File

@@ -100,7 +100,7 @@ WaypointMovementGenerator<Creature>::Initialize(Creature &u)
//i_nextMoveTime.Reset(0);
StopedByPlayer = false;
if(!path_id)
path_id = u.GetWaypointPath();
path_id = u.GetWaypointPathId();
waypoints = WaypointMgr.GetPath(path_id);
i_currentNode = 0;
if(waypoints && waypoints->size())
@@ -226,7 +226,7 @@ template bool WaypointMovementGenerator<Player>::Update(Player &, const uint32 &
template void WaypointMovementGenerator<Player>::MovementInform(Player &);
//----------------------------------------------------//
void FlightPathMovementGenerator::LoadPath(Player &)
void FlightPathMovementGenerator::SetWaypointPathId(Player &)
{
objmgr.GetTaxiPathNodes(i_pathId, i_path,i_mapIds);
}
@@ -252,7 +252,7 @@ void FlightPathMovementGenerator::Initialize(Player &player)
player.addUnitState(UNIT_STAT_IN_FLIGHT);
player.SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_TAXI_FLIGHT);
player.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
LoadPath(player);
SetWaypointPathId(player);
Traveller<Player> traveller(player);
// do not send movement, it was sent already
i_destinationHolder.SetDestination(traveller, i_path[i_currentNode].x, i_path[i_currentNode].y, i_path[i_currentNode].z, false);

View File

@@ -50,7 +50,7 @@ class TRINITY_DLL_SPEC PathMovementBase
bool MovementInProgress(void) const { return i_currentNode < i_path.Size(); }
void LoadPath(T &);
void SetWaypointPathId(T &);
void ReloadPath(T &);
uint32 GetCurrentNode() const { return i_currentNode; }
@@ -104,7 +104,7 @@ public PathMovementBase<Player>
bool Update(Player &, const uint32 &);
MovementGeneratorType GetMovementGeneratorType() { return FLIGHT_MOTION_TYPE; }
void LoadPath(Player &);
void SetWaypointPathId(Player &);
void ReloadPath(Player &) { /* don't reload flight path */ }
Path& GetPath() { return i_path; }

View File

@@ -29,9 +29,9 @@ extern DatabaseMysql WorldDatabase;
const char CreatureInfosrcfmt[]="iiiiiisssiiiiiiiiiiffiffiiiiiiiiiiiffiiiiiiiiiiiiiiiiiiiiiiiisiifflliiis";
const char CreatureInfodstfmt[]="iiiiiisssiiiiiiiiiiffiffiiiiiiiiiiiffiiiiiiiiiiiiiiiiiiiiiiiisiifflliiii";
const char CreatureDataAddonInfofmt[]="iiiiiiiis";
const char CreatureDataAddonInfofmt[]="iiiiiiis";
const char CreatureModelfmt[]="iffbi";
const char CreatureInfoAddonInfofmt[]="iiiiiiiis";
const char CreatureInfoAddonInfofmt[]="iiiiiiis";
const char EquipmentInfofmt[]="iiii";
const char GameObjectInfosrcfmt[]="iiisssiifiiiiiiiiiiiiiiiiiiiiiiiis";
const char GameObjectInfodstfmt[]="iiisssiifiiiiiiiiiiiiiiiiiiiiiiiii";