[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, `version` varchar(120) default NULL,
`creature_ai_version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL,
`cache_id` int(10) default '0', `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'; ) 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 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 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.'), ('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',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\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 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 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 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 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 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.'), ('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), (266,'Nothing found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(267,'Object not 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), (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), (270,'Creature Removed',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(271,'Creature moved.',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), (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 \ 10056_01_mangos_spell_proc_event.sql \
10086_01_mangos_command.sql \ 10086_01_mangos_command.sql \
10089_01_mangos_game_event_pool.sql \ 10089_01_mangos_game_event_pool.sql \
10106_01_mangos_command.sql \
10106_02_mangos_mangos_string.sql \
README README
## Additional files to include when running 'make dist' ## Additional files to include when running 'make dist'
@ -162,4 +164,6 @@ EXTRA_DIST = \
10056_01_mangos_spell_proc_event.sql \ 10056_01_mangos_spell_proc_event.sql \
10086_01_mangos_command.sql \ 10086_01_mangos_command.sql \
10089_01_mangos_game_event_pool.sql \ 10089_01_mangos_game_event_pool.sql \
10106_01_mangos_command.sql \
10106_02_mangos_mangos_string.sql \
README README

View file

@ -1928,38 +1928,6 @@ char* ChatHandler::extractKeyFromLink(char* text, char const* const* linkTypes,
return NULL; 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) GameObject* ChatHandler::GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid,uint32 entry)
{ {
if(!m_session) if(!m_session)
@ -2139,7 +2107,9 @@ enum LocationLinkType
LOCATION_LINK_TELE = 1, LOCATION_LINK_TELE = 1,
LOCATION_LINK_TAXINODE = 2, LOCATION_LINK_TAXINODE = 2,
LOCATION_LINK_CREATURE = 3, LOCATION_LINK_CREATURE = 3,
LOCATION_LINK_GAMEOBJECT = 4 LOCATION_LINK_GAMEOBJECT = 4,
LOCATION_LINK_CREATURE_ENTRY = 5,
LOCATION_LINK_GAMEOBJECT_ENTRY = 6
}; };
static char const* const locationKeys[] = static char const* const locationKeys[] =
@ -2149,6 +2119,8 @@ static char const* const locationKeys[] =
"Hplayer", "Hplayer",
"Hcreature", "Hcreature",
"Hgameobject", "Hgameobject",
"Hcreature_entry",
"Hgameobject_entry",
NULL NULL
}; };
@ -2161,6 +2133,8 @@ bool ChatHandler::extractLocationFromLink(char* text, uint32& mapid, float& x, f
// |color|Htaxinode:id|h[name]|h|r // |color|Htaxinode:id|h[name]|h|r
// |color|Hcreature:creature_guid|h[name]|h|r // |color|Hcreature:creature_guid|h[name]|h|r
// |color|Hgameobject:go_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); char* idS = extractKeyFromLink(text,locationKeys,&type);
if(!idS) if(!idS)
return false; return false;
@ -2251,6 +2225,54 @@ bool ChatHandler::extractLocationFromLink(char* text, uint32& mapid, float& x, f
else else
return false; 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? // unknown type?

View file

@ -559,7 +559,7 @@ class ChatHandler
void HandleCharacterLevel(Player* player, uint64 player_guid, uint32 oldlevel, uint32 newlevel); void HandleCharacterLevel(Player* player, uint64 player_guid, uint32 oldlevel, uint32 newlevel);
void HandleLearnSkillRecipesHelper(Player* player,uint32 skill_id); void HandleLearnSkillRecipesHelper(Player* player,uint32 skill_id);
void ShowSpellListHelper(Player* target, SpellEntry const* spellInfo, LocaleConstant loc); 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; Print* m_print;
}; };
char const *fmtstring( char const *format, ... );
#endif #endif

View file

@ -253,7 +253,7 @@ enum MangosStrings
LANG_COMMAND_TARGETOBJNOTFOUND = 266, LANG_COMMAND_TARGETOBJNOTFOUND = 266,
LANG_COMMAND_GOOBJNOTFOUND = 267, LANG_COMMAND_GOOBJNOTFOUND = 267,
LANG_COMMAND_GOCREATNOTFOUND = 268, LANG_COMMAND_GOCREATNOTFOUND = 268,
LANG_COMMAND_GOCREATMULTIPLE = 269, // 269, not used
LANG_COMMAND_DELCREATMESSAGE = 270, LANG_COMMAND_DELCREATMESSAGE = 270,
LANG_COMMAND_CREATUREMOVED = 271, LANG_COMMAND_CREATUREMOVED = 271,
LANG_COMMAND_CREATUREATSAMEMAP = 272, 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)) if (!Player::LoadPositionFromDB(map,x,y,z,o,in_flight,target_guid))
return false; return false;
// stop flight if need return HandleGoHelper(_player, map, x, y, &z);
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 true; return true;
@ -633,15 +623,7 @@ bool ChatHandler::HandleRecallCommand(const char* args)
return false; return false;
} }
// stop flight if need return HandleGoHelper(target, target->m_recallMap, target->m_recallX, target->m_recallY, &target->m_recallZ, &target->m_recallO);
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;
} }
//Edit Player HP //Edit Player HP
@ -1780,18 +1762,7 @@ bool ChatHandler::HandleTeleCommand(const char * args)
return false; return false;
} }
// stop flight if need return HandleGoHelper(_player, tele->mapId, tele->position_x, tele->position_y, &tele->position_z, &tele->orientation);
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;
} }
bool ChatHandler::HandleLookupAreaCommand(const char* args) bool ChatHandler::HandleLookupAreaCommand(const char* args)
@ -2030,17 +2001,7 @@ bool ChatHandler::HandleTeleNameCommand(const char * args)
if (needReportToTarget(target)) if (needReportToTarget(target))
ChatHandler(target).PSendSysMessage(LANG_TELEPORTED_TO_BY, GetNameLink().c_str()); ChatHandler(target).PSendSysMessage(LANG_TELEPORTED_TO_BY, GetNameLink().c_str());
// stop flight if need return HandleGoHelper(target, tele->mapId, tele->position_x, tele->position_y, &tele->position_z, &tele->orientation);
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);
} }
else else
{ {
@ -2226,16 +2187,20 @@ bool ChatHandler::HandleGroupgoCommand(const char* args)
return true; 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 z;
float ort = player->GetOrientation();
if (zPtr) if (zPtr)
{ {
z = *zPtr; z = *zPtr;
if (ortPtr)
ort = *ortPtr;
// check full provided coordinates // 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); PSendSysMessage(LANG_INVALID_TARGET_COORD,x,y,mapid);
SetSentErrorMessage(true); SetSentErrorMessage(true);
@ -2266,7 +2231,7 @@ bool ChatHandler::HandleGoHelper( Player* player, uint32 mapid, float x, float y
else else
player->SaveRecallPosition(); player->SaveRecallPosition();
player->TeleportTo(mapid, x, y, z, player->GetOrientation()); player->TeleportTo(mapid, x, y, z, ort);
return true; return true;
} }

View file

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

View file

@ -35,6 +35,7 @@
#include "Transports.h" #include "Transports.h"
#include "ProgressBar.h" #include "ProgressBar.h"
#include "Language.h" #include "Language.h"
#include "PoolManager.h"
#include "GameEventMgr.h" #include "GameEventMgr.h"
#include "Spell.h" #include "Spell.h"
#include "Chat.h" #include "Chat.h"
@ -8624,3 +8625,103 @@ Quest const* GetQuestTemplateStore(uint32 entry)
{ {
return sObjectMgr.GetQuestTemplate(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 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 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,CreatureLocale> CreatureLocaleMap;
typedef UNORDERED_MAP<uint32,GameObjectLocale> GameObjectLocaleMap; typedef UNORDERED_MAP<uint32,GameObjectLocale> GameObjectLocaleMap;
typedef UNORDERED_MAP<uint32,ItemLocale> ItemLocaleMap; typedef UNORDERED_MAP<uint32,ItemLocale> ItemLocaleMap;
@ -712,14 +756,30 @@ class ObjectMgr
return mMapObjectGuids[MAKE_PAIR32(mapid,spawnMode)][cell_id]; 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); CreatureDataMap::const_iterator itr = mCreatureDataMap.find(guid);
if(itr==mCreatureDataMap.end()) return NULL; 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]; } CreatureData& NewOrExistCreatureData(uint32 guid) { return mCreatureDataMap[guid]; }
void DeleteCreatureData(uint32 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 CreatureLocale const* GetCreatureLocale(uint32 entry) const
{ {
CreatureLocaleMap::const_iterator itr = mCreatureLocaleMap.find(entry); CreatureLocaleMap::const_iterator itr = mCreatureLocaleMap.find(entry);
@ -769,15 +829,30 @@ class ObjectMgr
return &itr->second; return &itr->second;
} }
GameObjectData const* GetGOData(uint32 guid) const GameObjectDataPair const* GetGODataPair(uint32 guid) const
{ {
GameObjectDataMap::const_iterator itr = mGameObjectDataMap.find(guid); GameObjectDataMap::const_iterator itr = mGameObjectDataMap.find(guid);
if(itr==mGameObjectDataMap.end()) return NULL; 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]; } GameObjectData& NewGOData(uint32 guid) { return mGameObjectDataMap[guid]; }
void DeleteGOData(uint32 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 MangosStringLocale const* GetMangosStringLocale(int32 entry) const
{ {
MangosStringLocaleMap::const_iterator itr = mMangosStringLocaleMap.find(entry); MangosStringLocaleMap::const_iterator itr = mMangosStringLocaleMap.find(entry);

View file

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

View file

@ -1,6 +1,6 @@
#ifndef __REVISION_SQL_H__ #ifndef __REVISION_SQL_H__
#define __REVISION_SQL_H__ #define __REVISION_SQL_H__
#define REVISION_DB_CHARACTERS "required_10051_01_characters_character_aura" #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" #define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version"
#endif // __REVISION_SQL_H__ #endif // __REVISION_SQL_H__