[10106] More modes for .go commands

* Now '.go' command can be used with creature_entry/gameobject_entry shift links (output of .lookup creature/object commands)
* Now '.go object' command sipport id-mode and name part mode similar .go creature case: .go object id #gameobject_id or .go object $namepart.
* HandleGoHelper use in more commands also.
This commit is contained in:
VladimirMangos 2010-06-26 14:57:36 +04:00
parent e203a235ba
commit a504b4d200
13 changed files with 439 additions and 235 deletions

View file

@ -24,7 +24,7 @@ CREATE TABLE `db_version` (
`version` varchar(120) default NULL,
`creature_ai_version` varchar(120) default NULL,
`cache_id` int(10) default '0',
`required_10089_01_mangos_game_event_pool` bit(1) default NULL
`required_10106_02_mangos_mangos_string` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
--
@ -577,11 +577,11 @@ INSERT INTO `command` VALUES
('gm ingame',0,'Syntax: .gm ingame\r\n\r\nDisplay a list of available in game Game Masters.'),
('gm list',3,'Syntax: .gm list\r\n\r\nDisplay a list of all Game Masters accounts and security levels.'),
('gm visible',1,'Syntax: .gm visible on/off\r\n\r\nOutput current visibility state or make GM visible(on) and invisible(off) for other players.'),
('go',1,'Syntax: .go [$playername|pointlink|#x #y #z [#mapid]]\r\nTeleport your character to point with coordinates of player $playername, or coordinates of one from shift-link types: player, tele, taxinode, creature, gameobject, or explicit #x #y #z #mapid coordinates.'),
('go creature',1,'Syntax: .go creature #creature_guid\r\nTeleport your character to creature with guid #creature_guid.\r\n.gocreature #creature_name\r\nTeleport your character to creature with this name.\r\n.gocreature id #creature_id\r\nTeleport your character to a creature that was spawned from the template with this entry.\r\n*If* more than one creature is found, then you are teleported to the first that is found inside the database.'),
('go',1,'Syntax: .go [$playername|pointlink|#x #y #z [#mapid]]\r\nTeleport your character to point with coordinates of player $playername, or coordinates of one from shift-link types: player, tele, taxinode, creature/creature_entry, gameobject/gameobject_entry, or explicit #x #y #z #mapid coordinates.'),
('go creature',1,'Syntax: .go creature (#creature_guid|$creature_name|id #creature_id)\r\nTeleport your character to creature with guid #creature_guid, or teleport your character to creature with name including as part $creature_name substring, or teleport your character to a creature that was spawned from the template with this entry #creature_id.'),
('go graveyard',1,'Syntax: .go graveyard #graveyardId\r\n Teleport to graveyard with the graveyardId specified.'),
('go grid',1,'Syntax: .go grid #gridX #gridY [#mapId]\r\n\r\nTeleport the gm to center of grid with provided indexes at map #mapId (or current map if it not provided).'),
('go object',1,'Syntax: .go object #object_guid\r\nTeleport your character to gameobject with guid #object_guid'),
('go object',1,'Syntax: .go object (#gameobject_guid|$gameobject_name|id #gameobject_id)\r\nTeleport your character to gameobject with guid #gameobject_guid, or teleport your character to gameobject with name including as part $gameobject_name substring, or teleport your character to a gameobject that was spawned from the template with this entry #gameobject_id.'),
('go taxinode',1,'Syntax: .go taxinode #taxinode\r\n\r\nTeleport player to taxinode coordinates. You can look up zone using .lookup taxinode $namepart'),
('go trigger',1,'Syntax: .go trigger #trigger_id\r\n\r\nTeleport your character to areatrigger with id #trigger_id. Character will be teleported to trigger target if selected areatrigger is telporting trigger.'),
('go xy',1,'Syntax: .go xy #x #y [#mapid]\r\n\r\nTeleport player to point with (#x,#y) coordinates at ground(water) level at map #mapid or same map if #mapid not provided.'),
@ -3176,7 +3176,6 @@ INSERT INTO `mangos_string` VALUES
(266,'Nothing found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(267,'Object not found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(268,'Creature not found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(269,'Warning: Mob found more than once - you will be teleported to the first one found in DB.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(270,'Creature Removed',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(271,'Creature moved.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(272,'Creature (GUID:%u) must be on the same map as player!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),

View file

@ -0,0 +1,7 @@
ALTER TABLE db_version CHANGE COLUMN required_10089_01_mangos_game_event_pool required_10106_01_mangos_command bit;
DELETE FROM command WHERE name IN('go', 'go creature','go object');
INSERT INTO command (name, security, help) VALUES
('go',1,'Syntax: .go [$playername|pointlink|#x #y #z [#mapid]]\r\nTeleport your character to point with coordinates of player $playername, or coordinates of one from shift-link types: player, tele, taxinode, creature/creature_entry, gameobject/gameobject_entry, or explicit #x #y #z #mapid coordinates.'),
('go creature',1,'Syntax: .go creature (#creature_guid|$creature_name|id #creature_id)\r\nTeleport your character to creature with guid #creature_guid, or teleport your character to creature with name including as part $creature_name substring, or teleport your character to a creature that was spawned from the template with this entry #creature_id.'),
('go object',1,'Syntax: .go object (#gameobject_guid|$gameobject_name|id #gameobject_id)\r\nTeleport your character to gameobject with guid #gameobject_guid, or teleport your character to gameobject with name including as part $gameobject_name substring, or teleport your character to a gameobject that was spawned from the template with this entry #gameobject_id.');

View file

@ -0,0 +1,3 @@
ALTER TABLE db_version CHANGE COLUMN required_10106_01_mangos_command required_10106_02_mangos_mangos_string bit;
DELETE FROM mangos_string WHERE entry IN (269);

View file

@ -91,6 +91,8 @@ pkgdata_DATA = \
10056_01_mangos_spell_proc_event.sql \
10086_01_mangos_command.sql \
10089_01_mangos_game_event_pool.sql \
10106_01_mangos_command.sql \
10106_02_mangos_mangos_string.sql \
README
## Additional files to include when running 'make dist'
@ -162,4 +164,6 @@ EXTRA_DIST = \
10056_01_mangos_spell_proc_event.sql \
10086_01_mangos_command.sql \
10089_01_mangos_game_event_pool.sql \
10106_01_mangos_command.sql \
10106_02_mangos_mangos_string.sql \
README

View file

@ -1928,38 +1928,6 @@ char* ChatHandler::extractKeyFromLink(char* text, char const* const* linkTypes,
return NULL;
}
char const *fmtstring( char const *format, ... )
{
va_list argptr;
#define MAX_FMT_STRING 32000
static char temp_buffer[MAX_FMT_STRING];
static char string[MAX_FMT_STRING];
static int index = 0;
char *buf;
int len;
va_start(argptr, format);
vsnprintf(temp_buffer,MAX_FMT_STRING, format, argptr);
va_end(argptr);
len = strlen(temp_buffer);
if( len >= MAX_FMT_STRING )
return "ERROR";
if (len + index >= MAX_FMT_STRING-1)
{
index = 0;
}
buf = &string[index];
memcpy( buf, temp_buffer, len+1 );
index += len + 1;
return buf;
}
GameObject* ChatHandler::GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid,uint32 entry)
{
if(!m_session)
@ -2135,11 +2103,13 @@ uint64 ChatHandler::extractGuidFromLink(char* text)
enum LocationLinkType
{
LOCATION_LINK_PLAYER = 0, // must be first for selection in not link case
LOCATION_LINK_TELE = 1,
LOCATION_LINK_TAXINODE = 2,
LOCATION_LINK_CREATURE = 3,
LOCATION_LINK_GAMEOBJECT = 4
LOCATION_LINK_PLAYER = 0, // must be first for selection in not link case
LOCATION_LINK_TELE = 1,
LOCATION_LINK_TAXINODE = 2,
LOCATION_LINK_CREATURE = 3,
LOCATION_LINK_GAMEOBJECT = 4,
LOCATION_LINK_CREATURE_ENTRY = 5,
LOCATION_LINK_GAMEOBJECT_ENTRY = 6
};
static char const* const locationKeys[] =
@ -2149,6 +2119,8 @@ static char const* const locationKeys[] =
"Hplayer",
"Hcreature",
"Hgameobject",
"Hcreature_entry",
"Hgameobject_entry",
NULL
};
@ -2161,6 +2133,8 @@ bool ChatHandler::extractLocationFromLink(char* text, uint32& mapid, float& x, f
// |color|Htaxinode:id|h[name]|h|r
// |color|Hcreature:creature_guid|h[name]|h|r
// |color|Hgameobject:go_guid|h[name]|h|r
// |color|Hcreature_entry:creature_id|h[name]|h|r
// |color|Hgameobject_entry:go_id|h[name]|h|r
char* idS = extractKeyFromLink(text,locationKeys,&type);
if(!idS)
return false;
@ -2251,6 +2225,54 @@ bool ChatHandler::extractLocationFromLink(char* text, uint32& mapid, float& x, f
else
return false;
}
case LOCATION_LINK_CREATURE_ENTRY:
{
uint32 id = (uint32)atol(idS);
if (sObjectMgr.GetCreatureTemplate(id))
{
FindCreatureData worker(id, m_session ? m_session->GetPlayer() : NULL);
sObjectMgr.DoCreatureData(worker);
if (CreatureDataPair const* dataPair = worker.GetResult())
{
mapid = dataPair->second.mapid;
x = dataPair->second.posX;
y = dataPair->second.posY;
z = dataPair->second.posZ;
return true;
}
else
return false;
}
else
return false;
}
case LOCATION_LINK_GAMEOBJECT_ENTRY:
{
uint32 id = (uint32)atol(idS);
if (sObjectMgr.GetGameObjectInfo(id))
{
FindGOData worker(id, m_session ? m_session->GetPlayer() : NULL);
sObjectMgr.DoGOData(worker);
if (GameObjectDataPair const* dataPair = worker.GetResult())
{
mapid = dataPair->second.mapid;
x = dataPair->second.posX;
y = dataPair->second.posY;
z = dataPair->second.posZ;
return true;
}
else
return false;
}
else
return false;
}
}
// unknown type?

View file

@ -559,7 +559,7 @@ class ChatHandler
void HandleCharacterLevel(Player* player, uint64 player_guid, uint32 oldlevel, uint32 newlevel);
void HandleLearnSkillRecipesHelper(Player* player,uint32 skill_id);
void ShowSpellListHelper(Player* target, SpellEntry const* spellInfo, LocaleConstant loc);
bool HandleGoHelper(Player* _player, uint32 mapid, float x, float y, float const* zPtr = NULL);
bool HandleGoHelper(Player* _player, uint32 mapid, float x, float y, float const* zPtr = NULL, float const* ortPtr = NULL);
/**
@ -614,6 +614,4 @@ class CliHandler : public ChatHandler
Print* m_print;
};
char const *fmtstring( char const *format, ... );
#endif

View file

@ -253,7 +253,7 @@ enum MangosStrings
LANG_COMMAND_TARGETOBJNOTFOUND = 266,
LANG_COMMAND_GOOBJNOTFOUND = 267,
LANG_COMMAND_GOCREATNOTFOUND = 268,
LANG_COMMAND_GOCREATMULTIPLE = 269,
// 269, not used
LANG_COMMAND_DELCREATMESSAGE = 270,
LANG_COMMAND_CREATUREMOVED = 271,
LANG_COMMAND_CREATUREATSAMEMAP = 272,

View file

@ -599,17 +599,7 @@ bool ChatHandler::HandleGonameCommand(const char* args)
if (!Player::LoadPositionFromDB(map,x,y,z,o,in_flight,target_guid))
return false;
// stop flight if need
if (_player->isInFlight())
{
_player->GetMotionMaster()->MovementExpired();
_player->m_taxi.ClearTaxiDestinations();
}
// save only in non-flight case
else
_player->SaveRecallPosition();
_player->TeleportTo(map, x, y, z,_player->GetOrientation());
return HandleGoHelper(_player, map, x, y, &z);
}
return true;
@ -633,15 +623,7 @@ bool ChatHandler::HandleRecallCommand(const char* args)
return false;
}
// stop flight if need
if(target->isInFlight())
{
target->GetMotionMaster()->MovementExpired();
target->m_taxi.ClearTaxiDestinations();
}
target->TeleportTo(target->m_recallMap, target->m_recallX, target->m_recallY, target->m_recallZ, target->m_recallO);
return true;
return HandleGoHelper(target, target->m_recallMap, target->m_recallX, target->m_recallY, &target->m_recallZ, &target->m_recallO);
}
//Edit Player HP
@ -1780,18 +1762,7 @@ bool ChatHandler::HandleTeleCommand(const char * args)
return false;
}
// stop flight if need
if(_player->isInFlight())
{
_player->GetMotionMaster()->MovementExpired();
_player->m_taxi.ClearTaxiDestinations();
}
// save only in non-flight case
else
_player->SaveRecallPosition();
_player->TeleportTo(tele->mapId, tele->position_x, tele->position_y, tele->position_z, tele->orientation);
return true;
return HandleGoHelper(_player, tele->mapId, tele->position_x, tele->position_y, &tele->position_z, &tele->orientation);
}
bool ChatHandler::HandleLookupAreaCommand(const char* args)
@ -2030,17 +2001,7 @@ bool ChatHandler::HandleTeleNameCommand(const char * args)
if (needReportToTarget(target))
ChatHandler(target).PSendSysMessage(LANG_TELEPORTED_TO_BY, GetNameLink().c_str());
// stop flight if need
if(target->isInFlight())
{
target->GetMotionMaster()->MovementExpired();
target->m_taxi.ClearTaxiDestinations();
}
// save only in non-flight case
else
target->SaveRecallPosition();
target->TeleportTo(tele->mapId,tele->position_x,tele->position_y,tele->position_z,tele->orientation);
return HandleGoHelper(target, tele->mapId, tele->position_x, tele->position_y, &tele->position_z, &tele->orientation);
}
else
{
@ -2226,16 +2187,20 @@ bool ChatHandler::HandleGroupgoCommand(const char* args)
return true;
}
bool ChatHandler::HandleGoHelper( Player* player, uint32 mapid, float x, float y, float const* zPtr )
bool ChatHandler::HandleGoHelper( Player* player, uint32 mapid, float x, float y, float const* zPtr, float const* ortPtr)
{
float z;
float ort = player->GetOrientation();
if (zPtr)
{
z = *zPtr;
if (ortPtr)
ort = *ortPtr;
// check full provided coordinates
if(!MapManager::IsValidMapCoord(mapid,x,y,z))
if(!MapManager::IsValidMapCoord(mapid,x,y,z,ort))
{
PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);
SetSentErrorMessage(true);
@ -2266,7 +2231,7 @@ bool ChatHandler::HandleGoHelper( Player* player, uint32 mapid, float x, float y
else
player->SaveRecallPosition();
player->TeleportTo(mapid, x, y, z, player->GetOrientation());
player->TeleportTo(mapid, x, y, z, ort);
return true;
}

View file

@ -165,25 +165,7 @@ bool ChatHandler::HandleGoTriggerCommand(const char* args)
return false;
}
if(!MapManager::IsValidMapCoord(at->mapid,at->x,at->y,at->z))
{
PSendSysMessage(LANG_INVALID_TARGET_COORD,at->x,at->y,at->mapid);
SetSentErrorMessage(true);
return false;
}
// stop flight if need
if(_player->isInFlight())
{
_player->GetMotionMaster()->MovementExpired();
_player->m_taxi.ClearTaxiDestinations();
}
// save only in non-flight case
else
_player->SaveRecallPosition();
_player->TeleportTo(at->mapid, at->x, at->y, at->z, _player->GetOrientation());
return true;
return HandleGoHelper(_player, at->mapid, at->x, at->y, &at->z);
}
bool ChatHandler::HandleGoGraveyardCommand(const char* args)
@ -210,25 +192,7 @@ bool ChatHandler::HandleGoGraveyardCommand(const char* args)
return false;
}
if(!MapManager::IsValidMapCoord(gy->map_id,gy->x,gy->y,gy->z))
{
PSendSysMessage(LANG_INVALID_TARGET_COORD,gy->x,gy->y,gy->map_id);
SetSentErrorMessage(true);
return false;
}
// stop flight if need
if(_player->isInFlight())
{
_player->GetMotionMaster()->MovementExpired();
_player->m_taxi.ClearTaxiDestinations();
}
// save only in non-flight case
else
_player->SaveRecallPosition();
_player->TeleportTo(gy->map_id, gy->x, gy->y, gy->z, _player->GetOrientation());
return true;
return HandleGoHelper(_player, gy->map_id, gy->x, gy->y, &gy->z);
}
/** \brief Teleport the GM to the specified creature
@ -244,155 +208,221 @@ bool ChatHandler::HandleGoGraveyardCommand(const char* args)
//teleport to creature
bool ChatHandler::HandleGoCreatureCommand(const char* args)
{
if(!*args)
if (!*args)
return false;
Player* _player = m_session->GetPlayer();
// "id" or number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
// "id" or number or [name] Shift-click form |color|Hcreature:creature_id|h[name]|h|r
char* pParam1 = extractKeyFromLink((char*)args,"Hcreature");
if (!pParam1)
return false;
std::ostringstream whereClause;
CreatureData const* data = NULL;
// User wants to teleport to the NPC's template entry
if( strcmp(pParam1, "id") == 0 )
if (strcmp(pParam1, "id") == 0)
{
//sLog.outError("DEBUG: ID found");
// Get the "creature_template.entry"
// number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
char* tail = strtok(NULL,"");
if(!tail)
if (!tail)
return false;
char* cId = extractKeyFromLink(tail,"Hcreature_entry");
if(!cId)
if (!cId)
return false;
int32 tEntry = atoi(cId);
//sLog.outError("DEBUG: ID value: %d", tEntry);
if(!tEntry)
if (!tEntry)
return false;
whereClause << "WHERE id = '" << tEntry << "'";
if (!sObjectMgr.GetCreatureTemplate(tEntry))
{
SendSysMessage(LANG_COMMAND_GOCREATNOTFOUND);
SetSentErrorMessage(true);
return false;
}
FindCreatureData worker(tEntry, m_session ? m_session->GetPlayer() : NULL);
sObjectMgr.DoCreatureData(worker);
CreatureDataPair const* dataPair = worker.GetResult();
if (!dataPair)
{
SendSysMessage(LANG_COMMAND_GOCREATNOTFOUND);
SetSentErrorMessage(true);
return false;
}
data = &dataPair->second;
}
else
{
//sLog.outError("DEBUG: ID *not found*");
int32 guid = atoi(pParam1);
int32 lowguid = atoi(pParam1);
// Number is invalid - maybe the user specified the mob's name
if(!guid)
if (lowguid)
{
std::string name = pParam1;
WorldDatabase.escape_string(name);
whereClause << ", creature_template WHERE creature.id = creature_template.entry AND creature_template.name "_LIKE_" '" << name << "'";
data = sObjectMgr.GetCreatureData(lowguid);
if (!data)
{
SendSysMessage(LANG_COMMAND_GOCREATNOTFOUND);
SetSentErrorMessage(true);
return false;
}
}
else
{
whereClause << "WHERE guid = '" << guid << "'";
std::string name = pParam1;
WorldDatabase.escape_string(name);
QueryResult *result = WorldDatabase.PQuery("SELECT guid FROM creature, creature_template WHERE creature.id = creature_template.entry AND creature_template.name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"), name.c_str());
if (!result)
{
SendSysMessage(LANG_COMMAND_GOCREATNOTFOUND);
SetSentErrorMessage(true);
return false;
}
FindCreatureData worker(0, m_session ? m_session->GetPlayer() : NULL);
do {
Field *fields = result->Fetch();
uint32 guid = fields[0].GetUInt32();
CreatureDataPair const* cr_data = sObjectMgr.GetCreatureDataPair(guid);
if (!cr_data)
continue;
worker(*cr_data);
} while (result->NextRow());
delete result;
CreatureDataPair const* dataPair = worker.GetResult();
if (!dataPair)
{
SendSysMessage(LANG_COMMAND_GOCREATNOTFOUND);
SetSentErrorMessage(true);
return false;
}
data = &dataPair->second;
}
}
//sLog.outError("DEBUG: %s", whereClause.c_str());
QueryResult *result = WorldDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map FROM creature %s", whereClause.str().c_str() );
if (!result)
{
SendSysMessage(LANG_COMMAND_GOCREATNOTFOUND);
SetSentErrorMessage(true);
return false;
}
if( result->GetRowCount() > 1 )
{
SendSysMessage(LANG_COMMAND_GOCREATMULTIPLE);
}
Field *fields = result->Fetch();
float x = fields[0].GetFloat();
float y = fields[1].GetFloat();
float z = fields[2].GetFloat();
float ort = fields[3].GetFloat();
int mapid = fields[4].GetUInt16();
delete result;
if(!MapManager::IsValidMapCoord(mapid,x,y,z,ort))
{
PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);
SetSentErrorMessage(true);
return false;
}
// stop flight if need
if(_player->isInFlight())
{
_player->GetMotionMaster()->MovementExpired();
_player->m_taxi.ClearTaxiDestinations();
}
// save only in non-flight case
else
_player->SaveRecallPosition();
_player->TeleportTo(mapid, x, y, z, ort);
return true;
return HandleGoHelper(_player, data->mapid, data->posX, data->posY, &data->posZ);
}
//teleport to gameobject
bool ChatHandler::HandleGoObjectCommand(const char* args)
{
if(!*args)
if (!*args)
return false;
Player* _player = m_session->GetPlayer();
// number or [name] Shift-click form |color|Hgameobject:go_guid|h[name]|h|r
char* cId = extractKeyFromLink((char*)args,"Hgameobject");
if(!cId)
char* pParam1 = extractKeyFromLink((char*)args,"Hgameobject");
if (!pParam1)
return false;
int32 guid = atoi(cId);
if(!guid)
return false;
GameObjectData const* data = NULL;
float x, y, z, ort;
int mapid;
// by DB guid
if (GameObjectData const* go_data = sObjectMgr.GetGOData(guid))
// User wants to teleport to the NPC's template entry
if (strcmp(pParam1, "id") == 0)
{
x = go_data->posX;
y = go_data->posY;
z = go_data->posZ;
ort = go_data->orientation;
mapid = go_data->mapid;
// number or [name] Shift-click form |color|Hgameobject_entry:creature_id|h[name]|h|r
char* tail = strtok(NULL,"");
if (!tail)
return false;
char* cId = extractKeyFromLink(tail,"Hgameobject_entry");
if (!cId)
return false;
int32 tEntry = atoi(cId);
if (!tEntry)
return false;
if (!sObjectMgr.GetGameObjectInfo(tEntry))
{
SendSysMessage(LANG_COMMAND_GOOBJNOTFOUND);
SetSentErrorMessage(true);
return false;
}
FindGOData worker(tEntry, m_session ? m_session->GetPlayer() : NULL);
sObjectMgr.DoGOData(worker);
GameObjectDataPair const* dataPair = worker.GetResult();
if (!dataPair)
{
SendSysMessage(LANG_COMMAND_GOOBJNOTFOUND);
SetSentErrorMessage(true);
return false;
}
data = &dataPair->second;
}
else
{
SendSysMessage(LANG_COMMAND_GOOBJNOTFOUND);
SetSentErrorMessage(true);
return false;
int32 guid = atoi(pParam1);
if (guid)
{
// by DB guid
data = sObjectMgr.GetGOData(guid);
if (!data)
{
SendSysMessage(LANG_COMMAND_GOOBJNOTFOUND);
SetSentErrorMessage(true);
return false;
}
}
else
{
std::string name = pParam1;
WorldDatabase.escape_string(name);
QueryResult *result = WorldDatabase.PQuery("SELECT guid FROM gameobject, gameobject_template WHERE gameobject.id = gameobject_template.entry AND gameobject_template.name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"), name.c_str());
if (!result)
{
SendSysMessage(LANG_COMMAND_GOOBJNOTFOUND);
SetSentErrorMessage(true);
return false;
}
FindGOData worker(0, m_session ? m_session->GetPlayer() : NULL);
do {
Field *fields = result->Fetch();
uint32 guid = fields[0].GetUInt32();
GameObjectDataPair const* go_data = sObjectMgr.GetGODataPair(guid);
if (!go_data)
continue;
worker(*go_data);
} while (result->NextRow());
delete result;
GameObjectDataPair const* dataPair = worker.GetResult();
if (!dataPair)
{
SendSysMessage(LANG_COMMAND_GOOBJNOTFOUND);
SetSentErrorMessage(true);
return false;
}
data = &dataPair->second;
}
}
if(!MapManager::IsValidMapCoord(mapid,x,y,z,ort))
{
PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);
SetSentErrorMessage(true);
return false;
}
// stop flight if need
if(_player->isInFlight())
{
_player->GetMotionMaster()->MovementExpired();
_player->m_taxi.ClearTaxiDestinations();
}
// save only in non-flight case
else
_player->SaveRecallPosition();
_player->TeleportTo(mapid, x, y, z, ort);
return true;
return HandleGoHelper(_player, data->mapid, data->posX, data->posY, &data->posZ);
}
bool ChatHandler::HandleGameObjectTargetCommand(const char* args)

View file

@ -35,6 +35,7 @@
#include "Transports.h"
#include "ProgressBar.h"
#include "Language.h"
#include "PoolManager.h"
#include "GameEventMgr.h"
#include "Spell.h"
#include "Chat.h"
@ -8624,3 +8625,103 @@ Quest const* GetQuestTemplateStore(uint32 entry)
{
return sObjectMgr.GetQuestTemplate(entry);
}
bool FindCreatureData::operator()( CreatureDataPair const& dataPair )
{
// skip wrong entry ids
if (i_id && dataPair.second.id != i_id)
return false;
if (!i_anyData)
i_anyData = &dataPair;
// without player we can't find more stricted cases, so use fouded
if (!i_player)
return true;
// skip diff. map cases
if (dataPair.second.mapid != i_player->GetMapId())
return false;
float new_dist = i_player->GetDistance2d(dataPair.second.posX, dataPair.second.posY);
if (!i_mapData || new_dist < i_mapDist)
{
i_mapData = &dataPair;
i_mapDist = new_dist;
}
// skip not spawned (in any state),
uint16 pool_id = sPoolMgr.IsPartOfAPool<Creature>(dataPair.first);
if (pool_id && !sPoolMgr.IsSpawnedObject<Creature>(dataPair.first))
return false;
if (!i_spawnedData || new_dist < i_spawnedDist)
{
i_spawnedData = &dataPair;
i_spawnedDist = new_dist;
}
return false;
}
CreatureDataPair const* FindCreatureData::GetResult() const
{
if (i_spawnedData)
return i_spawnedData;
if (i_mapData)
return i_mapData;
return i_anyData;
}
bool FindGOData::operator()( GameObjectDataPair const& dataPair )
{
// skip wrong entry ids
if (i_id && dataPair.second.id != i_id)
return false;
if (!i_anyData)
i_anyData = &dataPair;
// without player we can't find more stricted cases, so use fouded
if (!i_player)
return true;
// skip diff. map cases
if (dataPair.second.mapid != i_player->GetMapId())
return false;
float new_dist = i_player->GetDistance2d(dataPair.second.posX, dataPair.second.posY);
if (!i_mapData || new_dist < i_mapDist)
{
i_mapData = &dataPair;
i_mapDist = new_dist;
}
// skip not spawned (in any state)
uint16 pool_id = sPoolMgr.IsPartOfAPool<GameObject>(dataPair.first);
if (pool_id && !sPoolMgr.IsSpawnedObject<GameObject>(dataPair.first))
return false;
if (!i_spawnedData || new_dist < i_spawnedDist)
{
i_spawnedData = &dataPair;
i_spawnedDist = new_dist;
}
return false;
}
GameObjectDataPair const* FindGOData::GetResult() const
{
if (i_mapData)
return i_mapData;
if (i_spawnedData)
return i_spawnedData;
return i_anyData;
}

View file

@ -155,7 +155,51 @@ struct MangosStringLocale
};
typedef UNORDERED_MAP<uint32,CreatureData> CreatureDataMap;
typedef CreatureDataMap::value_type CreatureDataPair;
class FindCreatureData
{
public:
FindCreatureData(uint32 id, Player* player) : i_id(id), i_player(player),
i_anyData(NULL), i_mapData(NULL), i_mapDist(0.0f), i_spawnedData(NULL), i_spawnedDist(0.0f) {}
bool operator() (CreatureDataPair const& dataPair);
CreatureDataPair const* GetResult() const;
private:
uint32 i_id;
Player* i_player;
CreatureDataPair const* i_anyData;
CreatureDataPair const* i_mapData;
float i_mapDist;
CreatureDataPair const* i_spawnedData;
float i_spawnedDist;
};
typedef UNORDERED_MAP<uint32,GameObjectData> GameObjectDataMap;
typedef GameObjectDataMap::value_type GameObjectDataPair;
class FindGOData
{
public:
FindGOData(uint32 id, Player* player) : i_id(id), i_player(player),
i_anyData(NULL), i_mapData(NULL), i_mapDist(0.0f), i_spawnedData(NULL), i_spawnedDist(0.0f) {}
bool operator() (GameObjectDataPair const& dataPair);
GameObjectDataPair const* GetResult() const;
private:
uint32 i_id;
Player* i_player;
GameObjectDataPair const* i_anyData;
GameObjectDataPair const* i_mapData;
float i_mapDist;
GameObjectDataPair const* i_spawnedData;
float i_spawnedDist;
};
typedef UNORDERED_MAP<uint32,CreatureLocale> CreatureLocaleMap;
typedef UNORDERED_MAP<uint32,GameObjectLocale> GameObjectLocaleMap;
typedef UNORDERED_MAP<uint32,ItemLocale> ItemLocaleMap;
@ -712,14 +756,30 @@ class ObjectMgr
return mMapObjectGuids[MAKE_PAIR32(mapid,spawnMode)][cell_id];
}
CreatureData const* GetCreatureData(uint32 guid) const
CreatureDataPair const* GetCreatureDataPair(uint32 guid) const
{
CreatureDataMap::const_iterator itr = mCreatureDataMap.find(guid);
if(itr==mCreatureDataMap.end()) return NULL;
return &itr->second;
return &*itr;
}
CreatureData const* GetCreatureData(uint32 guid) const
{
CreatureDataPair const* dataPair = GetCreatureDataPair(guid);
return dataPair ? &dataPair->second : NULL;
}
CreatureData& NewOrExistCreatureData(uint32 guid) { return mCreatureDataMap[guid]; }
void DeleteCreatureData(uint32 guid);
template<typename Worker>
void DoCreatureData(Worker& worker) const
{
for (CreatureDataMap::const_iterator itr = mCreatureDataMap.begin(); itr != mCreatureDataMap.end(); ++itr)
if (worker(*itr))
break;
}
CreatureLocale const* GetCreatureLocale(uint32 entry) const
{
CreatureLocaleMap::const_iterator itr = mCreatureLocaleMap.find(entry);
@ -769,15 +829,30 @@ class ObjectMgr
return &itr->second;
}
GameObjectData const* GetGOData(uint32 guid) const
GameObjectDataPair const* GetGODataPair(uint32 guid) const
{
GameObjectDataMap::const_iterator itr = mGameObjectDataMap.find(guid);
if(itr==mGameObjectDataMap.end()) return NULL;
return &itr->second;
return &*itr;
}
GameObjectData const* GetGOData(uint32 guid) const
{
GameObjectDataPair const* dataPair = GetGODataPair(guid);
return dataPair ? &dataPair->second : NULL;
}
GameObjectData& NewGOData(uint32 guid) { return mGameObjectDataMap[guid]; }
void DeleteGOData(uint32 guid);
template<typename Worker>
void DoGOData(Worker& worker) const
{
for (GameObjectDataMap::const_iterator itr = mGameObjectDataMap.begin(); itr != mGameObjectDataMap.end(); ++itr)
if (worker(*itr)) // arg = GameObjectDataPair
break;
}
MangosStringLocale const* GetMangosStringLocale(int32 entry) const
{
MangosStringLocaleMap::const_iterator itr = mMangosStringLocaleMap.find(entry);

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "10105"
#define REVISION_NR "10106"
#endif // __REVISION_NR_H__

View file

@ -1,6 +1,6 @@
#ifndef __REVISION_SQL_H__
#define __REVISION_SQL_H__
#define REVISION_DB_CHARACTERS "required_10051_01_characters_character_aura"
#define REVISION_DB_MANGOS "required_10089_01_mangos_game_event_pool"
#define REVISION_DB_MANGOS "required_10106_02_mangos_mangos_string"
#define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version"
#endif // __REVISION_SQL_H__