From 8d02b5c7f24985c766f676665d8b43b32a740621 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Thu, 30 Oct 2008 19:47:04 +0300 Subject: [PATCH 01/12] Fixed sql update naming for 2008_10_27_01_npc_option.sql and 2008_10_27_02_locales_npc_option.sql. --- ...npc_option.sql => 2008_10_27_01_mangos_npc_option.sql} | 0 ...on.sql => 2008_10_27_02_mangos_locales_npc_option.sql} | 0 sql/updates/Makefile.am | 8 ++++---- 3 files changed, 4 insertions(+), 4 deletions(-) rename sql/updates/{2008_10_27_01_npc_option.sql => 2008_10_27_01_mangos_npc_option.sql} (100%) rename sql/updates/{2008_10_27_02_locales_npc_option.sql => 2008_10_27_02_mangos_locales_npc_option.sql} (100%) diff --git a/sql/updates/2008_10_27_01_npc_option.sql b/sql/updates/2008_10_27_01_mangos_npc_option.sql similarity index 100% rename from sql/updates/2008_10_27_01_npc_option.sql rename to sql/updates/2008_10_27_01_mangos_npc_option.sql diff --git a/sql/updates/2008_10_27_02_locales_npc_option.sql b/sql/updates/2008_10_27_02_mangos_locales_npc_option.sql similarity index 100% rename from sql/updates/2008_10_27_02_locales_npc_option.sql rename to sql/updates/2008_10_27_02_mangos_locales_npc_option.sql diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index f030b0b19..519b15072 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -107,8 +107,8 @@ pkgdata_DATA = \ 2008_10_23_04_mangos_command.sql \ 2008_10_23_05_mangos_command.sql \ 2008_10_26_01_mangos_mangos_string.sql \ - 2008_10_27_01_npc_option.sql \ - 2008_10_27_02_locales_npc_option.sql \ + 2008_10_27_01_mangos_npc_option.sql \ + 2008_10_27_02_mangos_locales_npc_option.sql \ 2008_10_28_01_mangos_mangos_string.sql \ 2008_10_28_02_mangos_mangos_string.sql \ 2008_10_28_03_mangos_command.sql \ @@ -206,8 +206,8 @@ EXTRA_DIST = \ 2008_10_23_04_mangos_command.sql \ 2008_10_23_05_mangos_command.sql \ 2008_10_26_01_mangos_mangos_string.sql \ - 2008_10_27_01_npc_option.sql \ - 2008_10_27_02_locales_npc_option.sql \ + 2008_10_27_01_mangos_npc_option.sql \ + 2008_10_27_02_mangos_locales_npc_option.sql \ 2008_10_28_01_mangos_mangos_string.sql \ 2008_10_28_02_mangos_mangos_string.sql \ 2008_10_28_03_mangos_command.sql \ From a26b72411a827890c5ea385079603191f116a71a Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Thu, 30 Oct 2008 21:00:19 +0300 Subject: [PATCH 02/12] Use characters.guid instead low guid value from characters.data in charcter enum data prepering for client. --- src/game/CharacterHandler.cpp | 21 +++++++++++---------- src/game/Player.cpp | 26 +++++++++++++------------- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index ef2fcbf59..0507ef53c 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -128,9 +128,10 @@ void WorldSession::HandleCharEnum(QueryResult * result) Player *plr = new Player(this); do { - sLog.outDetail("Loading char guid %u from account %u.",(*result)[0].GetUInt32(),GetAccountId()); + uint32 guidlow = (*result)[0].GetUInt32(); + sLog.outDetail("Loading char guid %u from account %u.",guidlow,GetAccountId()); - if(plr->MinimalLoadFromDB( result, (*result)[0].GetUInt32() )) + if(plr->MinimalLoadFromDB( result, guidlow )) { plr->BuildEnumData( result, &data ); ++num; @@ -153,18 +154,18 @@ void WorldSession::HandleCharEnumOpcode( WorldPacket & /*recv_data*/ ) CharacterDatabase.AsyncPQuery(&chrHandler, &CharacterHandler::HandleCharEnumCallback, GetAccountId(), !sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) ? // ------- Query Without Declined Names -------- - // 0 1 2 3 4 5 6 7 8 - "SELECT characters.data, characters.name, characters.position_x, characters.position_y, characters.position_z, characters.map, characters.totaltime, characters.leveltime, characters.at_login, " - // 9 10 11 - "character_pet.entry, character_pet.modelid, character_pet.level " + // 0 1 2 3 4 5 6 7 8 + "SELECT characters.guid, characters.data, characters.name, characters.position_x, characters.position_y, characters.position_z, characters.map, characters.totaltime, characters.leveltime, " + // 9 10 11 12 + "characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level " "FROM characters LEFT JOIN character_pet ON characters.guid=character_pet.owner AND character_pet.slot='0' " "WHERE characters.account = '%u' ORDER BY characters.guid" : // --------- Query With Declined Names --------- - // 0 1 2 3 4 5 6 7 8 - "SELECT characters.data, characters.name, characters.position_x, characters.position_y, characters.position_z, characters.map, characters.totaltime, characters.leveltime, characters.at_login, " - // 9 10 11 12 - "character_pet.entry, character_pet.modelid, character_pet.level, genitive " + // 0 1 2 3 4 5 6 7 8 + "SELECT characters.guid, characters.data, characters.name, characters.position_x, characters.position_y, characters.position_z, characters.map, characters.totaltime, characters.leveltime, " + // 9 10 11 12 13 + "characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, genitive " "FROM characters LEFT JOIN character_pet ON characters.guid = character_pet.owner AND character_pet.slot='0' " "LEFT JOIN character_declinedname ON characters.guid = character_declinedname.guid " "WHERE characters.account = '%u' ORDER BY characters.guid", diff --git a/src/game/Player.cpp b/src/game/Player.cpp index ed23d9c33..922e45884 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -1296,7 +1296,7 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) char_flags |= CHARACTER_FLAG_RENAME; // always send the flag if declined names aren't used // to let the client select a default method of declining the name - if(!sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) || (result && result->Fetch()[12].GetCppString() != "")) + if(!sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) || (result && result->Fetch()[13].GetCppString() != "")) char_flags |= CHARACTER_FLAG_DECLINED; *p_data << (uint32)char_flags; // character flags @@ -1314,12 +1314,12 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) { Field* fields = result->Fetch(); - uint32 entry = fields[9].GetUInt32(); + uint32 entry = fields[10].GetUInt32(); CreatureInfo const* cInfo = sCreatureStorage.LookupEntry(entry); if(cInfo) { - petDisplayId = fields[10].GetUInt32(); - petLevel = fields[11].GetUInt32(); + petDisplayId = fields[11].GetUInt32(); + petLevel = fields[12].GetUInt32(); petFamily = cInfo->family; } } @@ -13184,15 +13184,15 @@ bool Player::MinimalLoadFromDB( QueryResult *result, uint32 guid ) bool delete_result = true; if(!result) { - // 0 1 2 3 4 5 6 7 8 - result = CharacterDatabase.PQuery("SELECT data, name, position_x, position_y, position_z, map, totaltime, leveltime, at_login FROM characters WHERE guid = '%u'",guid); + // 0 1 2 3 4 5 6 7 8 9 + result = CharacterDatabase.PQuery("SELECT guid, data, name, position_x, position_y, position_z, map, totaltime, leveltime, at_login FROM characters WHERE guid = '%u'",guid); if(!result) return false; } else delete_result = false; Field *fields = result->Fetch(); - if(!LoadValues( fields[0].GetString())) + if(!LoadValues( fields[1].GetString())) { sLog.outError("ERROR: Player #%d have broken data in `data` field. Can't be loaded.",GUID_LOPART(guid)); if(delete_result) delete result; @@ -13202,16 +13202,16 @@ bool Player::MinimalLoadFromDB( QueryResult *result, uint32 guid ) // overwrite possible wrong/corrupted guid SetUInt64Value(OBJECT_FIELD_GUID, MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER)); - m_name = fields[1].GetCppString(); + m_name = fields[2].GetCppString(); - Relocate(fields[2].GetFloat(),fields[3].GetFloat(),fields[4].GetFloat()); - SetMapId(fields[5].GetUInt32()); + Relocate(fields[3].GetFloat(),fields[4].GetFloat(),fields[5].GetFloat()); + SetMapId(fields[6].GetUInt32()); // the instance id is not needed at character enum - m_Played_time[0] = fields[6].GetUInt32(); - m_Played_time[1] = fields[7].GetUInt32(); + m_Played_time[0] = fields[7].GetUInt32(); + m_Played_time[1] = fields[8].GetUInt32(); - m_atLoginFlags = fields[8].GetUInt32(); + m_atLoginFlags = fields[9].GetUInt32(); // I don't see these used anywhere .. /*_LoadGroup(); From 0bf682fdbd6c1103f9139b1ed0bfa86a89c34d30 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Thu, 30 Oct 2008 21:04:51 +0300 Subject: [PATCH 03/12] Fixied crash at .pinfo command use from console. Also apply mangos code style to related code. --- src/game/Level2.cpp | 3 +- src/game/World.cpp | 87 ++++++++++++++++++++------------------- src/game/WorldSession.cpp | 16 ++++--- 3 files changed, 54 insertions(+), 52 deletions(-) diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index bb47d5fc7..fa2dbae50 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -1794,7 +1794,8 @@ bool ChatHandler::HandlePInfoCommand(const char* args) else { accId = objmgr.GetPlayerAccountIdByGUID(targetGUID); - Player plr(m_session); // use current session for temporary load + WorldSession session(0,NULL,SEC_PLAYER,0,0,LOCALE_enUS); + Player plr(&session); // use fake session for temporary load plr.MinimalLoadFromDB(NULL, targetGUID); money = plr.GetMoney(); total_player_time = plr.GetTotalPlayedTime(); diff --git a/src/game/World.cpp b/src/game/World.cpp index c32c29759..a8bc9a669 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -178,67 +178,67 @@ bool World::RemoveSession(uint32 id) void World::AddSession(WorldSession* s) { - addSessQueue.add(s); + addSessQueue.add(s); } void World::AddSession_ (WorldSession* s) { - ASSERT (s); + ASSERT (s); - //NOTE - Still there is race condition in WorldSession* being used in the Sockets + //NOTE - Still there is race condition in WorldSession* being used in the Sockets - ///- kick already loaded player with same account (if any) and remove session - ///- if player is in loading and want to load again, return - if (!RemoveSession (s->GetAccountId ())) + ///- kick already loaded player with same account (if any) and remove session + ///- if player is in loading and want to load again, return + if (!RemoveSession (s->GetAccountId ())) { - s->KickPlayer (); - m_kicked_sessions.insert (s); - return; + s->KickPlayer (); + m_kicked_sessions.insert (s); + return; } - WorldSession* old = m_sessions[s->GetAccountId ()]; - m_sessions[s->GetAccountId ()] = s; + WorldSession* old = m_sessions[s->GetAccountId ()]; + m_sessions[s->GetAccountId ()] = s; - // if session already exist, prepare to it deleting at next world update - // NOTE - KickPlayer() should be called on "old" in RemoveSession() - if (old) - m_kicked_sessions.insert (old); + // if session already exist, prepare to it deleting at next world update + // NOTE - KickPlayer() should be called on "old" in RemoveSession() + if (old) + m_kicked_sessions.insert (old); - uint32 Sessions = GetActiveAndQueuedSessionCount (); - uint32 pLimit = GetPlayerAmountLimit (); - uint32 QueueSize = GetQueueSize (); //number of players in the queue - bool inQueue = false; - //so we don't count the user trying to - //login as a session and queue the socket that we are using - --Sessions; + uint32 Sessions = GetActiveAndQueuedSessionCount (); + uint32 pLimit = GetPlayerAmountLimit (); + uint32 QueueSize = GetQueueSize (); //number of players in the queue + bool inQueue = false; + //so we don't count the user trying to + //login as a session and queue the socket that we are using + --Sessions; - if (pLimit > 0 && Sessions >= pLimit && s->GetSecurity () == SEC_PLAYER ) + if (pLimit > 0 && Sessions >= pLimit && s->GetSecurity () == SEC_PLAYER ) { - AddQueuedPlayer (s); - UpdateMaxSessionCounters (); - sLog.outDetail ("PlayerQueue: Account id %u is in Queue Position (%u).", s->GetAccountId (), ++QueueSize); - return; + AddQueuedPlayer (s); + UpdateMaxSessionCounters (); + sLog.outDetail ("PlayerQueue: Account id %u is in Queue Position (%u).", s->GetAccountId (), ++QueueSize); + return; } - WorldPacket packet(SMSG_AUTH_RESPONSE, 1 + 4 + 1 + 4 + 1); - packet << uint8 (AUTH_OK); - packet << uint32 (0); // unknown random value... - packet << uint8 (0); - packet << uint32 (0); - packet << uint8 (s->Expansion()); // 0 - normal, 1 - TBC, must be set in database manually for each account - s->SendPacket (&packet); + WorldPacket packet(SMSG_AUTH_RESPONSE, 1 + 4 + 1 + 4 + 1); + packet << uint8 (AUTH_OK); + packet << uint32 (0); // unknown random value... + packet << uint8 (0); + packet << uint32 (0); + packet << uint8 (s->Expansion()); // 0 - normal, 1 - TBC, must be set in database manually for each account + s->SendPacket (&packet); - UpdateMaxSessionCounters (); + UpdateMaxSessionCounters (); - // Updates the population - if (pLimit > 0) + // Updates the population + if (pLimit > 0) { - float popu = GetActiveSessionCount (); //updated number of users on the server - popu /= pLimit; - popu *= 2; - loginDatabase.PExecute ("UPDATE realmlist SET population = '%f' WHERE id = '%d'", popu, realmID); - sLog.outDetail ("Server Population (%f).", popu); + float popu = GetActiveSessionCount (); //updated number of users on the server + popu /= pLimit; + popu *= 2; + loginDatabase.PExecute ("UPDATE realmlist SET population = '%f' WHERE id = '%d'", popu, realmID); + sLog.outDetail ("Server Population (%f).", popu); } } @@ -2414,7 +2414,10 @@ void World::UpdateSessions( time_t diff ) ///- Delete kicked sessions at add new session for (std::set::iterator itr = m_kicked_sessions.begin(); itr != m_kicked_sessions.end(); ++itr) + { + RemoveQueuedPlayer (*itr); delete *itr; + } m_kicked_sessions.clear(); ///- Then send an update signal to remaining ones diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp index 261d613bf..3018f1eb1 100644 --- a/src/game/WorldSession.cpp +++ b/src/game/WorldSession.cpp @@ -58,25 +58,23 @@ _logoutTime(0), m_playerLoading(false), m_playerLogout(false), m_playerRecentlyL WorldSession::~WorldSession() { ///- unload player if not unloaded - if(_player) - LogoutPlayer(true); + if (_player) + LogoutPlayer (true); /// - If have unclosed socket, close it - if (m_Socket) + if (m_Socket) { - m_Socket->CloseSocket (); - m_Socket->RemoveReference (); - m_Socket = NULL; + m_Socket->CloseSocket (); + m_Socket->RemoveReference (); + m_Socket = NULL; } ///- empty incoming packet queue while(!_recvQueue.empty()) { - WorldPacket *packet = _recvQueue.next(); + WorldPacket *packet = _recvQueue.next (); delete packet; } - - sWorld.RemoveQueuedPlayer(this); } void WorldSession::SizeError(WorldPacket const& packet, uint32 size) const From b724ae2fe43139291ece46fc2a62d07ce81e05f9 Mon Sep 17 00:00:00 2001 From: arrai Date: Thu, 30 Oct 2008 23:12:02 +0100 Subject: [PATCH 04/12] Fixed windows ad.exe build --- contrib/extractor/libmpq/common.h | 6 ++++++ contrib/extractor/libmpq/mpq.cpp | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/contrib/extractor/libmpq/common.h b/contrib/extractor/libmpq/common.h index ad2c0f101..5794c162e 100644 --- a/contrib/extractor/libmpq/common.h +++ b/contrib/extractor/libmpq/common.h @@ -49,6 +49,12 @@ #include #endif +#ifdef O_LARGEFILE + #define MPQ_FILE_OPEN_FLAGS (O_RDONLY | O_BINARY | O_LARGEFILE) +#else + #define MPQ_FILE_OPEN_FLAGS (O_RDONLY | O_BINARY) +#endif + #ifndef min #define min(a, b) ((a < b) ? a : b) #endif diff --git a/contrib/extractor/libmpq/mpq.cpp b/contrib/extractor/libmpq/mpq.cpp index 0761d81ca..9582b72b5 100644 --- a/contrib/extractor/libmpq/mpq.cpp +++ b/contrib/extractor/libmpq/mpq.cpp @@ -59,7 +59,7 @@ int libmpq_archive_open(mpq_archive *mpq_a, unsigned char *mpq_filename) { memset(mpq_a->header, 0, sizeof(mpq_header)); /* Check if file exists and is readable */ - fd = _open((char *)mpq_filename, O_RDONLY | O_BINARY | O_LARGEFILE); + fd = _open((char *)mpq_filename, MPQ_FILE_OPEN_FLAGS); if (fd == LIBMPQ_EFILE) { return LIBMPQ_EFILE; } From c7ac8577aefac9ae43cd3a391d5685d52181ed0a Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Fri, 31 Oct 2008 19:24:38 +0300 Subject: [PATCH 05/12] Exclude some generated files in contrib subdirs. --- contrib/extractor/.gitignore | 17 +++++++++++++++++ contrib/vmap_extractor_v2/.gitignore | 16 ++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 contrib/extractor/.gitignore create mode 100644 contrib/vmap_extractor_v2/.gitignore diff --git a/contrib/extractor/.gitignore b/contrib/extractor/.gitignore new file mode 100644 index 000000000..acae16e58 --- /dev/null +++ b/contrib/extractor/.gitignore @@ -0,0 +1,17 @@ +# +# NOTE! Don't add files that are generated in specific +# subdirectories here. Add them in the ".gitignore" file +# in that subdirectory instead. +# +# NOTE! Please use 'git-ls-files -i --exclude-standard' +# command after changing this file, to see if there are +# any tracked files which get ignored after the change. +# +# MaNGOS generated files at Windows build +# + +*.ncb +*.suo +debug +release +*.user diff --git a/contrib/vmap_extractor_v2/.gitignore b/contrib/vmap_extractor_v2/.gitignore new file mode 100644 index 000000000..69d56e264 --- /dev/null +++ b/contrib/vmap_extractor_v2/.gitignore @@ -0,0 +1,16 @@ +# +# NOTE! Don't add files that are generated in specific +# subdirectories here. Add them in the ".gitignore" file +# in that subdirectory instead. +# +# NOTE! Please use 'git-ls-files -i --exclude-standard' +# command after changing this file, to see if there are +# any tracked files which get ignored after the change. +# +# MaNGOS generated files at Windows build +# + +*.ncb +*.suo +*.user +bin \ No newline at end of file From 41b876b395a7c5943e3eb82bf662b79f20c27112 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Fri, 31 Oct 2008 20:45:22 +0300 Subject: [PATCH 06/12] [2008_10_31_01_mangos_creature_template.sql] Creature related code and DB cleanups. * Rename 2 creature_template fields to more clean names and related code update also. * Use enum values instead raw values for type_flags, use halper functions instead code repeating. * Move tamed pet creating code to new function. --- sql/mangos.sql | 4 +- ...2008_10_31_01_mangos_creature_template.sql | 5 ++ sql/updates/Makefile.am | 2 + src/game/Creature.cpp | 2 +- src/game/Creature.h | 24 +++++- src/game/QueryHandler.cpp | 2 +- src/game/SharedDefines.h | 7 ++ src/game/Spell.cpp | 14 +-- src/game/SpellEffects.cpp | 86 +++++++------------ src/game/Unit.cpp | 31 +++++++ src/game/Unit.h | 2 + 11 files changed, 103 insertions(+), 76 deletions(-) create mode 100644 sql/updates/2008_10_31_01_mangos_creature_template.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index c2331be8c..96ccd89de 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -711,7 +711,7 @@ CREATE TABLE `creature_template` ( `attackpower` int(10) unsigned NOT NULL default '0', `baseattacktime` int(10) unsigned NOT NULL default '0', `rangeattacktime` int(10) unsigned NOT NULL default '0', - `flags` int(10) unsigned NOT NULL default '0', + `unit_flags` int(10) unsigned NOT NULL default '0', `dynamicflags` int(10) unsigned NOT NULL default '0', `family` tinyint(4) NOT NULL default '0', `trainer_type` tinyint(4) NOT NULL default '0', @@ -722,7 +722,7 @@ CREATE TABLE `creature_template` ( `maxrangedmg` float NOT NULL default '0', `rangedattackpower` smallint(5) unsigned NOT NULL default '0', `type` tinyint(3) unsigned NOT NULL default '0', - `flag1` int(10) unsigned NOT NULL default '0', + `type_flags` int(10) unsigned NOT NULL default '0', `lootid` mediumint(8) unsigned NOT NULL default '0', `pickpocketloot` mediumint(8) unsigned NOT NULL default '0', `skinloot` mediumint(8) unsigned NOT NULL default '0', diff --git a/sql/updates/2008_10_31_01_mangos_creature_template.sql b/sql/updates/2008_10_31_01_mangos_creature_template.sql new file mode 100644 index 000000000..fb51f3e82 --- /dev/null +++ b/sql/updates/2008_10_31_01_mangos_creature_template.sql @@ -0,0 +1,5 @@ +ALTER TABLE db_version CHANGE COLUMN required_2008_10_29_05_mangos_command required_2008_10_31_01_mangos_creature_template bit; + +ALTER TABLE `creature_template` + CHANGE COLUMN `flags` `unit_flags` int(10) unsigned NOT NULL default '0', + CHANGE COLUMN `flag1` `type_flags` int(10) unsigned NOT NULL default '0'; diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 519b15072..55dec2ca2 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -118,6 +118,7 @@ pkgdata_DATA = \ 2008_10_29_03_mangos_db_version.sql \ 2008_10_29_04_mangos_mangos_string.sql \ 2008_10_29_05_mangos_command.sql \ + 2008_10_31_01_mangos_creature_template.sql \ README ## Additional files to include when running 'make dist' @@ -217,4 +218,5 @@ EXTRA_DIST = \ 2008_10_29_03_mangos_db_version.sql \ 2008_10_29_04_mangos_mangos_string.sql \ 2008_10_29_05_mangos_command.sql \ + 2008_10_31_01_mangos_creature_template.sql \ README diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 070007792..ce5d9f797 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -258,7 +258,7 @@ bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData *data ) SetAttackTime(OFF_ATTACK, GetCreatureInfo()->baseattacktime); SetAttackTime(RANGED_ATTACK,GetCreatureInfo()->rangeattacktime); - SetUInt32Value(UNIT_FIELD_FLAGS,GetCreatureInfo()->Flags); + SetUInt32Value(UNIT_FIELD_FLAGS,GetCreatureInfo()->unit_flags); SetUInt32Value(UNIT_DYNAMIC_FLAGS,GetCreatureInfo()->dynamicflags); SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, float(GetCreatureInfo()->armor)); diff --git a/src/game/Creature.h b/src/game/Creature.h index f8b9a9652..eae23ff8d 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -165,9 +165,9 @@ struct CreatureInfo uint32 attackpower; uint32 baseattacktime; uint32 rangeattacktime; - uint32 Flags; + uint32 unit_flags; // enum UnitFlags mask values uint32 dynamicflags; - uint32 family; + uint32 family; // enum CreatureFamily values for type==CREATURE_TYPE_BEAST, or 0 in another cases uint32 trainer_type; uint32 trainer_spell; uint32 classNum; @@ -175,8 +175,8 @@ struct CreatureInfo float minrangedmg; float maxrangedmg; uint32 rangedattackpower; - uint32 type; - uint32 flag1; + uint32 type; // enum CreatureType values + uint32 type_flags; // enum CreatureTypeFlags mask values uint32 lootid; uint32 pickpocketLootId; uint32 SkinLootId; @@ -202,6 +202,22 @@ struct CreatureInfo uint32 MechanicImmuneMask; uint32 flags_extra; char const* ScriptName; + + // helpers + SkillType GetRequiredLootSkill() const + { + if(type_flags & CREATURE_TYPEFLAGS_HERBLOOT) + return SKILL_HERBALISM; + else if(type_flags & CREATURE_TYPEFLAGS_MININGLOOT) + return SKILL_MINING; + else + return SKILL_SKINNING; // normal case + } + + bool isTameable() const + { + return type == CREATURE_TYPE_BEAST && family != 0 && (type_flags & CREATURE_TYPEFLAGS_TAMEBLE); + } }; struct CreatureLocale diff --git a/src/game/QueryHandler.cpp b/src/game/QueryHandler.cpp index 9dc17bcd7..713338c51 100644 --- a/src/game/QueryHandler.cpp +++ b/src/game/QueryHandler.cpp @@ -179,7 +179,7 @@ void WorldSession::HandleCreatureQueryOpcode( WorldPacket & recv_data ) data << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4, always empty data << SubName; data << ci->IconName; // "Directions" for guard, string for Icons 2.3.0 - data << (uint32)ci->flag1; // flags wdbFeild7=wad flags1 + data << (uint32)ci->type_flags; // flags wdbFeild7=wad flags1 data << (uint32)ci->type; data << (uint32)ci->family; // family wdbFeild9 data << (uint32)ci->rank; // rank wdbFeild10 diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index 34e3eb1c1..817ae8129 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -1531,6 +1531,13 @@ enum CreatureFamily CREATURE_FAMILY_SEA_LION = 36 }; +enum CreatureTypeFlags +{ + CREATURE_TYPEFLAGS_TAMEBLE = 0x0001, + CREATURE_TYPEFLAGS_HERBLOOT = 0x0100, + CREATURE_TYPEFLAGS_MININGLOOT = 0x0200, +}; + enum CreatureEliteType { CREATURE_ELITE_NORMAL = 0, diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 544432d15..982d5b02a 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -3517,12 +3517,8 @@ uint8 Spell::CanCast(bool strict) if (m_targets.getUnitTarget()->getLevel() > m_caster->getLevel()) return SPELL_FAILED_HIGHLEVEL; - CreatureInfo const *cinfo = ((Creature*)m_targets.getUnitTarget())->GetCreatureInfo(); - if( cinfo->type != CREATURE_TYPE_BEAST ) - return SPELL_FAILED_BAD_TARGETS; - // use SMSG_PET_TAME_FAILURE? - if( !(cinfo->flag1 & 1) || !(cinfo->family) ) + if (!((Creature*)m_targets.getUnitTarget())->GetCreatureInfo()->isTameable ()) return SPELL_FAILED_BAD_TARGETS; if(m_caster->GetPetGUID()) @@ -3634,13 +3630,7 @@ uint8 Spell::CanCast(bool strict) return SPELL_FAILED_TARGET_NOT_LOOTED; } - uint32 skill; - if(creature->GetCreatureInfo()->flag1 & 256) - skill = SKILL_HERBALISM; // special case - else if(creature->GetCreatureInfo()->flag1 & 512) - skill = SKILL_MINING; // special case - else - skill = SKILL_SKINNING; // normal case + uint32 skill = creature->GetCreatureInfo()->GetRequiredLootSkill(); int32 skillValue = ((Player*)m_caster)->GetSkillValue(skill); int32 TargetLevel = m_targets.getUnitTarget()->getLevel(); diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index e71114367..5077d87e7 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -3884,56 +3884,36 @@ void Spell::EffectTameCreature(uint32 /*i*/) if(creatureTarget->isPet()) return; - if(m_caster->getClass() == CLASS_HUNTER) + if(m_caster->getClass() != CLASS_HUNTER) + return; + + // cast finish successfully + //SendChannelUpdate(0); + finish(); + + Pet* pet = m_caster->CreateTamedPetFrom(creatureTarget,m_spellInfo->Id); + + // kill original creature + creatureTarget->setDeathState(JUST_DIED); + creatureTarget->RemoveCorpse(); + creatureTarget->SetHealth(0); // just for nice GM-mode view + + // prepare visual effect for levelup + pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel()-1); + + // add to world + MapManager::Instance().GetMap(pet->GetMapId(), pet)->Add((Creature*)pet); + + // visual effect for levelup + pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel()); + + // caster have pet now + m_caster->SetPet(pet); + + if(m_caster->GetTypeId() == TYPEID_PLAYER) { - // cast finish successfully - //SendChannelUpdate(0); - finish(); - - Pet* pet = new Pet(HUNTER_PET); - - if(!pet->CreateBaseAtCreature(creatureTarget)) - { - delete pet; - return; - } - - creatureTarget->setDeathState(JUST_DIED); - creatureTarget->RemoveCorpse(); - creatureTarget->SetHealth(0); // just for nice GM-mode view - - pet->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, m_caster->GetGUID()); - pet->SetUInt64Value(UNIT_FIELD_CREATEDBY, m_caster->GetGUID()); - pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,m_caster->getFaction()); - pet->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); - - if(!pet->InitStatsForLevel(creatureTarget->getLevel())) - { - sLog.outError("ERROR: InitStatsForLevel() in EffectTameCreature failed! Pet deleted."); - delete pet; - return; - } - - // prepare visual effect for levelup - pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel()-1); - - pet->GetCharmInfo()->SetPetNumber(objmgr.GeneratePetNumber(), true); - // this enables pet details window (Shift+P) - pet->AIM_Initialize(); - pet->InitPetCreateSpells(); - pet->SetHealth(pet->GetMaxHealth()); - - MapManager::Instance().GetMap(pet->GetMapId(), pet)->Add((Creature*)pet); - - // visual effect for levelup - pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel()); - - if(m_caster->GetTypeId() == TYPEID_PLAYER) - { - m_caster->SetPet(pet); - pet->SavePetToDB(PET_SAVE_AS_CURRENT); - ((Player*)m_caster)->PetSpellInitialize(); - } + pet->SavePetToDB(PET_SAVE_AS_CURRENT); + ((Player*)m_caster)->PetSpellInitialize(); } } @@ -5537,13 +5517,7 @@ void Spell::EffectSkinning(uint32 /*i*/) Creature* creature = (Creature*) unitTarget; int32 targetLevel = creature->getLevel(); - uint32 skill; - if(creature->GetCreatureInfo()->flag1 & 256) - skill = SKILL_HERBALISM; // special case - else if(creature->GetCreatureInfo()->flag1 & 512) - skill = SKILL_MINING; // special case - else - skill = SKILL_SKINNING; // normal case + uint32 skill = creature->GetCreatureInfo()->GetRequiredLootSkill(); ((Player*)m_caster)->SendLoot(creature->GetGUID(),LOOT_SKINNING); creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index aaf107d4e..4a247daa0 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -10817,3 +10817,34 @@ void Unit::RemovePetAura(PetAura const* petSpell) if(Pet* pet = GetPet()) pet->RemoveAurasDueToSpell(petSpell->GetAura(pet->GetEntry())); } + +Pet* Unit::CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id) +{ + Pet* pet = new Pet(HUNTER_PET); + + if(!pet->CreateBaseAtCreature(creatureTarget)) + { + delete pet; + return NULL; + } + + pet->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, this->GetGUID()); + pet->SetUInt64Value(UNIT_FIELD_CREATEDBY, this->GetGUID()); + pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,this->getFaction()); + pet->SetUInt32Value(UNIT_CREATED_BY_SPELL, spell_id); + + if(!pet->InitStatsForLevel(creatureTarget->getLevel())) + { + sLog.outError("ERROR: Pet::InitStatsForLevel() failed for creature (Entry: %u)!",creatureTarget->GetEntry()); + delete pet; + return NULL; + } + + pet->GetCharmInfo()->SetPetNumber(objmgr.GeneratePetNumber(), true); + // this enables pet details window (Shift+P) + pet->AIM_Initialize(); + pet->InitPetCreateSpells(); + pet->SetHealth(pet->GetMaxHealth()); + + return pet; +} diff --git a/src/game/Unit.h b/src/game/Unit.h index 99d6b61f2..ee5b94b77 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -985,6 +985,8 @@ class MANGOS_DLL_SPEC Unit : public WorldObject CharmInfo* GetCharmInfo() { return m_charmInfo; } CharmInfo* InitCharmInfo(Unit* charm); + Pet* CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id = 0); + bool AddAura(Aura *aur); void RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); From d99d43a1d90115dfdcd504e67334bbfff83abcce Mon Sep 17 00:00:00 2001 From: freghar Date: Tue, 28 Oct 2008 12:21:36 +0100 Subject: [PATCH 07/12] Disable world.log by default As it may cause bigger latency due to large amount of I/O. Signed-off-by: freghar (cherry picked from commit 87c210e5ccd4ee853b8f9e37100988d9e4bc4525) Signed-off-by: VladimirMangos --- src/mangosd/mangosd.conf.dist.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mangosd/mangosd.conf.dist.in b/src/mangosd/mangosd.conf.dist.in index d43f220e1..4c69f2de5 100644 --- a/src/mangosd/mangosd.conf.dist.in +++ b/src/mangosd/mangosd.conf.dist.in @@ -284,7 +284,7 @@ LogFileLevel = 0 LogFilter_TransportMoves = 1 LogFilter_CreatureMoves = 1 LogFilter_VisibilityChanges = 1 -WorldLogFile = "world.log" +WorldLogFile = "" DBErrorLogFile = "DBErrors.log" CharLogFile = "Char.log" CharLogTimestamp = 0 From 36508ba7adffe37d67dfe9d49ae042e2c1366e26 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sat, 1 Nov 2008 02:38:45 +0300 Subject: [PATCH 08/12] More contrib/extractor geenrated files in .gitignore --- contrib/extractor/.gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contrib/extractor/.gitignore b/contrib/extractor/.gitignore index acae16e58..4b5584e53 100644 --- a/contrib/extractor/.gitignore +++ b/contrib/extractor/.gitignore @@ -7,9 +7,10 @@ # command after changing this file, to see if there are # any tracked files which get ignored after the change. # -# MaNGOS generated files at Windows build +# Extractor generated files at Windows build # +*.bsc *.ncb *.suo debug From eb97c9e717622c8240a9b20a05fd63ed15dfb690 Mon Sep 17 00:00:00 2001 From: dythzer Date: Mon, 27 Oct 2008 00:25:00 +0100 Subject: [PATCH 09/12] [2008_10_31_02_mangos_mangos_string.sql 2008_10_31_03_mangos_command.sql] Added new command: .npc tame - Creates a pet of the selected creature. Works for all classes, not only hunter. Pet also saved in DB. Signed-off-by: dythzer Command renamed to .npc tame and code updated to use common function with spell effect. Targeted creature not killed and tamed pet show up before player. Signed-off-by: VladimirMangos --- sql/mangos.sql | 3 + .../2008_10_31_02_mangos_mangos_string.sql | 7 ++ sql/updates/2008_10_31_03_mangos_command.sql | 6 ++ sql/updates/Makefile.am | 4 ++ src/game/Chat.cpp | 1 + src/game/Chat.h | 1 + src/game/Language.h | 4 +- src/game/Level2.cpp | 64 +++++++++++++++++++ 8 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 sql/updates/2008_10_31_02_mangos_mangos_string.sql create mode 100644 sql/updates/2008_10_31_03_mangos_command.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index 96ccd89de..e9996524a 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -340,6 +340,7 @@ INSERT INTO `command` VALUES ('npc spawndist',2,'Syntax: .npc spawndist #dist\r\n\r\nAdjust spawndistance of selected creature to dist.'), ('npc spawntime',2,'Syntax: .npc spawntime #time \r\n\r\nAdjust spawntime of selected creature to time.'), ('npc subname',2,'Syntax: .npc subname $Name\r\n\r\nChange the subname of the selected creature or player to $Name.\r\n\r\nCommand disabled.'), +('npc tame',2,'Syntax: .npc tame\r\n\r\nTame selected creature (tameable non pet creature). You don''t must have pet.'), ('npc textemote',3,'Syntax: .npc textemote #emoteid\r\n\r\nMake the selected creature to do textemote with an emote of id #emoteid.'), ('npc whisper',1,'Syntax: .npc whisper #playerguid #text\r\nMake the selected npc whisper #text to #playerguid.'), ('npc unfollow',2,'Syntax: .npc unfollow\r\n\r\nSelected creature (non pet) stop follow you.'), @@ -2415,6 +2416,8 @@ INSERT INTO `mangos_string` VALUES (340,'%s is now following you.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (341,'%s is not following you.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (342,'%s is now not following you.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(343,'Creature (Entry: %u) cannot be tamed.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(344,'You already have pet.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (400,'|cffff0000[System Message]:|rScripts reloaded',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (401,'You change security level of account %s to %i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (402,'%s changed your security level to %i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), diff --git a/sql/updates/2008_10_31_02_mangos_mangos_string.sql b/sql/updates/2008_10_31_02_mangos_mangos_string.sql new file mode 100644 index 000000000..a9752a113 --- /dev/null +++ b/sql/updates/2008_10_31_02_mangos_mangos_string.sql @@ -0,0 +1,7 @@ +ALTER TABLE db_version CHANGE COLUMN required_2008_10_31_01_mangos_creature_template required_2008_10_31_02_mangos_mangos_string bit; + +DELETE FROM mangos_string WHERE entry IN (343,344); + +INSERT INTO mangos_string VALUES +(343,'Creature (Entry: %u) cannot be tamed.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(344,'You already have pet.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/2008_10_31_03_mangos_command.sql b/sql/updates/2008_10_31_03_mangos_command.sql new file mode 100644 index 000000000..65bb15597 --- /dev/null +++ b/sql/updates/2008_10_31_03_mangos_command.sql @@ -0,0 +1,6 @@ +ALTER TABLE db_version CHANGE COLUMN required_2008_10_31_02_mangos_mangos_string required_2008_10_31_03_mangos_command bit; + +DELETE FROM command WHERE name IN ('npc tame'); + +INSERT INTO command VALUES +('npc tame',2,'Syntax: .npc tame\r\n\r\nTame selected creature (tameable non pet creature). You don''t must have pet.'); diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 55dec2ca2..710f81c3d 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -119,6 +119,8 @@ pkgdata_DATA = \ 2008_10_29_04_mangos_mangos_string.sql \ 2008_10_29_05_mangos_command.sql \ 2008_10_31_01_mangos_creature_template.sql \ + 2008_10_31_02_mangos_mangos_string.sql \ + 2008_10_31_03_mangos_command.sql \ README ## Additional files to include when running 'make dist' @@ -219,4 +221,6 @@ EXTRA_DIST = \ 2008_10_29_04_mangos_mangos_string.sql \ 2008_10_29_05_mangos_command.sql \ 2008_10_31_01_mangos_creature_template.sql \ + 2008_10_31_02_mangos_mangos_string.sql \ + 2008_10_31_03_mangos_command.sql \ README diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index 2bceb2d0d..0a9097f43 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -379,6 +379,7 @@ ChatCommand * ChatHandler::getCommandTable() { "unfollow", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcUnFollowCommand, "", NULL }, { "whisper", SEC_MODERATOR, false, &ChatHandler::HandleNpcWhisperCommand, "", NULL }, { "yell", SEC_MODERATOR, false, &ChatHandler::HandleNpcYellCommand, "", NULL }, + { "tame", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcTameCommand, "", NULL }, //{ TODO: fix or remove this commands { "name", SEC_GAMEMASTER, false, &ChatHandler::HandleNameCommand, "", NULL }, diff --git a/src/game/Chat.h b/src/game/Chat.h index 4ddf2d92f..1319f30be 100644 --- a/src/game/Chat.h +++ b/src/game/Chat.h @@ -186,6 +186,7 @@ class ChatHandler bool HandleNpcSetMoveTypeCommand(const char* args); bool HandleNpcSpawnDistCommand(const char* args); bool HandleNpcSpawnTimeCommand(const char* args); + bool HandleNpcTameCommand(const char* args); bool HandleNpcTextEmoteCommand(const char* args); bool HandleNpcUnFollowCommand(const char* args); bool HandleNpcWhisperCommand(const char* args); diff --git a/src/game/Language.h b/src/game/Language.h index 974b94ee0..ad4137197 100644 --- a/src/game/Language.h +++ b/src/game/Language.h @@ -324,7 +324,9 @@ enum MangosStrings LANG_CREATURE_FOLLOW_YOU_NOW = 340, LANG_CREATURE_NOT_FOLLOW_YOU = 341, LANG_CREATURE_NOT_FOLLOW_YOU_NOW = 342, - // Room for more level 2 343-399 not used + LANG_CREATURE_NON_TAMEABLE = 343, + LANG_YOU_ALREADY_HAVE_PET = 344, + // Room for more level 2 345-399 not used // level 3 chat LANG_SCRIPTS_RELOADED = 400, diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index fa2dbae50..bd0f350cf 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -4156,3 +4156,67 @@ bool ChatHandler::HandleNpcUnFollowCommand(const char* /*args*/) PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU_NOW, creature->GetName()); return true; } + +bool ChatHandler::HandleNpcTameCommand(const char* args) +{ + Creature *creatureTarget = getSelectedCreature (); + if (!creatureTarget || creatureTarget->isPet ()) + { + PSendSysMessage (LANG_SELECT_CREATURE); + SetSentErrorMessage (true); + return false; + } + + Player *player = m_session->GetPlayer (); + + if(player->GetPetGUID ()) + { + SendSysMessage (LANG_YOU_ALREADY_HAVE_PET); + SetSentErrorMessage (true); + return false; + } + + CreatureInfo const* cInfo = creatureTarget->GetCreatureInfo(); + + if (!cInfo->isTameable ()) + { + PSendSysMessage (LANG_CREATURE_NON_TAMEABLE,cInfo->Entry); + SetSentErrorMessage (true); + return false; + } + + // Everything looks OK, create new pet + Pet* pet = player->CreateTamedPetFrom (creatureTarget); + if (!pet) + { + PSendSysMessage (LANG_CREATURE_NON_TAMEABLE,cInfo->Entry); + SetSentErrorMessage (true); + return false; + } + + // place pet before player + float x,y,z; + player->GetClosePoint (x,y,z,creatureTarget->GetObjectSize (),CONTACT_DISTANCE); + pet->Relocate (x,y,z,M_PI-player->GetOrientation ()); + + // set pet to defensive mode by default (some classes can't control contolled pets in fact). + pet->GetCharmInfo()->SetReactState(REACT_DEFENSIVE); + + + // prepare visual effect for levelup + pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel()-1); + + // add to world + MapManager::Instance().GetMap(pet->GetMapId(), pet)->Add((Creature*)pet); + + // visual effect for levelup + pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel()); + + // caster have pet now + player->SetPet(pet); + + pet->SavePetToDB(PET_SAVE_AS_CURRENT); + player->PetSpellInitialize(); + + return true; +} From 4f228f71cdf6dc37ee27fb2cd9c4dc0cd97a240b Mon Sep 17 00:00:00 2001 From: dythzer Date: Fri, 31 Oct 2008 19:44:47 +0100 Subject: [PATCH 10/12] Changed to correct entry for mangos strings: LANG_ACCOUNT_SETADDON (1100) and LANG_MOTD_NEW (1101) Signed-off-by: dythzer Signed-off-by: VladimirMangos --- src/game/Language.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/Language.h b/src/game/Language.h index ad4137197..ab11ee733 100644 --- a/src/game/Language.h +++ b/src/game/Language.h @@ -676,8 +676,8 @@ enum MangosStrings // Room for more level 4 1012-1099 not used // Level 3 (continue) - LANG_MOTD_NEW = 1100, - LANG_ACCOUNT_SETADDON = 1101, + LANG_ACCOUNT_SETADDON = 1100, + LANG_MOTD_NEW = 1101, LANG_SENDMESSAGE = 1102, LANG_EVENT_ENTRY_LIST_CONSOLE = 1103, LANG_CREATURE_ENTRY_LIST_CONSOLE = 1104, From 7b9e86e3f3af01bbe89ec7ecfe9e3aca487b37e0 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Fri, 31 Oct 2008 19:48:08 +0100 Subject: [PATCH 11/12] Fixed bug in respawn command from recent commit Command must now ignore implicit self-targeted player as target. And allow respawn all near creatures/go in this case. Signed-off-by: VladimirMangos --- src/game/Level3.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 87f092a60..c184ec5ea 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -5315,9 +5315,11 @@ bool ChatHandler::HandleBanListIPCommand(const char* args) bool ChatHandler::HandleRespawnCommand(const char* /*args*/) { - Unit* target = getSelectedUnit(); + Player* pl = m_session->GetPlayer(); - if(target) + // accept only explictly selected target (not implicitly self targeting case) + Unit* target = getSelectedUnit(); + if(pl->GetSelection() && target) { if(target->GetTypeId()!=TYPEID_UNIT) { @@ -5331,8 +5333,6 @@ bool ChatHandler::HandleRespawnCommand(const char* /*args*/) return true; } - Player* pl = m_session->GetPlayer(); - CellPair p(MaNGOS::ComputeCellPair(pl->GetPositionX(), pl->GetPositionY())); Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; From acf6f5d5cee46291161414953d742a3d05419549 Mon Sep 17 00:00:00 2001 From: dythzer Date: Mon, 27 Oct 2008 13:44:36 +0100 Subject: [PATCH 12/12] Added new command: .modify gender male/female - Turns selected player into a male or female No relog needed Signed-off-by: dythzer Add help and mangos strings. Allow accept partly types male/female arg values. Signed-off-by: VladimirMangos --- sql/mangos.sql | 6 +- .../2008_11_01_01_mangos_mangos_string.sql | 8 +++ sql/updates/2008_11_01_02_mangos_command.sql | 6 ++ sql/updates/Makefile.am | 4 ++ src/game/Chat.cpp | 1 + src/game/Chat.h | 1 + src/game/Language.h | 5 +- src/game/Level3.cpp | 60 +++++++++++++++++++ 8 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 sql/updates/2008_11_01_01_mangos_mangos_string.sql create mode 100644 sql/updates/2008_11_01_02_mangos_command.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index e9996524a..00d75513d 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -303,6 +303,7 @@ INSERT INTO `command` VALUES ('modify drunk',1,'Syntax: .modify drunk #value\r\n Set drunk level to #value (0..100). Value 0 remove drunk state, 100 is max drunked state.'), ('modify energy',1,'Syntax: .modify energy #energy\r\n\r\nModify the energy of the selected player. If no player is selected, modify your energy.'), ('modify faction',1,'Syntax: .modify faction #factionid #flagid #npcflagid #dynamicflagid\r\n\r\nModify the faction and flags of the selected creature. Without arguments, display the faction and flags of the selected creature.'), +('modify gender',2,'Syntax: .modify gender male/female\r\n\r\nChange gender of selected player.'), ('modify honor',1,'Syntax: .modify honor $amount\r\n\r\nAdd $amount honor points to the selected player.'), ('modify hp',1,'Syntax: .modify hp #newhp\r\n\r\nModify the hp of the selected player. If no player is selected, modify your hp.'), ('modify mana',1,'Syntax: .modify mana #newmana\r\n\r\nModify the mana of the selected player. If no player is selected, modify your mana.'), @@ -2707,7 +2708,10 @@ INSERT INTO `mangos_string` VALUES (1115,'Invalid character name!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1116,'Invalid character guid!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1117,'Character guid %u in use!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), -(1118,'%d - guild: %s (guid: %u) %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); +(1118,'%d - guild: %s (guid: %u) %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1119,'You must use male or female as gender.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1120,'You change gender of %s to %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1121,'Your gender changed to %s by %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); /*!40000 ALTER TABLE `mangos_string` ENABLE KEYS */; UNLOCK TABLES; diff --git a/sql/updates/2008_11_01_01_mangos_mangos_string.sql b/sql/updates/2008_11_01_01_mangos_mangos_string.sql new file mode 100644 index 000000000..f308a2523 --- /dev/null +++ b/sql/updates/2008_11_01_01_mangos_mangos_string.sql @@ -0,0 +1,8 @@ +ALTER TABLE db_version CHANGE COLUMN required_2008_10_31_03_mangos_command required_2008_11_01_01_mangos_mangos_string bit; + +DELETE FROM mangos_string WHERE entry IN (1119,1120,1121); + +INSERT INTO mangos_string VALUES +(1119,'You must use male or female as gender.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1120,'You change gender of %s to %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1121,'Your gender changed to %s by %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/2008_11_01_02_mangos_command.sql b/sql/updates/2008_11_01_02_mangos_command.sql new file mode 100644 index 000000000..750c98acd --- /dev/null +++ b/sql/updates/2008_11_01_02_mangos_command.sql @@ -0,0 +1,6 @@ +ALTER TABLE db_version CHANGE COLUMN required_2008_11_01_01_mangos_mangos_string required_2008_11_01_02_mangos_command bit; + +DELETE FROM command WHERE name IN ('modify gender'); + +INSERT INTO command VALUES +('modify gender',2,'Syntax: .modify gender male/female\r\n\r\nChange gender of selected player.'); diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 710f81c3d..00e34f9ae 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -121,6 +121,8 @@ pkgdata_DATA = \ 2008_10_31_01_mangos_creature_template.sql \ 2008_10_31_02_mangos_mangos_string.sql \ 2008_10_31_03_mangos_command.sql \ + 2008_11_01_01_mangos_mangos_string.sql \ + 2008_11_01_02_mangos_command.sql \ README ## Additional files to include when running 'make dist' @@ -223,4 +225,6 @@ EXTRA_DIST = \ 2008_10_31_01_mangos_creature_template.sql \ 2008_10_31_02_mangos_mangos_string.sql \ 2008_10_31_03_mangos_command.sql \ + 2008_11_01_01_mangos_mangos_string.sql \ + 2008_11_01_02_mangos_command.sql \ README diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index 0a9097f43..1f2bcdd35 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -100,6 +100,7 @@ ChatCommand * ChatHandler::getCommandTable() { "drunk", SEC_MODERATOR, false, &ChatHandler::HandleDrunkCommand, "", NULL }, { "standstate", SEC_GAMEMASTER, false, &ChatHandler::HandleStandStateCommand, "", NULL }, { "morph", SEC_GAMEMASTER, false, &ChatHandler::HandleMorphCommand, "", NULL }, + { "gender", SEC_ADMINISTRATOR, false, &ChatHandler::HandleModifyGenderCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; diff --git a/src/game/Chat.h b/src/game/Chat.h index 1319f30be..1967d0e28 100644 --- a/src/game/Chat.h +++ b/src/game/Chat.h @@ -170,6 +170,7 @@ class ChatHandler bool HandleModifyHonorCommand (const char* args); bool HandleModifyRepCommand(const char* args); bool HandleModifyArenaCommand(const char* args); + bool HandleModifyGenderCommand(const char* args); bool HandleNpcAddCommand(const char* args); bool HandleNpcAddMoveCommand(const char* args); diff --git a/src/game/Language.h b/src/game/Language.h index ab11ee733..7dcee62b9 100644 --- a/src/game/Language.h +++ b/src/game/Language.h @@ -695,7 +695,10 @@ enum MangosStrings LANG_INVALID_CHARACTER_GUID = 1116, LANG_CHARACTER_GUID_IN_USE = 1117, LANG_ITEMLIST_GUILD = 1118, - // Room for more level 3 1119-1199 not used + LANG_MUST_MALE_OR_FEMALE = 1119, + LANG_YOU_CHANGE_GENDER = 1120, + LANG_YOUR_GENDER_CHANGED = 1121, + // Room for more level 3 1122-1199 not used // FREE IDS 1200-9999 diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index c184ec5ea..ad5e93558 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -6155,3 +6155,63 @@ bool ChatHandler::HandleSendMessageCommand(const char* args) PSendSysMessage(LANG_SENDMESSAGE,name.c_str(),msg_str); return true; } + +bool ChatHandler::HandleModifyGenderCommand(const char *args) +{ + if(!*args) + return false; + + Player *player = getSelectedPlayer(); + + if(!player) + { + PSendSysMessage(LANG_NO_PLAYER); + SetSentErrorMessage(true); + return false; + } + + char const* gender_str = (char*)args; + int gender_len = strlen(gender_str); + + uint32 displayId = player->GetNativeDisplayId(); + char const* gender_full = NULL; + uint32 new_displayId = displayId; + Gender gender; + + if(!strncmp(gender_str,"male",gender_len)) // MALE + { + if(player->getGender() == GENDER_MALE) + return true; + + gender_full = "male"; + new_displayId = player->getRace() == RACE_BLOODELF ? displayId+1 : displayId-1; + gender = GENDER_MALE; + } + else if (!strncmp(gender_str,"female",gender_len)) // FEMALE + { + if(player->getGender() == GENDER_FEMALE) + return true; + + gender_full = "female"; + new_displayId = player->getRace() == RACE_BLOODELF ? displayId-1 : displayId+1; + gender = GENDER_FEMALE; + } + else + { + SendSysMessage(LANG_MUST_MALE_OR_FEMALE); + SetSentErrorMessage(true); + return false; + } + + // Set gender + player->SetByteValue(UNIT_FIELD_BYTES_0, 2, gender); + + // Change display ID + player->SetDisplayId(new_displayId); + player->SetNativeDisplayId(new_displayId); + + PSendSysMessage(LANG_YOU_CHANGE_GENDER, player->GetName(),gender_full); + if (needReportToTarget(player)) + ChatHandler(player).PSendSysMessage(LANG_YOUR_GENDER_CHANGED, gender_full,GetName()); + return true; +}