From 26b5e033ffde3d161382fc9addbfa99738379641 Mon Sep 17 00:00:00 2001 From: maximius Date: Sat, 17 Oct 2009 15:35:07 -0700 Subject: *Massive cleanup (\n\n -> \n, *\n -> \n, cleanup for(...) to for (...), and some other cleanups by hand) *Fix a possible crash in Spell::DoAllEffectOnTarget --HG-- branch : trunk --- src/game/AccountMgr.cpp | 51 - src/game/AccountMgr.h | 10 - src/game/AchievementMgr.cpp | 264 --- src/game/AchievementMgr.h | 38 - src/game/AnimalRandomMovementGenerator.h | 2 - src/game/ArenaTeam.cpp | 90 - src/game/ArenaTeam.h | 37 - src/game/ArenaTeamHandler.cpp | 85 - src/game/AuctionHouseBot.cpp | 172 -- src/game/AuctionHouseBot.h | 34 - src/game/AuctionHouseHandler.cpp | 99 - src/game/AuctionHouseMgr.cpp | 114 - src/game/AuctionHouseMgr.h | 33 - src/game/Bag.cpp | 43 - src/game/Bag.h | 15 - src/game/BattleGround.cpp | 258 --- src/game/BattleGround.h | 88 - src/game/BattleGroundAA.cpp | 14 - src/game/BattleGroundAA.h | 6 - src/game/BattleGroundAB.cpp | 82 - src/game/BattleGroundAB.h | 37 - src/game/BattleGroundAV.cpp | 93 - src/game/BattleGroundAV.h | 111 - src/game/BattleGroundBE.cpp | 36 - src/game/BattleGroundBE.h | 9 - src/game/BattleGroundDS.cpp | 14 - src/game/BattleGroundDS.h | 6 - src/game/BattleGroundEY.cpp | 120 -- src/game/BattleGroundEY.h | 43 - src/game/BattleGroundHandler.cpp | 106 - src/game/BattleGroundMgr.cpp | 201 -- src/game/BattleGroundMgr.h | 44 - src/game/BattleGroundNA.cpp | 30 - src/game/BattleGroundNA.h | 8 - src/game/BattleGroundRL.cpp | 30 - src/game/BattleGroundRL.h | 8 - src/game/BattleGroundRV.cpp | 14 - src/game/BattleGroundRV.h | 6 - src/game/BattleGroundSA.cpp | 15 - src/game/BattleGroundSA.h | 9 - src/game/BattleGroundWS.cpp | 80 - src/game/BattleGroundWS.h | 23 - src/game/Calendar.h | 3 - src/game/CalendarHandler.cpp | 40 - src/game/Cell.h | 25 - src/game/CellImpl.h | 36 - src/game/Channel.cpp | 155 +- src/game/Channel.h | 22 - src/game/ChannelHandler.cpp | 59 - src/game/ChannelMgr.cpp | 17 - src/game/ChannelMgr.h | 9 - src/game/CharacterHandler.cpp | 246 --- src/game/Chat.cpp | 312 +-- src/game/Chat.h | 83 - src/game/ChatHandler.cpp | 120 -- src/game/CombatAI.cpp | 40 - src/game/CombatAI.h | 14 - src/game/CombatHandler.cpp | 15 - src/game/ConfusedMovementGenerator.cpp | 27 +- src/game/ConfusedMovementGenerator.h | 7 - src/game/Corpse.cpp | 48 - src/game/Corpse.h | 18 - src/game/Creature.cpp | 419 +--- src/game/Creature.h | 128 -- src/game/CreatureAI.cpp | 23 - src/game/CreatureAI.h | 51 +- src/game/CreatureAIFactory.h | 7 - src/game/CreatureAIImpl.h | 60 - src/game/CreatureAIRegistry.cpp | 3 - src/game/CreatureAIRegistry.h | 2 - src/game/CreatureAISelector.cpp | 15 - src/game/CreatureAISelector.h | 3 - src/game/CreatureEventAI.cpp | 171 -- src/game/CreatureEventAI.h | 41 - src/game/CreatureEventAIMgr.cpp | 73 +- src/game/CreatureEventAIMgr.h | 7 - src/game/CreatureGroups.cpp | 48 +- src/game/CreatureGroups.h | 21 +- src/game/DBCEnums.h | 22 - src/game/DBCStores.cpp | 109 - src/game/DBCStores.h | 16 - src/game/DBCStructure.h | 183 -- src/game/DBCfmt.h | 3 - src/game/Debugcmds.cpp | 178 -- src/game/DestinationHolder.cpp | 1 - src/game/DestinationHolder.h | 9 - src/game/DestinationHolderImp.h | 24 - src/game/DuelHandler.cpp | 15 - src/game/DynamicObject.cpp | 24 - src/game/DynamicObject.h | 8 - src/game/FleeingMovementGenerator.cpp | 51 - src/game/FleeingMovementGenerator.h | 13 - src/game/FollowerRefManager.h | 5 - src/game/FollowerReference.cpp | 4 - src/game/FollowerReference.h | 4 - src/game/Formulas.h | 13 - src/game/GameEventMgr.cpp | 235 --- src/game/GameEventMgr.h | 15 - src/game/GameObject.cpp | 241 +-- src/game/GameObject.h | 54 - src/game/GlobalEvents.cpp | 11 - src/game/GlobalEvents.h | 3 - src/game/GossipDef.cpp | 130 -- src/game/GossipDef.h | 35 - src/game/GridDefines.h | 35 - src/game/GridNotifiers.cpp | 35 - src/game/GridNotifiers.h | 192 -- src/game/GridNotifiersImpl.h | 112 - src/game/GridStates.cpp | 5 - src/game/GridStates.h | 11 - src/game/Group.cpp | 238 --- src/game/Group.h | 55 - src/game/GroupHandler.cpp | 152 -- src/game/GroupRefManager.h | 4 - src/game/GroupReference.cpp | 4 - src/game/GroupReference.h | 4 - src/game/GuardAI.cpp | 19 - src/game/GuardAI.h | 9 - src/game/Guild.cpp | 401 ---- src/game/Guild.h | 59 - src/game/GuildHandler.cpp | 278 --- src/game/HomeMovementGenerator.cpp | 14 - src/game/HomeMovementGenerator.h | 10 - src/game/HostilRefManager.cpp | 20 - src/game/HostilRefManager.h | 14 - src/game/IdleMovementGenerator.cpp | 19 +- src/game/IdleMovementGenerator.h | 14 - src/game/InstanceData.cpp | 42 +- src/game/InstanceData.h | 35 - src/game/InstanceSaveMgr.cpp | 76 - src/game/InstanceSaveMgr.h | 25 - src/game/Item.cpp | 159 +- src/game/Item.h | 39 - src/game/ItemEnchantmentMgr.cpp | 30 - src/game/ItemEnchantmentMgr.h | 3 - src/game/ItemHandler.cpp | 214 -- src/game/ItemPrototype.h | 68 - src/game/LFGHandler.cpp | 88 - src/game/Language.h | 84 - src/game/Level0.cpp | 45 - src/game/Level1.cpp | 495 ----- src/game/Level2.cpp | 796 +------ src/game/Level3.cpp | 1130 ---------- src/game/LootHandler.cpp | 85 - src/game/LootMgr.cpp | 191 -- src/game/LootMgr.h | 64 - src/game/Mail.cpp | 150 -- src/game/Mail.h | 23 - src/game/Map.cpp | 518 ----- src/game/Map.h | 123 -- src/game/MapInstanced.cpp | 35 - src/game/MapInstanced.h | 14 - src/game/MapManager.cpp | 50 - src/game/MapManager.h | 29 - src/game/MapRefManager.h | 6 - src/game/MapReference.h | 3 - src/game/MiscHandler.cpp | 302 +-- src/game/MotionMaster.cpp | 67 - src/game/MotionMaster.h | 24 - src/game/MovementGenerator.cpp | 2 - src/game/MovementGenerator.h | 15 - src/game/MovementHandler.cpp | 108 +- src/game/NPCHandler.cpp | 169 -- src/game/NPCHandler.h | 11 - src/game/Object.cpp | 338 +-- src/game/Object.h | 116 - src/game/ObjectAccessor.cpp | 74 - src/game/ObjectAccessor.h | 51 - src/game/ObjectDefines.h | 13 - src/game/ObjectGridLoader.cpp | 47 - src/game/ObjectGridLoader.h | 20 - src/game/ObjectMgr.cpp | 1463 +------------ src/game/ObjectMgr.h | 169 +- src/game/Opcodes.cpp | 3 - src/game/Opcodes.h | 10 - src/game/OutdoorPvP.cpp | 84 - src/game/OutdoorPvP.h | 53 - src/game/OutdoorPvPEP.cpp | 73 - src/game/OutdoorPvPEP.h | 37 - src/game/OutdoorPvPHP.cpp | 28 - src/game/OutdoorPvPHP.h | 22 - src/game/OutdoorPvPImpl.h | 3 - src/game/OutdoorPvPMgr.cpp | 26 - src/game/OutdoorPvPMgr.h | 15 - src/game/OutdoorPvPNA.cpp | 55 - src/game/OutdoorPvPNA.h | 41 - src/game/OutdoorPvPSI.cpp | 13 - src/game/OutdoorPvPSI.h | 14 - src/game/OutdoorPvPTF.cpp | 34 - src/game/OutdoorPvPTF.h | 19 - src/game/OutdoorPvPZM.cpp | 35 - src/game/OutdoorPvPZM.h | 27 - src/game/PassiveAI.h | 16 - src/game/Path.h | 10 - src/game/Pet.cpp | 302 +-- src/game/Pet.h | 45 - src/game/PetAI.cpp | 75 - src/game/PetAI.h | 12 - src/game/PetHandler.cpp | 122 -- src/game/PetitionsHandler.cpp | 132 -- src/game/Player.cpp | 3380 +----------------------------- src/game/Player.h | 402 +--- src/game/PlayerDump.cpp | 101 - src/game/PlayerDump.h | 19 - src/game/PointMovementGenerator.cpp | 14 - src/game/PointMovementGenerator.h | 10 - src/game/PoolHandler.cpp | 84 - src/game/PoolHandler.h | 11 - src/game/QueryHandler.cpp | 54 - src/game/QuestDef.cpp | 32 - src/game/QuestDef.h | 29 - src/game/QuestHandler.cpp | 100 - src/game/RandomMovementGenerator.cpp | 31 - src/game/RandomMovementGenerator.h | 5 - src/game/ReactorAI.cpp | 7 - src/game/ReactorAI.h | 7 - src/game/ReputationMgr.cpp | 102 +- src/game/ReputationMgr.h | 22 - src/game/ScriptCalls.cpp | 14 - src/game/ScriptCalls.h | 11 - src/game/SharedDefines.h | 131 -- src/game/SkillDiscovery.cpp | 44 - src/game/SkillDiscovery.h | 4 - src/game/SkillExtraItems.cpp | 28 - src/game/SkillExtraItems.h | 3 - src/game/SkillHandler.cpp | 15 - src/game/SocialMgr.cpp | 48 - src/game/SocialMgr.h | 15 - src/game/Spell.cpp | 875 +------- src/game/Spell.h | 100 - src/game/SpellAuraDefines.h | 5 - src/game/SpellAuras.cpp | 753 +------ src/game/SpellAuras.h | 48 +- src/game/SpellEffects.cpp | 862 +------- src/game/SpellHandler.cpp | 111 +- src/game/SpellMgr.cpp | 500 +---- src/game/SpellMgr.h | 187 -- src/game/StatSystem.cpp | 175 -- src/game/TargetedMovementGenerator.cpp | 33 - src/game/TargetedMovementGenerator.h | 11 - src/game/TaxiHandler.cpp | 56 - src/game/TemporarySummon.cpp | 52 - src/game/TemporarySummon.h | 10 - src/game/ThreatManager.cpp | 84 - src/game/ThreatManager.h | 64 - src/game/TicketHandler.cpp | 27 +- src/game/Totem.cpp | 23 +- src/game/Totem.h | 8 - src/game/TotemAI.cpp | 17 - src/game/TotemAI.h | 8 - src/game/TradeHandler.cpp | 83 - src/game/Transports.cpp | 96 - src/game/Transports.h | 17 - src/game/Traveller.h | 19 - src/game/Unit.cpp | 1801 +--------------- src/game/Unit.h | 274 +-- src/game/UnitAI.cpp | 40 - src/game/UnitAI.h | 19 - src/game/UnitEvents.h | 36 - src/game/UpdateData.cpp | 26 - src/game/UpdateData.h | 9 - src/game/UpdateFields.h | 10 - src/game/UpdateMask.h | 23 - src/game/Vehicle.cpp | 47 +- src/game/Vehicle.h | 13 - src/game/VoiceChatHandler.cpp | 4 - src/game/WaypointManager.cpp | 32 - src/game/WaypointManager.h | 10 - src/game/WaypointMovementGenerator.cpp | 93 - src/game/WaypointMovementGenerator.h | 18 - src/game/Weather.cpp | 37 - src/game/Weather.h | 7 - src/game/Wintergrasp.cpp | 153 -- src/game/Wintergrasp.h | 50 - src/game/World.cpp | 423 +--- src/game/World.h | 76 +- src/game/WorldLog.cpp | 18 - src/game/WorldLog.h | 10 - src/game/WorldSession.cpp | 135 +- src/game/WorldSession.h | 119 -- src/game/WorldSocket.cpp | 204 +- src/game/WorldSocket.h | 48 - src/game/WorldSocketMgr.cpp | 80 - src/game/WorldSocketMgr.h | 17 - src/game/ZoneScript.h | 12 +- src/game/pchdef.h | 1 - 286 files changed, 99 insertions(+), 29664 deletions(-) (limited to 'src/game') diff --git a/src/game/AccountMgr.cpp b/src/game/AccountMgr.cpp index b3c9a76e720..d4c4c4aecce 100644 --- a/src/game/AccountMgr.cpp +++ b/src/game/AccountMgr.cpp @@ -17,53 +17,40 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "Database/DatabaseEnv.h" #include "Policies/SingletonImp.h" - #include "AccountMgr.h" #include "ObjectAccessor.h" #include "Player.h" #include "Util.h" #include "Auth/Sha1.h" - extern DatabaseType loginDatabase; - INSTANTIATE_SINGLETON_1(AccountMgr); - AccountMgr::AccountMgr() {} - AccountMgr::~AccountMgr() {} - AccountOpResult AccountMgr::CreateAccount(std::string username, std::string password) { if(utf8length(username) > MAX_ACCOUNT_STR) return AOR_NAME_TOO_LONG; // username's too long - normalizeString(username); normalizeString(password); - if(GetId(username)) { return AOR_NAME_ALREDY_EXIST; // username does already exist } - if(!loginDatabase.PExecute("INSERT INTO account(username,sha_pass_hash,joindate) VALUES('%s','%s',NOW())", username.c_str(), CalculateShaPassHash(username, password).c_str())) return AOR_DB_INTERNAL_ERROR; // unexpected error loginDatabase.Execute("INSERT INTO realmcharacters (realmid, acctid, numchars) SELECT realmlist.id, account.id, 0 FROM realmlist,account LEFT JOIN realmcharacters ON acctid=account.id WHERE acctid IS NULL"); - return AOR_OK; // everything's fine } - AccountOpResult AccountMgr::DeleteAccount(uint32 accid) { QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d'", accid); if(!result) return AOR_NAME_NOT_EXIST; // account doesn't exist delete result; - result = CharacterDatabase.PQuery("SELECT guid FROM characters WHERE account='%d'",accid); if (result) { @@ -72,7 +59,6 @@ AccountOpResult AccountMgr::DeleteAccount(uint32 accid) Field *fields = result->Fetch(); uint32 guidlo = fields[0].GetUInt32(); uint64 guid = MAKE_NEW_GUID(guidlo, 0, HIGHGUID_PLAYER); - // kick if player currently if(Player* p = ObjectAccessor::GetObjectInWorld(guid, (Player*)NULL)) { @@ -80,76 +66,54 @@ AccountOpResult AccountMgr::DeleteAccount(uint32 accid) s->KickPlayer(); // mark session to remove at next session list update s->LogoutPlayer(false); // logout player without waiting next session list update } - Player::DeleteFromDB(guid, accid, false); // no need to update realm characters } while (result->NextRow()); - delete result; } - // table realm specific but common for all characters of account for realm CharacterDatabase.PExecute("DELETE FROM character_tutorial WHERE account = '%u'",accid); - loginDatabase.BeginTransaction(); - bool res = loginDatabase.PExecute("DELETE FROM account WHERE id='%d'", accid) && loginDatabase.PExecute("DELETE FROM realmcharacters WHERE acctid='%d'", accid); - loginDatabase.CommitTransaction(); - if(!res) return AOR_DB_INTERNAL_ERROR; // unexpected error; - return AOR_OK; } - AccountOpResult AccountMgr::ChangeUsername(uint32 accid, std::string new_uname, std::string new_passwd) { QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d'", accid); if(!result) return AOR_NAME_NOT_EXIST; // account doesn't exist delete result; - if(utf8length(new_uname) > MAX_ACCOUNT_STR) return AOR_NAME_TOO_LONG; - if(utf8length(new_passwd) > MAX_ACCOUNT_STR) return AOR_PASS_TOO_LONG; - normalizeString(new_uname); normalizeString(new_passwd); - std::string safe_new_uname = new_uname; loginDatabase.escape_string(safe_new_uname); - if(!loginDatabase.PExecute("UPDATE account SET v='0',s='0',username='%s',sha_pass_hash='%s' WHERE id='%d'", safe_new_uname.c_str(), CalculateShaPassHash(new_uname, new_passwd).c_str(), accid)) return AOR_DB_INTERNAL_ERROR; // unexpected error - return AOR_OK; } - AccountOpResult AccountMgr::ChangePassword(uint32 accid, std::string new_passwd) { std::string username; - if(!GetName(accid, username)) return AOR_NAME_NOT_EXIST; // account doesn't exist - if (utf8length(new_passwd) > MAX_ACCOUNT_STR) return AOR_PASS_TOO_LONG; - normalizeString(new_passwd); - // also reset s and v to force update at next realmd login if(!loginDatabase.PExecute("UPDATE account SET v='0', s='0', sha_pass_hash='%s' WHERE id='%d'", CalculateShaPassHash(username, new_passwd).c_str(), accid)) return AOR_DB_INTERNAL_ERROR; // unexpected error - return AOR_OK; } - uint32 AccountMgr::GetId(std::string username) { loginDatabase.escape_string(username); @@ -163,7 +127,6 @@ uint32 AccountMgr::GetId(std::string username) return id; } } - uint32 AccountMgr::GetSecurity(uint32 acc_id) { QueryResult *result = loginDatabase.PQuery("SELECT gmlevel FROM account WHERE id = '%u'", acc_id); @@ -173,10 +136,8 @@ uint32 AccountMgr::GetSecurity(uint32 acc_id) delete result; return sec; } - return 0; } - bool AccountMgr::GetName(uint32 acc_id, std::string &name) { QueryResult *result = loginDatabase.PQuery("SELECT username FROM account WHERE id = '%u'", acc_id); @@ -186,41 +147,31 @@ bool AccountMgr::GetName(uint32 acc_id, std::string &name) delete result; return true; } - return false; } - bool AccountMgr::CheckPassword(uint32 accid, std::string passwd) { std::string username; if(!GetName(accid, username)) return false; - normalizeString(passwd); - QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d' AND sha_pass_hash='%s'", accid, CalculateShaPassHash(username, passwd).c_str()); if (result) { delete result; return true; } - return false; } - bool AccountMgr::normalizeString(std::string& utf8str) { wchar_t wstr_buf[MAX_ACCOUNT_STR+1]; - size_t wstr_len = MAX_ACCOUNT_STR; if(!Utf8toWStr(utf8str,wstr_buf,wstr_len)) return false; - std::transform( &wstr_buf[0], wstr_buf+wstr_len, &wstr_buf[0], wcharToUpperOnlyLatin ); - return WStrToUtf8(wstr_buf,wstr_len,utf8str); } - std::string AccountMgr::CalculateShaPassHash(std::string& name, std::string& password) { Sha1Hash sha; @@ -229,10 +180,8 @@ std::string AccountMgr::CalculateShaPassHash(std::string& name, std::string& pas sha.UpdateData(":"); sha.UpdateData(password); sha.Finalize(); - std::string encoded; hexEncodeByteArray(sha.GetDigest(), sha.GetLength(), encoded); - return encoded; } diff --git a/src/game/AccountMgr.h b/src/game/AccountMgr.h index c14110036a0..c35b9a37575 100644 --- a/src/game/AccountMgr.h +++ b/src/game/AccountMgr.h @@ -17,15 +17,11 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef _ACCMGR_H #define _ACCMGR_H - #include - #include "Common.h" #include "Policies/Singleton.h" - enum AccountOpResult { AOR_OK, @@ -35,29 +31,23 @@ enum AccountOpResult AOR_NAME_NOT_EXIST, AOR_DB_INTERNAL_ERROR }; - #define MAX_ACCOUNT_STR 16 - class AccountMgr { public: AccountMgr(); ~AccountMgr(); - AccountOpResult CreateAccount(std::string username, std::string password); AccountOpResult DeleteAccount(uint32 accid); AccountOpResult ChangeUsername(uint32 accid, std::string new_uname, std::string new_passwd); AccountOpResult ChangePassword(uint32 accid, std::string new_passwd); bool CheckPassword(uint32 accid, std::string passwd); - uint32 GetId(std::string username); uint32 GetSecurity(uint32 acc_id); bool GetName(uint32 acc_id, std::string &name); std::string CalculateShaPassHash(std::string& name, std::string& password); - static bool normalizeString(std::string& utf8str); }; - #define accmgr Trinity::Singleton::Instance() #endif diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp index c9b98c3ddef..50daa5c565f 100644 --- a/src/game/AchievementMgr.cpp +++ b/src/game/AchievementMgr.cpp @@ -15,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "Common.h" #include "DBCEnums.h" #include "ObjectMgr.h" @@ -23,7 +22,6 @@ #include "WorldPacket.h" #include "Database/DatabaseEnv.h" #include "Policies/SingletonImp.h" - #include "AchievementMgr.h" #include "ArenaTeam.h" #include "CellImpl.h" @@ -34,14 +32,11 @@ #include "Player.h" #include "ProgressBar.h" #include "SpellMgr.h" - #include "MapManager.h" #include "BattleGround.h" #include "BattleGroundAB.h" - INSTANTIATE_SINGLETON_1(AchievementGlobalMgr); - namespace MaNGOS { class AchievementChatBuilder @@ -52,7 +47,6 @@ namespace MaNGOS void operator()(WorldPacket& data, int32 loc_idx) { char const* text = objmgr.GetMangosString(i_textId,loc_idx); - data << uint8(i_msgtype); data << uint32(LANG_UNIVERSAL); data << uint64(i_player.GetGUID()); @@ -63,7 +57,6 @@ namespace MaNGOS data << uint8(0); data << uint32(i_achievementId); } - private: Player const& i_player; ChatMsg i_msgtype; @@ -72,7 +65,6 @@ namespace MaNGOS }; } // namespace MaNGOS - bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) { if(dataType >= MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE) @@ -80,7 +72,6 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) sLog.outErrorDb( "Table `achievement_criteria_data` for criteria (Entry: %u) have wrong data type (%u), ignore.", criteria->ID,dataType); return false; } - switch(criteria->requiredType) { case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE: @@ -98,7 +89,6 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) sLog.outErrorDb( "Table `achievement_criteria_data` have data for not supported criteria type (Entry: %u Type: %u), ignore.", criteria->ID, criteria->requiredType); return false; } - switch(dataType) { case ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE: @@ -245,7 +235,6 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) } return false; } - bool AchievementCriteriaData::Meets(Player const* source, Unit const* target, uint32 miscvalue1 /*= 0*/) const { switch(dataType) @@ -317,25 +306,20 @@ bool AchievementCriteriaData::Meets(Player const* source, Unit const* target, ui } return false; } - bool AchievementCriteriaDataSet::Meets(Player const* source, Unit const* target, uint32 miscvalue /*= 0*/) const { for(Storage::const_iterator itr = storage.begin(); itr != storage.end(); ++itr) if(!itr->Meets(source,target,miscvalue)) return false; - return true; } - AchievementMgr::AchievementMgr(Player *player) { m_player = player; } - AchievementMgr::~AchievementMgr() { } - void AchievementMgr::Reset() { for(CompletedAchievementMap::const_iterator iter = m_completedAchievements.begin(); iter!=m_completedAchievements.end(); ++iter) @@ -344,43 +328,34 @@ void AchievementMgr::Reset() data << uint32(iter->first); m_player->SendDirectMessage(&data); } - for(CriteriaProgressMap::const_iterator iter = m_criteriaProgress.begin(); iter!=m_criteriaProgress.end(); ++iter) { WorldPacket data(SMSG_CRITERIA_DELETED,4); data << uint32(iter->first); m_player->SendDirectMessage(&data); } - m_completedAchievements.clear(); m_criteriaProgress.clear(); DeleteFromDB(m_player->GetGUIDLow()); - // re-fill data CheckAllAchievementCriteria(); } - void AchievementMgr::ResetAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1, uint32 miscvalue2) { if((sLog.getLogFilter() & LOG_FILTER_ACHIEVEMENT_UPDATES)==0) sLog.outDetail("AchievementMgr::ResetAchievementCriteria(%u, %u, %u)", type, miscvalue1, miscvalue2); - if (!sWorld.getConfig(CONFIG_GM_ALLOW_ACHIEVEMENT_GAINS) && m_player->GetSession()->GetSecurity() > SEC_PLAYER) return; - AchievementCriteriaEntryList const& achievementCriteriaList = achievementmgr.GetAchievementCriteriaByType(type); for(AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i!=achievementCriteriaList.end(); ++i) { AchievementCriteriaEntry const *achievementCriteria = (*i); - AchievementEntry const *achievement = sAchievementStore.LookupEntry(achievementCriteria->referredAchievement); if (!achievement) continue; - // don't update already completed criteria if (IsCompletedCriteria(achievementCriteria,achievement)) continue; - switch (type) { case ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE: // have total statistic also not expected to be reset @@ -399,7 +374,6 @@ void AchievementMgr::ResetAchievementCriteria(AchievementCriteriaTypes type, uin } } } - void AchievementMgr::DeleteFromDB(uint32 lowguid) { CharacterDatabase.BeginTransaction (); @@ -407,7 +381,6 @@ void AchievementMgr::DeleteFromDB(uint32 lowguid) CharacterDatabase.PExecute("DELETE FROM character_achievement_progress WHERE guid = %u",lowguid); CharacterDatabase.CommitTransaction (); } - void AchievementMgr::SaveToDB() { if(!m_completedAchievements.empty()) @@ -419,7 +392,6 @@ void AchievementMgr::SaveToDB() { if(!iter->second.changed) continue; - /// first new/changed record prefix if(!need_execute) { @@ -433,25 +405,20 @@ void AchievementMgr::SaveToDB() ssdel << ", "; ssins << ", "; } - // new/changed record data ssdel << iter->first; ssins << "("<GetGUIDLow() << ", " << iter->first << ", " << uint64(iter->second.date) << ")"; - /// mark as saved in db iter->second.changed = false; } - if(need_execute) ssdel << ")"; - if(need_execute) { CharacterDatabase.Execute( ssdel.str().c_str() ); CharacterDatabase.Execute( ssins.str().c_str() ); } } - if(!m_criteriaProgress.empty()) { /// prepare deleting and insert @@ -463,7 +430,6 @@ void AchievementMgr::SaveToDB() { if(!iter->second.changed) continue; - // deleted data (including 0 progress state) { /// first new/changed record prefix (for any counter value) @@ -475,11 +441,9 @@ void AchievementMgr::SaveToDB() /// next new/changed record prefix else ssdel << ", "; - // new/changed record data ssdel << iter->first; } - // store data only for real progress if(iter->second.counter != 0) { @@ -492,18 +456,14 @@ void AchievementMgr::SaveToDB() /// next new/changed record prefix else ssins << ", "; - // new/changed record data ssins << "(" << GetPlayer()->GetGUIDLow() << ", " << iter->first << ", " << iter->second.counter << ", " << iter->second.date << ")"; } - /// mark as updated in db iter->second.changed = false; } - if(need_execute_del) // DELETE ... IN (.... _)_ ssdel << ")"; - if(need_execute_del || need_execute_ins) { if(need_execute_del) @@ -513,7 +473,6 @@ void AchievementMgr::SaveToDB() } } } - void AchievementMgr::LoadFromDB(QueryResult *achievementResult, QueryResult *criteriaResult) { if(achievementResult) @@ -521,30 +480,24 @@ void AchievementMgr::LoadFromDB(QueryResult *achievementResult, QueryResult *cri do { Field *fields = achievementResult->Fetch(); - uint32 achievement_id = fields[0].GetUInt32(); - // don't must happen: cleanup at server startup in achievementmgr.LoadCompletedAchievements() if(!sAchievementStore.LookupEntry(achievement_id)) continue; - CompletedAchievementData& ca = m_completedAchievements[achievement_id]; ca.date = time_t(fields[1].GetUInt64()); ca.changed = false; } while(achievementResult->NextRow()); delete achievementResult; } - if(criteriaResult) { do { Field *fields = criteriaResult->Fetch(); - uint32 id = fields[0].GetUInt32(); uint32 counter = fields[1].GetUInt32(); time_t date = time_t(fields[2].GetUInt64()); - AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(id); if (!criteria) { @@ -553,10 +506,8 @@ void AchievementMgr::LoadFromDB(QueryResult *achievementResult, QueryResult *cri CharacterDatabase.PExecute("DELETE FROM character_achievement_progress WHERE criteria = %u",id); continue; } - if (criteria->timeLimit && time_t(date + criteria->timeLimit) < time(NULL)) continue; - CriteriaProgress& progress = m_criteriaProgress[id]; progress.counter = counter; progress.date = date; @@ -564,26 +515,21 @@ void AchievementMgr::LoadFromDB(QueryResult *achievementResult, QueryResult *cri } while(criteriaResult->NextRow()); delete criteriaResult; } - } - void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement) { if(GetPlayer()->GetSession()->PlayerLoading()) return; - #ifdef TRINITY_DEBUG if((sLog.getLogFilter() & LOG_FILTER_ACHIEVEMENT_UPDATES)==0) sLog.outDebug("AchievementMgr::SendAchievementEarned(%u)", achievement->ID); #endif - if(Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId())) { MaNGOS::AchievementChatBuilder say_builder(*GetPlayer(), CHAT_MSG_GUILD_ACHIEVEMENT, LANG_ACHIEVEMENT_EARNED,achievement->ID); MaNGOS::LocalizedPacketDo say_do(say_builder); guild->BroadcastWorker(say_do,GetPlayer()); } - if(achievement->flags & (ACHIEVEMENT_FLAG_REALM_FIRST_KILL|ACHIEVEMENT_FLAG_REALM_FIRST_REACH)) { // broadcast realm first reached @@ -597,11 +543,9 @@ void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement) else { CellPair p = MaNGOS::ComputeCellPair(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY()); - Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); - MaNGOS::AchievementChatBuilder say_builder(*GetPlayer(), CHAT_MSG_ACHIEVEMENT, LANG_ACHIEVEMENT_EARNED,achievement->ID); MaNGOS::LocalizedPacketDo say_do(say_builder); MaNGOS::PlayerDistWorker > say_worker(GetPlayer(),sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY),say_do); @@ -609,7 +553,6 @@ void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement) CellLock cell_lock(cell, p); cell_lock->Visit(cell_lock, message, *GetPlayer()->GetMap(), *GetPlayer(), sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY)); } - WorldPacket data(SMSG_ACHIEVEMENT_EARNED, 8+4+8); data.append(GetPlayer()->GetPackGUID()); data << uint32(achievement->ID); @@ -617,15 +560,12 @@ void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement) data << uint32(0); GetPlayer()->SendMessageToSetInRange(&data, sWorld.getConfig(CONFIG_LISTEN_RANGE_SAY), true); } - void AchievementMgr::SendCriteriaUpdate(uint32 id, CriteriaProgress const* progress) { WorldPacket data(SMSG_CRITERIA_UPDATE, 8+4+8); data << uint32(id); - // the counter is packed like a packed Guid data.appendPackGUID(progress->counter); - data.append(GetPlayer()->GetPackGUID()); data << uint32(0); data << uint32(secsToTimeBitFields(progress->date)); @@ -633,7 +573,6 @@ void AchievementMgr::SendCriteriaUpdate(uint32 id, CriteriaProgress const* progr data << uint32(0); // timer 2 GetPlayer()->SendDirectMessage(&data); } - /** * called at player login. The player might have fulfilled some achievements when the achievement system wasn't working yet */ @@ -643,7 +582,6 @@ void AchievementMgr::CheckAllAchievementCriteria() for(uint32 i=0; iGetSession()->GetSecurity() > SEC_PLAYER) return; - AchievementCriteriaEntryList const& achievementCriteriaList = achievementmgr.GetAchievementCriteriaByType(type); for(AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i!=achievementCriteriaList.end(); ++i) { AchievementCriteriaEntry const *achievementCriteria = (*i); - if (achievementCriteria->groupFlag & ACHIEVEMENT_CRITERIA_GROUP_NOT_IN_GROUP && GetPlayer()->GetGroup()) continue; - AchievementEntry const *achievement = sAchievementStore.LookupEntry(achievementCriteria->referredAchievement); if (!achievement) continue; - if ((achievement->factionFlag == ACHIEVEMENT_FACTION_FLAG_HORDE && GetPlayer()->GetTeam() != HORDE) || (achievement->factionFlag == ACHIEVEMENT_FACTION_FLAG_ALLIANCE && GetPlayer()->GetTeam() != ALLIANCE)) continue; - // don't update already completed criteria if (IsCompletedCriteria(achievementCriteria,achievement)) continue; - switch (type) { // std. case: increment at 1 @@ -729,9 +659,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui continue; SetCriteriaProgress(achievementCriteria, miscvalue1, PROGRESS_HIGHEST); break; - // specialized cases - case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG: { // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case @@ -739,7 +667,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui continue; if (achievementCriteria->win_bg.bgMapID != GetPlayer()->GetMapId()) continue; - if (achievementCriteria->win_bg.additionalRequirement1_type) { // those requirements couldn't be found in the dbc @@ -753,7 +680,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui BattleGround* bg = GetPlayer()->GetBattleGround(); if (!bg) continue; - switch(achievementCriteria->referredAchievement) { case 161: // AB, Overcome a 500 resource disadvantage @@ -776,7 +702,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui continue; // not implemented } } - SetCriteriaProgress(achievementCriteria, miscvalue1, PROGRESS_ACCUMULATE); break; } @@ -787,12 +712,10 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui continue; if(achievementCriteria->kill_creature.creatureID != miscvalue1) continue; - // those requirements couldn't be found in the dbc AchievementCriteriaDataSet const* data = achievementmgr.GetCriteriaDataSet(achievementCriteria); if(!data || !data->Meets(GetPlayer(),unit)) continue; - SetCriteriaProgress(achievementCriteria, miscvalue2, PROGRESS_ACCUMULATE); break; } @@ -831,7 +754,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui // speedup for non-login case if(miscvalue1 && miscvalue1 != achievementCriteria->complete_quests_in_zone.zoneID) continue; - uint32 counter =0; for(QuestStatusMap::const_iterator itr = GetPlayer()->getQuestStatusMap().begin(); itr!=GetPlayer()->getQuestStatusMap().end(); itr++) { @@ -872,13 +794,11 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui BattleGround* bg = GetPlayer()->GetBattleGround(); if(!bg || !bg->isArena() || ArenaTeam::GetSlotByType(bg->GetArenaType()) != j) notfit = true; - break; } } if(notfit) continue; - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); break; } @@ -887,11 +807,9 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case if(!miscvalue1) continue; - Map const* map = GetPlayer()->IsInWorld() ? GetPlayer()->GetMap() : MapManager::Instance().FindMap(GetPlayer()->GetMapId(), GetPlayer()->GetInstanceId()); if(!map || !map->IsDungeon()) continue; - // search case bool found = false; for(int j = 0; achievIdForDangeon[j][0]; ++j) @@ -916,20 +834,17 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if(!achievIdForDangeon[j][3]) break; // for } - found = true; break; // for } } if(!found) continue; - //FIXME: work only for instances where max==min for players if(((InstanceMap*)map)->GetMaxPlayers() != achievementCriteria->death_in_dungeon.manLimit) continue; SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); break; - } case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE: // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case @@ -943,11 +858,9 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case if(!miscvalue1) continue; - // if team check required: must kill by opposition faction if(achievement->ID==318 && miscvalue2==GetPlayer()->GetTeam()) continue; - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); break; case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING: @@ -955,12 +868,10 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case if(!miscvalue1) continue; - // those requirements couldn't be found in the dbc AchievementCriteriaDataSet const* data = achievementmgr.GetCriteriaDataSet(achievementCriteria); if(!data || !data->Meets(GetPlayer(),unit)) continue; - // miscvalue1 is the ingame fallheight*100 as stored in dbc SetCriteriaProgress(achievementCriteria, miscvalue1); break; @@ -987,7 +898,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if(!GetPlayer()->GetQuestRewardStatus(achievementCriteria->complete_quest.questID)) continue; } - // exist many achievements with this criteria, use at this moment hardcoded check to skil simple case switch(achievement->ID) { @@ -1008,7 +918,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui break; } - SetCriteriaProgress(achievementCriteria, 1); break; } @@ -1023,22 +932,18 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui { if (!miscvalue1 || miscvalue1 != achievementCriteria->cast_spell.spellID) continue; - // those requirements couldn't be found in the dbc AchievementCriteriaDataSet const* data = achievementmgr.GetCriteriaDataSet(achievementCriteria); if(!data) continue; - if(!data->Meets(GetPlayer(),unit)) continue; - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); break; } case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL: if(miscvalue1 && miscvalue1!=achievementCriteria->learn_spell.spellID) continue; - if(GetPlayer()->HasSpell(achievementCriteria->learn_spell.spellID)) SetCriteriaProgress(achievementCriteria, 1); break; @@ -1050,7 +955,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui continue; if (miscvalue1 != achievementCriteria->loot_type.lootType) continue; - // zone specific if(achievementCriteria->loot_type.lootTypeCount==1) { @@ -1059,7 +963,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if(!data || !data->Meets(GetPlayer(),unit)) continue; } - SetCriteriaProgress(achievementCriteria, miscvalue2, PROGRESS_ACCUMULATE); break; } @@ -1073,7 +976,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui // miscvalue1 contains the personal rating if (!miscvalue1) // no update at login continue; - // additional requirements if(achievementCriteria->win_rated_arena.flag==ACHIEVEMENT_CRITERIA_CONDITION_NO_LOOSE) { @@ -1086,7 +988,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui continue; } } - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); break; case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM: @@ -1110,28 +1011,23 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui WorldMapOverlayEntry const* worldOverlayEntry = sWorldMapOverlayStore.LookupEntry(achievementCriteria->explore_area.areaReference); if(!worldOverlayEntry) break; - bool matchFound = false; for (int j = 0; j < MAX_WORLD_MAP_OVERLAY_AREA_IDX; ++j) { uint32 area_id = worldOverlayEntry->areatableID[j]; if(!area_id) // array have 0 only in empty tail break; - int32 exploreFlag = GetAreaFlagByAreaID(area_id); if(exploreFlag < 0) continue; - uint32 playerIndexOffset = uint32(exploreFlag) / 32; uint32 mask = 1<< (uint32(exploreFlag) % 32); - if(GetPlayer()->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + playerIndexOffset) & mask) { matchFound = true; break; } } - if(matchFound) SetCriteriaProgress(achievementCriteria, 1); break; @@ -1144,7 +1040,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui // skip faction check only at loading if (miscvalue1 && miscvalue1 != achievementCriteria->gain_reputation.factionID) continue; - int32 reputation = GetPlayer()->GetReputationMgr().GetReputation(achievementCriteria->gain_reputation.factionID); if (reputation > 0) SetCriteriaProgress(achievementCriteria, reputation); @@ -1173,11 +1068,9 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if(miscvalue2 != achievementCriteria->roll_greed_on_loot.rollValue) continue; ItemPrototype const *pProto = objmgr.GetItemPrototype( miscvalue1 ); - uint32 requiredItemLevel = 0; if (achievementCriteria->ID == 2412 || achievementCriteria->ID == 2358) requiredItemLevel = 185; - if(!pProto || pProto->ItemLevel Meets(GetPlayer(),unit)) continue; } - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); break; } @@ -1206,17 +1098,14 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui { if (!miscvalue1) continue; - if (achievementCriteria->healing_done.flag == ACHIEVEMENT_CRITERIA_CONDITION_MAP) { if(GetPlayer()->GetMapId() != achievementCriteria->healing_done.mapid) continue; - // map specific case (BG in fact) expected player targeted damage/heal if(!unit || unit->GetTypeId()!=TYPEID_PLAYER) continue; } - SetCriteriaProgress(achievementCriteria, miscvalue1, PROGRESS_ACCUMULATE); break; } @@ -1226,7 +1115,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui continue; if (miscvalue1 != achievementCriteria->equip_item.itemID) continue; - SetCriteriaProgress(achievementCriteria, 1); break; case ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT: @@ -1235,7 +1123,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui continue; if (miscvalue1 != achievementCriteria->use_gameobject.goEntry) continue; - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); break; case ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT: @@ -1243,14 +1130,12 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui continue; if (miscvalue1 != achievementCriteria->fish_in_gameobject.goEntry) continue; - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); break; case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS: { if (miscvalue1 && miscvalue1 != achievementCriteria->learn_skillline_spell.skillLine) continue; - uint32 spellCount = 0; for (PlayerSpellMap::const_iterator spellIter = GetPlayer()->GetSpellMap().begin(); spellIter != GetPlayer()->GetSpellMap().end(); @@ -1270,18 +1155,15 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case if (!miscvalue1) continue; - if (achievementCriteria->win_duel.duelCount) { // those requirements couldn't be found in the dbc AchievementCriteriaDataSet const* data = achievementmgr.GetCriteriaDataSet(achievementCriteria); if (!data) continue; - if (!data->Meets(GetPlayer(),unit)) continue; } - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); break; case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION: @@ -1297,7 +1179,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui { if (miscvalue1 && miscvalue1 != achievementCriteria->learn_skill_line.skillLine) continue; - uint32 spellCount = 0; for (PlayerSpellMap::const_iterator spellIter = GetPlayer()->GetSpellMap().begin(); spellIter != GetPlayer()->GetSpellMap().end(); @@ -1317,13 +1198,11 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui case ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS: if (!miscvalue1 || miscvalue1 != achievementCriteria->hk_class.classID) continue; - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); break; case ACHIEVEMENT_CRITERIA_TYPE_HK_RACE: if (!miscvalue1 || miscvalue1 != achievementCriteria->hk_race.raceID) continue; - SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE); break; case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_GOLD_VALUE_OWNED: @@ -1364,7 +1243,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui } if(IsCompletedCriteria(achievementCriteria,achievement)) CompletedCriteriaFor(achievement); - // check again the completeness for SUMM and REQ COUNT achievements, // as they don't depend on the completed criteria but on the sum of the progress of each individual criteria if (achievement->flags & ACHIEVEMENT_FLAG_SUMM) @@ -1372,7 +1250,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if (IsCompletedAchievement(achievement)) CompletedAchievement(achievement); } - if(AchievementEntryList const* achRefList = achievementmgr.GetAchievementByReferencedId(achievement->ID)) { for(AchievementEntryList::const_iterator itr = achRefList->begin(); itr != achRefList->end(); ++itr) @@ -1381,29 +1258,23 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui } } } - static const uint32 achievIdByClass[MAX_CLASSES] = { 0, 459, 465 , 462, 458, 464, 461, 467, 460, 463, 0, 466 }; static const uint32 achievIdByRace[MAX_RACES] = { 0, 1408, 1410, 1407, 1409, 1413, 1411, 1404, 1412, 0, 1405, 1406 }; - bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achievementCriteria, AchievementEntry const* achievement) { // counter can never complete if(achievement->flags & ACHIEVEMENT_FLAG_COUNTER) return false; - if(achievement->flags & (ACHIEVEMENT_FLAG_REALM_FIRST_REACH | ACHIEVEMENT_FLAG_REALM_FIRST_KILL)) { // someone on this realm has already completed that achievement if(achievementmgr.IsRealmCompleted(achievement)) return false; } - CriteriaProgressMap::const_iterator itr = m_criteriaProgress.find(achievementCriteria->ID); if(itr == m_criteriaProgress.end()) return false; - CriteriaProgress const* progress = &itr->second; - switch(achievementCriteria->requiredType) { case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG: @@ -1416,12 +1287,10 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve for(int i = 1; i < MAX_CLASSES; ++i) if(achievIdByClass[i] == achievement->ID && i != GetPlayer()->getClass()) return false; - // skip wrong race achievements for(int i = 1; i < MAX_RACES; ++i) if(achievIdByRace[i] == achievement->ID && i != GetPlayer()->getRace()) return false; - // appropriate class/race or not class/race specific return progress->counter >= achievementCriteria->reach_level.level; } @@ -1530,36 +1399,29 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve } return false; } - void AchievementMgr::CompletedCriteriaFor(AchievementEntry const* achievement) { // counter can never complete if(achievement->flags & ACHIEVEMENT_FLAG_COUNTER) return; - // already completed and stored if (m_completedAchievements.find(achievement->ID)!=m_completedAchievements.end()) return; - if (IsCompletedAchievement(achievement)) CompletedAchievement(achievement); } - bool AchievementMgr::IsCompletedAchievement(AchievementEntry const* entry) { // counter can never complete if(entry->flags & ACHIEVEMENT_FLAG_COUNTER) return false; - // for achievement with referenced achievement criterias get from referenced and counter from self uint32 achievmentForTestId = entry->refAchievement ? entry->refAchievement : entry->ID; uint32 achievmentForTestCount = entry->count; - AchievementCriteriaEntryList const* cList = achievementmgr.GetAchievementCriteriaByAchievement(achievmentForTestId); if(!cList) return false; uint32 count = 0; - // For SUMM achievements, we have to count the progress of each criteria of the achievement. // Oddly, the target count is NOT countained in the achievement, but in each individual criteria if (entry->flags & ACHIEVEMENT_FLAG_SUMM) @@ -1567,62 +1429,48 @@ bool AchievementMgr::IsCompletedAchievement(AchievementEntry const* entry) for(AchievementCriteriaEntryList::const_iterator itr = cList->begin(); itr != cList->end(); ++itr) { AchievementCriteriaEntry const* criteria = *itr; - CriteriaProgressMap::const_iterator itrProgress = m_criteriaProgress.find(criteria->ID); if(itrProgress == m_criteriaProgress.end()) continue; - CriteriaProgress const* progress = &itrProgress->second; count += progress->counter; - // for counters, field4 contains the main count requirement if (count >= criteria->raw.count) return true; } return false; } - // Default case - need complete all or bool completed_all = true; for(AchievementCriteriaEntryList::const_iterator itr = cList->begin(); itr != cList->end(); ++itr) { AchievementCriteriaEntry const* criteria = *itr; - bool completed = IsCompletedCriteria(criteria,entry); - // found an uncompleted criteria, but DONT return false yet - there might be a completed criteria with ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL if(completed) ++count; else completed_all = false; - // completed as have req. count of completed criterias if(achievmentForTestCount > 0 && achievmentForTestCount <= count) return true; } - // all criterias completed requirement if(completed_all && achievmentForTestCount==0) return true; - return false; } - void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 changeValue, ProgressType ptype) { if((sLog.getLogFilter() & LOG_FILTER_ACHIEVEMENT_UPDATES)==0) sLog.outDetail("AchievementMgr::SetCriteriaProgress(%u, %u) for (GUID:%u)", entry->ID, changeValue, m_player->GetGUIDLow()); - CriteriaProgress *progress = NULL; - CriteriaProgressMap::iterator iter = m_criteriaProgress.find(entry->ID); - if(iter == m_criteriaProgress.end()) { // not create record for 0 counter if(changeValue == 0) return; - progress = &m_criteriaProgress[entry->ID]; progress->counter = changeValue; progress->date = time(NULL); @@ -1630,7 +1478,6 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, else { progress = &iter->second; - uint32 newValue = 0; switch(ptype) { @@ -1648,81 +1495,62 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, newValue = progress->counter < changeValue ? changeValue : progress->counter; break; } - // not update (not mark as changed) if counter will have same value if(progress->counter == newValue) return; - progress->counter = newValue; } - progress->changed = true; - if(entry->timeLimit) { time_t now = time(NULL); if(time_t(progress->date + entry->timeLimit) < now) progress->counter = 1; - // also it seems illogical, the timeframe will be extended at every criteria update progress->date = now; } SendCriteriaUpdate(entry->ID,progress); } - void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement) { sLog.outDetail("AchievementMgr::CompletedAchievement(%u)", achievement->ID); - if(!sWorld.getConfig(CONFIG_GM_ALLOW_ACHIEVEMENT_GAINS) && m_player->GetSession()->GetSecurity() > SEC_PLAYER) return; - if(achievement->flags & ACHIEVEMENT_FLAG_COUNTER || m_completedAchievements.find(achievement->ID)!=m_completedAchievements.end()) return; - SendAchievementEarned(achievement); CompletedAchievementData& ca = m_completedAchievements[achievement->ID]; ca.date = time(NULL); ca.changed = true; - // don't insert for ACHIEVEMENT_FLAG_REALM_FIRST_KILL since otherwise only the first group member would reach that achievement // TODO: where do set this instead? if(!(achievement->flags & ACHIEVEMENT_FLAG_REALM_FIRST_KILL)) achievementmgr.SetRealmCompleted(achievement); - UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT); - // reward items and titles if any AchievementReward const* reward = achievementmgr.GetAchievementReward(achievement); - // no rewards if(!reward) return; - // titles if(uint32 titleId = reward->titleId[GetPlayer()->GetTeam() == HORDE ? 0 : 1]) { if(CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(titleId)) GetPlayer()->SetTitle(titleEntry); } - // mail if(reward->sender) { Item* item = reward->itemId ? Item::CreateItem(reward->itemId,1,GetPlayer ()) : NULL; - MailItemsInfo mi; if(item) { // save new item before send item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted - // item mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item); } - int loc_idx = GetPlayer()->GetSession()->GetSessionDbLocaleIndex(); - // subject and text std::string subject = reward->subject; std::string text = reward->text; @@ -1736,36 +1564,28 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement) text = loc->text[loc_idx]; } } - uint32 itemTextId = objmgr.CreateItemText( text ); - WorldSession::SendMailTo(GetPlayer(), MAIL_CREATURE, MAIL_STATIONERY_NORMAL, reward->sender, GetPlayer()->GetGUIDLow(), subject, itemTextId , &mi, 0, 0, MAIL_CHECK_MASK_NONE); } } - void AchievementMgr::SendAllAchievementData() { uint32 size = 18 + m_completedAchievements.size()*8 + m_criteriaProgress.size() * 36; - bool send = false; - WorldPacket data(SMSG_ALL_ACHIEVEMENT_DATA); if( size < 0x8000 ) data.resize( size ); else data.resize( 0x7fff ); // More than this causes client trouble - CompletedAchievementMap::const_iterator iter = m_completedAchievements.begin(); CriteriaProgressMap::const_iterator iter2 = m_criteriaProgress.begin(); - bool cAchievements = false; bool cProgress = false; while( !cAchievements || !cProgress ) { data.clear(); send = false; - if( !cAchievements ) { for(; iter != m_completedAchievements.end() && !send; ++iter) @@ -1774,11 +1594,9 @@ void AchievementMgr::SendAllAchievementData() data << uint32(secsToTimeBitFields(iter->second.date)); send = data.size() > 0x7f00; } - if( iter == m_completedAchievements.end() ) cAchievements = true; } - data << int32(-1); for(; iter2 != m_criteriaProgress.end() && !send; ++iter2) { @@ -1791,15 +1609,12 @@ void AchievementMgr::SendAllAchievementData() data << uint32(0); send = data.size() > 0x7f00; } - if( iter2 == m_criteriaProgress.end() ) cProgress = true; - data << int32(-1); GetPlayer()->GetSession()->SendPacket(&data); } } - void AchievementMgr::SendRespondInspectAchievements(Player* player) { // since we don't know the exact size of the packed GUIDs this is just an approximation @@ -1808,7 +1623,6 @@ void AchievementMgr::SendRespondInspectAchievements(Player* player) BuildAllDataPacket(&data); player->GetSession()->SendPacket(&data); } - /** * used by SMSG_RESPOND_INSPECT_ACHIEVEMENT */ @@ -1820,7 +1634,6 @@ void AchievementMgr::BuildAllDataPacket(WorldPacket *data) *data << uint32(secsToTimeBitFields(iter->second.date)); } *data << int32(-1); - for(CriteriaProgressMap::const_iterator iter = m_criteriaProgress.begin(); iter!=m_criteriaProgress.end(); ++iter) { *data << uint32(iter->first); @@ -1831,91 +1644,72 @@ void AchievementMgr::BuildAllDataPacket(WorldPacket *data) *data << uint32(0); *data << uint32(0); } - *data << int32(-1); } - //========================================================== AchievementCriteriaEntryList const& AchievementGlobalMgr::GetAchievementCriteriaByType(AchievementCriteriaTypes type) { return m_AchievementCriteriasByType[type]; } - void AchievementGlobalMgr::LoadAchievementCriteriaList() { if(sAchievementCriteriaStore.GetNumRows()==0) { barGoLink bar(1); bar.step(); - sLog.outString(); sLog.outErrorDb(">> Loaded 0 achievement criteria."); return; } - barGoLink bar( sAchievementCriteriaStore.GetNumRows() ); for (uint32 entryId = 0; entryId < sAchievementCriteriaStore.GetNumRows(); ++entryId) { bar.step(); - AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(entryId); if(!criteria) continue; - m_AchievementCriteriasByType[criteria->requiredType].push_back(criteria); m_AchievementCriteriaListByAchievement[criteria->referredAchievement].push_back(criteria); } - sLog.outString(); sLog.outString(">> Loaded %lu achievement criteria.",(unsigned long)m_AchievementCriteriasByType->size()); } - void AchievementGlobalMgr::LoadAchievementReferenceList() { if(sAchievementStore.GetNumRows()==0) { barGoLink bar(1); bar.step(); - sLog.outString(); sLog.outErrorDb(">> Loaded 0 achievement references."); return; } - uint32 count = 0; barGoLink bar( sAchievementStore.GetNumRows() ); for (uint32 entryId = 0; entryId < sAchievementStore.GetNumRows(); ++entryId) { bar.step(); - AchievementEntry const* achievement = sAchievementStore.LookupEntry(entryId); if(!achievement || !achievement->refAchievement) continue; - m_AchievementListByReferencedId[achievement->refAchievement].push_back(achievement); ++count; } - sLog.outString(); sLog.outString(">> Loaded %u achievement references.",count); } - void AchievementGlobalMgr::LoadAchievementCriteriaData() { m_criteriaDataMap.clear(); // need for reload case - QueryResult *result = WorldDatabase.Query("SELECT criteria_id, type, value1, value2 FROM achievement_criteria_data"); - if(!result) { barGoLink bar(1); bar.step(); - sLog.outString(); sLog.outString(">> Loaded 0 additional achievement criteria data. DB table `achievement_criteria_data` is empty."); return; } - uint32 count = 0; uint32 disabled_count = 0; barGoLink bar(result->GetRowCount()); @@ -1924,45 +1718,34 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData() bar.step(); Field *fields = result->Fetch(); uint32 criteria_id = fields[0].GetUInt32(); - AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(criteria_id); - if (!criteria) { sLog.outErrorDb( "Table `achievement_criteria_data` have data for not existed criteria (Entry: %u), ignore.", criteria_id); continue; } - AchievementCriteriaData data(fields[1].GetUInt32(),fields[2].GetUInt32(),fields[3].GetUInt32()); - if (!data.IsValid(criteria)) { continue; } - // this will allocate empty data set storage AchievementCriteriaDataSet& dataSet = m_criteriaDataMap[criteria_id]; - if (data.dataType == ACHIEVEMENT_CRITERIA_DATA_TYPE_DISABLED) ++disabled_count; - // add real data only for not NONE data types if (data.dataType != ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE) dataSet.Add(data); - // counting data by and data types ++count; } while(result->NextRow()); - delete result; - // post loading checks for (uint32 entryId = 0; entryId < sAchievementCriteriaStore.GetNumRows(); ++entryId) { AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(entryId); if(!criteria) continue; - switch(criteria->requiredType) { case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG: @@ -1976,7 +1759,6 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData() AchievementEntry const* achievement = sAchievementStore.LookupEntry(criteria->referredAchievement); if(!achievement) continue; - // exist many achievements with this criteria, use at this moment hardcoded check to skil simple case switch(achievement->ID) { @@ -2016,35 +1798,28 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData() default: // type not use DB data, ignore continue; } - if(!GetCriteriaDataSet(criteria)) sLog.outErrorDb( "Table `achievement_criteria_data` not have expected data for criteria (Entry: %u Type: %u) for achievement %u.", criteria->ID, criteria->requiredType, criteria->referredAchievement); } - sLog.outString(); sLog.outString(">> Loaded %u additional achievement criteria data (%u disabled).",count,disabled_count); } - void AchievementGlobalMgr::LoadCompletedAchievements() { QueryResult *result = CharacterDatabase.Query("SELECT achievement FROM character_achievement GROUP BY achievement"); - if(!result) { barGoLink bar(1); bar.step(); - sLog.outString(); sLog.outString(">> Loaded 0 realm completed achievements . DB table `character_achievement` is empty."); return; } - barGoLink bar(result->GetRowCount()); do { bar.step(); Field *fields = result->Fetch(); - uint32 achievement_id = fields[0].GetUInt32(); if(!sAchievementStore.LookupEntry(achievement_id)) { @@ -2053,41 +1828,30 @@ void AchievementGlobalMgr::LoadCompletedAchievements() CharacterDatabase.PExecute("DELETE FROM character_achievement WHERE achievement = %u",achievement_id); continue; } - m_allCompletedAchievements.insert(achievement_id); } while(result->NextRow()); - delete result; - sLog.outString(); sLog.outString(">> Loaded %lu realm completed achievements.",(unsigned long)m_allCompletedAchievements.size()); } - void AchievementGlobalMgr::LoadRewards() { m_achievementRewards.clear(); // need for reload case - // 0 1 2 3 4 5 6 QueryResult *result = WorldDatabase.Query("SELECT entry, title_A, title_H, item, sender, subject, text FROM achievement_reward"); - if(!result) { barGoLink bar(1); - bar.step(); - sLog.outString(); sLog.outErrorDb(">> Loaded 0 achievement rewards. DB table `achievement_reward` is empty."); return; } - uint32 count = 0; barGoLink bar(result->GetRowCount()); - do { bar.step(); - Field *fields = result->Fetch(); uint32 entry = fields[0].GetUInt32(); if (!sAchievementStore.LookupEntry(entry)) @@ -2095,7 +1859,6 @@ void AchievementGlobalMgr::LoadRewards() sLog.outErrorDb( "Table `achievement_reward` has wrong achievement (Entry: %u), ignore", entry); continue; } - AchievementReward reward; reward.titleId[0] = fields[1].GetUInt32(); reward.titleId[1] = fields[2].GetUInt32(); @@ -2103,17 +1866,14 @@ void AchievementGlobalMgr::LoadRewards() reward.sender = fields[4].GetUInt32(); reward.subject = fields[5].GetCppString(); reward.text = fields[6].GetCppString(); - if ((reward.titleId[0]==0)!=(reward.titleId[1]==0)) sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) has title (A: %u H: %u) only for one from teams.", entry, reward.titleId[0], reward.titleId[1]); - // must be title or mail at least if (!reward.titleId[0] && !reward.titleId[1] && !reward.sender) { sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) not have title or item reward data, ignore.", entry); continue; } - if (reward.titleId[0]) { CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(reward.titleId[0]); @@ -2123,7 +1883,6 @@ void AchievementGlobalMgr::LoadRewards() reward.titleId[0] = 0; } } - if (reward.titleId[1]) { CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(reward.titleId[1]); @@ -2133,7 +1892,6 @@ void AchievementGlobalMgr::LoadRewards() reward.titleId[1] = 0; } } - //check mail data before item for report including wrong item case if (reward.sender) { @@ -2147,14 +1905,11 @@ void AchievementGlobalMgr::LoadRewards() { if (reward.itemId) sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) not have sender data but have item reward, item will not rewarded", entry); - if (!reward.subject.empty()) sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) not have sender data but have mail subject.", entry); - if (!reward.text.empty()) sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) not have sender data but have mail text.", entry); } - if (reward.itemId) { if (!objmgr.GetItemPrototype(reward.itemId)) @@ -2163,52 +1918,37 @@ void AchievementGlobalMgr::LoadRewards() reward.itemId = 0; } } - m_achievementRewards[entry] = reward; ++count; - } while (result->NextRow()); - delete result; - sLog.outString(); sLog.outString( ">> Loaded %u achievement rewards", count ); } - void AchievementGlobalMgr::LoadRewardLocales() { m_achievementRewardLocales.clear(); // need for reload case - QueryResult *result = WorldDatabase.Query("SELECT entry,subject_loc1,text_loc1,subject_loc2,text_loc2,subject_loc3,text_loc3,subject_loc4,text_loc4,subject_loc5,text_loc5,subject_loc6,text_loc6,subject_loc7,text_loc7,subject_loc8,text_loc8 FROM locales_achievement_reward"); - if(!result) { barGoLink bar(1); - bar.step(); - sLog.outString(); sLog.outString(">> Loaded 0 achievement reward locale strings. DB table `locales_achievement_reward` is empty."); return; } - barGoLink bar(result->GetRowCount()); - do { Field *fields = result->Fetch(); bar.step(); - uint32 entry = fields[0].GetUInt32(); - if(m_achievementRewards.find(entry)==m_achievementRewards.end()) { sLog.outErrorDb( "Table `locales_achievement_reward` (Entry: %u) has locale strings for not existed achievement reward .", entry); continue; } - AchievementRewardLocale& data = m_achievementRewardLocales[entry]; - for(int i = 1; i < MAX_LOCALE; ++i) { std::string str = fields[1+2*(i-1)].GetCppString(); @@ -2219,7 +1959,6 @@ void AchievementGlobalMgr::LoadRewardLocales() { if(data.subject.size() <= size_t(idx)) data.subject.resize(idx+1); - data.subject[idx] = str; } } @@ -2231,16 +1970,13 @@ void AchievementGlobalMgr::LoadRewardLocales() { if(data.text.size() <= size_t(idx)) data.text.resize(idx+1); - data.text[idx] = str; } } } } while (result->NextRow()); - delete result; - sLog.outString(); sLog.outString( ">> Loaded %lu achievement reward locale strings", (unsigned long)m_achievementRewardLocales.size() ); } diff --git a/src/game/AchievementMgr.h b/src/game/AchievementMgr.h index 5020539bb5c..2a2f02e243f 100644 --- a/src/game/AchievementMgr.h +++ b/src/game/AchievementMgr.h @@ -17,29 +17,23 @@ */ #ifndef __MANGOS_ACHIEVEMENTMGR_H #define __MANGOS_ACHIEVEMENTMGR_H - #include #include - #include "Common.h" #include "Policies/Singleton.h" #include "Database/DatabaseEnv.h" #include "DBCEnums.h" #include "DBCStores.h" - typedef std::list AchievementCriteriaEntryList; typedef std::list AchievementEntryList; - typedef std::map AchievementCriteriaListByAchievement; typedef std::map AchievementListByReferencedId; - struct CriteriaProgress { uint32 counter; time_t date; bool changed; }; - enum AchievementCriteriaDataType { // value1 value2 comment ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE = 0, // 0 0 @@ -61,12 +55,9 @@ enum AchievementCriteriaDataType ACHIEVEMENT_CRITERIA_DATA_TYPE_HOLIDAY = 16,// holiday_id 0 event in holiday time ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_LOSS_TEAM_SCORE = 17,// min_score max_score player's team win bg and opposition team have team score in range }; - #define MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE 18 // maximum value in AchievementCriteriaDataType enum - class Player; class Unit; - struct AchievementCriteriaData { AchievementCriteriaDataType dataType; @@ -160,23 +151,19 @@ struct AchievementCriteriaData uint32 value2; } raw; }; - AchievementCriteriaData() : dataType(ACHIEVEMENT_CRITERIA_DATA_TYPE_NONE) { raw.value1 = 0; raw.value2 = 0; } - AchievementCriteriaData(uint32 _dataType, uint32 _value1, uint32 _value2) : dataType(AchievementCriteriaDataType(_dataType)) { raw.value1 = _value1; raw.value2 = _value2; } - bool IsValid(AchievementCriteriaEntry const* criteria); bool Meets(Player const* source, Unit const* target, uint32 miscvalue1 = 0) const; }; - struct AchievementCriteriaDataSet { typedef std::vector Storage; @@ -186,9 +173,7 @@ struct AchievementCriteriaDataSet Storage storage; }; - typedef std::map AchievementCriteriaDataMap; - struct AchievementReward { uint32 titleId[2]; @@ -197,37 +182,29 @@ struct AchievementReward std::string subject; std::string text; }; - typedef std::map AchievementRewards; - struct AchievementRewardLocale { std::vector subject; std::vector text; }; - typedef std::map AchievementRewardLocales; - struct CompletedAchievementData { time_t date; bool changed; }; - typedef UNORDERED_MAP CriteriaProgressMap; typedef UNORDERED_MAP CompletedAchievementMap; - class Unit; class Player; class WorldPacket; - class AchievementMgr { public: AchievementMgr(Player* pl); ~AchievementMgr(); - void Reset(); static void DeleteFromDB(uint32 lowguid); void LoadFromDB(QueryResult *achievementResult, QueryResult *criteriaResult); @@ -239,7 +216,6 @@ class AchievementMgr void SendAllAchievementData(); void SendRespondInspectAchievements(Player* player); Player* GetPlayer() { return m_player;} - private: enum ProgressType { PROGRESS_SET, PROGRESS_ACCUMULATE, PROGRESS_HIGHEST }; void SendAchievementEarned(AchievementEntry const* achievement); @@ -250,12 +226,10 @@ class AchievementMgr bool IsCompletedAchievement(AchievementEntry const* entry); void CompleteAchievementsWithRefs(AchievementEntry const* entry); void BuildAllDataPacket(WorldPacket *data); - Player* m_player; CriteriaProgressMap m_criteriaProgress; CompletedAchievementMap m_completedAchievements; }; - class AchievementGlobalMgr { public: @@ -265,41 +239,34 @@ class AchievementGlobalMgr AchievementCriteriaListByAchievement::const_iterator itr = m_AchievementCriteriaListByAchievement.find(id); return itr != m_AchievementCriteriaListByAchievement.end() ? &itr->second : NULL; } - AchievementEntryList const* GetAchievementByReferencedId(uint32 id) const { AchievementListByReferencedId::const_iterator itr = m_AchievementListByReferencedId.find(id); return itr != m_AchievementListByReferencedId.end() ? &itr->second : NULL; } - AchievementReward const* GetAchievementReward(AchievementEntry const* achievement) const { AchievementRewards::const_iterator iter = m_achievementRewards.find(achievement->ID); return iter!=m_achievementRewards.end() ? &iter->second : NULL; } - AchievementRewardLocale const* GetAchievementRewardLocale(AchievementEntry const* achievement) const { AchievementRewardLocales::const_iterator iter = m_achievementRewardLocales.find(achievement->ID); return iter!=m_achievementRewardLocales.end() ? &iter->second : NULL; } - AchievementCriteriaDataSet const* GetCriteriaDataSet(AchievementCriteriaEntry const *achievementCriteria) { AchievementCriteriaDataMap::const_iterator iter = m_criteriaDataMap.find(achievementCriteria->ID); return iter!=m_criteriaDataMap.end() ? &iter->second : NULL; } - bool IsRealmCompleted(AchievementEntry const* achievement) const { return m_allCompletedAchievements.find(achievement->ID) != m_allCompletedAchievements.end(); } - void SetRealmCompleted(AchievementEntry const* achievement) { m_allCompletedAchievements.insert(achievement->ID); } - void LoadAchievementCriteriaList(); void LoadAchievementCriteriaData(); void LoadAchievementReferenceList(); @@ -308,21 +275,16 @@ class AchievementGlobalMgr void LoadRewardLocales(); private: AchievementCriteriaDataMap m_criteriaDataMap; - // store achievement criterias by type to speed up lookup AchievementCriteriaEntryList m_AchievementCriteriasByType[ACHIEVEMENT_CRITERIA_TYPE_TOTAL]; // store achievement criterias by achievement to speed up lookup AchievementCriteriaListByAchievement m_AchievementCriteriaListByAchievement; // store achievements by referenced achievement id to speed up lookup AchievementListByReferencedId m_AchievementListByReferencedId; - typedef std::set AllCompletedAchievements; AllCompletedAchievements m_allCompletedAchievements; - AchievementRewards m_achievementRewards; AchievementRewardLocales m_achievementRewardLocales; }; - #define achievementmgr Trinity::Singleton::Instance() - #endif diff --git a/src/game/AnimalRandomMovementGenerator.h b/src/game/AnimalRandomMovementGenerator.h index 9c64edcaa44..4767eff91ad 100644 --- a/src/game/AnimalRandomMovementGenerator.h +++ b/src/game/AnimalRandomMovementGenerator.h @@ -17,10 +17,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef TRINITY_ANIMAL_RANDOMMOVEMENTGENERATOR_H #define TRINITY_ANIMAL_RANDOMMOVEMENTGENERATOR_H - /** AnimalRandomMovementGenerator follows the research on * quantifying scale-dependant effects of animal movement * with simple per-location models (R.H. Gardner, R.V. O'Neil, diff --git a/src/game/ArenaTeam.cpp b/src/game/ArenaTeam.cpp index 22d121c38c1..c00c22b7b48 100644 --- a/src/game/ArenaTeam.cpp +++ b/src/game/ArenaTeam.cpp @@ -15,13 +15,10 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "ObjectMgr.h" #include "WorldPacket.h" - #include "ArenaTeam.h" #include "World.h" - void ArenaTeamMember::ModifyPersonalRating(Player* plr, int32 mod, uint32 slot) { int32 memberRating = int32(personal_rating) + mod; @@ -30,7 +27,6 @@ void ArenaTeamMember::ModifyPersonalRating(Player* plr, int32 mod, uint32 slot) plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot*6) + 5, personal_rating); //sLog.outArena("Modify personal rating for player %s: personal rating %u, mod %d, rating %d", plr->GetName(), personal_rating, mod, rating); } - ArenaTeam::ArenaTeam() { m_TeamId = 0; @@ -52,29 +48,22 @@ ArenaTeam::ArenaTeam() m_stats.wins_week = 0; m_stats.wins_season = 0; } - ArenaTeam::~ArenaTeam() { } - bool ArenaTeam::Create(uint64 captainGuid, uint32 type, std::string ArenaTeamName) { if(!objmgr.GetPlayer(captainGuid)) // player not exist return false; if(objmgr.GetArenaTeamByName(ArenaTeamName)) // arena team with this name already exist return false; - sLog.outDebug("GUILD: creating arena team %s to leader: %u", ArenaTeamName.c_str(), GUID_LOPART(captainGuid)); - m_CaptainGuid = captainGuid; m_Name = ArenaTeamName; m_Type = type; - m_TeamId = objmgr.GenerateArenaTeamId(); - // ArenaTeamName already assigned to ArenaTeam::name, use it to encode string for DB CharacterDatabase.escape_string(ArenaTeamName); - CharacterDatabase.BeginTransaction(); // CharacterDatabase.PExecute("DELETE FROM arena_team WHERE arenateamid='%u'", m_TeamId); - MAX(arenateam)+1 not exist CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid='%u'", m_TeamId); @@ -83,23 +72,18 @@ bool ArenaTeam::Create(uint64 captainGuid, uint32 type, std::string ArenaTeamNam m_TeamId, ArenaTeamName.c_str(), GUID_LOPART(m_CaptainGuid), m_Type, m_BackgroundColor, m_EmblemStyle, m_EmblemColor, m_BorderStyle, m_BorderColor); CharacterDatabase.PExecute("INSERT INTO arena_team_stats (arenateamid, rating, games, wins, played, wins2, rank) VALUES " "('%u', '%u', '%u', '%u', '%u', '%u', '%u')", m_TeamId, m_stats.rating, m_stats.games_week, m_stats.wins_week, m_stats.games_season, m_stats.wins_season, m_stats.rank); - CharacterDatabase.CommitTransaction(); - AddMember(m_CaptainGuid); sLog.outArena("New ArenaTeam created [Id: %u] [Type: %u] [Captain GUID: %u]", GetId(), GetType(), GetCaptain()); return true; } - bool ArenaTeam::AddMember(const uint64& PlayerGuid) { std::string plName; uint8 plClass; - // arena team is full (can't have more than type * 2 players!) if(GetMembersSize() >= GetType() * 2) return false; - Player *pl = objmgr.GetPlayer(PlayerGuid); if(pl) { @@ -108,7 +92,6 @@ bool ArenaTeam::AddMember(const uint64& PlayerGuid) sLog.outError("Arena::AddMember() : player already in this sized team"); return false; } - plClass = (uint8)pl->getClass(); plName = pl->GetName(); } @@ -118,11 +101,9 @@ bool ArenaTeam::AddMember(const uint64& PlayerGuid) QueryResult *result = CharacterDatabase.PQuery("SELECT name, class FROM characters WHERE guid='%u'", GUID_LOPART(PlayerGuid)); if(!result) return false; - plName = (*result)[0].GetCppString(); plClass = (*result)[1].GetUInt8(); delete result; - // check if player already in arenateam of that size if(Player::GetArenaTeamIdFromDB(PlayerGuid, GetType()) != 0) { @@ -130,11 +111,9 @@ bool ArenaTeam::AddMember(const uint64& PlayerGuid) return false; } } - // remove all player signs from another petitions // this will be prevent attempt joining player to many arenateams and corrupt arena team data integrity Player::RemovePetitionsAndSigns(PlayerGuid, GetType()); - ArenaTeamMember newmember; newmember.name = plName; newmember.guid = PlayerGuid; @@ -155,15 +134,12 @@ bool ArenaTeam::AddMember(const uint64& PlayerGuid) newmember.personal_rating = 1500; } m_members.push_back(newmember); - CharacterDatabase.PExecute("INSERT INTO arena_team_member (arenateamid, guid, personal_rating) VALUES ('%u', '%u', '%u')", m_TeamId, GUID_LOPART(newmember.guid), newmember.personal_rating ); - if(pl) { pl->SetInArenaTeam(m_TeamId, GetSlot()); pl->SetArenaTeamIdInvited(0); pl->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot()*6) + 5, newmember.personal_rating ); - // hide promote/remove buttons if(m_CaptainGuid != PlayerGuid) pl->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6) + 1, 1); @@ -171,16 +147,12 @@ bool ArenaTeam::AddMember(const uint64& PlayerGuid) } return true; } - bool ArenaTeam::LoadArenaTeamFromDB(uint32 ArenaTeamId) { QueryResult *result = CharacterDatabase.PQuery("SELECT arenateamid,name,captainguid,type,BackgroundColor,EmblemStyle,EmblemColor,BorderStyle,BorderColor FROM arena_team WHERE arenateamid = '%u'", ArenaTeamId); - if(!result) return false; - Field *fields = result->Fetch(); - m_TeamId = fields[0].GetUInt32(); m_Name = fields[1].GetCppString(); m_CaptainGuid = MAKE_NEW_GUID(fields[2].GetUInt32(), 0, HIGHGUID_PLAYER); @@ -190,13 +162,10 @@ bool ArenaTeam::LoadArenaTeamFromDB(uint32 ArenaTeamId) m_EmblemColor = fields[6].GetUInt32(); m_BorderStyle = fields[7].GetUInt32(); m_BorderColor = fields[8].GetUInt32(); - delete result; - // only load here, so additional checks can be made LoadStatsFromDB(ArenaTeamId); LoadMembersFromDB(ArenaTeamId); - if(Empty()) { // arena team is empty, delete from db @@ -207,30 +176,23 @@ bool ArenaTeam::LoadArenaTeamFromDB(uint32 ArenaTeamId) CharacterDatabase.CommitTransaction(); return false; } - return true; } - void ArenaTeam::LoadStatsFromDB(uint32 ArenaTeamId) { // 0 1 2 3 4 5 QueryResult *result = CharacterDatabase.PQuery("SELECT rating,games,wins,played,wins2,rank FROM arena_team_stats WHERE arenateamid = '%u'", ArenaTeamId); - if(!result) return; - Field *fields = result->Fetch(); - m_stats.rating = fields[0].GetUInt32(); m_stats.games_week = fields[1].GetUInt32(); m_stats.wins_week = fields[2].GetUInt32(); m_stats.games_season = fields[3].GetUInt32(); m_stats.wins_season = fields[4].GetUInt32(); m_stats.rank = fields[5].GetUInt32(); - delete result; } - void ArenaTeam::LoadMembersFromDB(uint32 ArenaTeamId) { // 0 1 2 3 4 5 6 7 @@ -240,7 +202,6 @@ void ArenaTeam::LoadMembersFromDB(uint32 ArenaTeamId) "WHERE member.arenateamid = '%u'", ArenaTeamId); if(!result) return; - do { Field *fields = result->Fetch(); @@ -257,20 +218,16 @@ void ArenaTeam::LoadMembersFromDB(uint32 ArenaTeamId) }while( result->NextRow() ); delete result; } - void ArenaTeam::SetCaptain(const uint64& guid) { // disable remove/promote buttons Player *oldcaptain = objmgr.GetPlayer(GetCaptain()); if(oldcaptain) oldcaptain->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 1); - // set new captain m_CaptainGuid = guid; - // update database CharacterDatabase.PExecute("UPDATE arena_team SET captainguid = '%u' WHERE arenateamid = '%u'", GUID_LOPART(guid), m_TeamId); - // enable remove/promote buttons Player *newcaptain = objmgr.GetPlayer(guid); if(newcaptain) @@ -279,7 +236,6 @@ void ArenaTeam::SetCaptain(const uint64& guid) sLog.outArena("Player: %s [GUID: %u] promoted player: %s [GUID: %u] to leader of arena team [Id: %u] [Type: %u].", oldcaptain->GetName(), oldcaptain->GetGUIDLow(), newcaptain->GetName(), newcaptain->GetGUID(), GetId(), GetType()); } } - void ArenaTeam::DelMember(uint64 guid) { for (MemberList::iterator itr = m_members.begin(); itr != m_members.end(); ++itr) @@ -290,9 +246,7 @@ void ArenaTeam::DelMember(uint64 guid) break; } } - Player *player = objmgr.GetPlayer(guid); - if(player) { player->SetInArenaTeam(0, GetSlot()); @@ -306,23 +260,19 @@ void ArenaTeam::DelMember(uint64 guid) } CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid = '%u' AND guid = '%u'", GetId(), GUID_LOPART(guid)); } - void ArenaTeam::Disband(WorldSession *session) { // event WorldPacket data; session->BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_DISBANDED_S, 2, session->GetPlayerName(), GetName(), ""); BroadcastPacket(&data); - while (!m_members.empty()) { // Removing from members is done in DelMember. DelMember(m_members.front().guid); } - if(Player *player = session->GetPlayer()) sLog.outArena("Player: %s [GUID: %u] disbanded arena team type: %u [Id: %u].", player->GetName(), player->GetGUIDLow(), GetType(), GetId()); - CharacterDatabase.BeginTransaction(); CharacterDatabase.PExecute("DELETE FROM arena_team WHERE arenateamid = '%u'", m_TeamId); CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid = '%u'", m_TeamId); //< this should be alredy done by calling DelMember(memberGuids[j]); for each member @@ -330,23 +280,18 @@ void ArenaTeam::Disband(WorldSession *session) CharacterDatabase.CommitTransaction(); objmgr.RemoveArenaTeam(m_TeamId); } - void ArenaTeam::Roster(WorldSession *session) { Player *pl = NULL; - uint8 unk308 = 0; - WorldPacket data(SMSG_ARENA_TEAM_ROSTER, 100); data << uint32(GetId()); // team id data << uint8(unk308); // 308 unknown value but affect packet structure data << uint32(GetMembersSize()); // members count data << uint32(GetType()); // arena team type? - for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) { pl = objmgr.GetPlayer(itr->guid); - data << uint64(itr->guid); // guid data << uint8((pl ? 1 : 0)); // online flag data << itr->name; // member name @@ -364,11 +309,9 @@ void ArenaTeam::Roster(WorldSession *session) data << float(0.0); // 308 unk } } - session->SendPacket(&data); sLog.outDebug("WORLD: Sent SMSG_ARENA_TEAM_ROSTER"); } - void ArenaTeam::Query(WorldSession *session) { WorldPacket data(SMSG_ARENA_TEAM_QUERY_RESPONSE, 4*7+GetName().size()+1); @@ -383,7 +326,6 @@ void ArenaTeam::Query(WorldSession *session) session->SendPacket(&data); sLog.outDebug("WORLD: Sent SMSG_ARENA_TEAM_QUERY_RESPONSE"); } - void ArenaTeam::Stats(WorldSession *session) { WorldPacket data(SMSG_ARENA_TEAM_STATS, 4*7); @@ -396,7 +338,6 @@ void ArenaTeam::Stats(WorldSession *session) data << uint32(m_stats.rank); // rank session->SendPacket(&data); } - void ArenaTeam::NotifyStatsChanged() { // this is called after a rated match ended @@ -408,13 +349,11 @@ void ArenaTeam::NotifyStatsChanged() Stats(plr->GetSession()); } } - void ArenaTeam::InspectStats(WorldSession *session, uint64 guid) { ArenaTeamMember* member = GetMember(guid); if(!member) return; - WorldPacket data(MSG_INSPECT_ARENA_TEAMS, 8+1+4*6); data << uint64(guid); // player guid data << uint8(GetSlot()); // slot (0...2) @@ -426,7 +365,6 @@ void ArenaTeam::InspectStats(WorldSession *session, uint64 guid) data << uint32(member->personal_rating); // personal rating session->SendPacket(&data); } - void ArenaTeam::SetEmblem(uint32 backgroundColor, uint32 emblemStyle, uint32 emblemColor, uint32 borderStyle, uint32 borderColor) { m_BackgroundColor = backgroundColor; @@ -434,10 +372,8 @@ void ArenaTeam::SetEmblem(uint32 backgroundColor, uint32 emblemStyle, uint32 emb m_EmblemColor = emblemColor; m_BorderStyle = borderStyle; m_BorderColor = borderColor; - CharacterDatabase.PExecute("UPDATE arena_team SET BackgroundColor='%u', EmblemStyle='%u', EmblemColor='%u', BorderStyle='%u', BorderColor='%u' WHERE arenateamid='%u'", m_BackgroundColor, m_EmblemStyle, m_EmblemColor, m_BorderStyle, m_BorderColor, m_TeamId); } - void ArenaTeam::SetStats(uint32 stat_type, uint32 value) { switch(stat_type) @@ -471,7 +407,6 @@ void ArenaTeam::SetStats(uint32 stat_type, uint32 value) break; } } - void ArenaTeam::BroadcastPacket(WorldPacket *packet) { for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) @@ -481,7 +416,6 @@ void ArenaTeam::BroadcastPacket(WorldPacket *packet) player->GetSession()->SendPacket(packet); } } - uint8 ArenaTeam::GetSlotByType( uint32 type ) { switch(type) @@ -495,56 +429,45 @@ uint8 ArenaTeam::GetSlotByType( uint32 type ) sLog.outError("FATAL: Unknown arena team type %u for some arena team", type); return 0xFF; } - bool ArenaTeam::HaveMember( const uint64& guid ) const { for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) if(itr->guid == guid) return true; - return false; } - uint32 ArenaTeam::GetPoints(uint32 MemberRating) { // returns how many points would be awarded with this team type with this rating float points; - uint32 rating = MemberRating + 150 < m_stats.rating ? MemberRating : m_stats.rating; - if(rating<=1500) // points = (float)1500 * 0.22f + 14.0f; points = 344.0f; // 3.1 change - teams with rating below 1500 get arena points for 1500 rating else points = 1511.26f / (1.0f + 1639.28f * exp(-0.00412f * (float)rating)); - // type penalties for <5v5 teams if(m_Type == ARENA_TEAM_2v2) points *= 0.76f; else if(m_Type == ARENA_TEAM_3v3) points *= 0.88f; - return (uint32) points; } - float ArenaTeam::GetChanceAgainst(uint32 own_rating, uint32 enemy_rating) { // returns the chance to win against a team with the given rating, used in the rating adjustment calculation // ELO system - if (sWorld.getConfig(CONFIG_ARENA_SEASON_ID) >= 6) if (enemy_rating < 1300) enemy_rating = 1300; return 1.0f/(1.0f+exp(log(10.0f)*(float)((float)enemy_rating - (float)own_rating)/400.0f)); } - void ArenaTeam::FinishGame(int32 mod) { if (int32(m_stats.rating) + mod < 0) m_stats.rating = 0; else m_stats.rating += mod; - m_stats.games_week += 1; m_stats.games_season += 1; // update team's rank @@ -556,7 +479,6 @@ void ArenaTeam::FinishGame(int32 mod) ++m_stats.rank; } } - int32 ArenaTeam::WonAgainst(uint32 againstRating) { // called when the team has won @@ -568,11 +490,9 @@ int32 ArenaTeam::WonAgainst(uint32 againstRating) FinishGame(mod); m_stats.wins_week += 1; m_stats.wins_season += 1; - // return the rating change, used to display it on the results screen return mod; } - int32 ArenaTeam::LostAgainst(uint32 againstRating) { // called when the team has lost @@ -582,11 +502,9 @@ int32 ArenaTeam::LostAgainst(uint32 againstRating) int32 mod = (int32)ceil(32.0f * (0.0f - chance)); // modify the team stats accordingly FinishGame(mod); - // return the rating change, used to display it on the results screen return mod; } - void ArenaTeam::MemberLost(Player * plr, uint32 againstRating) { // called for each participant of a match after losing @@ -608,7 +526,6 @@ void ArenaTeam::MemberLost(Player * plr, uint32 againstRating) } } } - void ArenaTeam::OfflineMemberLost(uint64 guid, uint32 againstRating) { // called for offline player after ending rated arena match! @@ -630,7 +547,6 @@ void ArenaTeam::OfflineMemberLost(uint64 guid, uint32 againstRating) } } } - void ArenaTeam::MemberWon(Player * plr, uint32 againstRating) { // called for each participant after winning a match @@ -654,7 +570,6 @@ void ArenaTeam::MemberWon(Player * plr, uint32 againstRating) } } } - void ArenaTeam::UpdateArenaPointsHelper(std::map& PlayerPoints) { // called after a match has ended and the stats are already modified @@ -671,7 +586,6 @@ void ArenaTeam::UpdateArenaPointsHelper(std::map& PlayerPoints) if (itr->games_week >= min_plays) points_to_add = GetPoints(itr->personal_rating); // OBSOLETE : CharacterDatabase.PExecute("UPDATE arena_team_member SET points_to_add = '%u' WHERE arenateamid = '%u' AND guid = '%u'", points_to_add, m_TeamId, itr->guid); - std::map::iterator plr_itr = PlayerPoints.find(GUID_LOPART(itr->guid)); if (plr_itr != PlayerPoints.end()) { @@ -683,7 +597,6 @@ void ArenaTeam::UpdateArenaPointsHelper(std::map& PlayerPoints) PlayerPoints[GUID_LOPART(itr->guid)] = points_to_add; } } - void ArenaTeam::SaveToDB() { // save team and member stats to db @@ -696,7 +609,6 @@ void ArenaTeam::SaveToDB() } CharacterDatabase.CommitTransaction(); } - void ArenaTeam::FinishWeek() { m_stats.games_week = 0; // played this week @@ -707,7 +619,6 @@ void ArenaTeam::FinishWeek() itr->wins_week = 0; } } - bool ArenaTeam::IsFighting() const { for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) @@ -720,7 +631,6 @@ bool ArenaTeam::IsFighting() const } return false; } - /* arenateam fields (id from 2.3.3 client): 1414 - arena team id 2v2 diff --git a/src/game/ArenaTeam.h b/src/game/ArenaTeam.h index dbeac2f09f0..fe7a4d04ea5 100644 --- a/src/game/ArenaTeam.h +++ b/src/game/ArenaTeam.h @@ -17,10 +17,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef TRINITYCORE_ARENATEAM_H #define TRINITYCORE_ARENATEAM_H - enum ArenaTeamCommandTypes { ERR_ARENA_TEAM_CREATE_S = 0x00, @@ -29,7 +27,6 @@ enum ArenaTeamCommandTypes ERR_ARENA_TEAM_QUIT_S = 0x03, ERR_ARENA_TEAM_FOUNDER_S = 0x0C // need check, probably wrong... }; - enum ArenaTeamCommandErrors { //ARENA_TEAM_PLAYER_NO_MORE_IN_ARENA_TEAM = 0x00, @@ -49,7 +46,6 @@ enum ArenaTeamCommandErrors ERR_ARENA_TEAM_PLAYER_TO_LOW = 0x15, ERR_ARENA_TEAM_FULL = 0x16 }; - enum ArenaTeamEvents { ERR_ARENA_TEAM_JOIN_SS = 3, // player name + arena team name @@ -59,7 +55,6 @@ enum ArenaTeamEvents ERR_ARENA_TEAM_LEADER_CHANGED_SSS = 7, // old captain + new captain + arena team name ERR_ARENA_TEAM_DISBANDED_S = 8 // captain name + arena team name }; - /* need info how to send these ones: ERR_ARENA_TEAM_YOU_JOIN_S - client show it automatically when accept invite @@ -67,7 +62,6 @@ ERR_ARENA_TEAM_TARGET_TOO_LOW_S ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S ERR_ARENA_TEAM_LEVEL_TOO_LOW_I */ - enum ArenaTeamStatTypes { STAT_TYPE_RATING = 0, @@ -77,14 +71,12 @@ enum ArenaTeamStatTypes STAT_TYPE_WINS_SEASON = 4, STAT_TYPE_RANK = 5 }; - enum ArenaTeamTypes { ARENA_TEAM_2v2 = 2, ARENA_TEAM_3v3 = 3, ARENA_TEAM_5v5 = 5 }; - struct ArenaTeamMember { uint64 guid; @@ -95,10 +87,8 @@ struct ArenaTeamMember uint32 games_season; uint32 wins_season; uint32 personal_rating; - void ModifyPersonalRating(Player* plr, int32 mod, uint32 slot); }; - struct ArenaTeamStats { uint32 rating; @@ -108,20 +98,15 @@ struct ArenaTeamStats uint32 wins_season; uint32 rank; }; - #define MAX_ARENA_SLOT 3 // 0..2 slots - class ArenaTeam { public: ArenaTeam(); ~ArenaTeam(); - bool Create(uint64 captainGuid, uint32 type, std::string ArenaTeamName); void Disband(WorldSession *session); - typedef std::list MemberList; - uint32 GetId() const { return m_TeamId; } uint32 GetType() const { return m_Type; } uint8 GetSlot() const { return GetSlotByType(GetType()); } @@ -131,61 +116,46 @@ class ArenaTeam const ArenaTeamStats& GetStats() const { return m_stats; } void SetStats(uint32 stat_type, uint32 value); uint32 GetRating() const { return m_stats.rating; } - uint32 GetEmblemStyle() const { return m_EmblemStyle; } uint32 GetEmblemColor() const { return m_EmblemColor; } uint32 GetBorderStyle() const { return m_BorderStyle; } uint32 GetBorderColor() const { return m_BorderColor; } uint32 GetBackgroundColor() const { return m_BackgroundColor; } - void SetCaptain(const uint64& guid); bool AddMember(const uint64& PlayerGuid); - // Shouldn't be const uint64& ed, because than can reference guid from members on Disband // and this method removes given record from list. So invalid reference can happen. void DelMember(uint64 guid); - void SetEmblem(uint32 backgroundColor, uint32 emblemStyle, uint32 emblemColor, uint32 borderStyle, uint32 borderColor); - size_t GetMembersSize() const { return m_members.size(); } bool Empty() const { return m_members.empty(); } MemberList::iterator m_membersBegin() { return m_members.begin(); } MemberList::iterator m_membersEnd() { return m_members.end(); } bool HaveMember(const uint64& guid) const; - ArenaTeamMember* GetMember(const uint64& guid) { for (MemberList::iterator itr = m_members.begin(); itr != m_members.end(); ++itr) if(itr->guid == guid) return &(*itr); - return NULL; } - ArenaTeamMember* GetMember(const std::string& name) { for (MemberList::iterator itr = m_members.begin(); itr != m_members.end(); ++itr) if(itr->name == name) return &(*itr); - return NULL; } - bool IsFighting() const; - bool LoadArenaTeamFromDB(uint32 ArenaTeamId); void LoadMembersFromDB(uint32 ArenaTeamId); void LoadStatsFromDB(uint32 ArenaTeamId); - void SaveToDB(); - void BroadcastPacket(WorldPacket *packet); - void Roster(WorldSession *session); void Query(WorldSession *session); void Stats(WorldSession *session); void InspectStats(WorldSession *session, uint64 guid); - uint32 GetPoints(uint32 MemberRating); float GetChanceAgainst(uint32 own_rating, uint32 enemy_rating); int32 WonAgainst(uint32 againstRating); @@ -193,27 +163,20 @@ class ArenaTeam int32 LostAgainst(uint32 againstRating); void MemberLost(Player * plr, uint32 againstRating); void OfflineMemberLost(uint64 guid, uint32 againstRating); - void UpdateArenaPointsHelper(std::map & PlayerPoints); - void NotifyStatsChanged(); - void FinishWeek(); void FinishGame(int32 mod); - protected: - uint32 m_TeamId; uint32 m_Type; std::string m_Name; uint64 m_CaptainGuid; - uint32 m_BackgroundColor; // ARGB format uint32 m_EmblemStyle; // icon id uint32 m_EmblemColor; // ARGB format uint32 m_BorderStyle; // border image id uint32 m_BorderColor; // ARGB format - MemberList m_members; ArenaTeamStats m_stats; }; diff --git a/src/game/ArenaTeamHandler.cpp b/src/game/ArenaTeamHandler.cpp index c7ecf5b1d80..b5ecab3d424 100644 --- a/src/game/ArenaTeamHandler.cpp +++ b/src/game/ArenaTeamHandler.cpp @@ -17,26 +17,21 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "Player.h" #include "World.h" #include "WorldPacket.h" #include "WorldSession.h" #include "Database/DatabaseEnv.h" - #include "ArenaTeam.h" #include "Log.h" #include "ObjectMgr.h" #include "SocialMgr.h" - void WorldSession::HandleInspectArenaTeamsOpcode(WorldPacket & recv_data) { sLog.outDebug("MSG_INSPECT_ARENA_TEAMS"); - uint64 guid; recv_data >> guid; sLog.outDebug("Inspect Arena stats (GUID: %u TypeId: %u)", GUID_LOPART(guid),GuidHigh2TypeId(GUID_HIPART(guid))); - if(Player *plr = objmgr.GetPlayer(guid)) { for (uint8 i = 0; i < MAX_ARENA_SLOT; ++i) @@ -49,160 +44,123 @@ void WorldSession::HandleInspectArenaTeamsOpcode(WorldPacket & recv_data) } } } - void WorldSession::HandleArenaTeamQueryOpcode(WorldPacket & recv_data) { sLog.outDebug( "WORLD: Received CMSG_ARENA_TEAM_QUERY" ); - uint32 ArenaTeamId; recv_data >> ArenaTeamId; - ArenaTeam *arenateam = objmgr.GetArenaTeamById(ArenaTeamId); if(!arenateam) // arena team not found return; - arenateam->Query(this); arenateam->Stats(this); } - void WorldSession::HandleArenaTeamRosterOpcode(WorldPacket & recv_data) { sLog.outDebug( "WORLD: Received CMSG_ARENA_TEAM_ROSTER" ); - uint32 ArenaTeamId; // arena team id recv_data >> ArenaTeamId; - ArenaTeam *arenateam = objmgr.GetArenaTeamById(ArenaTeamId); if(!arenateam) return; - arenateam->Roster(this); } - void WorldSession::HandleArenaTeamInviteOpcode(WorldPacket & recv_data) { sLog.outDebug("CMSG_ARENA_TEAM_INVITE"); - uint32 ArenaTeamId; // arena team id std::string Invitedname; - Player * player = NULL; - recv_data >> ArenaTeamId >> Invitedname; - if(!Invitedname.empty()) { if(!normalizePlayerName(Invitedname)) return; - player = ObjectAccessor::Instance().FindPlayerByName(Invitedname.c_str()); } - if(!player) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", Invitedname, ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S); return; } - if(player->getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", player->GetName(), ERR_ARENA_TEAM_PLAYER_TO_LOW); return; } - ArenaTeam *arenateam = objmgr.GetArenaTeamById(ArenaTeamId); if(!arenateam) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM); return; } - // OK result but not send invite if(player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) return; - if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && player->GetTeam() != GetPlayer()->GetTeam()) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_NOT_ALLIED); return; } - if(player->GetArenaTeamId(arenateam->GetSlot())) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", player->GetName(), ERR_ALREADY_IN_ARENA_TEAM_S); return; } - if(player->GetArenaTeamIdInvited()) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", player->GetName(), ERR_ALREADY_INVITED_TO_ARENA_TEAM_S); return; } - if(arenateam->GetMembersSize() >= arenateam->GetType() * 2) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S,arenateam->GetName(),"",ERR_ARENA_TEAM_FULL); return; } - sLog.outDebug("Player %s Invited %s to Join his ArenaTeam", GetPlayer()->GetName(), Invitedname.c_str()); - player->SetArenaTeamIdInvited(arenateam->GetId()); - WorldPacket data(SMSG_ARENA_TEAM_INVITE, (8+10)); data << GetPlayer()->GetName(); data << arenateam->GetName(); player->GetSession()->SendPacket(&data); - sLog.outDebug("WORLD: Sent SMSG_ARENA_TEAM_INVITE"); } - void WorldSession::HandleArenaTeamAcceptOpcode(WorldPacket & /*recv_data*/) { sLog.outDebug("CMSG_ARENA_TEAM_ACCEPT"); // empty opcode - ArenaTeam *at = objmgr.GetArenaTeamById(_player->GetArenaTeamIdInvited()); if(!at) return; - if(_player->GetArenaTeamId(at->GetSlot())) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S,"","",ERR_ALREADY_IN_ARENA_TEAM); // already in arena team that size return; } - if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && _player->GetTeam() != objmgr.GetPlayerTeamByGUID(at->GetCaptain())) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S,"","",ERR_ARENA_TEAM_NOT_ALLIED);// not let enemies sign petition return; } - if(!at->AddMember(_player->GetGUID())) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S,"","",ERR_ARENA_TEAM_INTERNAL);// arena team not found return; } - // event WorldPacket data; BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_JOIN_SS, 2, _player->GetName(), at->GetName(), ""); at->BroadcastPacket(&data); } - void WorldSession::HandleArenaTeamDeclineOpcode(WorldPacket & /*recv_data*/) { sLog.outDebug("CMSG_ARENA_TEAM_DECLINE"); // empty opcode - _player->SetArenaTeamIdInvited(0); // no more invited } - void WorldSession::HandleArenaTeamLeaveOpcode(WorldPacket & recv_data) { sLog.outDebug("CMSG_ARENA_TEAM_LEAVE"); - uint32 ArenaTeamId; // arena team id recv_data >> ArenaTeamId; - ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId); if(!at) return; @@ -219,124 +177,94 @@ void WorldSession::HandleArenaTeamLeaveOpcode(WorldPacket & recv_data) delete at; return; } - at->DelMember(_player->GetGUID()); - // event WorldPacket data; BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_LEAVE_SS, 2, _player->GetName(), at->GetName(), ""); at->BroadcastPacket(&data); - //send you are no longer member of team SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, at->GetName(), "", 0); } - void WorldSession::HandleArenaTeamDisbandOpcode(WorldPacket & recv_data) { sLog.outDebug("CMSG_ARENA_TEAM_DISBAND"); - uint32 ArenaTeamId; // arena team id recv_data >> ArenaTeamId; - ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId); if(!at) return; - if(at->GetCaptain() != _player->GetGUID()) return; - if (at->IsFighting()) return; - at->Disband(this); delete at; } - void WorldSession::HandleArenaTeamRemoveOpcode(WorldPacket & recv_data) { sLog.outDebug("CMSG_ARENA_TEAM_REMOVE"); - uint32 ArenaTeamId; std::string name; - recv_data >> ArenaTeamId; recv_data >> name; - ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId); if(!at) // arena team not found return; - if(at->GetCaptain() != _player->GetGUID()) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS); return; } - if(!normalizePlayerName(name)) return; - ArenaTeamMember* member = at->GetMember(name); if(!member) // member not found { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", name, ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S); return; } - if(at->GetCaptain() == member->guid) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, "", "", ERR_ARENA_TEAM_LEADER_LEAVE_S); return; } - at->DelMember(member->guid); - // event WorldPacket data; BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_REMOVE_SSS, 3, name, at->GetName(), _player->GetName()); at->BroadcastPacket(&data); } - void WorldSession::HandleArenaTeamLeaderOpcode(WorldPacket & recv_data) { sLog.outDebug("CMSG_ARENA_TEAM_LEADER"); - uint32 ArenaTeamId; std::string name; - recv_data >> ArenaTeamId; recv_data >> name; - ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId); if(!at) // arena team not found return; - if(at->GetCaptain() != _player->GetGUID()) { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS); return; } - if(!normalizePlayerName(name)) return; - ArenaTeamMember* member = at->GetMember(name); if(!member) // member not found { SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", name, ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S); return; } - if(at->GetCaptain() == member->guid) // target player already captain return; - at->SetCaptain(member->guid); - // event WorldPacket data; BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_LEADER_CHANGED_SSS, 3, _player->GetName(), name, at->GetName()); at->BroadcastPacket(&data); } - void WorldSession::SendArenaTeamCommandResult(uint32 team_action, const std::string& team, const std::string& player, uint32 error_id) { WorldPacket data(SMSG_ARENA_TEAM_COMMAND_RESULT, 4+team.length()+1+player.length()+1+4); @@ -346,7 +274,6 @@ void WorldSession::SendArenaTeamCommandResult(uint32 team_action, const std::str data << error_id; SendPacket(&data); } - void WorldSession::BuildArenaTeamEventPacket(WorldPacket *data, uint8 eventid, uint8 str_count, const std::string& str1, const std::string& str2, const std::string& str3) { data->Initialize(SMSG_ARENA_TEAM_EVENT, 1+1+1); @@ -371,7 +298,6 @@ void WorldSession::BuildArenaTeamEventPacket(WorldPacket *data, uint8 eventid, u return; } } - void WorldSession::SendNotInArenaTeamPacket(uint8 type) { WorldPacket data(SMSG_ARENA_ERROR, 4+1); // 886 - You are not in a %uv%u arena team @@ -381,15 +307,12 @@ void WorldSession::SendNotInArenaTeamPacket(uint8 type) data << uint8(type); // team type (2=2v2,3=3v3,5=5v5), can be used for custom types... SendPacket(&data); } - /* +ERR_ARENA_NO_TEAM_II "You are not in a %dv%d arena team" - +ERR_ARENA_TEAM_CREATE_S "%s created. To disband, use /teamdisband [2v2, 3v3, 5v5]." +ERR_ARENA_TEAM_INVITE_SS "You have invited %s to join %s" +ERR_ARENA_TEAM_QUIT_S "You are no longer a member of %s" ERR_ARENA_TEAM_FOUNDER_S "Congratulations, you are a founding member of %s! To leave, use /teamquit [2v2, 3v3, 5v5]." - +ERR_ARENA_TEAM_INTERNAL "Internal arena team error" +ERR_ALREADY_IN_ARENA_TEAM "You are already in an arena team of that size" +ERR_ALREADY_IN_ARENA_TEAM_S "%s is already in an arena team of that size" @@ -403,23 +326,15 @@ ERR_ARENA_TEAM_FOUNDER_S "Congratulations, you are a founding member of %s! To +ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM_SS "%s is not in %s" +ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S "\"%s\" not found" +ERR_ARENA_TEAM_NOT_ALLIED "You cannot invite players from the opposing alliance" - +ERR_ARENA_TEAM_JOIN_SS "%s has joined %s" +ERR_ARENA_TEAM_YOU_JOIN_S "You have joined %s. To leave, use /teamquit [2v2, 3v3, 5v5]." - +ERR_ARENA_TEAM_LEAVE_SS "%s has left %s" - +ERR_ARENA_TEAM_LEADER_IS_SS "%s is the captain of %s" +ERR_ARENA_TEAM_LEADER_CHANGED_SSS "%s has made %s the new captain of %s" - +ERR_ARENA_TEAM_REMOVE_SSS "%s has been kicked out of %s by %s" - +ERR_ARENA_TEAM_DISBANDED_S "%s has disbanded %s" - ERR_ARENA_TEAM_TARGET_TOO_LOW_S "%s is not high enough level to join your team" - ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S "%s is full" - ERR_ARENA_TEAM_LEVEL_TOO_LOW_I "You must be level %d to form an arena team" */ diff --git a/src/game/AuctionHouseBot.cpp b/src/game/AuctionHouseBot.cpp index cef09af8252..4722aace318 100644 --- a/src/game/AuctionHouseBot.cpp +++ b/src/game/AuctionHouseBot.cpp @@ -2,10 +2,8 @@ #include "AuctionHouseMgr.h" #include "AuctionHouseBot.h" #include - #include "Policies/SingletonImp.h" INSTANTIATE_SINGLETON_1(AuctionHouseBot); - using namespace std; vector npcItems; vector lootItems; @@ -29,22 +27,18 @@ AuctionHouseBot::AuctionHouseBot() debug_Out_Filters = false; AHBSeller = false; AHBBuyer = false; - //Begin Filters - Vendor_Items = false; Loot_Items = false; Other_Items = false; Vendor_TGs = false; Loot_TGs = false; Other_TGs = false; - No_Bind = false; Bind_When_Picked_Up = false; Bind_When_Equipped = false; Bind_When_Use = false; Bind_Quest_Item = false; - DisableBeta_PTR_Unused = false; DisablePermEnchant = false; #if CLIENT_VER > 300 @@ -57,7 +51,6 @@ AuctionHouseBot::AuctionHouseBot() DisableKeys = false; DisableDuration = false; DisableBOP_Or_Quest_NoReqLevel = false; - DisableWarriorItems = false; DisablePaladinItems = false; DisableHunterItems = false; @@ -69,7 +62,6 @@ AuctionHouseBot::AuctionHouseBot() DisableWarlockItems = false; DisableUnusedClassItems = false; DisableDruidItems = false; - DisableItemsBelowLevel = 0; DisableItemsAboveLevel = 0; DisableTGsBelowLevel = 0; @@ -86,22 +78,17 @@ AuctionHouseBot::AuctionHouseBot() DisableItemsAboveReqSkillRank = 0; DisableTGsBelowReqSkillRank = 0; DisableTGsAboveReqSkillRank = 0; - //End Filters - _lastrun_a = time(NULL); _lastrun_h = time(NULL); _lastrun_n = time(NULL); - AllianceConfig = AHBConfig(2); HordeConfig = AHBConfig(6); NeutralConfig = AHBConfig(7); } - AuctionHouseBot::~AuctionHouseBot() { } - void AuctionHouseBot::addNewAuctions(Player *AHBplayer, AHBConfig *config) { if (!AHBSeller) @@ -109,16 +96,13 @@ void AuctionHouseBot::addNewAuctions(Player *AHBplayer, AHBConfig *config) if (debug_Out) sLog.outError("AHSeller: Disabled"); return; } - uint32 minItems = config->GetMinItems(); uint32 maxItems = config->GetMaxItems(); - if (maxItems == 0) { //if (debug_Out) sLog.outString("AHSeller: Auctions disabled"); return; } - AuctionHouseEntry const* ahEntry = auctionmgr.GetAuctionHouseEntry(config->GetAHFID()); if (!ahEntry) { @@ -129,31 +113,24 @@ void AuctionHouseBot::addNewAuctions(Player *AHBplayer, AHBConfig *config) { return; } - uint32 auctions = auctionHouse->Getcount(); - if (auctions >= minItems) { //if (debug_Out) sLog.outString("AHSeller: Auctions above minimum"); return; } - if (auctions >= maxItems) { //if (debug_Out) sLog.outString("AHSeller: Auctions at or above maximum"); return; } - uint32 items = 0; if ((maxItems - auctions) >= ItemsPerCycle) items = ItemsPerCycle; else items = (maxItems - auctions); - if (debug_Out) sLog.outString("AHSeller: Adding %u Auctions", items); - uint32 AuctioneerGUID = 0; - switch (config->GetAHID()) { case 2: @@ -170,9 +147,7 @@ void AuctionHouseBot::addNewAuctions(Player *AHBplayer, AHBConfig *config) AuctioneerGUID = 23442; //default to neutral 7 break; } - if (debug_Out) sLog.outString("AHSeller: Current Auctineer GUID is %u", AuctioneerGUID); - uint32 greyTGcount = config->GetPercents(AHB_GREY_TG); uint32 whiteTGcount = config->GetPercents(AHB_WHITE_TG); uint32 greenTGcount = config->GetPercents(AHB_GREEN_TG); @@ -191,7 +166,6 @@ void AuctionHouseBot::addNewAuctions(Player *AHBplayer, AHBConfig *config) + purpleTGcount + orangeTGcount + yellowTGcount + whiteIcount + greenIcount + blueIcount + purpleIcount + orangeIcount + yellowIcount; - uint32 greyTGoods = config->GetItemCounts(AHB_GREY_TG); uint32 whiteTGoods = config->GetItemCounts(AHB_WHITE_TG); uint32 greenTGoods = config->GetItemCounts(AHB_GREEN_TG); @@ -199,7 +173,6 @@ void AuctionHouseBot::addNewAuctions(Player *AHBplayer, AHBConfig *config) uint32 purpleTGoods = config->GetItemCounts(AHB_PURPLE_TG); uint32 orangeTGoods = config->GetItemCounts(AHB_ORANGE_TG); uint32 yellowTGoods = config->GetItemCounts(AHB_YELLOW_TG); - uint32 greyItems = config->GetItemCounts(AHB_GREY_I); uint32 whiteItems = config->GetItemCounts(AHB_WHITE_I); uint32 greenItems = config->GetItemCounts(AHB_GREEN_I); @@ -208,7 +181,6 @@ void AuctionHouseBot::addNewAuctions(Player *AHBplayer, AHBConfig *config) uint32 orangeItems = config->GetItemCounts(AHB_ORANGE_I); uint32 yellowItems = config->GetItemCounts(AHB_YELLOW_I); if (debug_Out) sLog.outString("AHSeller: %u items", items); - // only insert a few at a time, so as not to peg the processor for (uint32 cnt = 1;cnt <= items;cnt++) { @@ -327,20 +299,17 @@ void AuctionHouseBot::addNewAuctions(Player *AHBplayer, AHBConfig *config) break; } } - if (itemID == 0) { if (debug_Out) sLog.outError("AHSeller: Item::CreateItem() - ItemID is 0"); continue; } - ItemPrototype const* prototype = objmgr.GetItemPrototype(itemID); if (prototype == NULL) { if (debug_Out) sLog.outError("AHSeller: Huh?!?! prototype == NULL"); continue; } - Item* item = Item::CreateItem(itemID, 1, AHBplayer); if (item == NULL) { @@ -348,15 +317,12 @@ void AuctionHouseBot::addNewAuctions(Player *AHBplayer, AHBConfig *config) break; } item->AddToUpdateQueueOf(AHBplayer); - uint32 randomPropertyId = Item::GenerateItemRandomPropertyId(itemID); if (randomPropertyId != 0) item->SetItemRandomProperties(randomPropertyId); - uint64 buyoutPrice = 0; uint64 bidPrice = 0; uint32 stackCount = 1; - switch (SellMethod) { case 0: @@ -366,7 +332,6 @@ void AuctionHouseBot::addNewAuctions(Player *AHBplayer, AHBConfig *config) buyoutPrice = prototype->BuyPrice; break; } - if ((prototype->Quality >= 0) && (prototype->Quality <= AHB_MAX_QUALITY)) { if (config->GetMaxStack(prototype->Quality) > 1 && item->GetMaxStackCount() > 1) @@ -387,7 +352,6 @@ void AuctionHouseBot::addNewAuctions(Player *AHBplayer, AHBConfig *config) item->RemoveFromUpdateQueueOf(AHBplayer); continue; } - uint32 etime = urand(1,3); switch(etime) { @@ -405,9 +369,7 @@ void AuctionHouseBot::addNewAuctions(Player *AHBplayer, AHBConfig *config) break; } item->SetCount(stackCount); - uint32 dep = auctionmgr.GetAuctionDeposit(ahEntry, etime, item); - AuctionEntry* auctionEntry = new AuctionEntry; auctionEntry->Id = objmgr.GenerateAuctionID(); auctionEntry->auctioneer = AuctioneerGUID; @@ -426,7 +388,6 @@ void AuctionHouseBot::addNewAuctions(Player *AHBplayer, AHBConfig *config) auctionmgr.AddAItem(item); auctionHouse->AddAuction(auctionEntry); auctionEntry->SaveToDB(); - switch(itemColor) { case 0: @@ -484,32 +445,26 @@ void AuctionHouseBot::addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *con if (debug_Out) sLog.outError("AHBuyer: Disabled"); return; } - QueryResult* result = CharacterDatabase.PQuery("SELECT id FROM auctionhouse WHERE itemowner<>%u AND buyguid<>%u", AHBplayerGUID, AHBplayerGUID); - if (!result) { delete result; return; } - if (result->GetRowCount() == 0) { delete result; return; } - // Fetches content of selected AH AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap(config->GetAHFID()); vector possibleBids; - do { uint32 tmpdata = result->Fetch()->GetUInt32(); possibleBids.push_back(tmpdata); }while (result->NextRow()); delete result; - for (uint32 count = 1;count <= config->GetBidsPerInterval();++count) { // Do we have anything to bid? If not, stop here. @@ -519,23 +474,18 @@ void AuctionHouseBot::addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *con count = config->GetBidsPerInterval(); continue; } - // Choose random auction from possible auctions uint32 vectorPos = urand(0, possibleBids.size() - 1); vector::iterator iter = possibleBids.begin(); advance(iter, vectorPos); - // from auctionhousehandler.cpp, creates auction pointer & player pointer AuctionEntry* auction = auctionHouse->GetAuction(*iter); - // Erase the auction from the vector to prevent bidding on item in next iteration. possibleBids.erase(iter); - if (!auction) { continue; } - // get exact item information Item *pItem = auctionmgr.GetAItem(auction->item_guidlow); if (!pItem) @@ -543,21 +493,17 @@ void AuctionHouseBot::addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *con if (debug_Out) sLog.outError("AHBuyer: Item %u doesn't exist, perhaps bought already?", auction->item_guidlow); continue; } - // get item prototype ItemPrototype const* prototype = objmgr.GetItemPrototype(auction->item_template); - // check which price we have to use, startbid or if it is bidded already uint32 currentprice; if (auction->bid) currentprice = auction->bid; else currentprice = auction->startbid; - // Prepare portion from maximum bid double bidrate = static_cast(urand(1, 100)) / 100; long double bidMax = 0; - // check that bid has acceptable value and take bid based on vendorprice, stacksize and quality switch (BuyMethod) { @@ -592,7 +538,6 @@ void AuctionHouseBot::addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *con break; } } - // check some special items, and do recalculating to their prices switch (prototype->Class) { @@ -603,22 +548,18 @@ void AuctionHouseBot::addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *con default: break; } - if (bidMax == 0) { // quality check failed to get bidmax, let's get out of here continue; } - // Calculate our bid long double bidvalue = currentprice + ((bidMax - currentprice) * bidrate); // Convert to uint32 uint32 bidprice = static_cast(bidvalue); - // Check our bid is high enough to be valid. If not, correct it to minimum. if ((currentprice + auction->GetAuctionOutBid()) > bidprice) bidprice = currentprice + auction->GetAuctionOutBid(); - if (debug_Out) { sLog.outString("-------------------------------------------------"); @@ -648,11 +589,9 @@ void AuctionHouseBot::addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *con sLog.outString("AHBuyer: Ammo Type: %u", prototype->AmmoType); sLog.outString("-------------------------------------------------"); } - // Check whether we do normal bid, or buyout if ((bidprice < auction->buyout) || (auction->buyout == 0)) { - if (auction->bidder > 0) { if (auction->bidder == AHBplayer->GetGUIDLow()) @@ -666,10 +605,8 @@ void AuctionHouseBot::addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *con //pl->ModifyMoney(-int32(price)); } } - auction->bidder = AHBplayer->GetGUIDLow(); auction->bid = bidprice; - // Saving auction into database CharacterDatabase.PExecute("UPDATE auctionhouse SET buyguid = '%u',lastbid = '%u' WHERE id = '%u'", auction->bidder, auction->bid, auction->Id); } @@ -682,7 +619,6 @@ void AuctionHouseBot::addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *con } auction->bidder = AHBplayer->GetGUIDLow(); auction->bid = auction->buyout; - // Send mails to buyer & seller auctionmgr.SendAuctionSalePendingMail(auction); auctionmgr.SendAuctionSuccessfulMail(auction); @@ -694,18 +630,15 @@ void AuctionHouseBot::addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *con } } } - void AuctionHouseBot::Update() { time_t _newrun = time(NULL); if ((!AHBSeller) && (!AHBBuyer)) return; - WorldSession _session(AHBplayerAccount, NULL, SEC_PLAYER, true, 0, LOCALE_enUS); Player _AHBplayer(&_session); _AHBplayer.MinimalLoadFromDB(NULL, AHBplayerGUID); ObjectAccessor::Instance().AddObject(&_AHBplayer); - // Only for testing, this can likely be removed, once I know it's working as expected. /* AuctionHouseObject* auctionHouse1 = auctionmgr.GetAuctionsMap(55); @@ -719,7 +652,6 @@ void AuctionHouseBot::Update() return; } */ - // Add New Bids if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION)) { @@ -731,7 +663,6 @@ void AuctionHouseBot::Update() addNewAuctionBuyerBotBid(&_AHBplayer, &AllianceConfig, &_session); _lastrun_a = _newrun; } - addNewAuctions(&_AHBplayer, &HordeConfig); if (((_newrun - _lastrun_h) >= (HordeConfig.GetBiddingInterval() * MINUTE)) && (HordeConfig.GetBidsPerInterval() > 0)) { @@ -741,7 +672,6 @@ void AuctionHouseBot::Update() _lastrun_h = _newrun; } } - addNewAuctions(&_AHBplayer, &NeutralConfig); if (((_newrun - _lastrun_n) >= (NeutralConfig.GetBiddingInterval() * MINUTE)) && (NeutralConfig.GetBidsPerInterval() > 0)) { @@ -752,37 +682,30 @@ void AuctionHouseBot::Update() } ObjectAccessor::Instance().RemoveObject(&_AHBplayer); } - void AuctionHouseBot::Initialize() { debug_Out = sConfig.GetBoolDefault("AuctionHouseBot.DEBUG", false); debug_Out_Filters = sConfig.GetBoolDefault("AuctionHouseBot.DEBUG_FILTERS", false); - AHBSeller = sConfig.GetBoolDefault("AuctionHouseBot.EnableSeller", false); AHBBuyer = sConfig.GetBoolDefault("AuctionHouseBot.EnableBuyer", false); SellMethod = sConfig.GetBoolDefault("AuctionHouseBot.UseBuyPriceForSeller", false); BuyMethod = sConfig.GetBoolDefault("AuctionHouseBot.UseBuyPriceForBuyer", false); - AHBplayerAccount = sConfig.GetIntDefault("AuctionHouseBot.Account", 0); AHBplayerGUID = sConfig.GetIntDefault("AuctionHouseBot.GUID", 0); ItemsPerCycle = sConfig.GetIntDefault("AuctionHouseBot.ItemsPerCycle", 200); - //Begin Filters - Vendor_Items = sConfig.GetBoolDefault("AuctionHouseBot.VendorItems", false); Loot_Items = sConfig.GetBoolDefault("AuctionHouseBot.LootItems", true); Other_Items = sConfig.GetBoolDefault("AuctionHouseBot.OtherItems", false); Vendor_TGs = sConfig.GetBoolDefault("AuctionHouseBot.VendorTradeGoods", false); Loot_TGs = sConfig.GetBoolDefault("AuctionHouseBot.LootTradeGoods", true); Other_TGs = sConfig.GetBoolDefault("AuctionHouseBot.OtherTradeGoods", false); - No_Bind = sConfig.GetBoolDefault("AuctionHouseBot.No_Bind", true); Bind_When_Picked_Up = sConfig.GetBoolDefault("AuctionHouseBot.Bind_When_Picked_Up", false); Bind_When_Equipped = sConfig.GetBoolDefault("AuctionHouseBot.Bind_When_Equipped", true); Bind_When_Use = sConfig.GetBoolDefault("AuctionHouseBot.Bind_When_Use", true); Bind_Quest_Item = sConfig.GetBoolDefault("AuctionHouseBot.Bind_Quest_Item", false); - DisableBeta_PTR_Unused = sConfig.GetBoolDefault("AuctionHouseBot.DisableBeta_PTR_Unused", false); DisablePermEnchant = sConfig.GetBoolDefault("AuctionHouseBot.DisablePermEnchant", false); #if CLIENT_VER > 300 @@ -795,7 +718,6 @@ void AuctionHouseBot::Initialize() DisableKeys = sConfig.GetBoolDefault("AuctionHouseBot.DisableKeys", false); DisableDuration = sConfig.GetBoolDefault("AuctionHouseBot.DisableDuration", false); DisableBOP_Or_Quest_NoReqLevel = sConfig.GetBoolDefault("AuctionHouseBot.DisableBOP_Or_Quest_NoReqLevel", false); - DisableWarriorItems = sConfig.GetBoolDefault("AuctionHouseBot.DisableWarriorItems", false); DisablePaladinItems = sConfig.GetBoolDefault("AuctionHouseBot.DisablePaladinItems", false); DisableHunterItems = sConfig.GetBoolDefault("AuctionHouseBot.DisableHunterItems", false); @@ -807,7 +729,6 @@ void AuctionHouseBot::Initialize() DisableWarlockItems = sConfig.GetBoolDefault("AuctionHouseBot.DisableWarlockItems", false); DisableUnusedClassItems = sConfig.GetBoolDefault("AuctionHouseBot.DisableUnusedClassItems", false); DisableDruidItems = sConfig.GetBoolDefault("AuctionHouseBot.DisableDruidItems", false); - DisableItemsBelowLevel = sConfig.GetIntDefault("AuctionHouseBot.DisableItemsBelowLevel", 0); DisableItemsAboveLevel = sConfig.GetIntDefault("AuctionHouseBot.DisableItemsAboveLevel", 0); DisableTGsBelowLevel = sConfig.GetIntDefault("AuctionHouseBot.DisableTGsBelowLevel", 0); @@ -824,7 +745,6 @@ void AuctionHouseBot::Initialize() DisableItemsAboveReqSkillRank = sConfig.GetIntDefault("AuctionHouseBot.DisableItemsAboveReqSkillRank", 0); DisableTGsBelowReqSkillRank = sConfig.GetIntDefault("AuctionHouseBot.DisableTGsBelowReqSkillRank", 0); DisableTGsAboveReqSkillRank = sConfig.GetIntDefault("AuctionHouseBot.DisableTGsAboveReqSkillRank", 0); - //End Filters if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION)) { @@ -832,7 +752,6 @@ void AuctionHouseBot::Initialize() LoadValues(&HordeConfig); } LoadValues(&NeutralConfig); - if (AHBSeller) { QueryResult* results = (QueryResult*) NULL; @@ -844,16 +763,13 @@ void AuctionHouseBot::Initialize() { Field* fields = results->Fetch(); npcItems.push_back(fields[0].GetUInt32()); - } while (results->NextRow()); - delete results; } else { if (debug_Out) sLog.outString("AuctionHouseBot: \"%s\" failed", npcQuery); } - char lootQuery[] = "SELECT item FROM creature_loot_template UNION " "SELECT item FROM disenchant_loot_template UNION " "SELECT item FROM fishing_loot_template UNION " @@ -865,7 +781,6 @@ void AuctionHouseBot::Initialize() "SELECT item FROM pickpocketing_loot_template UNION " "SELECT item FROM prospecting_loot_template UNION " "SELECT item FROM skinning_loot_template"; - results = WorldDatabase.PQuery(lootQuery); if (results != NULL) { @@ -873,23 +788,18 @@ void AuctionHouseBot::Initialize() { Field* fields = results->Fetch(); lootItems.push_back(fields[0].GetUInt32()); - } while (results->NextRow()); - delete results; } else { if (debug_Out) sLog.outString("AuctionHouseBot: \"%s\" failed", lootQuery); } - for (uint32 itemID = 0; itemID < sItemStorage.MaxEntry; itemID++) { ItemPrototype const* prototype = objmgr.GetItemPrototype(itemID); - if (prototype == NULL) continue; - switch (prototype->Bonding) { case NO_BIND: @@ -916,7 +826,6 @@ void AuctionHouseBot::Initialize() continue; break; } - switch (SellMethod) { case 0: @@ -928,71 +837,56 @@ void AuctionHouseBot::Initialize() continue; break; } - if ((prototype->Quality < 0) || (prototype->Quality > 6)) continue; - if ((Vendor_Items == 0) && !(prototype->Class == ITEM_CLASS_TRADE_GOODS)) { bool isVendorItem = false; - for (unsigned int i = 0; (i < npcItems.size()) && (!isVendorItem); i++) { if (itemID == npcItems[i]) isVendorItem = true; } - if (isVendorItem) continue; } - if ((Vendor_TGs == 0) && (prototype->Class == ITEM_CLASS_TRADE_GOODS)) { bool isVendorTG = false; - for (unsigned int i = 0; (i < npcItems.size()) && (!isVendorTG); i++) { if (itemID == npcItems[i]) isVendorTG = true; } - if (isVendorTG) continue; } - if ((Loot_Items == 0) && !(prototype->Class == ITEM_CLASS_TRADE_GOODS)) { bool isLootItem = false; - for (unsigned int i = 0; (i < lootItems.size()) && (!isLootItem); i++) { if (itemID == lootItems[i]) isLootItem = true; } - if (isLootItem) continue; } - if ((Loot_TGs == 0) && (prototype->Class == ITEM_CLASS_TRADE_GOODS)) { bool isLootTG = false; - for (unsigned int i = 0; (i < lootItems.size()) && (!isLootTG); i++) { if (itemID == lootItems[i]) isLootTG = true; } - if (isLootTG) continue; } - if ((Other_Items == 0) && !(prototype->Class == ITEM_CLASS_TRADE_GOODS)) { bool isVendorItem = false; bool isLootItem = false; - for (unsigned int i = 0; (i < npcItems.size()) && (!isVendorItem); i++) { if (itemID == npcItems[i]) @@ -1006,12 +900,10 @@ void AuctionHouseBot::Initialize() if ((!isLootItem) && (!isVendorItem)) continue; } - if ((Other_TGs == 0) && (prototype->Class == ITEM_CLASS_TRADE_GOODS)) { bool isVendorTG = false; bool isLootTG = false; - for (unsigned int i = 0; (i < npcItems.size()) && (!isVendorTG); i++) { if (itemID == npcItems[i]) @@ -1025,7 +917,6 @@ void AuctionHouseBot::Initialize() if ((!isLootTG) && (!isVendorTG)) continue; } - //TODO:Make list of items and create a vector // Disable PTR/Beta/Unused items if ((DisableBeta_PTR_Unused) && ((prototype->ItemId == 21878) || (prototype->ItemId == 27774) || (prototype->ItemId == 27811) || (prototype->ItemId == 28117) || (prototype->ItemId == 28112))) @@ -1033,14 +924,12 @@ void AuctionHouseBot::Initialize() if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (PTR/Beta/Unused Item)", prototype->ItemId); continue; } - // Disable permanent enchants items if ((DisablePermEnchant) && (prototype->Class == ITEM_CLASS_PERMANENT)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Permanent Enchant Item)", prototype->ItemId); continue; } - #if CLIENT_VER > 300 // Disable conjured items if ((DisableConjured) && (prototype->IsConjuredConsumable())) @@ -1049,245 +938,210 @@ void AuctionHouseBot::Initialize() continue; } #endif - // Disable gems if ((DisableGems) && (prototype->Class == ITEM_CLASS_GEM)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Gem)", prototype->ItemId); continue; } - // Disable money if ((DisableMoney) && (prototype->Class == ITEM_CLASS_MONEY)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Money)", prototype->ItemId); continue; } - // Disable moneyloot if ((DisableMoneyLoot) && (prototype->MinMoneyLoot > 0)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (MoneyLoot)", prototype->ItemId); continue; } - // Disable lootable items if ((DisableLootable) && (prototype->Flags & 4)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Lootable Item)", prototype->ItemId); continue; } - // Disable Keys if ((DisableKeys) && (prototype->Class == ITEM_CLASS_KEY)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Quest Item)", prototype->ItemId); continue; } - // Disable items with duration if ((DisableDuration) && (prototype->Duration > 0)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Has a Duration)", prototype->ItemId); continue; } - // Disable items which are BOP or Quest Items and have a required level lower than the item level if ((DisableBOP_Or_Quest_NoReqLevel) && ((prototype->Bonding == BIND_WHEN_PICKED_UP || prototype->Bonding == BIND_QUEST_ITEM) && (prototype->RequiredLevel < prototype->ItemLevel))) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (BOP or BQI and Required Level is less than Item Level)", prototype->ItemId); continue; } - // Disable items specifically for Warrior if ((DisableWarriorItems) && (prototype->AllowableClass == 1)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Warrior Item)", prototype->ItemId); continue; } - // Disable items specifically for Paladin if ((DisablePaladinItems) && (prototype->AllowableClass == 2)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Paladin Item)", prototype->ItemId); continue; } - // Disable items specifically for Hunter if ((DisableHunterItems) && (prototype->AllowableClass == 4)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Hunter Item)", prototype->ItemId); continue; } - // Disable items specifically for Rogue if ((DisableRogueItems) && (prototype->AllowableClass == 8)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Rogue Item)", prototype->ItemId); continue; } - // Disable items specifically for Priest if ((DisablePriestItems) && (prototype->AllowableClass == 16)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Priest Item)", prototype->ItemId); continue; } - // Disable items specifically for DK if ((DisableDKItems) && (prototype->AllowableClass == 32)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (DK Item)", prototype->ItemId); continue; } - // Disable items specifically for Shaman if ((DisableShamanItems) && (prototype->AllowableClass == 64)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Shaman Item)", prototype->ItemId); continue; } - // Disable items specifically for Mage if ((DisableMageItems) && (prototype->AllowableClass == 128)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Mage Item)", prototype->ItemId); continue; } - // Disable items specifically for Warlock if ((DisableWarlockItems) && (prototype->AllowableClass == 256)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Warlock Item)", prototype->ItemId); continue; } - // Disable items specifically for Unused Class if ((DisableUnusedClassItems) && (prototype->AllowableClass == 512)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Unused Item)", prototype->ItemId); continue; } - // Disable items specifically for Druid if ((DisableDruidItems) && (prototype->AllowableClass == 1024)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Druid Item)", prototype->ItemId); continue; } - // Disable Items below level X if ((DisableItemsBelowLevel) && (prototype->Class != ITEM_CLASS_TRADE_GOODS) && (prototype->ItemLevel < DisableItemsBelowLevel)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Item Level = %u)", prototype->ItemId, prototype->ItemLevel); continue; } - // Disable Items above level X if ((DisableItemsAboveLevel) && (prototype->Class != ITEM_CLASS_TRADE_GOODS) && (prototype->ItemLevel > DisableItemsAboveLevel)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Item Level = %u)", prototype->ItemId, prototype->ItemLevel); continue; } - // Disable Trade Goods below level X if ((DisableTGsBelowLevel) && (prototype->Class == ITEM_CLASS_TRADE_GOODS) && (prototype->ItemLevel < DisableTGsBelowLevel)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Trade Good %u disabled (Trade Good Level = %u)", prototype->ItemId, prototype->ItemLevel); continue; } - // Disable Trade Goods above level X if ((DisableTGsAboveLevel) && (prototype->Class == ITEM_CLASS_TRADE_GOODS) && (prototype->ItemLevel > DisableTGsAboveLevel)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Trade Good %u disabled (Trade Good Level = %u)", prototype->ItemId, prototype->ItemLevel); continue; } - // Disable Items below GUID X if ((DisableItemsBelowGUID) && (prototype->Class != ITEM_CLASS_TRADE_GOODS) && (prototype->ItemId < DisableItemsBelowGUID)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Item Level = %u)", prototype->ItemId, prototype->ItemLevel); continue; } - // Disable Items above GUID X if ((DisableItemsAboveGUID) && (prototype->Class != ITEM_CLASS_TRADE_GOODS) && (prototype->ItemId > DisableItemsAboveGUID)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Item Level = %u)", prototype->ItemId, prototype->ItemLevel); continue; } - // Disable Trade Goods below GUID X if ((DisableTGsBelowGUID) && (prototype->Class == ITEM_CLASS_TRADE_GOODS) && (prototype->ItemId < DisableTGsBelowGUID)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Trade Good Level = %u)", prototype->ItemId, prototype->ItemLevel); continue; } - // Disable Trade Goods above GUID X if ((DisableTGsAboveGUID) && (prototype->Class == ITEM_CLASS_TRADE_GOODS) && (prototype->ItemId > DisableTGsAboveGUID)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (Trade Good Level = %u)", prototype->ItemId, prototype->ItemLevel); continue; } - // Disable Items for level lower than X if ((DisableItemsBelowReqLevel) && (prototype->RequiredLevel < DisableItemsBelowReqLevel)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (RequiredLevel = %u)", prototype->ItemId, prototype->RequiredLevel); continue; } - // Disable Items for level higher than X if ((DisableItemsAboveReqLevel) && (prototype->RequiredLevel > DisableItemsAboveReqLevel)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (RequiredLevel = %u)", prototype->ItemId, prototype->RequiredLevel); continue; } - // Disable Trade Goods for level lower than X if ((DisableTGsBelowReqLevel) && (prototype->RequiredLevel < DisableTGsBelowReqLevel)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Trade Good %u disabled (RequiredLevel = %u)", prototype->ItemId, prototype->RequiredLevel); continue; } - // Disable Trade Goods for level higher than X if ((DisableTGsAboveReqLevel) && (prototype->RequiredLevel > DisableTGsAboveReqLevel)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Trade Good %u disabled (RequiredLevel = %u)", prototype->ItemId, prototype->RequiredLevel); continue; } - // Disable Items that require skill lower than X if ((DisableItemsBelowReqSkillRank) && (prototype->RequiredSkillRank < DisableItemsBelowReqSkillRank)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (RequiredSkillRank = %u)", prototype->ItemId, prototype->RequiredSkillRank); continue; } - // Disable Items that require skill higher than X if ((DisableItemsAboveReqSkillRank) && (prototype->RequiredSkillRank > DisableItemsAboveReqSkillRank)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (RequiredSkillRank = %u)", prototype->ItemId, prototype->RequiredSkillRank); continue; } - // Disable Trade Goods that require skill lower than X if ((DisableTGsBelowReqSkillRank) && (prototype->RequiredSkillRank < DisableTGsBelowReqSkillRank)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (RequiredSkillRank = %u)", prototype->ItemId, prototype->RequiredSkillRank); continue; } - // Disable Trade Goods that require skill higher than X if ((DisableTGsAboveReqSkillRank) && (prototype->RequiredSkillRank > DisableTGsAboveReqSkillRank)) { if (debug_Out_Filters) sLog.outString("AuctionHouseBot: Item %u disabled (RequiredSkillRank = %u)", prototype->ItemId, prototype->RequiredSkillRank); continue; } - switch (prototype->Quality) { case AHB_GREY: @@ -1296,42 +1150,36 @@ void AuctionHouseBot::Initialize() else greyItemsBin.push_back(itemID); break; - case AHB_WHITE: if (prototype->Class == ITEM_CLASS_TRADE_GOODS) whiteTradeGoodsBin.push_back(itemID); else whiteItemsBin.push_back(itemID); break; - case AHB_GREEN: if (prototype->Class == ITEM_CLASS_TRADE_GOODS) greenTradeGoodsBin.push_back(itemID); else greenItemsBin.push_back(itemID); break; - case AHB_BLUE: if (prototype->Class == ITEM_CLASS_TRADE_GOODS) blueTradeGoodsBin.push_back(itemID); else blueItemsBin.push_back(itemID); break; - case AHB_PURPLE: if (prototype->Class == ITEM_CLASS_TRADE_GOODS) purpleTradeGoodsBin.push_back(itemID); else purpleItemsBin.push_back(itemID); break; - case AHB_ORANGE: if (prototype->Class == ITEM_CLASS_TRADE_GOODS) orangeTradeGoodsBin.push_back(itemID); else orangeItemsBin.push_back(itemID); break; - case AHB_YELLOW: if (prototype->Class == ITEM_CLASS_TRADE_GOODS) yellowTradeGoodsBin.push_back(itemID); @@ -1340,7 +1188,6 @@ void AuctionHouseBot::Initialize() break; } } - if ((greyTradeGoodsBin.size() == 0) && (whiteTradeGoodsBin.size() == 0) && (greenTradeGoodsBin.size() == 0) && @@ -1359,7 +1206,6 @@ void AuctionHouseBot::Initialize() sLog.outError("AuctionHouseBot: No items"); AHBSeller = 0; } - sLog.outString("AuctionHouseBot:"); sLog.outString("loaded %u grey trade goods", greyTradeGoodsBin.size()); sLog.outString("loaded %u white trade goods", whiteTradeGoodsBin.size()); @@ -1379,11 +1225,9 @@ void AuctionHouseBot::Initialize() sLog.outString("AuctionHouseBot by Paradox (original by ChrisK) has been loaded."); sLog.outString("AuctionHouseBot now includes AHBuyer by Kerbe and Paradox"); } - void AuctionHouseBot::IncrementItemCounts(AuctionEntry* ah) { // from auctionhousehandler.cpp, creates auction pointer & player pointer - // get exact item information Item *pItem = auctionmgr.GetAItem(ah->item_guidlow); if (!pItem) @@ -1391,12 +1235,9 @@ void AuctionHouseBot::IncrementItemCounts(AuctionEntry* ah) if (debug_Out) sLog.outError("AHBot: Item %u doesn't exist, perhaps bought already?", ah->item_guidlow); return; } - // get item prototype ItemPrototype const* prototype = objmgr.GetItemPrototype(ah->item_template); - AHBConfig *config; - FactionTemplateEntry const* u_entry = sFactionTemplateStore.LookupEntry(ah->GetHouseFaction()); if (!u_entry) { @@ -1418,17 +1259,13 @@ void AuctionHouseBot::IncrementItemCounts(AuctionEntry* ah) if (debug_Out) sLog.outError("AHBot: %u returned as House Faction. Neutral", ah->GetHouseFaction()); config = &NeutralConfig; } - config->IncItemCounts(prototype->Class, prototype->Quality); } - void AuctionHouseBot::DecrementItemCounts(AuctionEntry* ah, uint32 item_template) { // get item prototype ItemPrototype const* prototype = objmgr.GetItemPrototype(item_template); - AHBConfig *config; - FactionTemplateEntry const* u_entry = sFactionTemplateStore.LookupEntry(ah->GetHouseFaction()); if (!u_entry) { @@ -1450,10 +1287,8 @@ void AuctionHouseBot::DecrementItemCounts(AuctionEntry* ah, uint32 item_template if (debug_Out) sLog.outError("AHBot: %u returned as House Faction. Neutral", ah->GetHouseFaction()); config = &NeutralConfig; } - config->DecItemCounts(prototype->Class, prototype->Quality); } - void AuctionHouseBot::Commands(uint32 command, uint32 ahMapID, uint32 col, char* args) { AHBConfig *config; @@ -1501,15 +1336,12 @@ void AuctionHouseBot::Commands(uint32 command, uint32 ahMapID, uint32 col, char* case 0: //ahexpire { AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap(config->GetAHFID()); - AuctionHouseObject::AuctionEntryMap::iterator itr; itr = auctionHouse->GetAuctionsBegin(); - while (itr != auctionHouse->GetAuctionsEnd()) { if (itr->second->owner == AHBplayerGUID) itr->second->expire_time = sWorld.GetGameTime(); - ++itr; } } @@ -1564,7 +1396,6 @@ void AuctionHouseBot::Commands(uint32 command, uint32 ahMapID, uint32 col, char* uint32 purplei = (uint32) strtoul(param12, NULL, 0); uint32 orangei = (uint32) strtoul(param13, NULL, 0); uint32 yellowi = (uint32) strtoul(param14, NULL, 0); - CharacterDatabase.BeginTransaction(); CharacterDatabase.PExecute("UPDATE auctionhousebot SET percentgreytradegoods = '%u' WHERE auctionhouse = '%u'", greytg, ahMapID); CharacterDatabase.PExecute("UPDATE auctionhousebot SET percentwhitetradegoods = '%u' WHERE auctionhouse = '%u'", whitetg, ahMapID); @@ -1652,7 +1483,6 @@ void AuctionHouseBot::Commands(uint32 command, uint32 ahMapID, uint32 col, char* break; } } - void AuctionHouseBot::LoadValues(AHBConfig *config) { if (debug_Out) sLog.outString("Start Settings for %s Auctionhouses:", CharacterDatabase.PQuery("SELECT name FROM auctionhousebot WHERE auctionhouse = %u",config->GetAHID())->Fetch()->GetString()); @@ -1771,10 +1601,8 @@ void AuctionHouseBot::LoadValues(AHBConfig *config) } AuctionHouseEntry const* ahEntry = auctionmgr.GetAuctionHouseEntry(config->GetAHFID()); AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap(config->GetAHFID()); - config->ResetItemCounts(); uint32 auctions = auctionHouse->Getcount(); - if (auctions) { for (AuctionHouseObject::AuctionEntryMap::const_iterator itr = auctionHouse->GetAuctionsBegin();itr != auctionHouse->GetAuctionsEnd();++itr) diff --git a/src/game/AuctionHouseBot.h b/src/game/AuctionHouseBot.h index d135af5c479..9e04dde87cf 100644 --- a/src/game/AuctionHouseBot.h +++ b/src/game/AuctionHouseBot.h @@ -1,10 +1,8 @@ #ifndef AUCTION_HOUSE_BOT_H #define AUCTION_HOUSE_BOT_H - #include "World.h" #include "Config/ConfigEnv.h" #include "ItemPrototype.h" - #define AHB_GREY 0 #define AHB_WHITE 1 #define AHB_GREEN 2 @@ -27,7 +25,6 @@ #define AHB_PURPLE_I 11 #define AHB_ORANGE_I 12 #define AHB_YELLOW_I 13 - class AHBConfig { private: @@ -84,7 +81,6 @@ private: uint32 minBidPriceYellow; uint32 maxBidPriceYellow; uint32 maxStackYellow; - uint32 buyerPriceGrey; uint32 buyerPriceWhite; uint32 buyerPriceGreen; @@ -94,7 +90,6 @@ private: uint32 buyerPriceYellow; uint32 buyerBiddingInterval; uint32 buyerBidsPerInterval; - uint32 greytgp; uint32 whitetgp; uint32 greentgp; @@ -109,7 +104,6 @@ private: uint32 purpleip; uint32 orangeip; uint32 yellowip; - uint32 greyTGoods; uint32 whiteTGoods; uint32 greenTGoods; @@ -117,7 +111,6 @@ private: uint32 purpleTGoods; uint32 orangeTGoods; uint32 yellowTGoods; - uint32 greyItems; uint32 whiteItems; uint32 greenItems; @@ -125,7 +118,6 @@ private: uint32 purpleItems; uint32 orangeItems; uint32 yellowItems; - public: AHBConfig(uint32 ahid) { @@ -182,7 +174,6 @@ public: void SetPercentages(uint32 greytg, uint32 whitetg, uint32 greentg, uint32 bluetg, uint32 purpletg, uint32 orangetg, uint32 yellowtg, uint32 greyi, uint32 whitei, uint32 greeni, uint32 bluei, uint32 purplei, uint32 orangei, uint32 yellowi) { uint32 totalPercent = greytg + whitetg + greentg + bluetg + purpletg + orangetg + yellowtg + greyi + whitei + greeni + bluei + purplei + orangei + yellowi; - if (totalPercent == 0) { maxItems = 0; @@ -892,7 +883,6 @@ public: break; } } - void DecItemCounts(uint32 Class, uint32 Quality) { switch(Class) @@ -905,7 +895,6 @@ public: break; } } - void DecItemCounts(uint32 color) { switch(color) @@ -956,7 +945,6 @@ public: break; } } - void IncItemCounts(uint32 Class, uint32 Quality) { switch(Class) @@ -969,7 +957,6 @@ public: break; } } - void IncItemCounts(uint32 color) { switch(color) @@ -1020,7 +1007,6 @@ public: break; } } - void ResetItemCounts() { greyTGoods = 0; @@ -1030,7 +1016,6 @@ public: purpleTGoods = 0; orangeTGoods = 0; yellowTGoods = 0; - greyItems = 0; whiteItems = 0; greenItems = 0; @@ -1039,7 +1024,6 @@ public: orangeItems = 0; yellowItems = 0; } - uint32 TotalItemCounts() { return( @@ -1050,7 +1034,6 @@ public: purpleTGoods + orangeTGoods + yellowTGoods + - greyItems + whiteItems + greenItems + @@ -1059,7 +1042,6 @@ public: orangeItems + yellowItems); } - uint32 GetItemCounts(uint32 color) { switch(color) @@ -1126,34 +1108,27 @@ public: class AuctionHouseBot { private: - bool debug_Out; bool debug_Out_Filters; - bool AHBSeller; bool AHBBuyer; bool BuyMethod; bool SellMethod; - uint32 AHBplayerAccount; uint32 AHBplayerGUID; uint32 ItemsPerCycle; - //Begin Filters - bool Vendor_Items; bool Loot_Items; bool Other_Items; bool Vendor_TGs; bool Loot_TGs; bool Other_TGs; - bool No_Bind; bool Bind_When_Picked_Up; bool Bind_When_Equipped; bool Bind_When_Use; bool Bind_Quest_Item; - bool DisableBeta_PTR_Unused; bool DisablePermEnchant; #if CLIENT_VER > 300 @@ -1166,7 +1141,6 @@ private: bool DisableKeys; bool DisableDuration; bool DisableBOP_Or_Quest_NoReqLevel; - bool DisableWarriorItems; bool DisablePaladinItems; bool DisableHunterItems; @@ -1178,7 +1152,6 @@ private: bool DisableWarlockItems; bool DisableUnusedClassItems; bool DisableDruidItems; - uint32 DisableItemsBelowLevel; uint32 DisableItemsAboveLevel; uint32 DisableTGsBelowLevel; @@ -1195,21 +1168,16 @@ private: uint32 DisableItemsAboveReqSkillRank; uint32 DisableTGsBelowReqSkillRank; uint32 DisableTGsAboveReqSkillRank; - //End Filters - AHBConfig AllianceConfig; AHBConfig HordeConfig; AHBConfig NeutralConfig; - time_t _lastrun_a; time_t _lastrun_h; time_t _lastrun_n; - inline uint32 minValue(uint32 a, uint32 b) { return a <= b ? a : b; }; void addNewAuctions(Player *AHBplayer, AHBConfig *config); void addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *config, WorldSession *session); - public: AuctionHouseBot(); ~AuctionHouseBot(); @@ -1221,7 +1189,5 @@ public: void Commands(uint32, uint32, uint32, char*); uint32 GetAHBplayerGUID() { return AHBplayerGUID; }; }; - #define auctionbot Trinity::Singleton::Instance() - #endif diff --git a/src/game/AuctionHouseHandler.cpp b/src/game/AuctionHouseHandler.cpp index 52790526dd7..13df6c3a6a4 100644 --- a/src/game/AuctionHouseHandler.cpp +++ b/src/game/AuctionHouseHandler.cpp @@ -17,13 +17,11 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "ObjectMgr.h" #include "Player.h" #include "World.h" #include "WorldPacket.h" #include "WorldSession.h" - #include "AuctionHouseBot.h" #include "AuctionHouseMgr.h" #include "Log.h" @@ -31,43 +29,35 @@ #include "UpdateMask.h" #include "Util.h" - //please DO NOT use iterator++, because it is slower than ++iterator!!! //post-incrementation is always slower than pre-incrementation ! - //void called when player click on auctioneer npc void WorldSession::HandleAuctionHelloOpcode(WorldPacket & recv_data) { uint64 guid; //NPC guid recv_data >> guid; - Creature *unit = GetPlayer()->GetNPCIfCanInteractWith(guid,UNIT_NPC_FLAG_AUCTIONEER); if (!unit) { sLog.outDebug("WORLD: HandleAuctionHelloOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid))); return; } - // remove fake death if (GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); - SendAuctionHello(guid, unit); } - //this void causes that auction window is opened void WorldSession::SendAuctionHello(uint64 guid, Creature* unit) { AuctionHouseEntry const* ahEntry = AuctionHouseMgr::GetAuctionHouseEntry(unit->getFaction()); if (!ahEntry) return; - WorldPacket data(MSG_AUCTION_HELLO, 12); data << (uint64) guid; data << (uint32) ahEntry->houseId; SendPacket(&data); } - //call this method when player bids, creates, or deletes auction void WorldSession::SendAuctionCommandResult(uint32 auctionId, uint32 Action, uint32 ErrorCode, uint32 bidError) { @@ -79,7 +69,6 @@ void WorldSession::SendAuctionCommandResult(uint32 auctionId, uint32 Action, uin data << bidError; //when bid, then send 0, once... SendPacket(&data); } - //this function sends notification, if bidder is online void WorldSession::SendAuctionBidderNotification(uint32 location, uint32 auctionId, uint64 bidder, uint32 bidSum, uint32 diff, uint32 item_template) { @@ -93,7 +82,6 @@ void WorldSession::SendAuctionBidderNotification(uint32 location, uint32 auction data << uint32(0); SendPacket(&data); } - //this void causes on client to display: "Your auction sold" void WorldSession::SendAuctionOwnerNotification(AuctionEntry* auction) { @@ -107,53 +95,42 @@ void WorldSession::SendAuctionOwnerNotification(AuctionEntry* auction) data << (uint32) 0; //unk SendPacket(&data); } - //this function sends mail to old bidder void WorldSession::SendAuctionOutbiddedMail(AuctionEntry *auction, uint32 newPrice) { uint64 oldBidder_guid = MAKE_NEW_GUID(auction->bidder,0, HIGHGUID_PLAYER); Player *oldBidder = objmgr.GetPlayer(oldBidder_guid); - uint32 oldBidder_accId = 0; if (!oldBidder) oldBidder_accId = objmgr.GetPlayerAccountIdByGUID(oldBidder_guid); - // old bidder exist if (oldBidder || oldBidder_accId) { std::ostringstream msgAuctionOutbiddedSubject; msgAuctionOutbiddedSubject << auction->item_template << ":0:" << AUCTION_OUTBIDDED; - if (oldBidder && !_player) oldBidder->GetSession()->SendAuctionBidderNotification(auction->GetHouseId(), auction->Id, auctionbot.GetAHBplayerGUID(), newPrice, auction->GetAuctionOutBid(), auction->item_template); - if (oldBidder && _player) oldBidder->GetSession()->SendAuctionBidderNotification(auction->GetHouseId(), auction->Id, _player->GetGUID(), newPrice, auction->GetAuctionOutBid(), auction->item_template); - WorldSession::SendMailTo(oldBidder, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), auction->bidder, msgAuctionOutbiddedSubject.str(), 0, NULL, auction->bid, 0, MAIL_CHECK_MASK_NONE); } } - //this function sends mail, when auction is cancelled to old bidder void WorldSession::SendAuctionCancelledToBidderMail(AuctionEntry* auction) { uint64 bidder_guid = MAKE_NEW_GUID(auction->bidder, 0, HIGHGUID_PLAYER); Player *bidder = objmgr.GetPlayer(bidder_guid); - uint32 bidder_accId = 0; if (!bidder) bidder_accId = objmgr.GetPlayerAccountIdByGUID(bidder_guid); - // bidder exist if (bidder || bidder_accId) { std::ostringstream msgAuctionCancelledSubject; msgAuctionCancelledSubject << auction->item_template << ":0:" << AUCTION_CANCELLED_TO_BIDDER; - WorldSession::SendMailTo(bidder, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), auction->bidder, msgAuctionCancelledSubject.str(), 0, NULL, auction->bid, 0, MAIL_CHECK_MASK_NONE); } } - //this void creates new auction and adds auction to some auctionhouse void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data) { @@ -162,31 +139,24 @@ void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data) recv_data >> auctioneer >> item; recv_data >> bid >> buyout >> etime; Player *pl = GetPlayer(); - if (!item || !bid || !etime) return; //check for cheaters - Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer,UNIT_NPC_FLAG_AUCTIONEER); if (!pCreature) { sLog.outDebug("WORLD: HandleAuctionSellItem - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(auctioneer))); return; } - AuctionHouseEntry const* auctionHouseEntry = AuctionHouseMgr::GetAuctionHouseEntry(pCreature->getFaction()); if (!auctionHouseEntry) { sLog.outDebug("WORLD: HandleAuctionSellItem - Unit (GUID: %u) has wrong faction.", uint32(GUID_LOPART(auctioneer))); return; } - sLog.outDebug("WORLD: HandleAuctionSellItem - ETIME: %u", etime); - // client send time in minutes, convert to common used sec time etime *= MINUTE; - sLog.outDebug("WORLD: HandleAuctionSellItem - ETIME: %u", etime); - // client understand only 3 auction time switch(etime) { @@ -197,11 +167,9 @@ void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data) default: return; } - // remove fake death if (GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); - Item *it = pl->GetItemByGuid(item); //do not allow to sell already auctioned items if (auctionmgr.GetAItem(GUID_LOPART(item))) @@ -216,21 +184,17 @@ void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data) SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_ITEM_NOT_FOUND); return; } - if (!it->CanBeTraded()) { SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_INTERNAL_ERROR); return; } - if (it->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_CONJURED) || it->GetUInt32Value(ITEM_FIELD_DURATION)) { SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_INTERNAL_ERROR); return; } - AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap(pCreature->getFaction()); - //we have to take deposit : uint32 deposit = auctionmgr.GetAuctionDeposit(auctionHouseEntry, etime, it); if (pl->GetMoney() < deposit) @@ -238,17 +202,13 @@ void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data) SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_NOT_ENOUGHT_MONEY); return; } - if (GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE)) { sLog.outCommand(GetAccountId(),"GM %s (Account: %u) create auction: %s (Entry: %u Count: %u)", GetPlayerName(),GetAccountId(),it->GetProto()->Name1,it->GetEntry(),it->GetCount()); } - pl->ModifyMoney(-int32(deposit)); - uint32 auction_time = uint32(etime * sWorld.getRate(RATE_AUCTION_TIME)); - AuctionEntry *AH = new AuctionEntry; AH->Id = objmgr.GenerateAuctionID(); if (sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION)) @@ -265,23 +225,18 @@ void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data) AH->expire_time = time(NULL) + auction_time; AH->deposit = deposit; AH->auctionHouseEntry = auctionHouseEntry; - sLog.outDetail("selling item %u to auctioneer %u with initial bid %u with buyout %u and with time %u (in sec) in auctionhouse %u", GUID_LOPART(item), AH->auctioneer, bid, buyout, auction_time, AH->GetHouseId()); auctionmgr.AddAItem(it); auctionHouse->AddAuction(AH); - pl->MoveItemFromInventory(it->GetBagSlot(), it->GetSlot(), true); - CharacterDatabase.BeginTransaction(); it->DeleteFromInventoryDB(); it->SaveToDB(); // recursive and not have transaction guard into self, not in inventiory and can be save standalone AH->SaveToDB(); pl->SaveInventoryAndGoldToDB(); CharacterDatabase.CommitTransaction(); - SendAuctionCommandResult(AH->Id, AUCTION_SELL_ITEM, AUCTION_OK); } - //this function is called when client bids or buys out auction void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data) { @@ -290,33 +245,26 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data) uint32 price; recv_data >> auctioneer; recv_data >> auctionId >> price; - if (!auctionId || !price) return; //check for cheaters - Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer,UNIT_NPC_FLAG_AUCTIONEER); if (!pCreature) { sLog.outDebug("WORLD: HandleAuctionPlaceBid - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(auctioneer))); return; } - // remove fake death if (GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); - AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap(pCreature->getFaction()); - AuctionEntry *auction = auctionHouse->GetAuction(auctionId); Player *pl = GetPlayer(); - if (!auction || auction->owner == pl->GetGUIDLow()) { //you cannot bid your own auction: SendAuctionCommandResult(0, AUCTION_PLACE_BID, CANNOT_BID_YOUR_AUCTION_ERROR); return; } - // impossible have online own another character (use this for speedup check in case online owner) Player* auction_owner = objmgr.GetPlayer(MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER)); if (!auction_owner && objmgr.GetPlayerAccountIdByGUID(MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER)) == pl->GetSession()->GetAccountId()) @@ -325,11 +273,9 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data) SendAuctionCommandResult(0, AUCTION_PLACE_BID, CANNOT_BID_YOUR_AUCTION_ERROR); return; } - // cheating if (price <= auction->bid) return; - // price too low for next bid if not buyout if ((price < auction->buyout || auction->buyout == 0) && price < auction->bid + auction->GetAuctionOutBid()) @@ -337,14 +283,12 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data) //auction has already higher bid, client tests it! return; } - if (price > pl->GetMoney()) { //you don't have enought money!, client tests! //SendAuctionCommandResult(auction->auctionId, AUCTION_PLACE_BID, ???); return; } - if ((price < auction->buyout) || (auction->buyout == 0)) { if (auction->bidder > 0) @@ -367,10 +311,8 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data) auction->bidder = pl->GetGUIDLow(); auction->bid = price; GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, price); - // after this update we should save player's money ... CharacterDatabase.PExecute("UPDATE auctionhouse SET buyguid = '%u',lastbid = '%u' WHERE id = '%u'", auction->bidder, auction->bid, auction->Id); - SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, AUCTION_OK, 0); } else @@ -391,11 +333,9 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data) auction->bidder = pl->GetGUIDLow(); auction->bid = auction->buyout; GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, auction->buyout); - auctionmgr.SendAuctionSalePendingMail(auction); auctionmgr.SendAuctionSuccessfulMail(auction); auctionmgr.SendAuctionWonMail(auction); - SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, AUCTION_OK); auction->DeleteFromDB(); uint32 item_template = auction->item_template; @@ -406,7 +346,6 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data) pl->SaveInventoryAndGoldToDB(); CharacterDatabase.CommitTransaction(); } - //this void is called when auction_owner cancels his auction void WorldSession::HandleAuctionRemoveItem(WorldPacket & recv_data) { @@ -415,23 +354,18 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket & recv_data) recv_data >> auctioneer; recv_data >> auctionId; //sLog.outDebug("Cancel AUCTION AuctionID: %u", auctionId); - Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer,UNIT_NPC_FLAG_AUCTIONEER); if (!pCreature) { sLog.outDebug("WORLD: HandleAuctionRemoveItem - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(auctioneer))); return; } - // remove fake death if (GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); - AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap(pCreature->getFaction()); - AuctionEntry *auction = auctionHouse->GetAuction(auctionId); Player *pl = GetPlayer(); - if (auction && auction->owner == pl->GetGUIDLow()) { Item *pItem = auctionmgr.GetAItem(auction->item_guidlow); @@ -449,10 +383,8 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket & recv_data) // Return the item by mail std::ostringstream msgAuctionCanceledOwner; msgAuctionCanceledOwner << auction->item_template << ":0:" << AUCTION_CANCELED; - MailItemsInfo mi; mi.AddItem(auction->item_guidlow, auction->item_template, pItem); - // item will deleted or added to received mail list WorldSession::SendMailTo(pl, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), pl->GetGUIDLow(), msgAuctionCanceledOwner.str(), 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE); } @@ -470,7 +402,6 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket & recv_data) sLog.outError("CHEATER : %u, he tried to cancel auction (id: %u) of another player, or auction is NULL", pl->GetGUIDLow(), auctionId); return; } - //inform player, that auction is removed SendAuctionCommandResult(auction->Id, AUCTION_CANCEL, AUCTION_OK); // Now remove the auction @@ -482,14 +413,12 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket & recv_data) auctionmgr.RemoveAItem(auction->item_guidlow); auctionHouse->RemoveAuction(auction, item_template); } - //called when player lists his bids void WorldSession::HandleAuctionListBidderItems(WorldPacket & recv_data) { uint64 guid; //NPC guid uint32 listfrom; //page of auctions uint32 outbiddedCount; //count of outbidded auctions - recv_data >> guid; recv_data >> listfrom; // not used in fact (this list not have page control in client) recv_data >> outbiddedCount; @@ -498,20 +427,16 @@ void WorldSession::HandleAuctionListBidderItems(WorldPacket & recv_data) sLog.outError("Client sent bad opcode!!! with count: %u and size : %lu (must be: %u)", outbiddedCount, (unsigned long)recv_data.size(),(16 + outbiddedCount * 4)); outbiddedCount = 0; } - Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid,UNIT_NPC_FLAG_AUCTIONEER); if (!pCreature) { sLog.outDebug("WORLD: HandleAuctionListBidderItems - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid))); return; } - // remove fake death if (GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); - AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap(pCreature->getFaction()); - WorldPacket data(SMSG_AUCTION_BIDDER_LIST_RESULT, (4+4+4)); Player *pl = GetPlayer(); data << (uint32) 0; //add 0 as count @@ -529,49 +454,39 @@ void WorldSession::HandleAuctionListBidderItems(WorldPacket & recv_data) ++count; } } - auctionHouse->BuildListBidderItems(data,pl,count,totalcount); data.put(0, count); // add count to placeholder data << totalcount; data << (uint32)300; //unk 2.3.0 SendPacket(&data); } - //this void sends player info about his auctions void WorldSession::HandleAuctionListOwnerItems(WorldPacket & recv_data) { uint32 listfrom; uint64 guid; - recv_data >> guid; recv_data >> listfrom; // not used in fact (this list not have page control in client) - Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid,UNIT_NPC_FLAG_AUCTIONEER); if (!pCreature) { sLog.outDebug("WORLD: HandleAuctionListOwnerItems - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid))); return; } - // remove fake death if (GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); - AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap(pCreature->getFaction()); - WorldPacket data(SMSG_AUCTION_OWNER_LIST_RESULT, (4+4+4)); data << (uint32) 0; // amount place holder - uint32 count = 0; uint32 totalcount = 0; - auctionHouse->BuildListOwnerItems(data,_player,count,totalcount); data.put(0, count); data << (uint32) totalcount; data << (uint32) 0; SendPacket(&data); } - //this void is called when player clicks on search button void WorldSession::HandleAuctionListItems(WorldPacket & recv_data) { @@ -579,61 +494,47 @@ void WorldSession::HandleAuctionListItems(WorldPacket & recv_data) uint8 levelmin, levelmax, usable; uint32 listfrom, auctionSlotID, auctionMainCategory, auctionSubCategory, quality; uint64 guid; - recv_data >> guid; recv_data >> listfrom; // start, used for page control listing by 50 elements recv_data >> searchedname; - recv_data >> levelmin >> levelmax; recv_data >> auctionSlotID >> auctionMainCategory >> auctionSubCategory; recv_data >> quality >> usable; - Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid,UNIT_NPC_FLAG_AUCTIONEER); if (!pCreature) { sLog.outDebug("WORLD: HandleAuctionListItems - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid))); return; } - // remove fake death if (GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); - AuctionHouseObject* auctionHouse = auctionmgr.GetAuctionsMap(pCreature->getFaction()); - //sLog.outDebug("Auctionhouse search (GUID: %u TypeId: %u)", , list from: %u, searchedname: %s, levelmin: %u, levelmax: %u, auctionSlotID: %u, auctionMainCategory: %u, auctionSubCategory: %u, quality: %u, usable: %u", // GUID_LOPART(guid),GuidHigh2TypeId(GUID_HIPART(guid)), listfrom, searchedname.c_str(), levelmin, levelmax, auctionSlotID, auctionMainCategory, auctionSubCategory, quality, usable); - WorldPacket data(SMSG_AUCTION_LIST_RESULT, (4+4+4)); uint32 count = 0; uint32 totalcount = 0; data << (uint32) 0; - // converting string that we try to find to lower case std::wstring wsearchedname; if (!Utf8toWStr(searchedname,wsearchedname)) return; - wstrToLower(wsearchedname); - auctionHouse->BuildListAuctionItems(data,_player, wsearchedname, listfrom, levelmin, levelmax, usable, auctionSlotID, auctionMainCategory, auctionSubCategory, quality, count,totalcount); - data.put(0, count); data << (uint32) totalcount; data << (uint32) 300; // unk 2.3.0 const? SendPacket(&data); } - void WorldSession::HandleAuctionListPendingSales(WorldPacket & recv_data) { sLog.outDebug("CMSG_AUCTION_LIST_PENDING_SALES"); recv_data.hexlike(); - uint32 count = 0; - WorldPacket data(SMSG_AUCTION_LIST_PENDING_SALES, 4); data << uint32(count); // count /*for (uint32 i = 0; i < count; ++i) diff --git a/src/game/AuctionHouseMgr.cpp b/src/game/AuctionHouseMgr.cpp index ffc0c55d9d3..2f7ba808fb3 100644 --- a/src/game/AuctionHouseMgr.cpp +++ b/src/game/AuctionHouseMgr.cpp @@ -15,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "Common.h" #include "ObjectMgr.h" #include "Player.h" @@ -26,7 +25,6 @@ #include "Database/SQLStorage.h" #include "Policies/SingletonImp.h" #include "DBCStores.h" - #include "AccountMgr.h" #include "AuctionHouseMgr.h" #include "Item.h" @@ -35,26 +33,20 @@ #include "ProgressBar.h" #include - INSTANTIATE_SINGLETON_1(AuctionHouseMgr); - using namespace std; - AuctionHouseMgr::AuctionHouseMgr() { } - AuctionHouseMgr::~AuctionHouseMgr() { for (ItemMap::const_iterator itr = mAitems.begin(); itr != mAitems.end(); ++itr) delete itr->second; } - AuctionHouseObject * AuctionHouseMgr::GetAuctionsMap(uint32 factionTemplateId) { if (sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION)) return &mNeutralAuctions; - // team have linked auction houses FactionTemplateEntry const* u_entry = sFactionTemplateStore.LookupEntry(factionTemplateId); if (!u_entry) @@ -66,18 +58,15 @@ AuctionHouseObject * AuctionHouseMgr::GetAuctionsMap(uint32 factionTemplateId) else return &mNeutralAuctions; } - uint32 AuctionHouseMgr::GetAuctionDeposit(AuctionHouseEntry const* entry, uint32 time, Item *pItem) { uint32 MSV = pItem->GetProto()->SellPrice; int32 deposit; uint32 timeHr = (((time / 60) / 60) / 12); - if (MSV > 0) deposit = (int32)floor((double)MSV * (((double)(entry->depositPercent * 3) / 100.0f * (double)sWorld.getRate(RATE_AUCTION_DEPOSIT) * (double)pItem->GetCount()))) * timeHr; else deposit = 0; - sLog.outDebug("SellPrice:\t\t%u", MSV); sLog.outDebug("Deposit Percent:\t%f", ((double)entry->depositPercent / 100.0f)); sLog.outDebug("Auction Time1:\t\t%u", time); @@ -95,14 +84,12 @@ uint32 AuctionHouseMgr::GetAuctionDeposit(AuctionHouseEntry const* entry, uint32 return 0; } } - //does not clear ram void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry *auction) { Item *pItem = GetAItem(auction->item_guidlow); if (!pItem) return; - uint32 bidder_accId = 0; uint32 bidder_security = 0; uint64 bidder_guid = MAKE_NEW_GUID(auction->bidder, 0, HIGHGUID_PLAYER); @@ -121,7 +108,6 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry *auction) { bidder_accId = objmgr.GetPlayerAccountIdByGUID(bidder_guid); bidder_security = accmgr.GetSecurity(bidder_accId); - if (bidder_security > SEC_PLAYER) // not do redundant DB requests { if (!objmgr.GetPlayerNameByGUID(bidder_guid,bidder_name)) @@ -133,44 +119,34 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry *auction) std::string owner_name; if (!objmgr.GetPlayerNameByGUID(auction->owner,owner_name)) owner_name = objmgr.GetTrinityStringForDBCLocale(LANG_UNKNOWN); - uint32 owner_accid = objmgr.GetPlayerAccountIdByGUID(auction->owner); - sLog.outCommand(bidder_accId,"GM %s (Account: %u) won item in auction: %s (Entry: %u Count: %u) and pay money: %u. Original owner %s (Account: %u)", bidder_name.c_str(),bidder_accId,pItem->GetProto()->Name1,pItem->GetEntry(),pItem->GetCount(),auction->bid,owner_name.c_str(),owner_accid); } } - // receiver exist if (bidder || bidder_accId) { std::ostringstream msgAuctionWonSubject; msgAuctionWonSubject << auction->item_template << ":0:" << AUCTION_WON; - std::ostringstream msgAuctionWonBody; msgAuctionWonBody.width(16); msgAuctionWonBody << std::right << std::hex << auction->owner; msgAuctionWonBody << std::dec << ":" << auction->bid << ":" << auction->buyout; sLog.outDebug("AuctionWon body string : %s", msgAuctionWonBody.str().c_str()); - //prepare mail data... : uint32 itemTextId = objmgr.CreateItemText(msgAuctionWonBody.str()); - // set owner to bidder (to prevent delete item with sender char deleting) // owner in `data` will set at mail receive and item extracting CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'",auction->bidder,pItem->GetGUIDLow()); CharacterDatabase.CommitTransaction(); - MailItemsInfo mi; mi.AddItem(auction->item_guidlow, auction->item_template, pItem); - if (bidder) bidder->GetSession()->SendAuctionBidderNotification(auction->GetHouseId(), auction->Id, bidder_guid, 0, 0, auction->item_template); - WorldSession::SendMailTo(bidder, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), auction->bidder, msgAuctionWonSubject.str(), itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_AUCTION); } } - void AuctionHouseMgr::SendAuctionSalePendingMail(AuctionEntry * auction) { uint64 owner_guid = MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER); @@ -181,26 +157,19 @@ void AuctionHouseMgr::SendAuctionSalePendingMail(AuctionEntry * auction) { std::ostringstream msgAuctionSalePendingSubject; msgAuctionSalePendingSubject << auction->item_template << ":0:" << AUCTION_SALE_PENDING; - std::ostringstream msgAuctionSalePendingBody; uint32 auctionCut = auction->GetAuctionCut(); - time_t distrTime = time(NULL) + sWorld.getConfig(CONFIG_MAIL_DELIVERY_DELAY); - msgAuctionSalePendingBody.width(16); msgAuctionSalePendingBody << std::right << std::hex << auction->bidder; msgAuctionSalePendingBody << std::dec << ":" << auction->bid << ":" << auction->buyout; msgAuctionSalePendingBody << ":" << auction->deposit << ":" << auctionCut << ":0:"; msgAuctionSalePendingBody << secsToTimeBitFields(distrTime); - sLog.outDebug("AuctionSalePending body string : %s", msgAuctionSalePendingBody.str().c_str()); - uint32 itemTextId = objmgr.CreateItemText(msgAuctionSalePendingBody.str()); - WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), auction->owner, msgAuctionSalePendingSubject.str(), itemTextId, NULL, 0, 0, MAIL_CHECK_MASK_AUCTION); } } - //call this method to send mail to auction owner, when auction is successful, it does not clear ram void AuctionHouseMgr::SendAuctionSuccessfulMail(AuctionEntry * auction) { @@ -212,21 +181,15 @@ void AuctionHouseMgr::SendAuctionSuccessfulMail(AuctionEntry * auction) { std::ostringstream msgAuctionSuccessfulSubject; msgAuctionSuccessfulSubject << auction->item_template << ":0:" << AUCTION_SUCCESSFUL; - std::ostringstream auctionSuccessfulBody; uint32 auctionCut = auction->GetAuctionCut(); - auctionSuccessfulBody.width(16); auctionSuccessfulBody << std::right << std::hex << auction->bidder; auctionSuccessfulBody << std::dec << ":" << auction->bid << ":" << auction->buyout; auctionSuccessfulBody << ":" << auction->deposit << ":" << auctionCut; - sLog.outDebug("AuctionSuccessful body string : %s", auctionSuccessfulBody.str().c_str()); - uint32 itemTextId = objmgr.CreateItemText(auctionSuccessfulBody.str()); - uint32 profit = auction->bid + auction->deposit - auctionCut; - //FIXME: what do if owner offline if (owner && owner->GetGUIDLow() != auctionbot.GetAHBplayerGUID()) { @@ -237,14 +200,12 @@ void AuctionHouseMgr::SendAuctionSuccessfulMail(AuctionEntry * auction) WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), auction->owner, msgAuctionSuccessfulSubject.str(), itemTextId, NULL, profit, 0, MAIL_CHECK_MASK_AUCTION, sWorld.getConfig(CONFIG_MAIL_DELIVERY_DELAY)); } } - //does not clear ram void AuctionHouseMgr::SendAuctionExpiredMail(AuctionEntry * auction) { //return an item in auction to its owner by mail Item *pItem = GetAItem(auction->item_guidlow); if (!pItem) return; - uint64 owner_guid = MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER); Player *owner = objmgr.GetPlayer(owner_guid); uint32 owner_accId = objmgr.GetPlayerAccountIdByGUID(owner_guid); @@ -253,22 +214,17 @@ void AuctionHouseMgr::SendAuctionExpiredMail(AuctionEntry * auction) { std::ostringstream subject; subject << auction->item_template << ":0:" << AUCTION_EXPIRED; - if (owner && owner->GetGUIDLow() != auctionbot.GetAHBplayerGUID()) owner->GetSession()->SendAuctionOwnerNotification(auction); - MailItemsInfo mi; mi.AddItem(auction->item_guidlow, auction->item_template, pItem); - WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), GUID_LOPART(owner_guid), subject.str(), 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE); } } - void AuctionHouseMgr::LoadAuctionItems() { // data needs to be at first place for Item::LoadFromDB QueryResult *result = CharacterDatabase.Query("SELECT data,itemguid,item_template FROM auctionhouse JOIN item_instance ON itemguid = guid"); - if (!result) { barGoLink bar(1); @@ -277,45 +233,34 @@ void AuctionHouseMgr::LoadAuctionItems() sLog.outString(">> Loaded 0 auction items"); return; } - barGoLink bar(result->GetRowCount()); - uint32 count = 0; - Field *fields; do { bar.step(); - fields = result->Fetch(); uint32 item_guid = fields[1].GetUInt32(); uint32 item_template = fields[2].GetUInt32(); - ItemPrototype const *proto = objmgr.GetItemPrototype(item_template); - if (!proto) { sLog.outError("AuctionHouseMgr::LoadAuctionItems: Unknown item (GUID: %u id: #%u) in auction, skipped.", item_guid,item_template); continue; } - Item *item = NewItemOrBag(proto); - if (!item->LoadFromDB(item_guid,0, result)) { delete item; continue; } AddAItem(item); - ++count; } while (result->NextRow()); delete result; - sLog.outString(); sLog.outString(">> Loaded %u auction items", count); } - void AuctionHouseMgr::LoadAuctions() { QueryResult *result = CharacterDatabase.Query("SELECT COUNT(*) FROM auctionhouse"); @@ -327,11 +272,9 @@ void AuctionHouseMgr::LoadAuctions() sLog.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty."); return; } - Field *fields = result->Fetch(); uint32 AuctionCount=fields[0].GetUInt32(); delete result; - if (!AuctionCount) { barGoLink bar(1); @@ -340,7 +283,6 @@ void AuctionHouseMgr::LoadAuctions() sLog.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty."); return; } - result = CharacterDatabase.Query("SELECT id,auctioneerguid,itemguid,item_template,itemowner,buyoutprice,time,buyguid,lastbid,startbid,deposit FROM auctionhouse"); if (!result) { @@ -350,17 +292,12 @@ void AuctionHouseMgr::LoadAuctions() sLog.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty."); return; } - barGoLink bar(AuctionCount); - AuctionEntry *aItem; - do { fields = result->Fetch(); - bar.step(); - aItem = new AuctionEntry; aItem->Id = fields[0].GetUInt32(); aItem->auctioneer = fields[1].GetUInt32(); @@ -373,7 +310,6 @@ void AuctionHouseMgr::LoadAuctions() aItem->bid = fields[8].GetUInt32(); aItem->startbid = fields[9].GetUInt32(); aItem->deposit = fields[10].GetUInt32(); - CreatureData const* auctioneerData = objmgr.GetCreatureData(aItem->auctioneer); if (!auctioneerData) { @@ -382,7 +318,6 @@ void AuctionHouseMgr::LoadAuctions() delete aItem; continue; } - CreatureInfo const* auctioneerInfo = objmgr.GetCreatureTemplate(auctioneerData->id); if (!auctioneerInfo) { @@ -391,7 +326,6 @@ void AuctionHouseMgr::LoadAuctions() delete aItem; continue; } - aItem->auctionHouseEntry = AuctionHouseMgr::GetAuctionHouseEntry(auctioneerInfo->faction_A); if (!aItem->auctionHouseEntry) { @@ -401,7 +335,6 @@ void AuctionHouseMgr::LoadAuctions() delete aItem; continue; } - // check if sold item exists for guid // and item_template in fact (GetAItem will fail if problematic in result check in AuctionHouseMgr::LoadAuctionItems) if (!GetAItem(aItem->item_guidlow)) @@ -411,44 +344,35 @@ void AuctionHouseMgr::LoadAuctions() delete aItem; continue; } - GetAuctionsMap(auctioneerInfo->faction_A)->AddAuction(aItem); - } while (result->NextRow()); delete result; - sLog.outString(); sLog.outString(">> Loaded %u auctions", AuctionCount); } - void AuctionHouseMgr::AddAItem(Item* it) { ASSERT(it); ASSERT(mAitems.find(it->GetGUIDLow()) == mAitems.end()); mAitems[it->GetGUIDLow()] = it; } - bool AuctionHouseMgr::RemoveAItem(uint32 id) { ItemMap::iterator i = mAitems.find(id); if (i == mAitems.end()) return false; - mAitems.erase(i); return true; } - void AuctionHouseMgr::Update() { mHordeAuctions.Update(); mAllianceAuctions.Update(); mNeutralAuctions.Update(); } - AuctionHouseEntry const* AuctionHouseMgr::GetAuctionHouseEntry(uint32 factionTemplateId) { uint32 houseid = 7; // goblin auction house - if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION)) { //FIXME: found way for proper auctionhouse selection by another way @@ -481,7 +405,6 @@ AuctionHouseEntry const* AuctionHouseMgr::GetAuctionHouseEntry(uint32 factionTem } } } - return sAuctionHouseStore.LookupEntry(houseid); } void AuctionHouseObject::AddAuction(AuctionEntry *ah) @@ -490,57 +413,45 @@ AuctionHouseEntry const* AuctionHouseMgr::GetAuctionHouseEntry(uint32 factionTem AuctionsMap[ah->Id] = ah; auctionbot.IncrementItemCounts(ah); } - bool AuctionHouseObject::RemoveAuction(AuctionEntry *auction, uint32 item_template) { auctionbot.DecrementItemCounts(auction, item_template); return AuctionsMap.erase(auction->Id) ? true : false; } - void AuctionHouseObject::Update() { time_t curTime = sWorld.GetGameTime(); ///- Handle expired auctions - // If storage is empty, no need to update. next == NULL in this case. if (AuctionsMap.empty()) return; - QueryResult* result = CharacterDatabase.PQuery("SELECT id FROM auctionhouse WHERE time <= %u ORDER BY TIME ASC", (uint32)curTime+60); - if (!result) { delete result; return; } - if (result->GetRowCount() == 0) { delete result; return; } - vector expiredAuctions; - do { uint32 tmpdata = result->Fetch()->GetUInt32(); expiredAuctions.push_back(tmpdata); } while (result->NextRow()); delete result; - vector::iterator iter = expiredAuctions.begin(); while (!expiredAuctions.empty()) { // from auctionhousehandler.cpp, creates auction pointer & player pointer AuctionEntry* auction = GetAuction(*iter); - // Erase the auction from the vector. expiredAuctions.erase(iter); - if (!auction) continue; - ///- Either cancel the auction if there was no bidder if (auction->bidder == 0) auctionmgr.SendAuctionExpiredMail(auction); @@ -553,7 +464,6 @@ void AuctionHouseObject::Update() auctionmgr.SendAuctionSuccessfulMail(auction); auctionmgr.SendAuctionWonMail(auction); } - ///- In any case clear the auction auction->DeleteFromDB(); uint32 item_template = auction->item_template; @@ -561,7 +471,6 @@ void AuctionHouseObject::Update() RemoveAuction(auction, item_template); } } - void AuctionHouseObject::BuildListBidderItems(WorldPacket& data, Player* player, uint32& count, uint32& totalcount) { for (AuctionEntryMap::const_iterator itr = AuctionsMap.begin();itr != AuctionsMap.end();++itr) @@ -571,12 +480,10 @@ void AuctionHouseObject::BuildListBidderItems(WorldPacket& data, Player* player, { if (itr->second->BuildAuctionInfo(data)) ++count; - ++totalcount; } } } - void AuctionHouseObject::BuildListOwnerItems(WorldPacket& data, Player* player, uint32& count, uint32& totalcount) { for (AuctionEntryMap::const_iterator itr = AuctionsMap.begin();itr != AuctionsMap.end();++itr) @@ -586,50 +493,38 @@ void AuctionHouseObject::BuildListOwnerItems(WorldPacket& data, Player* player, { if (Aentry->BuildAuctionInfo(data)) ++count; - ++totalcount; } } } - void AuctionHouseObject::BuildListAuctionItems(WorldPacket& data, Player* player, std::wstring const& wsearchedname, uint32 listfrom, uint32 levelmin, uint32 levelmax, uint32 usable, uint32 inventoryType, uint32 itemClass, uint32 itemSubClass, uint32 quality, uint32& count, uint32& totalcount) { int loc_idx = player->GetSession()->GetSessionDbLocaleIndex(); - for (AuctionEntryMap::const_iterator itr = AuctionsMap.begin();itr != AuctionsMap.end();++itr) { AuctionEntry *Aentry = itr->second; Item *item = auctionmgr.GetAItem(Aentry->item_guidlow); if (!item) continue; - ItemPrototype const *proto = item->GetProto(); - if (itemClass != 0xffffffff && proto->Class != itemClass) continue; - if (itemSubClass != 0xffffffff && proto->SubClass != itemSubClass) continue; - if (inventoryType != 0xffffffff && proto->InventoryType != inventoryType) continue; - if (quality != 0xffffffff && proto->Quality != quality) continue; - if (levelmin != 0x00 && (proto->RequiredLevel < levelmin || (levelmax != 0x00 && proto->RequiredLevel > levelmax))) continue; - if (usable != 0x00 && player->CanUseItem(item) != EQUIP_ERR_OK) continue; - std::string name = proto->Name1; if (name.empty()) continue; - // local name if (loc_idx >= 0) { @@ -640,10 +535,8 @@ void AuctionHouseObject::BuildListAuctionItems(WorldPacket& data, Player* player name = il->Name[loc_idx]; } } - if (!wsearchedname.empty() && !Utf8FitTo(name, wsearchedname)) continue; - if (count < 50 && totalcount >= listfrom) { ++count; @@ -652,7 +545,6 @@ void AuctionHouseObject::BuildListAuctionItems(WorldPacket& data, Player* player ++totalcount; } } - //this function inserts to WorldPacket auction's data bool AuctionEntry::BuildAuctionInfo(WorldPacket & data) const { @@ -664,14 +556,12 @@ bool AuctionEntry::BuildAuctionInfo(WorldPacket & data) const } data << uint32(Id); data << uint32(pItem->GetEntry()); - for (uint8 i = 0; i < MAX_INSPECTED_ENCHANTMENT_SLOT; ++i) { data << uint32(pItem->GetEnchantmentId(EnchantmentSlot(i))); data << uint32(pItem->GetEnchantmentDuration(EnchantmentSlot(i))); data << uint32(pItem->GetEnchantmentCharges(EnchantmentSlot(i))); } - data << uint32(pItem->GetItemRandomPropertyId()); //random item property id data << uint32(pItem->GetItemSuffixFactor()); //SuffixFactor data << uint32(pItem->GetCount()); //item->count @@ -687,7 +577,6 @@ bool AuctionEntry::BuildAuctionInfo(WorldPacket & data) const data << uint32(bid); //current bid return true; } - uint32 AuctionEntry::GetAuctionCut() const { int32 cut = int32(((double)auctionHouseEntry->cutPercent / 100.0f) * (double)sWorld.getRate(RATE_AUCTION_CUT)) * bid; @@ -696,7 +585,6 @@ uint32 AuctionEntry::GetAuctionCut() const else return 0; } - /// the sum of outbid is (1% from current bid)*5, if bid is very small, it is 1c uint32 AuctionEntry::GetAuctionOutBid() const { @@ -705,13 +593,11 @@ uint32 AuctionEntry::GetAuctionOutBid() const outbid = 1; return outbid; } - void AuctionEntry::DeleteFromDB() const { //No SQL injection (Id is integer) CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",Id); } - void AuctionEntry::SaveToDB() const { //No SQL injection (no strings) diff --git a/src/game/AuctionHouseMgr.h b/src/game/AuctionHouseMgr.h index 0e3ead4f608..5d62e16ab85 100644 --- a/src/game/AuctionHouseMgr.h +++ b/src/game/AuctionHouseMgr.h @@ -17,22 +17,15 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef _AUCTION_HOUSE_MGR_H #define _AUCTION_HOUSE_MGR_H - #include "Policies/Singleton.h" - #include "SharedDefines.h" - #include "AuctionHouseBot.h" - class Item; class Player; class WorldPacket; - #define MIN_AUCTION_TIME (12*HOUR) - enum AuctionError { AUCTION_OK = 0, @@ -41,14 +34,12 @@ enum AuctionError AUCTION_ITEM_NOT_FOUND = 4, CANNOT_BID_YOUR_AUCTION_ERROR = 10 }; - enum AuctionAction { AUCTION_SELL_ITEM = 0, AUCTION_CANCEL = 1, AUCTION_PLACE_BID = 2 }; - struct AuctionEntry { uint32 Id; @@ -63,7 +54,6 @@ struct AuctionEntry uint32 bidder; uint32 deposit; //deposit can be calculated only when creating auction AuctionHouseEntry const* auctionHouseEntry; // in AuctionHouse.dbc - // helpers uint32 GetHouseId() const { return auctionHouseEntry->houseId; } uint32 GetHouseFaction() const { return auctionHouseEntry->faction; } @@ -73,7 +63,6 @@ struct AuctionEntry void DeleteFromDB() const; void SaveToDB() const; }; - //this class is used as auctionhouse instance class AuctionHouseObject { @@ -85,51 +74,37 @@ class AuctionHouseObject for (AuctionEntryMap::iterator itr = AuctionsMap.begin(); itr != AuctionsMap.end(); ++itr) delete itr->second; } - typedef std::map AuctionEntryMap; - uint32 Getcount() { return AuctionsMap.size(); } - AuctionEntryMap::iterator GetAuctionsBegin() {return AuctionsMap.begin();} AuctionEntryMap::iterator GetAuctionsEnd() {return AuctionsMap.end();} - AuctionEntry* GetAuction(uint32 id) const { AuctionEntryMap::const_iterator itr = AuctionsMap.find(id); return itr != AuctionsMap.end() ? itr->second : NULL; } - void AddAuction(AuctionEntry *ah); - bool RemoveAuction(AuctionEntry *auction, uint32 item_template); - void Update(); - void BuildListBidderItems(WorldPacket& data, Player* player, uint32& count, uint32& totalcount); void BuildListOwnerItems(WorldPacket& data, Player* player, uint32& count, uint32& totalcount); void BuildListAuctionItems(WorldPacket& data, Player* player, std::wstring const& searchedname, uint32 listfrom, uint32 levelmin, uint32 levelmax, uint32 usable, uint32 inventoryType, uint32 itemClass, uint32 itemSubClass, uint32 quality, uint32& count, uint32& totalcount); - private: AuctionEntryMap AuctionsMap; - // storage for "next" auction item for next Update() AuctionEntryMap::const_iterator next; }; - class AuctionHouseMgr { public: AuctionHouseMgr(); ~AuctionHouseMgr(); - typedef UNORDERED_MAP ItemMap; - AuctionHouseObject* GetAuctionsMap(uint32 factionTemplateId); AuctionHouseObject* GetBidsMap(uint32 factionTemplateId); - Item* GetAItem(uint32 id) { ItemMap::const_iterator itr = mAitems.find(id); @@ -139,7 +114,6 @@ class AuctionHouseMgr } return NULL; } - //auction messages void SendAuctionWonMail(AuctionEntry * auction); void SendAuctionSalePendingMail(AuctionEntry * auction); @@ -147,25 +121,18 @@ class AuctionHouseMgr void SendAuctionExpiredMail(AuctionEntry * auction); static uint32 GetAuctionDeposit(AuctionHouseEntry const* entry, uint32 time, Item *pItem); static AuctionHouseEntry const* GetAuctionHouseEntry(uint32 factionTemplateId); - public: //load first auction items, because of check if item exists, when loading void LoadAuctionItems(); void LoadAuctions(); - void AddAItem(Item* it); bool RemoveAItem(uint32 id); - void Update(); - private: AuctionHouseObject mHordeAuctions; AuctionHouseObject mAllianceAuctions; AuctionHouseObject mNeutralAuctions; - ItemMap mAitems; }; - #define auctionmgr Trinity::Singleton::Instance() - #endif diff --git a/src/game/Bag.cpp b/src/game/Bag.cpp index 2d58b63c0a9..5b406c2eb08 100644 --- a/src/game/Bag.cpp +++ b/src/game/Bag.cpp @@ -17,25 +17,19 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "Common.h" #include "ObjectMgr.h" #include "Database/DatabaseEnv.h" - #include "Bag.h" #include "Log.h" #include "UpdateData.h" - Bag::Bag( ): Item() { m_objectType |= TYPEMASK_CONTAINER; m_objectTypeId = TYPEID_CONTAINER; - m_valuesCount = CONTAINER_END; - memset(m_bagslot, 0, sizeof(Item *) * MAX_BAG_SIZE); } - Bag::~Bag() { for(uint8 i = 0; i < MAX_BAG_SIZE; ++i) @@ -51,68 +45,52 @@ Bag::~Bag() delete m_bagslot[i]; } } - void Bag::AddToWorld() { Item::AddToWorld(); - for(uint32 i = 0; i < GetBagSize(); ++i) if(m_bagslot[i]) m_bagslot[i]->AddToWorld(); } - void Bag::RemoveFromWorld() { for(uint32 i = 0; i < GetBagSize(); ++i) if(m_bagslot[i]) m_bagslot[i]->RemoveFromWorld(); - Item::RemoveFromWorld(); } - bool Bag::Create(uint32 guidlow, uint32 itemid, Player const* owner) { ItemPrototype const * itemProto = objmgr.GetItemPrototype(itemid); - if(!itemProto || itemProto->ContainerSlots > MAX_BAG_SIZE) return false; - Object::_Create( guidlow, 0, HIGHGUID_CONTAINER ); - SetEntry(itemid); SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f); - SetUInt64Value(ITEM_FIELD_OWNER, owner ? owner->GetGUID() : 0); SetUInt64Value(ITEM_FIELD_CONTAINED, owner ? owner->GetGUID() : 0); - SetUInt32Value(ITEM_FIELD_MAXDURABILITY, itemProto->MaxDurability); SetUInt32Value(ITEM_FIELD_DURABILITY, itemProto->MaxDurability); SetUInt32Value(ITEM_FIELD_FLAGS, itemProto->Flags); SetUInt32Value(ITEM_FIELD_STACK_COUNT, 1); - // Setting the number of Slots the Container has SetUInt32Value(CONTAINER_FIELD_NUM_SLOTS, itemProto->ContainerSlots); - // Cleaning 20 slots for (uint8 i = 0; i < MAX_BAG_SIZE; ++i) { SetUInt64Value(CONTAINER_FIELD_SLOT_1 + (i*2), 0); m_bagslot[i] = NULL; } - return true; } - void Bag::SaveToDB() { Item::SaveToDB(); } - bool Bag::LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult *result) { if(!Item::LoadFromDB(guid, owner_guid, result)) return false; - // cleanup bag content related item value fields (its will be filled correctly from `character_inventory`) for (uint8 i = 0; i < MAX_BAG_SIZE; ++i) { @@ -123,44 +101,34 @@ bool Bag::LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult *result) m_bagslot[i] = NULL; } } - return true; } - void Bag::DeleteFromDB() { for (uint8 i = 0; i < MAX_BAG_SIZE; ++i) if (m_bagslot[i]) m_bagslot[i]->DeleteFromDB(); - Item::DeleteFromDB(); } - uint32 Bag::GetFreeSlots() const { uint32 slots = 0; for (uint32 i=0; i < GetBagSize(); ++i) if (!m_bagslot[i]) ++slots; - return slots; } - void Bag::RemoveItem( uint8 slot, bool /*update*/ ) { assert(slot < MAX_BAG_SIZE); - if (m_bagslot[slot]) m_bagslot[slot]->SetContainer(NULL); - m_bagslot[slot] = NULL; SetUInt64Value( CONTAINER_FIELD_SLOT_1 + (slot * 2), 0 ); } - void Bag::StoreItem( uint8 slot, Item *pItem, bool /*update*/ ) { assert(slot < MAX_BAG_SIZE); - if( pItem ) { m_bagslot[slot] = pItem; @@ -171,26 +139,21 @@ void Bag::StoreItem( uint8 slot, Item *pItem, bool /*update*/ ) pItem->SetSlot(slot); } } - void Bag::BuildCreateUpdateBlockForPlayer( UpdateData *data, Player *target ) const { Item::BuildCreateUpdateBlockForPlayer( data, target ); - for (uint32 i = 0; i < GetBagSize(); ++i) if(m_bagslot[i]) m_bagslot[i]->BuildCreateUpdateBlockForPlayer( data, target ); } - // If the bag is empty returns true bool Bag::IsEmpty() const { for(uint32 i = 0; i < GetBagSize(); ++i) if (m_bagslot[i]) return false; - return true; } - uint32 Bag::GetItemCount( uint32 item, Item* eItem ) const { Item *pItem; @@ -201,7 +164,6 @@ uint32 Bag::GetItemCount( uint32 item, Item* eItem ) const if( pItem && pItem != eItem && pItem->GetEntry() == item ) count += pItem->GetCount(); } - if(eItem && eItem->GetProto()->GemProperties) { for(uint32 i=0; i < GetBagSize(); ++i) @@ -211,25 +173,20 @@ uint32 Bag::GetItemCount( uint32 item, Item* eItem ) const count += pItem->GetGemCountWithID(item); } } - return count; } - uint8 Bag::GetSlotByItemGUID(uint64 guid) const { for(uint32 i = 0; i < GetBagSize(); ++i) if(m_bagslot[i] != 0) if(m_bagslot[i]->GetGUID() == guid) return i; - return NULL_SLOT; } - Item* Bag::GetItemByPos( uint8 slot ) const { if( slot < GetBagSize() ) return m_bagslot[slot]; - return NULL; } diff --git a/src/game/Bag.h b/src/game/Bag.h index 3ae786512ce..649c2e21a27 100644 --- a/src/game/Bag.h +++ b/src/game/Bag.h @@ -17,40 +17,29 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef TRINITY_BAG_H #define TRINITY_BAG_H - // Maximum 36 Slots ( (CONTAINER_END - CONTAINER_FIELD_SLOT_1)/2 #define MAX_BAG_SIZE 36 // 2.0.12 - #include "Item.h" #include "ItemPrototype.h" - class Bag : public Item { public: - Bag(); ~Bag(); - void AddToWorld(); void RemoveFromWorld(); - bool Create(uint32 guidlow, uint32 itemid, Player const* owner); - void Clear(); void StoreItem( uint8 slot, Item *pItem, bool update ); void RemoveItem( uint8 slot, bool update ); - Item* GetItemByPos( uint8 slot ) const; uint32 GetItemCount( uint32 item, Item* eItem = NULL ) const; - uint8 GetSlotByItemGUID(uint64 guid) const; bool IsEmpty() const; uint32 GetFreeSlots() const; uint32 GetBagSize() const { return GetUInt32Value(CONTAINER_FIELD_NUM_SLOTS); } - // DB operations // overwrite virtual Item::SaveToDB void SaveToDB(); @@ -58,15 +47,11 @@ class Bag : public Item bool LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult *result = NULL); // overwrite virtual Item::DeleteFromDB void DeleteFromDB(); - void BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) const; - protected: - // Bag Storage space Item* m_bagslot[MAX_BAG_SIZE]; }; - inline Item* NewItemOrBag(ItemPrototype const * proto) { return (proto->InventoryType == INVTYPE_BAG) ? new Bag : new Item; diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp index 3eb699472d8..92c82f620f5 100644 --- a/src/game/BattleGround.cpp +++ b/src/game/BattleGround.cpp @@ -17,12 +17,10 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "Player.h" #include "ObjectMgr.h" #include "World.h" #include "WorldPacket.h" - #include "ArenaTeam.h" #include "BattleGround.h" #include "BattleGroundMgr.h" @@ -36,7 +34,6 @@ #include "SpellAuras.h" #include "Util.h" - namespace MaNGOS { class BattleGroundChatBuilder @@ -47,17 +44,14 @@ namespace MaNGOS void operator()(WorldPacket& data, int32 loc_idx) { char const* text = objmgr.GetMangosString(i_textId,loc_idx); - if (i_args) { // we need copy va_list before use or original va_list will corrupted va_list ap; va_copy(ap,*i_args); - char str [2048]; vsnprintf(str,2048,text, ap ); va_end(ap); - do_helper(data,&str[0]); } else @@ -67,7 +61,6 @@ namespace MaNGOS void do_helper(WorldPacket& data, char const* text) { uint64 target_guid = i_source ? i_source ->GetGUID() : 0; - data << uint8(i_msgtype); data << uint32(LANG_UNIVERSAL); data << uint64(target_guid); // there 0 for BG messages @@ -77,13 +70,11 @@ namespace MaNGOS data << text; data << uint8(i_source ? i_source->chatTag() : uint8(0)); } - ChatMsg i_msgtype; int32 i_textId; Player const* i_source; va_list* i_args; }; - class BattleGround2ChatBuilder { public: @@ -94,12 +85,9 @@ namespace MaNGOS char const* text = objmgr.GetMangosString(i_textId,loc_idx); char const* arg1str = i_arg1 ? objmgr.GetMangosString(i_arg1,loc_idx) : ""; char const* arg2str = i_arg2 ? objmgr.GetMangosString(i_arg2,loc_idx) : ""; - char str [2048]; snprintf(str,2048,text, arg1str, arg2str ); - uint64 target_guid = i_source ? i_source ->GetGUID() : 0; - data << uint8(i_msgtype); data << uint32(LANG_UNIVERSAL); data << uint64(target_guid); // there 0 for BG messages @@ -110,7 +98,6 @@ namespace MaNGOS data << uint8(i_source ? i_source->chatTag() : uint8(0)); } private: - ChatMsg i_msgtype; int32 i_textId; Player const* i_source; @@ -118,7 +105,6 @@ namespace MaNGOS int32 i_arg2; }; } // namespace MaNGOS - template void BattleGround::BroadcastWorker(Do& _do) { @@ -126,7 +112,6 @@ void BattleGround::BroadcastWorker(Do& _do) if (Player *plr = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER))) _do(plr); } - BattleGround::BattleGround() { m_TypeID = BattleGroundTypeId(0); @@ -150,46 +135,32 @@ BattleGround::BattleGround() m_LevelMax = 0; m_InBGFreeSlotQueue = false; m_SetDeleteThis = false; - m_MaxPlayersPerTeam = 0; m_MaxPlayers = 0; m_MinPlayersPerTeam = 0; m_MinPlayers = 0; - m_MapId = 0; - m_TeamStartLocX[BG_TEAM_ALLIANCE] = 0; m_TeamStartLocX[BG_TEAM_HORDE] = 0; - m_TeamStartLocY[BG_TEAM_ALLIANCE] = 0; m_TeamStartLocY[BG_TEAM_HORDE] = 0; - m_TeamStartLocZ[BG_TEAM_ALLIANCE] = 0; m_TeamStartLocZ[BG_TEAM_HORDE] = 0; - m_TeamStartLocO[BG_TEAM_ALLIANCE] = 0; m_TeamStartLocO[BG_TEAM_HORDE] = 0; - m_ArenaTeamIds[BG_TEAM_ALLIANCE] = 0; m_ArenaTeamIds[BG_TEAM_HORDE] = 0; - m_ArenaTeamRatingChanges[BG_TEAM_ALLIANCE] = 0; m_ArenaTeamRatingChanges[BG_TEAM_HORDE] = 0; - m_BgRaids[BG_TEAM_ALLIANCE] = NULL; m_BgRaids[BG_TEAM_HORDE] = NULL; - m_PlayersCount[BG_TEAM_ALLIANCE] = 0; m_PlayersCount[BG_TEAM_HORDE] = 0; - m_TeamScores[BG_TEAM_ALLIANCE] = 0; m_TeamScores[BG_TEAM_HORDE] = 0; - m_PrematureCountDown = false; m_PrematureCountDown = 0; - m_HonorMode = BG_NORMAL; - m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_2M; m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_1M; m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_30S; @@ -200,7 +171,6 @@ BattleGround::BattleGround() m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_WS_START_HALF_MINUTE; m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_WS_HAS_BEGUN; } - BattleGround::~BattleGround() { // remove objects and creatures @@ -208,11 +178,9 @@ BattleGround::~BattleGround() int size = m_BgCreatures.size(); for(int i = 0; i < size; ++i) DelCreature(i); - size = m_BgObjects.size(); for(int i = 0; i < size; ++i) DelObject(i); - if (GetInstanceID()) // not spam by useless queries in case BG templates { // delete creature and go respawn times @@ -222,7 +190,6 @@ BattleGround::~BattleGround() CharacterDatabase.PExecute("DELETE FROM instance WHERE id = '%u'",GetInstanceID()); // remove from battlegrounds } - sBattleGroundMgr.RemoveBattleGround(GetInstanceID(), GetTypeID()); // unload map if (Map * map = MapManager::Instance().FindMap(GetMapId(), GetInstanceID())) @@ -230,11 +197,9 @@ BattleGround::~BattleGround() ((BattleGroundMap*)map)->SetUnload(); // remove from bg free slot queue this->RemoveFromBGFreeSlotQueue(); - for(BattleGroundScoreMap::const_iterator itr = m_PlayerScores.begin(); itr != m_PlayerScores.end(); ++itr) delete itr->second; } - void BattleGround::Update(uint32 diff) { if (!GetPlayersSize()) @@ -253,7 +218,6 @@ void BattleGround::Update(uint32 diff) m_SetDeleteThis = true; return; } - // remove offline players from bg after 5 minutes if (!m_OfflineQueue.empty()) { @@ -268,11 +232,9 @@ void BattleGround::Update(uint32 diff) } } } - /*********************************************************/ /*** BATTLEGROUND RESSURECTION SYSTEM ***/ /*********************************************************/ - //this should be handled by spell system m_LastResurrectTime += diff; if (m_LastResurrectTime >= RESURRECTION_INTERVAL) @@ -287,7 +249,6 @@ void BattleGround::Update(uint32 diff) Player *plr = objmgr.GetPlayer(*itr2); if (!plr) continue; - if (!sh && plr->IsInWorld()) { sh = plr->GetMap()->GetCreature(itr->first); @@ -296,14 +257,12 @@ void BattleGround::Update(uint32 diff) // Spirit Heal, effect 117 sh->CastSpell(sh, SPELL_SPIRIT_HEAL, true); } - // Resurrection visual plr->CastSpell(plr, SPELL_RESURRECTION_VISUAL, true); m_ResurrectQueue.push_back(*itr2); } (itr->second).clear(); } - m_ReviveQueue.clear(); m_LastResurrectTime = 0; } @@ -325,11 +284,9 @@ void BattleGround::Update(uint32 diff) } m_ResurrectQueue.clear(); } - /*********************************************************/ /*** BATTLEGROUND BALLANCE SYSTEM ***/ /*********************************************************/ - // if less then minimum players are in on one side, then start premature finish timer if (GetStatus() == STATUS_IN_PROGRESS && !isArena() && sBattleGroundMgr.GetPrematureFinishTime() && (GetPlayersCountByTeam(ALLIANCE) < GetMinPlayersPerTeam() || GetPlayersCountByTeam(HORDE) < GetMinPlayersPerTeam())) { @@ -346,7 +303,6 @@ void BattleGround::Update(uint32 diff) winner = ALLIANCE; else if (GetPlayersCountByTeam(HORDE) >= GetMinPlayersPerTeam()) winner = HORDE; - EndBattleGround(winner); m_PrematureCountDown = false; } @@ -370,26 +326,21 @@ void BattleGround::Update(uint32 diff) } else if (m_PrematureCountDown) m_PrematureCountDown = false; - /*********************************************************/ /*** BATTLEGROUND STARTING SYSTEM ***/ /*********************************************************/ - if (GetStatus() == STATUS_WAIT_JOIN && GetPlayersSize()) { ModifyStartDelayTime(diff); - if (!(m_Events & BG_STARTING_EVENT_1)) { m_Events |= BG_STARTING_EVENT_1; - // setup here, only when at least one player has ported to the map if (!SetupBattleGround()) { EndNow(); return; } - StartingEventCloseDoors(); SetStartDelayTime(m_StartDelayTimes[BG_STARTING_EVENT_FIRST]); //first start warning - 2 or 1 minute @@ -411,18 +362,14 @@ void BattleGround::Update(uint32 diff) else if (GetStartDelayTime() <= 0 && !(m_Events & BG_STARTING_EVENT_4)) { m_Events |= BG_STARTING_EVENT_4; - StartingEventOpenDoors(); - SendMessageToAll(m_StartMessageIds[BG_STARTING_EVENT_FOURTH], CHAT_MSG_BG_SYSTEM_NEUTRAL); SetStatus(STATUS_IN_PROGRESS); SetStartDelayTime(m_StartDelayTimes[BG_STARTING_EVENT_FOURTH]); - //remove preparation if (isArena()) { //TODO : add arena sound PlaySoundToAll(SOUND_ARENA_START); - for(BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr) if (Player *plr = objmgr.GetPlayer(itr->first)) { @@ -443,14 +390,11 @@ void BattleGround::Update(uint32 diff) ++iter; } } - CheckArenaWinConditions(); } else { - PlaySoundToAll(SOUND_BG_START); - for(BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr) if (Player* plr = objmgr.GetPlayer(itr->first)) plr->RemoveAurasDueToSpell(SPELL_PREPARATION); @@ -462,11 +406,9 @@ void BattleGround::Update(uint32 diff) } } } - /*********************************************************/ /*** BATTLEGROUND ENDING SYSTEM ***/ /*********************************************************/ - if (GetStatus() == STATUS_WAIT_LEAVE) { // remove all players from battleground after 2 minutes @@ -485,11 +427,9 @@ void BattleGround::Update(uint32 diff) } } } - //update start time m_StartTime += diff; } - void BattleGround::SetTeamStartLoc(uint32 TeamID, float X, float Y, float Z, float O) { BattleGroundTeamId idx = GetTeamIndexByTeamId(TeamID); @@ -498,7 +438,6 @@ void BattleGround::SetTeamStartLoc(uint32 TeamID, float X, float Y, float Z, flo m_TeamStartLocZ[idx] = Z; m_TeamStartLocO[idx] = O; } - void BattleGround::SendPacketToAll(WorldPacket *packet) { for(BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) @@ -510,54 +449,43 @@ void BattleGround::SendPacketToAll(WorldPacket *packet) sLog.outError("BattleGround: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); } } - void BattleGround::SendPacketToTeam(uint32 TeamID, WorldPacket *packet, Player *sender, bool self) { for(BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { Player *plr = objmgr.GetPlayer(itr->first); - if (!plr) { sLog.outError("BattleGround: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); continue; } - if (!self && sender == plr) continue; - uint32 team = itr->second.Team; if(!team) team = plr->GetTeam(); - if (team == TeamID) plr->GetSession()->SendPacket(packet); } } - void BattleGround::PlaySoundToAll(uint32 SoundID) { WorldPacket data; sBattleGroundMgr.BuildPlaySoundPacket(&data, SoundID); SendPacketToAll(&data); } - void BattleGround::PlaySoundToTeam(uint32 SoundID, uint32 TeamID) { WorldPacket data; - for(BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { Player *plr = objmgr.GetPlayer(itr->first); - if (!plr) { sLog.outError("BattleGround: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); continue; } - uint32 team = itr->second.Team; if(!team) team = plr->GetTeam(); - if (team == TeamID) { sBattleGroundMgr.BuildPlaySoundPacket(&data, SoundID); @@ -565,27 +493,22 @@ void BattleGround::PlaySoundToTeam(uint32 SoundID, uint32 TeamID) } } } - void BattleGround::CastSpellOnTeam(uint32 SpellID, uint32 TeamID) { for(BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { Player *plr = objmgr.GetPlayer(itr->first); - if (!plr) { sLog.outError("BattleGround: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); continue; } - uint32 team = itr->second.Team; if(!team) team = plr->GetTeam(); - if (team == TeamID) plr->CastSpell(plr, SpellID, true); } } - void BattleGround::YellToAll(Creature* creature, const char* text, uint32 language) { for(std::map::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) @@ -602,102 +525,81 @@ void BattleGround::YellToAll(Creature* creature, const char* text, uint32 langua } } - void BattleGround::RewardHonorToTeam(uint32 Honor, uint32 TeamID) { for(BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { Player *plr = objmgr.GetPlayer(itr->first); - if (!plr) { sLog.outError("BattleGround: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); continue; } - uint32 team = itr->second.Team; if(!team) team = plr->GetTeam(); - if (team == TeamID) UpdatePlayerScore(plr, SCORE_BONUS_HONOR, Honor); } } - void BattleGround::RewardReputationToTeam(uint32 faction_id, uint32 Reputation, uint32 TeamID) { FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction_id); - if (!factionEntry) return; - for(BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { Player *plr = objmgr.GetPlayer(itr->first); - if (!plr) { sLog.outError("BattleGround: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); continue; } - uint32 team = itr->second.Team; if(!team) team = plr->GetTeam(); - if (team == TeamID) plr->GetReputationMgr().ModifyReputation(factionEntry, Reputation); } } - void BattleGround::UpdateWorldState(uint32 Field, uint32 Value) { WorldPacket data; sBattleGroundMgr.BuildUpdateWorldStatePacket(&data, Field, Value); SendPacketToAll(&data); } - void BattleGround::UpdateWorldStateForPlayer(uint32 Field, uint32 Value, Player *Source) { WorldPacket data; sBattleGroundMgr.BuildUpdateWorldStatePacket(&data, Field, Value); Source->GetSession()->SendPacket(&data); } - void BattleGround::EndBattleGround(uint32 winner) { this->RemoveFromBGFreeSlotQueue(); - ArenaTeam * winner_arena_team = NULL; ArenaTeam * loser_arena_team = NULL; uint32 loser_rating = 0; uint32 winner_rating = 0; WorldPacket data; int32 winmsg_id = 0; - if (winner == ALLIANCE) { winmsg_id = isBattleGround() ? LANG_BG_A_WINS : LANG_ARENA_GOLD_WINS; - PlaySoundToAll(SOUND_ALLIANCE_WINS); // alliance wins sound - SetWinner(WINNER_ALLIANCE); } else if (winner == HORDE) { winmsg_id = isBattleGround() ? LANG_BG_H_WINS : LANG_ARENA_GREEN_WINS; - PlaySoundToAll(SOUND_HORDE_WINS); // horde wins sound - SetWinner(WINNER_HORDE); } else { SetWinner(3); } - SetStatus(STATUS_WAIT_LEAVE); //we must set it this way, because end time is sent in packet! m_EndTime = TIME_TO_AUTOREMOVE; - // arena rating calculation if (isArena() && isRated()) { @@ -720,12 +622,10 @@ void BattleGround::EndBattleGround(uint32 winner) SetArenaTeamRatingChangeForTeam(HORDE, 0); } } - for(BattleGroundPlayerMap::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { Player *plr = objmgr.GetPlayer(itr->first); uint32 team = itr->second.Team; - if (!plr) { //if rated arena match - make member lost! @@ -739,11 +639,9 @@ void BattleGround::EndBattleGround(uint32 winner) sLog.outError("BattleGround: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); continue; } - // should remove spirit of redemption if(plr->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION)) plr->RemoveAurasByType(SPELL_AURA_MOD_SHAPESHIFT); - if (!plr->isAlive()) { plr->ResurrectPlayer(1.0f); @@ -754,10 +652,8 @@ void BattleGround::EndBattleGround(uint32 winner) plr->CombatStop(); plr->getHostilRefManager().deleteReferences(); } - //this line is obsolete - team is set ALWAYS //if(!team) team = plr->GetTeam(); - // per player calculation if (isArena() && isRated() && winner_arena_team && loser_arena_team && winner_arena_team != loser_arena_team) { @@ -767,18 +663,15 @@ void BattleGround::EndBattleGround(uint32 winner) ArenaTeamMember* member = winner_arena_team->GetMember(plr->GetGUID()); if (member) plr->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, member->personal_rating); - winner_arena_team->MemberWon(plr,loser_rating); } else { loser_arena_team->MemberLost(plr,winner_rating); - // Arena lost => reset the win_rated_arena having the "no_loose" condition plr->GetAchievementMgr().ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, ACHIEVEMENT_CRITERIA_CONDITION_NO_LOOSE); } } - if (team == winner) { RewardMark(plr,ITEM_WINNER_COUNT); @@ -787,20 +680,15 @@ void BattleGround::EndBattleGround(uint32 winner) } else if(winner) RewardMark(plr,ITEM_LOSER_COUNT); - plr->CombatStopWithPets(true); - BlockMovement(plr); - sBattleGroundMgr.BuildPvpLogDataPacket(&data, this); plr->GetSession()->SendPacket(&data); - BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType()); sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime(), GetArenaType()); plr->GetSession()->SendPacket(&data); plr->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, 1); } - if (isArena() && isRated() && winner_arena_team && loser_arena_team && winner_arena_team != loser_arena_team) { // update arena points only after increasing the player's match count! @@ -814,17 +702,14 @@ void BattleGround::EndBattleGround(uint32 winner) winner_arena_team->NotifyStatsChanged(); loser_arena_team->NotifyStatsChanged(); } - if (winmsg_id) SendMessageToAll(winmsg_id, CHAT_MSG_BG_SYSTEM_NEUTRAL); } - uint32 BattleGround::GetBonusHonorFromKill(uint32 kills) const { //variable kills means how many honorable kills you scored (so we need kills * honor_for_one_kill) return MaNGOS::Honor::hk_honor_at_level(GetMaxLevel(), kills); } - uint32 BattleGround::GetBattlemasterEntry() const { switch(GetTypeID()) @@ -837,7 +722,6 @@ uint32 BattleGround::GetBattlemasterEntry() const default: return 0; } } - void BattleGround::RewardMark(Player *plr,uint32 count) { BattleGroundMarks mark; @@ -858,75 +742,60 @@ void BattleGround::RewardMark(Player *plr,uint32 count) default: return; } - //if (IsSpell) // RewardSpellCast(plr,mark); //else RewardItem(plr,mark,count); } - void BattleGround::RewardSpellCast(Player *plr, uint32 spell_id) { // 'Inactive' this aura prevents the player from gaining honor points and battleground tokens if (plr->HasAura(SPELL_AURA_PLAYER_INACTIVE)) return; - SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id); if(!spellInfo) { sLog.outError("Battleground reward casting spell %u not exist.",spell_id); return; } - plr->CastSpell(plr, spellInfo, true); } - void BattleGround::RewardItem(Player *plr, uint32 item_id, uint32 count) { // 'Inactive' this aura prevents the player from gaining honor points and battleground tokens if (plr->HasAura(SPELL_AURA_PLAYER_INACTIVE)) return; - ItemPosCountVec dest; uint32 no_space_count = 0; uint8 msg = plr->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, item_id, count, &no_space_count ); - if( msg == EQUIP_ERR_ITEM_NOT_FOUND) { sLog.outErrorDb("Battleground reward item (Entry %u) not exist in `item_template`.",item_id); return; } - if( msg != EQUIP_ERR_OK ) // convert to possible store amount count -= no_space_count; - if( count != 0 && !dest.empty()) // can add some if (Item* item = plr->StoreNewItem( dest, item_id, true, 0)) plr->SendNewItem(item,count,true,false); - if (no_space_count > 0) SendRewardMarkByMail(plr,item_id,no_space_count); } - void BattleGround::SendRewardMarkByMail(Player *plr,uint32 mark, uint32 count) { uint32 bmEntry = GetBattlemasterEntry(); if (!bmEntry) return; - ItemPrototype const* markProto = objmgr.GetItemPrototype(mark); if (!markProto) return; - if (Item* markItem = Item::CreateItem(mark,count,plr)) { // save new item before send markItem->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted - // item MailItemsInfo mi; mi.AddItem(markItem->GetGUIDLow(), markItem->GetEntry(), markItem); - // subject: item name std::string subject = markProto->Name1; int loc_idx = plr->GetSession()->GetSessionDbLocaleIndex(); @@ -934,17 +803,14 @@ void BattleGround::SendRewardMarkByMail(Player *plr,uint32 mark, uint32 count) if (ItemLocale const *il = objmgr.GetItemLocale(markProto->ItemId)) if (il->Name.size() > size_t(loc_idx) && !il->Name[loc_idx].empty()) subject = il->Name[loc_idx]; - // text std::string textFormat = plr->GetSession()->GetTrinityString(LANG_BG_MARK_BY_MAIL); char textBuf[300]; snprintf(textBuf,300,textFormat.c_str(),GetName(),GetName()); uint32 itemTextId = objmgr.CreateItemText( textBuf ); - WorldSession::SendMailTo(plr, MAIL_CREATURE, MAIL_STATIONERY_NORMAL, bmEntry, plr->GetGUIDLow(), subject, itemTextId , &mi, 0, 0, MAIL_CHECK_MASK_NONE); } } - void BattleGround::RewardQuestComplete(Player *plr) { uint32 quest; @@ -965,15 +831,12 @@ void BattleGround::RewardQuestComplete(Player *plr) default: return; } - RewardSpellCast(plr, quest); } - void BattleGround::BlockMovement(Player *plr) { plr->SetClientControl(plr, 0); // movement disabled NOTE: the effect will be automatically removed by client when the player is teleported from the battleground, so no need to send with uint8(1) in RemovePlayerAtLeave() } - void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPacket) { uint32 team = GetPlayerTeam(guid); @@ -987,30 +850,23 @@ void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac // check if the player was a participant of the match, or only entered through gm command (goname) participant = true; } - BattleGroundScoreMap::iterator itr2 = m_PlayerScores.find(guid); if (itr2 != m_PlayerScores.end()) { delete itr2->second; // delete player's score m_PlayerScores.erase(itr2); } - RemovePlayerFromResurrectQueue(guid); - Player *plr = objmgr.GetPlayer(guid); - // should remove spirit of redemption if(plr && plr->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION)) plr->RemoveAurasByType(SPELL_AURA_MOD_SHAPESHIFT); - if(plr && !plr->isAlive()) // resurrect on exit { plr->ResurrectPlayer(1.0f); plr->SpawnCorpseBones(); } - RemovePlayer(plr, guid); // BG subclass specific code - if(participant) // if the player was a match participant, remove auras, calc rating, update queue { BattleGroundTypeId bgTypeId = GetTypeID(); @@ -1018,19 +874,15 @@ void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac if (plr) { plr->ClearAfkReports(); - if(!team) team = plr->GetTeam(); - // if arena, remove the specific arena auras if (isArena()) { plr->RemoveArenaAuras(true); // removes debuffs / dots etc., we don't want the player to die after porting out bgTypeId=BATTLEGROUND_AA; // set the bg type to all arenas (it will be used for queue refreshing) - // unsummon current and summon old pet if there was one and there isn't a current pet plr->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT); plr->ResummonPetTemporaryUnSummonedIfAny(); - if (isRated() && GetStatus() == STATUS_IN_PROGRESS) { //left a rated match while the encounter was in progress, consider as loser @@ -1046,7 +898,6 @@ void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_NONE, 0, 0, 0); plr->GetSession()->SendPacket(&data); } - // this call is important, because player, when joins to battleground, this method is not called, so it must be called when leaving bg plr->RemoveBattleGroundQueueId(bgQueueTypeId); } @@ -1062,7 +913,6 @@ void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac players_arena_team->OfflineMemberLost(guid, others_arena_team->GetRating()); } } - // remove from raid group if player is member if (Group *group = GetBgRaid(team)) { @@ -1085,23 +935,18 @@ void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac sBattleGroundMgr.BuildPlayerLeftBattleGroundPacket(&data, guid); SendPacketToTeam(team, &data, plr, false); } - if (plr) { // Do next only if found in battleground plr->SetBattleGroundId(0, BATTLEGROUND_TYPE_NONE); // We're not in BG. // reset destination bg team plr->SetBGTeam(0); - if (Transport) plr->TeleportToBGEntryPoint(); - sLog.outDetail("BATTLEGROUND: Removed player %s from BattleGround.", plr->GetName()); } - //battleground object will be deleted next BattleGround::Update() call } - // this method is called when no players remains in battleground void BattleGround::Reset() { @@ -1113,32 +958,24 @@ void BattleGround::Reset() SetLastResurrectTime(0); SetArenaType(0); SetRated(false); - m_Events = 0; - if (m_InvitedAlliance > 0 || m_InvitedHorde > 0) sLog.outError("BattleGround system: bad counter, m_InvitedAlliance: %d, m_InvitedHorde: %d", m_InvitedAlliance, m_InvitedHorde); - m_InvitedAlliance = 0; m_InvitedHorde = 0; m_InBGFreeSlotQueue = false; - m_Players.clear(); - for(BattleGroundScoreMap::const_iterator itr = m_PlayerScores.begin(); itr != m_PlayerScores.end(); ++itr) delete itr->second; m_PlayerScores.clear(); - ResetBGSubclass(); } - void BattleGround::StartBattleGround() { SetStartTime(0); SetLastResurrectTime(0); // add BG to free slot queue AddToBGFreeSlotQueue(); - // add bg to update list // This must be done here, because we need to have already invited some players when first BG::Update() method is executed // and it doesn't matter if we call StartBattleGround() more times, because m_BattleGrounds is a map and instance id never changes @@ -1146,31 +983,23 @@ void BattleGround::StartBattleGround() if(m_IsRated) sLog.outArena("Arena match type: %u for Team1Id: %u - Team2Id: %u started.", m_ArenaType, m_ArenaTeamIds[BG_TEAM_ALLIANCE], m_ArenaTeamIds[BG_TEAM_HORDE]); } - void BattleGround::AddPlayer(Player *plr) { // remove afk from player if (plr->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_AFK)) plr->ToggleAFK(); - // score struct must be created in inherited class - uint64 guid = plr->GetGUID(); uint32 team = plr->GetBGTeam(); - BattleGroundPlayer bp; bp.OfflineRemoveTime = 0; bp.Team = team; - // Add to list/maps m_Players[guid] = bp; - UpdatePlayersCountByTeam(team, false); // +1 player - WorldPacket data; sBattleGroundMgr.BuildPlayerJoinedBattleGroundPacket(&data, plr); SendPacketToTeam(team, &data, plr, false); - // add arena specific auras if (isArena()) { @@ -1191,14 +1020,11 @@ void BattleGround::AddPlayer(Player *plr) else plr->CastSpell(plr, SPELL_ALLIANCE_GREEN_FLAG,true); } - plr->DestroyConjuredItems(true); plr->UnsummonPetTemporaryIfAny(); - if(GetStatus() == STATUS_WAIT_JOIN) // not started yet { plr->CastSpell(plr, SPELL_ARENA_PREPARATION, true); - plr->SetHealth(plr->GetMaxHealth()); plr->SetPower(POWER_MANA, plr->GetMaxPower(POWER_MANA)); } @@ -1208,18 +1034,14 @@ void BattleGround::AddPlayer(Player *plr) if(GetStatus() == STATUS_WAIT_JOIN) // not started yet plr->CastSpell(plr, SPELL_PREPARATION, true); // reduces all mana cost of spells. } - plr->GetAchievementMgr().ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE, ACHIEVEMENT_CRITERIA_CONDITION_MAP, GetMapId()); plr->GetAchievementMgr().ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE, ACHIEVEMENT_CRITERIA_CONDITION_MAP, GetMapId()); - // setup BG group membership PlayerAddedToBGCheckIfBGIsRunning(plr); AddOrSetPlayerToCorrectBgGroup(plr, guid, team); - // Log sLog.outDetail("BATTLEGROUND: Player %s joined the battle.", plr->GetName()); } - /* this method adds player to his team's bg group, or sets his correct group if player is already in bg group */ void BattleGround::AddOrSetPlayerToCorrectBgGroup(Player *plr, uint64 plr_guid, uint32 team) { @@ -1246,7 +1068,6 @@ void BattleGround::AddOrSetPlayerToCorrectBgGroup(Player *plr, uint64 plr_guid, } } } - // This method should be called when player logs into running battleground void BattleGround::EventPlayerLoggedIn(Player* player, uint64 plr_guid) { @@ -1264,7 +1085,6 @@ void BattleGround::EventPlayerLoggedIn(Player* player, uint64 plr_guid) // if battleground is starting, then add preparation aura // we don't have to do that, because preparation aura isn't removed when player logs out } - // This method should be called when player logs out from running battleground void BattleGround::EventPlayerLoggedOut(Player* player) { @@ -1283,7 +1103,6 @@ void BattleGround::EventPlayerLoggedOut(Player* player) } } } - /* This method should be called only once ... it adds pointer to queue */ void BattleGround::AddToBGFreeSlotQueue() { @@ -1294,7 +1113,6 @@ void BattleGround::AddToBGFreeSlotQueue() m_InBGFreeSlotQueue = true; } } - /* This method removes this battleground from free queue - it must be called when deleting battleground - not used now*/ void BattleGround::RemoveFromBGFreeSlotQueue() { @@ -1310,7 +1128,6 @@ void BattleGround::RemoveFromBGFreeSlotQueue() } } } - // get the number of free slots for team // returns the number how many players can join battleground to MaxPlayersPerTeam uint32 BattleGround::GetFreeSlotsForTeam(uint32 Team) const @@ -1342,7 +1159,6 @@ uint32 BattleGround::GetFreeSlotsForTeam(uint32 Team) const // allow join more ppl if the other side has more players else if(otherTeam > GetInvitedCount(Team)) diff = otherTeam - GetInvitedCount(Team); - // difference based on max players per team (don't allow inviting more) uint32 diff2 = (GetInvitedCount(Team) < GetMaxPlayersPerTeam()) ? GetMaxPlayersPerTeam() - GetInvitedCount(Team) : 0; // difference based on players who already entered @@ -1357,9 +1173,7 @@ uint32 BattleGround::GetFreeSlotsForTeam(uint32 Team) const // or other side has less than minPlayersPerTeam else if (GetInvitedCount(Team) <= GetMinPlayersPerTeam()) diff3 = GetMinPlayersPerTeam() - GetInvitedCount(Team) + 1; - // return the minimum of the 3 differences - // min of diff and diff 2 diff = diff < diff2 ? diff : diff2; // min of diff, diff2 and diff3 @@ -1367,20 +1181,16 @@ uint32 BattleGround::GetFreeSlotsForTeam(uint32 Team) const } return 0; } - bool BattleGround::HasFreeSlots() const { return GetPlayersSize() < GetMaxPlayers(); } - void BattleGround::UpdatePlayerScore(Player *Source, uint32 type, uint32 value) { //this procedure is called from virtual function implemented in bg subclass BattleGroundScoreMap::const_iterator itr = m_PlayerScores.find(Source->GetGUID()); - if(itr == m_PlayerScores.end()) // player not found... return; - switch(type) { case SCORE_KILLING_BLOWS: // Killing blows @@ -1413,18 +1223,14 @@ void BattleGround::UpdatePlayerScore(Player *Source, uint32 type, uint32 value) break; } } - void BattleGround::AddPlayerToResurrectQueue(uint64 npc_guid, uint64 player_guid) { m_ReviveQueue[npc_guid].push_back(player_guid); - Player *plr = objmgr.GetPlayer(player_guid); if (!plr) return; - plr->CastSpell(plr, SPELL_WAITING_FOR_RESURRECT, true); } - void BattleGround::RemovePlayerFromResurrectQueue(uint64 player_guid) { for(std::map >::iterator itr = m_ReviveQueue.begin(); itr != m_ReviveQueue.end(); ++itr) @@ -1434,25 +1240,20 @@ void BattleGround::RemovePlayerFromResurrectQueue(uint64 player_guid) if (*itr2 == player_guid) { (itr->second).erase(itr2); - Player *plr = objmgr.GetPlayer(player_guid); if (!plr) return; - plr->RemoveAurasDueToSpell(SPELL_WAITING_FOR_RESURRECT); - return; } } } } - bool BattleGround::AddObject(uint32 type, uint32 entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime) { Map * map = MapManager::Instance().FindMap(GetMapId(),GetInstanceID()); if (!map) return false; - // must be created this way, adding to godatamap would add it to the base map of the instance // and when loading it (in go::LoadFromDB()), a new guid would be assigned to the object, and a new object would be created // so we must create it specific for this instance @@ -1467,11 +1268,9 @@ bool BattleGround::AddObject(uint32 type, uint32 entry, float x, float y, float } /* uint32 guid = go->GetGUIDLow(); - // without this, UseButtonOrDoor caused the crash, since it tried to get go info from godata // iirc that was changed, so adding to go data map is no longer required if that was the only function using godata from GameObject without checking if it existed GameObjectData& data = objmgr.NewGOData(guid); - data.id = entry; data.mapid = GetMapId(); data.posX = x; @@ -1492,7 +1291,6 @@ bool BattleGround::AddObject(uint32 type, uint32 entry, float x, float y, float m_BgObjects[type] = go->GetGUID(); return true; } - //some doors aren't despawned so we cannot handle their closing in gameobject::update() //it would be nice to correctly implement GO_ACTIVATED state and open/close doors in gameobject code void BattleGround::DoorClose(uint32 type) @@ -1513,7 +1311,6 @@ void BattleGround::DoorClose(uint32 type) sLog.outError("BattleGround: Door object not found (cannot close doors)"); } } - void BattleGround::DoorOpen(uint32 type) { GameObject *obj = HashMapHolder::Find(m_BgObjects[type]); @@ -1528,7 +1325,6 @@ void BattleGround::DoorOpen(uint32 type) sLog.outError("BattleGround: Door object not found! - doors will be closed."); } } - GameObject* BattleGround::GetBGObject(uint32 type) { GameObject *obj = HashMapHolder::Find(m_BgObjects[type]); @@ -1536,7 +1332,6 @@ GameObject* BattleGround::GetBGObject(uint32 type) sLog.outError("couldn't get gameobject %i",type); return obj; } - Creature* BattleGround::GetBGCreature(uint32 type) { Creature *creature = HashMapHolder::Find(m_BgCreatures[type]); @@ -1544,7 +1339,6 @@ Creature* BattleGround::GetBGCreature(uint32 type) sLog.outError("couldn't get creature %i",type); return creature; } - void BattleGround::SpawnBGObject(uint32 type, uint32 respawntime) { Map * map = MapManager::Instance().FindMap(GetMapId(),GetInstanceID()); @@ -1573,13 +1367,11 @@ void BattleGround::SpawnBGObject(uint32 type, uint32 respawntime) } } } - Creature* BattleGround::AddCreature(uint32 entry, uint32 type, uint32 teamval, float x, float y, float z, float o, uint32 respawntime) { Map * map = MapManager::Instance().FindMap(GetMapId(),GetInstanceID()); if (!map) return NULL; - Creature* pCreature = new Creature; if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, PHASEMASK_NORMAL, entry, 0, teamval, x, y, z, o)) { @@ -1587,14 +1379,10 @@ Creature* BattleGround::AddCreature(uint32 entry, uint32 type, uint32 teamval, f delete pCreature; return NULL; } - pCreature->SetHomePosition(x, y, z, o); - //pCreature->SetDungeonDifficulty(0); - map->Add(pCreature); m_BgCreatures[type] = pCreature->GetGUID(); - return pCreature; } /* @@ -1603,7 +1391,6 @@ void BattleGround::SpawnBGCreature(uint32 type, uint32 respawntime) Map * map = MapManager::Instance().FindMap(GetMapId(),GetInstanceId()); if (!map) return false; - if (respawntime == 0) { Creature *obj = HashMapHolder::Find(m_BgCreatures[type]); @@ -1631,7 +1418,6 @@ bool BattleGround::DelCreature(uint32 type) { if (!m_BgCreatures[type]) return true; - Creature *cr = HashMapHolder::Find(m_BgCreatures[type]); if (!cr) { @@ -1642,12 +1428,10 @@ bool BattleGround::DelCreature(uint32 type) m_BgCreatures[type] = 0; return true; } - bool BattleGround::DelObject(uint32 type) { if (!m_BgObjects[type]) return true; - GameObject *obj = HashMapHolder::Find(m_BgObjects[type]); if (!obj) { @@ -1659,16 +1443,13 @@ bool BattleGround::DelObject(uint32 type) m_BgObjects[type] = 0; return true; } - bool BattleGround::AddSpiritGuide(uint32 type, float x, float y, float z, float o, uint32 team) { uint32 entry = 0; - if (team == ALLIANCE) entry = BG_CREATURE_ENTRY_A_SPIRITGUIDE; else entry = BG_CREATURE_ENTRY_H_SPIRITGUIDE; - Creature* pCreature = AddCreature(entry,type,team,x,y,z,o); if (!pCreature) { @@ -1676,14 +1457,11 @@ bool BattleGround::AddSpiritGuide(uint32 type, float x, float y, float z, float EndNow(); return false; } - pCreature->setDeathState(DEAD); - pCreature->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, pCreature->GetGUID()); // aura //TODO: Fix display here //pCreature->SetVisibleAura(0, SPELL_SPIRIT_HEAL_CHANNEL); - //pCreature->SetUInt32Value(UNIT_FIELD_AURAFLAGS, 0x00000009); //pCreature->SetUInt32Value(UNIT_FIELD_AURALEVELS, 0x0000003C); //pCreature->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS, 0x000000FF); @@ -1691,52 +1469,42 @@ bool BattleGround::AddSpiritGuide(uint32 type, float x, float y, float z, float pCreature->SetUInt32Value(UNIT_CHANNEL_SPELL, SPELL_SPIRIT_HEAL_CHANNEL); // correct cast speed pCreature->SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f); - //pCreature->CastSpell(pCreature, SPELL_SPIRIT_HEAL_CHANNEL, true); - return true; } - void BattleGround::SendMessageToAll(int32 entry, ChatMsg type, Player const* source) { MaNGOS::BattleGroundChatBuilder bg_builder(type, entry, source); MaNGOS::LocalizedPacketDo bg_do(bg_builder); BroadcastWorker(bg_do); } - void BattleGround::PSendMessageToAll(int32 entry, ChatMsg type, Player const* source, ...) { va_list ap; va_start(ap, source); - MaNGOS::BattleGroundChatBuilder bg_builder(type, entry, source, &ap); MaNGOS::LocalizedPacketDo bg_do(bg_builder); BroadcastWorker(bg_do); - va_end(ap); } - void BattleGround::SendMessage2ToAll(int32 entry, ChatMsg type, Player const* source, int32 arg1, int32 arg2) { MaNGOS::BattleGround2ChatBuilder bg_builder(type, entry, source, arg1, arg2); MaNGOS::LocalizedPacketDo bg_do(bg_builder); BroadcastWorker(bg_do); } - void BattleGround::EndNow() { RemoveFromBGFreeSlotQueue(); SetStatus(STATUS_WAIT_LEAVE); SetEndTime(0); } - //to be removed const char *BattleGround::GetTrinityString(int32 entry) { // FIXME: now we have different DBC locales and need localized message for each target client return objmgr.GetTrinityStringForDBCLocale(entry); } - /* important notice: buffs aren't spawned/despawned when players captures anything @@ -1747,7 +1515,6 @@ void BattleGround::HandleTriggerBuff(uint64 const& go_guid) GameObject *obj = HashMapHolder::Find(go_guid); if (!obj || obj->GetGoType() != GAMEOBJECT_TYPE_TRAP || !obj->isSpawned()) return; - //change buff type, when buff is used: int32 index = m_BgObjects.size() - 1; while (index >= 0 && m_BgObjects[index] != go_guid) @@ -1757,7 +1524,6 @@ void BattleGround::HandleTriggerBuff(uint64 const& go_guid) sLog.outError("BattleGround (Type: %u) has buff gameobject (Guid: %u Entry: %u Type:%u) but it hasn't that object in its internal data",GetTypeID(),GUID_LOPART(go_guid),obj->GetEntry(),obj->GetGoType()); return; } - //randomly select new buff uint8 buff = urand(0, 2); uint32 entry = obj->GetEntry(); @@ -1773,40 +1539,31 @@ void BattleGround::HandleTriggerBuff(uint64 const& go_guid) index += buff; } } - SpawnBGObject(index, BUFF_RESPAWN_TIME); } - void BattleGround::HandleKillPlayer( Player *player, Player *killer ) { //keep in mind that for arena this will have to be changed a bit - // add +1 deaths UpdatePlayerScore(player, SCORE_DEATHS, 1); - // add +1 kills to group and +1 killing_blows to killer if (killer) { UpdatePlayerScore(killer, SCORE_HONORABLE_KILLS, 1); UpdatePlayerScore(killer, SCORE_KILLING_BLOWS, 1); - for(BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { Player *plr = objmgr.GetPlayer(itr->first); - if (!plr || plr == killer) continue; - if (plr->GetTeam() == killer->GetTeam() && plr->IsAtGroupRewardDistance(player)) UpdatePlayerScore(plr, SCORE_HONORABLE_KILLS, 1); } } - // to be able to remove insignia -- ONLY IN BattleGrounds if (!isArena()) player->SetFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE ); } - // return the player's team based on battlegroundplayer info // used in same faction arena matches mainly uint32 BattleGround::GetPlayerTeam(uint64 guid) @@ -1816,12 +1573,10 @@ uint32 BattleGround::GetPlayerTeam(uint64 guid) return itr->second.Team; return 0; } - uint32 BattleGround::GetOtherTeam(uint32 teamId) { return (teamId) ? ((teamId == ALLIANCE) ? HORDE : ALLIANCE) : 0; } - bool BattleGround::IsPlayerInBattleGround(uint64 guid) { BattleGroundPlayerMap::const_iterator itr = m_Players.find(guid); @@ -1829,24 +1584,18 @@ bool BattleGround::IsPlayerInBattleGround(uint64 guid) return true; return false; } - void BattleGround::PlayerAddedToBGCheckIfBGIsRunning(Player* plr) { if (GetStatus() != STATUS_WAIT_LEAVE) return; - WorldPacket data; BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType()); - BlockMovement(plr); - sBattleGroundMgr.BuildPvpLogDataPacket(&data, this); plr->GetSession()->SendPacket(&data); - sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, GetEndTime(), GetStartTime(), GetArenaType()); plr->GetSession()->SendPacket(&data); } - uint32 BattleGround::GetAlivePlayersCountByTeam(uint32 Team) const { int count = 0; @@ -1861,7 +1610,6 @@ uint32 BattleGround::GetAlivePlayersCountByTeam(uint32 Team) const } return count; } - void BattleGround::SetHoliday(bool is_holiday) { if(is_holiday) @@ -1869,7 +1617,6 @@ void BattleGround::SetHoliday(bool is_holiday) else m_HonorMode = BG_NORMAL; } - int32 BattleGround::GetObjectType(uint64 guid) { for(uint32 i = 0; i < m_BgObjects.size(); ++i) @@ -1878,11 +1625,9 @@ int32 BattleGround::GetObjectType(uint64 guid) sLog.outError("BattleGround: cheating? a player used a gameobject which isnt supposed to be a usable object!"); return -1; } - void BattleGround::HandleKillUnit(Creature *creature, Player *killer) { } - void BattleGround::CheckArenaWinConditions() { if (!GetAlivePlayersCountByTeam(ALLIANCE) && GetPlayersCountByTeam(HORDE)) @@ -1890,7 +1635,6 @@ void BattleGround::CheckArenaWinConditions() else if (GetPlayersCountByTeam(ALLIANCE) && !GetAlivePlayersCountByTeam(HORDE)) EndBattleGround(ALLIANCE); } - void BattleGround::SetBgRaid( uint32 TeamID, Group *bg_raid ) { Group* &old_raid = TeamID == ALLIANCE ? m_BgRaids[BG_TEAM_ALLIANCE] : m_BgRaids[BG_TEAM_HORDE]; @@ -1898,12 +1642,10 @@ void BattleGround::SetBgRaid( uint32 TeamID, Group *bg_raid ) if(bg_raid) bg_raid->SetBattlegroundGroup(this); old_raid = bg_raid; } - WorldSafeLocsEntry const* BattleGround::GetClosestGraveYard( Player* player ) { return objmgr.GetClosestGraveYard( player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), player->GetTeam() ); } - bool BattleGround::IsTeamScoreInRange(uint32 team, uint32 minScore, uint32 maxScore) const { BattleGroundTeamId team_idx = GetTeamIndexByTeamId(team); diff --git a/src/game/BattleGround.h b/src/game/BattleGround.h index 007f7a642dd..cb19fd92525 100644 --- a/src/game/BattleGround.h +++ b/src/game/BattleGround.h @@ -17,21 +17,16 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef __BATTLEGROUND_H #define __BATTLEGROUND_H - #include "Common.h" #include "SharedDefines.h" - class Creature; class GameObject; class Group; class Player; class WorldPacket; - struct WorldSafeLocsEntry; - enum BattleGroundSounds { SOUND_HORDE_WINS = 8454, @@ -39,7 +34,6 @@ enum BattleGroundSounds SOUND_BG_START = 3439, SOUND_BG_START_L70ETC = 11803, }; - enum BattleGroundQuests { SPELL_WS_QUEST_REWARD = 43483, @@ -50,7 +44,6 @@ enum BattleGroundQuests SPELL_AB_QUEST_REWARD_4_BASES = 24061, SPELL_AB_QUEST_REWARD_5_BASES = 24064 }; - enum BattleGroundMarks { SPELL_WS_MARK_LOSER = 24950, @@ -64,19 +57,16 @@ enum BattleGroundMarks ITEM_AB_MARK_OF_HONOR = 20559, ITEM_EY_MARK_OF_HONOR = 29024 }; - enum BattleGroundMarksCount { ITEM_WINNER_COUNT = 3, ITEM_LOSER_COUNT = 1 }; - enum BattleGroundCreatures { BG_CREATURE_ENTRY_A_SPIRITGUIDE = 13116, // alliance BG_CREATURE_ENTRY_H_SPIRITGUIDE = 13117, // horde }; - enum BattleGroundSpells { SPELL_WAITING_FOR_RESURRECT = 2584, // Waiting to Resurrect @@ -93,7 +83,6 @@ enum BattleGroundSpells SPELL_RECENTLY_DROPPED_FLAG = 42792, // Recently Dropped Flag SPELL_AURA_PLAYER_INACTIVE = 43681 // Inactive }; - enum BattleGroundTimeIntervals { RESURRECTION_INTERVAL = 30000, // ms @@ -106,7 +95,6 @@ enum BattleGroundTimeIntervals RESPAWN_IMMEDIATELY = 0, // secs BUFF_RESPAWN_TIME = 180, // secs }; - enum BattleGroundStartTimeIntervals { BG_START_DELAY_2M = 120000, // ms (2 minutes) @@ -115,16 +103,13 @@ enum BattleGroundStartTimeIntervals BG_START_DELAY_15S = 15000, // ms (15 seconds) Used only in arena BG_START_DELAY_NONE = 0, // ms }; - enum BattleGroundBuffObjects { BG_OBJECTID_SPEEDBUFF_ENTRY = 179871, BG_OBJECTID_REGENBUFF_ENTRY = 179904, BG_OBJECTID_BERSERKERBUFF_ENTRY = 179905 }; - const uint32 Buff_Entries[3] = { BG_OBJECTID_SPEEDBUFF_ENTRY, BG_OBJECTID_REGENBUFF_ENTRY, BG_OBJECTID_BERSERKERBUFF_ENTRY }; - enum BattleGroundStatus { STATUS_NONE = 0, // first status, should mean bg is not instance @@ -133,22 +118,18 @@ enum BattleGroundStatus STATUS_IN_PROGRESS = 3, // means bg is running STATUS_WAIT_LEAVE = 4 // means some faction has won BG and it is ending }; - struct BattleGroundPlayer { time_t OfflineRemoveTime; // for tracking and removing offline players from queue after 5 minutes uint32 Team; // Player's team }; - struct BattleGroundObjectInfo { BattleGroundObjectInfo() : object(NULL), timer(0), spellid(0) {} - GameObject *object; int32 timer; uint32 spellid; }; - // handle the queue types and bg types separately to enable joining queue for different sized arenas at the same time enum BattleGroundQueueTypeId { @@ -163,7 +144,6 @@ enum BattleGroundQueueTypeId BATTLEGROUND_QUEUE_5v5 = 8 }; #define MAX_BATTLEGROUND_QUEUE_TYPES 9 - enum BGQueueIdBasedOnLevel // queue_id for level ranges { QUEUE_ID_MAX_LEVEL_19 = 0, @@ -176,7 +156,6 @@ enum BGQueueIdBasedOnLevel // queue_id for level ranges QUEUE_ID_MAX_LEVEL_80 = 7 }; #define MAX_BATTLEGROUND_QUEUES 8 - enum ScoreType { SCORE_KILLING_BLOWS = 1, @@ -202,34 +181,29 @@ enum ScoreType SCORE_SECONDARY_OBJECTIVES = 17 // TODO : implement them }; - enum ArenaType { ARENA_TYPE_2v2 = 2, ARENA_TYPE_3v3 = 3, ARENA_TYPE_5v5 = 5 }; - enum BattleGroundType { TYPE_BATTLEGROUND = 3, TYPE_ARENA = 4 }; - enum BattleGroundWinner { WINNER_HORDE = 0, WINNER_ALLIANCE = 1, WINNER_NONE = 2 }; - enum BattleGroundTeamId { BG_TEAM_ALLIANCE = 0, BG_TEAM_HORDE = 1 }; #define BG_TEAMS_COUNT 2 - enum BattleGroundStartingEvents { BG_STARTING_EVENT_NONE = 0x00, @@ -238,7 +212,6 @@ enum BattleGroundStartingEvents BG_STARTING_EVENT_3 = 0x04, BG_STARTING_EVENT_4 = 0x08 }; - enum BattleGroundStartingEventsIds { BG_STARTING_EVENT_FIRST = 0, @@ -247,7 +220,6 @@ enum BattleGroundStartingEventsIds BG_STARTING_EVENT_FOURTH = 3 }; #define BG_STARTING_EVENT_COUNT 4 - enum BattleGroundJoinError { BG_JOIN_ERR_OK = 0, @@ -261,7 +233,6 @@ enum BattleGroundJoinError BG_JOIN_ERR_ALL_QUEUES_USED = 8, BG_JOIN_ERR_GROUP_NOT_ENOUGH = 9 }; - class BattleGroundScore { public: @@ -269,7 +240,6 @@ class BattleGroundScore BonusHonor(0), DamageDone(0), HealingDone(0) {} virtual ~BattleGroundScore() {} //virtual destructor is used when deleting score from scores map - uint32 KillingBlows; uint32 Deaths; uint32 HonorableKills; @@ -277,14 +247,12 @@ class BattleGroundScore uint32 DamageDone; uint32 HealingDone; }; - enum BGHonorMode { BG_NORMAL = 0, BG_HOLIDAY, BG_HONOR_MODE_NUM }; - /* This class is used to: 1. Add player to battleground @@ -295,7 +263,6 @@ This class is used to: class BattleGround { friend class BattleGroundMgr; - public: /* Construction */ BattleGround(); @@ -312,11 +279,9 @@ class BattleGround virtual void ResetBGSubclass() // must be implemented in BG subclass { } - /* achievement req. */ virtual bool IsAllNodesConrolledByTeam(uint32 /*team*/) const { return false; } bool IsTeamScoreInRange(uint32 team, uint32 minScore, uint32 maxScore) const; - /* Battleground */ // Get methods: char const* GetName() const { return m_Name; } @@ -330,19 +295,15 @@ class BattleGround uint32 GetLastResurrectTime() const { return m_LastResurrectTime; } uint32 GetMaxPlayers() const { return m_MaxPlayers; } uint32 GetMinPlayers() const { return m_MinPlayers; } - uint32 GetMinLevel() const { return m_LevelMin; } uint32 GetMaxLevel() const { return m_LevelMax; } - uint32 GetMaxPlayersPerTeam() const { return m_MaxPlayersPerTeam; } uint32 GetMinPlayersPerTeam() const { return m_MinPlayersPerTeam; } - int32 GetStartDelayTime() const { return m_StartDelayTime; } uint8 GetArenaType() const { return m_ArenaType; } uint8 GetWinner() const { return m_Winner; } uint32 GetBattlemasterEntry() const; uint32 GetBonusHonorFromKill(uint32 kills) const; - // Set methods: void SetName(char const* Name) { m_Name = Name; } void SetTypeID(BattleGroundTypeId TypeID) { m_TypeID = TypeID; } @@ -366,16 +327,12 @@ class BattleGround void SetArenaType(uint8 type) { m_ArenaType = type; } void SetArenaorBGType(bool _isArena) { m_IsArena = _isArena; } void SetWinner(uint8 winner) { m_Winner = winner; } - void ModifyStartDelayTime(int diff) { m_StartDelayTime -= diff; } void SetStartDelayTime(int Time) { m_StartDelayTime = Time; } - void SetMaxPlayersPerTeam(uint32 MaxPlayers) { m_MaxPlayersPerTeam = MaxPlayers; } void SetMinPlayersPerTeam(uint32 MinPlayers) { m_MinPlayersPerTeam = MinPlayers; } - void AddToBGFreeSlotQueue(); //this queue will be useful when more battlegrounds instances will be available void RemoveFromBGFreeSlotQueue(); //this method could delete whole BG instance, if another free is available - void DecreaseInvitedCount(uint32 team) { (team == ALLIANCE) ? --m_InvitedAlliance : --m_InvitedHorde; } void IncreaseInvitedCount(uint32 team) { (team == ALLIANCE) ? ++m_InvitedAlliance : ++m_InvitedHorde; } uint32 GetInvitedCount(uint32 team) const @@ -387,33 +344,25 @@ class BattleGround } bool HasFreeSlots() const; uint32 GetFreeSlotsForTeam(uint32 Team) const; - bool isArena() const { return m_IsArena; } bool isBattleGround() const { return !m_IsArena; } bool isRated() const { return m_IsRated; } - typedef std::map BattleGroundPlayerMap; BattleGroundPlayerMap const& GetPlayers() const { return m_Players; } uint32 GetPlayersSize() const { return m_Players.size(); } - typedef std::map BattleGroundScoreMap; BattleGroundScoreMap::const_iterator GetPlayerScoresBegin() const { return m_PlayerScores.begin(); } BattleGroundScoreMap::const_iterator GetPlayerScoresEnd() const { return m_PlayerScores.end(); } uint32 GetPlayerScoresSize() const { return m_PlayerScores.size(); } - uint32 GetReviveQueueSize() const { return m_ReviveQueue.size(); } - void AddPlayerToResurrectQueue(uint64 npc_guid, uint64 player_guid); void RemovePlayerFromResurrectQueue(uint64 player_guid); - void StartBattleGround(); - GameObject* GetBGObject(uint32 type); Creature* GetBGCreature(uint32 type); /* Location */ void SetMapId(uint32 MapID) { m_MapId = MapID; } uint32 GetMapId() const { return m_MapId; } - void SetTeamStartLoc(uint32 TeamID, float X, float Y, float Z, float O); void GetTeamStartLoc(uint32 TeamID, float &X, float &Y, float &Z, float &O) const { @@ -423,17 +372,14 @@ class BattleGround Z = m_TeamStartLocZ[idx]; O = m_TeamStartLocO[idx]; } - /* Packet Transfer */ // method that should fill worldpacket with actual world states (not yet implemented for all battlegrounds!) virtual void FillInitialWorldStates(WorldPacket& /*data*/) {} void SendPacketToTeam(uint32 TeamID, WorldPacket *packet, Player *sender = NULL, bool self = true); void SendPacketToAll(WorldPacket *packet); void YellToAll(Creature* creature, const char* text, uint32 language); - template void BroadcastWorker(Do& _do); - void PlaySoundToTeam(uint32 SoundID, uint32 TeamID); void PlaySoundToAll(uint32 SoundID); void CastSpellOnTeam(uint32 SpellID, uint32 TeamID); @@ -448,19 +394,14 @@ class BattleGround void UpdateWorldStateForPlayer(uint32 Field, uint32 Value, Player *Source); void EndBattleGround(uint32 winner); void BlockMovement(Player *plr); - void SendMessageToAll(int32 entry, ChatMsg type, Player const* source = NULL); void PSendMessageToAll(int32 entry, ChatMsg type, Player const* source, ... ); - // specialized version with 2 string id args void SendMessage2ToAll(int32 entry, ChatMsg type, Player const* source, int32 strId1 = 0, int32 strId2 = 0); - /* Raid Group */ Group *GetBgRaid(uint32 TeamID) const { return TeamID == ALLIANCE ? m_BgRaids[BG_TEAM_ALLIANCE] : m_BgRaids[BG_TEAM_HORDE]; } void SetBgRaid(uint32 TeamID, Group *bg_raid); - virtual void UpdatePlayerScore(Player *Source, uint32 type, uint32 value); - static BattleGroundTeamId GetTeamIndexByTeamId(uint32 Team) { return Team == ALLIANCE ? BG_TEAM_ALLIANCE : BG_TEAM_HORDE; } uint32 GetPlayersCountByTeam(uint32 Team) const { return m_PlayersCount[GetTeamIndexByTeamId(Team)]; } uint32 GetAlivePlayersCountByTeam(uint32 Team) const; // used in arenas to correctly handle death in spirit of redemption / last stand etc. (killer = killed) cases @@ -471,41 +412,32 @@ class BattleGround else ++m_PlayersCount[GetTeamIndexByTeamId(Team)]; } - // used for rated arena battles void SetArenaTeamIdForTeam(uint32 Team, uint32 ArenaTeamId) { m_ArenaTeamIds[GetTeamIndexByTeamId(Team)] = ArenaTeamId; } uint32 GetArenaTeamIdForTeam(uint32 Team) const { return m_ArenaTeamIds[GetTeamIndexByTeamId(Team)]; } void SetArenaTeamRatingChangeForTeam(uint32 Team, int32 RatingChange) { m_ArenaTeamRatingChanges[GetTeamIndexByTeamId(Team)] = RatingChange; } int32 GetArenaTeamRatingChangeForTeam(uint32 Team) const { return m_ArenaTeamRatingChanges[GetTeamIndexByTeamId(Team)]; } void CheckArenaWinConditions(); - /* Triggers handle */ // must be implemented in BG subclass virtual void HandleAreaTrigger(Player* /*Source*/, uint32 /*Trigger*/) {} // must be implemented in BG subclass if need AND call base class generic code virtual void HandleKillPlayer(Player *player, Player *killer); virtual void HandleKillUnit(Creature* /*unit*/, Player* /*killer*/); - /* Battleground events */ virtual void EventPlayerDroppedFlag(Player* /*player*/) {} virtual void EventPlayerClickedOnFlag(Player* /*player*/, GameObject* /*target_obj*/) {} virtual void EventPlayerCapturedFlag(Player* /*player*/) {} void EventPlayerLoggedIn(Player* player, uint64 plr_guid); void EventPlayerLoggedOut(Player* player); - /* Death related */ virtual WorldSafeLocsEntry const* GetClosestGraveYard(Player* player); - virtual void AddPlayer(Player *plr); // must be implemented in BG subclass - void AddOrSetPlayerToCorrectBgGroup(Player *plr, uint64 plr_guid, uint32 team); - virtual void RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPacket); // can be extended in in BG subclass - void HandleTriggerBuff(uint64 const& go_guid); void SetHoliday(bool is_holiday); - // TODO: make this protected: typedef std::vector BGObjects; typedef std::vector BGCreatures; @@ -519,40 +451,30 @@ class BattleGround bool DelObject(uint32 type); bool AddSpiritGuide(uint32 type, float x, float y, float z, float o, uint32 team); int32 GetObjectType(uint64 guid); - void DoorOpen(uint32 type); void DoorClose(uint32 type); //to be removed const char *GetTrinityString(int32 entry); - virtual bool HandlePlayerUnderMap(Player * /*plr*/) { return false; } - // since arenas can be AvA or Hvh, we have to get the "temporary" team of a player uint32 GetPlayerTeam(uint64 guid); uint32 GetOtherTeam(uint32 teamId); bool IsPlayerInBattleGround(uint64 guid); - void SetDeleteThis() {m_SetDeleteThis = true;} - /* virtual score-array - get's used in bg-subclasses */ int32 m_TeamScores[BG_TEAMS_COUNT]; - protected: //this method is called, when BG cannot spawn its own spirit guide, or something is wrong, It correctly ends BattleGround void EndNow(); void PlayerAddedToBGCheckIfBGIsRunning(Player* plr); - /* Scorekeeping */ - BattleGroundScoreMap m_PlayerScores; // Player scores // must be implemented in BG subclass virtual void RemovePlayer(Player * /*player*/, uint64 /*guid*/) {} - /* Player lists, those need to be accessible by inherited classes */ BattleGroundPlayerMap m_Players; // Spirit Guide guid + Player list GUIDS std::map > m_ReviveQueue; - /* these are important variables used for starting messages */ @@ -560,9 +482,7 @@ class BattleGround BattleGroundStartTimeIntervals m_StartDelayTimes[BG_STARTING_EVENT_COUNT]; //this must be filled in constructors! uint32 m_StartMessageIds[BG_STARTING_EVENT_COUNT]; - bool m_BuffChange; - BGHonorMode m_HonorMode; private: /* Battleground */ @@ -584,28 +504,21 @@ class BattleGround bool m_PrematureCountDown; uint32 m_PrematureCountDownTimer; char const *m_Name; - /* Player lists */ std::vector m_ResurrectQueue; // Player GUID std::deque m_OfflineQueue; // Player GUID - /* Invited counters are useful for player invitation to BG - do not allow, if BG is started to one faction to have 2 more players than another faction */ /* Invited counters will be changed only when removing already invited player from queue, removing player from battleground and inviting player to BG */ /* Invited players counters*/ uint32 m_InvitedAlliance; uint32 m_InvitedHorde; - /* Raid Group */ Group *m_BgRaids[BG_TEAMS_COUNT]; // 0 - alliance, 1 - horde - /* Players count by team */ uint32 m_PlayersCount[BG_TEAMS_COUNT]; - /* Arena team ids by team */ uint32 m_ArenaTeamIds[BG_TEAMS_COUNT]; - int32 m_ArenaTeamRatingChanges[BG_TEAMS_COUNT]; - /* Limits */ uint32 m_LevelMin; uint32 m_LevelMax; @@ -613,7 +526,6 @@ class BattleGround uint32 m_MaxPlayers; uint32 m_MinPlayersPerTeam; uint32 m_MinPlayers; - /* Start location */ uint32 m_MapId; float m_TeamStartLocX[BG_TEAMS_COUNT]; diff --git a/src/game/BattleGroundAA.cpp b/src/game/BattleGroundAA.cpp index 6133508ece1..4122325cd66 100644 --- a/src/game/BattleGroundAA.cpp +++ b/src/game/BattleGroundAA.cpp @@ -17,15 +17,12 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "BattleGround.h" #include "BattleGroundAA.h" #include "Language.h" #include "Player.h" - BattleGroundAA::BattleGroundAA() { - m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M; m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S; m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S; @@ -36,47 +33,36 @@ BattleGroundAA::BattleGroundAA() m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS; m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN; } - BattleGroundAA::~BattleGroundAA() { - } - void BattleGroundAA::Update(uint32 diff) { BattleGround::Update(diff); } - void BattleGroundAA::StartingEventCloseDoors() { } - void BattleGroundAA::StartingEventOpenDoors() { } - void BattleGroundAA::AddPlayer(Player *plr) { BattleGround::AddPlayer(plr); //create score and add it to map, default values are set in constructor BattleGroundAAScore* sc = new BattleGroundAAScore; - m_PlayerScores[plr->GetGUID()] = sc; } - void BattleGroundAA::RemovePlayer(Player * /*plr*/, uint64 /*guid*/) { } - void BattleGroundAA::HandleKillPlayer(Player* player, Player* killer) { BattleGround::HandleKillPlayer(player, killer); } - void BattleGroundAA::HandleAreaTrigger(Player * /*Source*/, uint32 /*Trigger*/) { } - bool BattleGroundAA::SetupBattleGround() { return true; diff --git a/src/game/BattleGroundAA.h b/src/game/BattleGroundAA.h index 06793ea38e0..241a1ba73c1 100644 --- a/src/game/BattleGroundAA.h +++ b/src/game/BattleGroundAA.h @@ -19,9 +19,7 @@ */ #ifndef __BATTLEGROUNDAA_H #define __BATTLEGROUNDAA_H - class BattleGround; - class BattleGroundAAScore : public BattleGroundScore { public: @@ -29,21 +27,17 @@ class BattleGroundAAScore : public BattleGroundScore virtual ~BattleGroundAAScore() {}; //TODO fix me }; - class BattleGroundAA : public BattleGround { friend class BattleGroundMgr; - public: BattleGroundAA(); ~BattleGroundAA(); void Update(uint32 diff); - /* inherited from BattlegroundClass */ virtual void AddPlayer(Player *plr); virtual void StartingEventCloseDoors(); virtual void StartingEventOpenDoors(); - void RemovePlayer(Player *plr, uint64 guid); void HandleAreaTrigger(Player *Source, uint32 Trigger); bool SetupBattleGround(); diff --git a/src/game/BattleGroundAB.cpp b/src/game/BattleGroundAB.cpp index 6609c3400be..16eda4b9e94 100644 --- a/src/game/BattleGroundAB.cpp +++ b/src/game/BattleGroundAB.cpp @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "World.h" #include "WorldPacket.h" #include "ObjectMgr.h" @@ -29,42 +28,34 @@ #include "Object.h" #include "Player.h" #include "Util.h" - // these variables aren't used outside of this file, so declare them only here uint32 BG_AB_HonorScoreTicks[BG_HONOR_MODE_NUM] = { 330, // normal honor 200 // holiday }; - uint32 BG_AB_ReputationScoreTicks[BG_HONOR_MODE_NUM] = { 200, // normal honor 150 // holiday }; - BattleGroundAB::BattleGroundAB() { m_BuffChange = true; m_BgObjects.resize(BG_AB_OBJECT_MAX); m_BgCreatures.resize(BG_AB_ALL_NODES_COUNT); - m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_AB_START_TWO_MINUTES; m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_AB_START_ONE_MINUTE; m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_AB_START_HALF_MINUTE; m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_AB_HAS_BEGUN; } - BattleGroundAB::~BattleGroundAB() { } - void BattleGroundAB::Update(uint32 diff) { BattleGround::Update(diff); - if (GetStatus() == STATUS_IN_PROGRESS) { int team_points[BG_TEAMS_COUNT] = { 0, 0 }; - for (int node = 0; node < BG_AB_DYNAMIC_NODES_COUNT; ++node) { // 3 sec delay to spawn new banner instead previous despawned one @@ -78,7 +69,6 @@ void BattleGroundAB::Update(uint32 diff) _CreateBanner(node, m_BannerTimers[node].type, m_BannerTimers[node].teamIndex, false); } } - // 1-minute to occupy a node from contested state if (m_NodeTimers[node]) { @@ -98,7 +88,6 @@ void BattleGroundAB::Update(uint32 diff) _SendNodeUpdate(node); _NodeOccupied(node,(teamIndex == 0) ? ALLIANCE:HORDE); // Message to chatlog - if (teamIndex == 0) { // FIXME: team and node names not localized @@ -113,12 +102,10 @@ void BattleGroundAB::Update(uint32 diff) } } } - for (int team = 0; team < BG_TEAMS_COUNT; ++team) if (m_Nodes[node] == team + BG_AB_NODE_TYPE_OCCUPIED) ++team_points[team]; } - // Accumulate points for (int team = 0; team < BG_TEAMS_COUNT; ++team) { @@ -151,7 +138,6 @@ void BattleGroundAB::Update(uint32 diff) PlaySoundToAll(BG_AB_SOUND_NEAR_VICTORY); m_IsInformedNearVictory = true; } - if (m_TeamScores[team] > BG_AB_MAX_TEAM_SCORE) m_TeamScores[team] = BG_AB_MAX_TEAM_SCORE; if (team == BG_TEAM_ALLIANCE) @@ -165,7 +151,6 @@ void BattleGroundAB::Update(uint32 diff) m_TeamScores500Disadvantage[otherTeam] = true; } } - // Test win condition if (m_TeamScores[BG_TEAM_ALLIANCE] >= BG_AB_MAX_TEAM_SCORE) EndBattleGround(ALLIANCE); @@ -173,7 +158,6 @@ void BattleGroundAB::Update(uint32 diff) EndBattleGround(HORDE); } } - void BattleGroundAB::StartingEventCloseDoors() { // despawn banners, auras and buffs @@ -181,18 +165,15 @@ void BattleGroundAB::StartingEventCloseDoors() SpawnBGObject(obj, RESPAWN_ONE_DAY); for (int i = 0; i < BG_AB_DYNAMIC_NODES_COUNT * 3; ++i) SpawnBGObject(BG_AB_OBJECT_SPEEDBUFF_STABLES + i, RESPAWN_ONE_DAY); - // Starting doors DoorClose(BG_AB_OBJECT_GATE_A); DoorClose(BG_AB_OBJECT_GATE_H); SpawnBGObject(BG_AB_OBJECT_GATE_A, RESPAWN_IMMEDIATELY); SpawnBGObject(BG_AB_OBJECT_GATE_H, RESPAWN_IMMEDIATELY); - // Starting base spirit guides _NodeOccupied(BG_AB_SPIRIT_ALIANCE,ALLIANCE); _NodeOccupied(BG_AB_SPIRIT_HORDE,HORDE); } - void BattleGroundAB::StartingEventOpenDoors() { // spawn neutral banners @@ -207,26 +188,20 @@ void BattleGroundAB::StartingEventOpenDoors() DoorOpen(BG_AB_OBJECT_GATE_A); DoorOpen(BG_AB_OBJECT_GATE_H); } - void BattleGroundAB::AddPlayer(Player *plr) { BattleGround::AddPlayer(plr); //create score and add it to map, default values are set in the constructor BattleGroundABScore* sc = new BattleGroundABScore; - m_PlayerScores[plr->GetGUID()] = sc; } - void BattleGroundAB::RemovePlayer(Player * /*plr*/, uint64 /*guid*/) { - } - void BattleGroundAB::HandleAreaTrigger(Player *Source, uint32 Trigger) { if (GetStatus() != STATUS_IN_PROGRESS) return; - switch(Trigger) { case 3948: // Arathi Basin Alliance Exit. @@ -255,7 +230,6 @@ void BattleGroundAB::HandleAreaTrigger(Player *Source, uint32 Trigger) break; } } - /* type: 0-neutral, 1-contested, 3-occupied teamIndex: 0-ally, 1-horde */ void BattleGroundAB::_CreateBanner(uint8 node, uint8 type, uint8 teamIndex, bool delay) @@ -268,30 +242,24 @@ void BattleGroundAB::_CreateBanner(uint8 node, uint8 type, uint8 teamIndex, bool m_BannerTimers[node].teamIndex = teamIndex; return; } - uint8 obj = node*8 + type + teamIndex; - SpawnBGObject(obj, RESPAWN_IMMEDIATELY); - // handle aura with banner if (!type) return; obj = node * 8 + ((type == BG_AB_NODE_TYPE_OCCUPIED) ? (5 + teamIndex) : 7); SpawnBGObject(obj, RESPAWN_IMMEDIATELY); } - void BattleGroundAB::_DelBanner(uint8 node, uint8 type, uint8 teamIndex) { uint8 obj = node*8 + type + teamIndex; SpawnBGObject(obj, RESPAWN_ONE_DAY); - // handle aura with banner if (!type) return; obj = node * 8 + ((type == BG_AB_NODE_TYPE_OCCUPIED) ? (5 + teamIndex) : 7); SpawnBGObject(obj, RESPAWN_ONE_DAY); } - int32 BattleGroundAB::_GetNodeNameId(uint8 node) { switch (node) @@ -306,20 +274,16 @@ int32 BattleGroundAB::_GetNodeNameId(uint8 node) } return 0; } - void BattleGroundAB::FillInitialWorldStates(WorldPacket& data) { const uint8 plusArray[] = {0, 2, 3, 0, 1}; - // Node icons for (uint8 node = 0; node < BG_AB_DYNAMIC_NODES_COUNT; ++node) data << uint32(BG_AB_OP_NODEICONS[node]) << uint32((m_Nodes[node]==0)?1:0); - // Node occupied states for (uint8 node = 0; node < BG_AB_DYNAMIC_NODES_COUNT; ++node) for (uint8 i = 1; i < BG_AB_DYNAMIC_NODES_COUNT; ++i) data << uint32(BG_AB_OP_NODESTATES[node] + plusArray[i]) << uint32((m_Nodes[node]==i)?1:0); - // How many bases each team owns uint8 ally = 0, horde = 0; for (uint8 node = 0; node < BG_AB_DYNAMIC_NODES_COUNT; ++node) @@ -327,32 +291,25 @@ void BattleGroundAB::FillInitialWorldStates(WorldPacket& data) ++ally; else if (m_Nodes[node] == BG_AB_NODE_STATUS_HORDE_OCCUPIED) ++horde; - data << uint32(BG_AB_OP_OCCUPIED_BASES_ALLY) << uint32(ally); data << uint32(BG_AB_OP_OCCUPIED_BASES_HORDE) << uint32(horde); - // Team scores data << uint32(BG_AB_OP_RESOURCES_MAX) << uint32(BG_AB_MAX_TEAM_SCORE); data << uint32(BG_AB_OP_RESOURCES_WARNING) << uint32(BG_AB_WARNING_NEAR_VICTORY_SCORE); data << uint32(BG_AB_OP_RESOURCES_ALLY) << uint32(m_TeamScores[BG_TEAM_ALLIANCE]); data << uint32(BG_AB_OP_RESOURCES_HORDE) << uint32(m_TeamScores[BG_TEAM_HORDE]); - // other unknown data << uint32(0x745) << uint32(0x2); // 37 1861 unk } - void BattleGroundAB::_SendNodeUpdate(uint8 node) { // Send node owner state update to refresh map icons on client const uint8 plusArray[] = {0, 2, 3, 0, 1}; - if (m_prevNodes[node]) UpdateWorldState(BG_AB_OP_NODESTATES[node] + plusArray[m_prevNodes[node]], 0); else UpdateWorldState(BG_AB_OP_NODEICONS[node], 0); - UpdateWorldState(BG_AB_OP_NODESTATES[node] + plusArray[m_Nodes[node]], 1); - // How many bases each team owns uint8 ally = 0, horde = 0; for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i) @@ -360,17 +317,14 @@ void BattleGroundAB::_SendNodeUpdate(uint8 node) ++ally; else if (m_Nodes[i] == BG_AB_NODE_STATUS_HORDE_OCCUPIED) ++horde; - UpdateWorldState(BG_AB_OP_OCCUPIED_BASES_ALLY, ally); UpdateWorldState(BG_AB_OP_OCCUPIED_BASES_HORDE, horde); } - void BattleGroundAB::_NodeOccupied(uint8 node,Team team) { if (!AddSpiritGuide(node, BG_AB_SpiritGuidePos[node][0], BG_AB_SpiritGuidePos[node][1], BG_AB_SpiritGuidePos[node][2], BG_AB_SpiritGuidePos[node][3], team)) sLog.outError("Failed to spawn spirit guide! point: %u, team: %u,", node, team); // SpawnBGCreature(node,RESPAWN_IMMEDIATELY); - uint8 capturedNodes = 0; for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i) { @@ -382,12 +336,10 @@ void BattleGroundAB::_NodeOccupied(uint8 node,Team team) if (capturedNodes >= 4) CastSpellOnTeam(SPELL_AB_QUEST_REWARD_4_BASES, team); } - void BattleGroundAB::_NodeDeOccupied(uint8 node) { if (node >= BG_AB_DYNAMIC_NODES_COUNT) return; - // Those who are waiting to resurrect at this node are taken to the closest own node's graveyard std::vector ghost_list = m_ReviveQueue[m_BgCreatures[node]]; if (!ghost_list.empty()) @@ -398,27 +350,21 @@ void BattleGroundAB::_NodeDeOccupied(uint8 node) Player* plr = objmgr.GetPlayer(*itr); if (!plr) continue; - if (!ClosestGrave) // cache ClosestGrave = GetClosestGraveYard(plr); - if (ClosestGrave) plr->TeleportTo(GetMapId(), ClosestGrave->x, ClosestGrave->y, ClosestGrave->z, plr->GetOrientation()); } } - if (m_BgCreatures[node]) DelCreature(node); - // buff object isn't despawned } - /* Invoked if a player used a banner as a gameobject */ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*target_obj*/) { if (GetStatus() != STATUS_IN_PROGRESS) return; - uint8 node = BG_AB_NODE_STABLES; GameObject* obj=HashMapHolder::Find(m_BgObjects[node*8+7]); while ( (node < BG_AB_DYNAMIC_NODES_COUNT) && ((!obj) || (!source->IsWithinDistInMap(obj,10)))) @@ -426,19 +372,15 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ ++node; obj=HashMapHolder::Find(m_BgObjects[node*8+BG_AB_OBJECT_AURA_CONTESTED]); } - if (node == BG_AB_DYNAMIC_NODES_COUNT) { // this means our player isn't close to any of banners - maybe cheater ?? return; } - BattleGroundTeamId teamIndex = GetTeamIndexByTeamId(source->GetTeam()); - // Check if player really could use this banner, not cheated if (!(m_Nodes[node] == 0 || teamIndex == m_Nodes[node]%2)) return; - source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT); uint32 sound = 0; // If node is neutral, change to contested @@ -453,13 +395,11 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ _CreateBanner(node, BG_AB_NODE_TYPE_CONTESTED, teamIndex, true); _SendNodeUpdate(node); m_NodeTimers[node] = BG_AB_FLAG_CAPTURING_TIME; - // FIXME: team and node names not localized if (teamIndex == 0) SendMessage2ToAll(LANG_BG_AB_NODE_CLAIMED,CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node), LANG_BG_AB_ALLY); else SendMessage2ToAll(LANG_BG_AB_NODE_CLAIMED,CHAT_MSG_BG_SYSTEM_HORDE, source, _GetNodeNameId(node), LANG_BG_AB_HORDE); - sound = BG_AB_SOUND_NODE_CLAIMED; } // If node is contested @@ -477,7 +417,6 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ _CreateBanner(node, BG_AB_NODE_TYPE_CONTESTED, teamIndex, true); _SendNodeUpdate(node); m_NodeTimers[node] = BG_AB_FLAG_CAPTURING_TIME; - // FIXME: node names not localized if (teamIndex == BG_TEAM_ALLIANCE) SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED,CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node)); @@ -497,7 +436,6 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ _SendNodeUpdate(node); m_NodeTimers[node] = 0; _NodeOccupied(node,(teamIndex == BG_TEAM_ALLIANCE) ? ALLIANCE:HORDE); - // FIXME: node names not localized if (teamIndex == BG_TEAM_ALLIANCE) SendMessage2ToAll(LANG_BG_AB_NODE_DEFENDED,CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node)); @@ -519,16 +457,13 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ _SendNodeUpdate(node); _NodeDeOccupied(node); m_NodeTimers[node] = BG_AB_FLAG_CAPTURING_TIME; - // FIXME: node names not localized if (teamIndex == BG_TEAM_ALLIANCE) SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED,CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node)); else SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED,CHAT_MSG_BG_SYSTEM_HORDE, source, _GetNodeNameId(node)); - sound = (teamIndex == BG_TEAM_ALLIANCE) ? BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE : BG_AB_SOUND_NODE_ASSAULTED_HORDE; } - // If node is occupied again, send "X has taken the Y" msg. if (m_Nodes[node] >= BG_AB_NODE_TYPE_OCCUPIED) { @@ -540,7 +475,6 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ } PlaySoundToAll(sound); } - bool BattleGroundAB::SetupBattleGround() { for (int i = 0 ; i < BG_AB_DYNAMIC_NODES_COUNT; ++i) @@ -575,15 +509,12 @@ bool BattleGroundAB::SetupBattleGround() ) sLog.outErrorDb("BatteGroundAB: Failed to spawn buff object!"); } - return true; } - void BattleGroundAB::Reset() { //call parent's class reset BattleGround::Reset(); - m_TeamScores[BG_TEAM_ALLIANCE] = 0; m_TeamScores[BG_TEAM_HORDE] = 0; m_lastTick[BG_TEAM_ALLIANCE] = 0; @@ -598,7 +529,6 @@ void BattleGroundAB::Reset() m_ReputationTics = (isBGWeekend) ? BG_AB_ABBGWeekendReputationTicks : BG_AB_NotABBGWeekendReputationTicks; m_TeamScores500Disadvantage[BG_TEAM_ALLIANCE] = false; m_TeamScores500Disadvantage[BG_TEAM_HORDE] = false; - for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i) { m_Nodes[i] = 0; @@ -606,12 +536,10 @@ void BattleGroundAB::Reset() m_NodeTimers[i] = 0; m_BannerTimers[i].timer = 0; } - for (uint8 i = 0; i < BG_AB_ALL_NODES_COUNT; ++i) if (m_BgCreatures[i]) DelCreature(i); } - void BattleGroundAB::EndBattleGround(uint32 winner) { //win reward @@ -622,27 +550,22 @@ void BattleGroundAB::EndBattleGround(uint32 winner) //complete map_end rewards (even if no team wins) RewardHonorToTeam(GetBonusHonorFromKill(1), HORDE); RewardHonorToTeam(GetBonusHonorFromKill(1), ALLIANCE); - BattleGround::EndBattleGround(winner); } - WorldSafeLocsEntry const* BattleGroundAB::GetClosestGraveYard(Player* player) { BattleGroundTeamId teamIndex = GetTeamIndexByTeamId(player->GetTeam()); - // Is there any occupied node for this team? std::vector nodes; for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i) if (m_Nodes[i] == teamIndex + 3) nodes.push_back(i); - WorldSafeLocsEntry const* good_entry = NULL; // If so, select the closest node to place ghost on if (!nodes.empty()) { float plr_x = player->GetPositionX(); float plr_y = player->GetPositionY(); - float mindist = 999999.0f; for (uint8 i = 0; i < nodes.size(); ++i) { @@ -661,16 +584,13 @@ WorldSafeLocsEntry const* BattleGroundAB::GetClosestGraveYard(Player* player) // If not, place ghost on starting location if (!good_entry) good_entry = sWorldSafeLocsStore.LookupEntry( BG_AB_GraveyardIds[teamIndex+5] ); - return good_entry; } - void BattleGroundAB::UpdatePlayerScore(Player *Source, uint32 type, uint32 value) { BattleGroundScoreMap::iterator itr = m_PlayerScores.find(Source->GetGUID()); if( itr == m_PlayerScores.end() ) // player not found... return; - switch(type) { case SCORE_BASES_ASSAULTED: @@ -684,7 +604,6 @@ void BattleGroundAB::UpdatePlayerScore(Player *Source, uint32 type, uint32 value break; } } - bool BattleGroundAB::IsAllNodesConrolledByTeam(uint32 team) const { uint32 count = 0; @@ -692,6 +611,5 @@ bool BattleGroundAB::IsAllNodesConrolledByTeam(uint32 team) const if ((team == ALLIANCE && m_Nodes[i] == BG_AB_NODE_STATUS_ALLY_OCCUPIED) || (team == HORDE && m_Nodes[i] == BG_AB_NODE_STATUS_HORDE_OCCUPIED)) ++count; - return count == BG_AB_DYNAMIC_NODES_COUNT; } diff --git a/src/game/BattleGroundAB.h b/src/game/BattleGroundAB.h index ef151ad187b..7da1c517528 100644 --- a/src/game/BattleGroundAB.h +++ b/src/game/BattleGroundAB.h @@ -19,9 +19,7 @@ */ #ifndef __BATTLEGROUNDAB_H #define __BATTLEGROUNDAB_H - class BattleGround; - enum BG_AB_WorldStates { BG_AB_OP_OCCUPIED_BASES_HORDE = 1778, @@ -41,7 +39,6 @@ enum BG_AB_WorldStates BG_AB_OP_FARM_STATE_HORDE = 1773, //Farm state (HORDE) BG_AB_OP_FARM_STATE_CON_ALI = 1774, //Farm state (CON ALIENCE) BG_AB_OP_FARM_STATE_CON_HOR = 1775, //Farm state (CON HORDE) - BG_AB_OP_BLACKSMITH_ICON = 1846, //Blacksmith map icon (NONE) BG_AB_OP_BLACKSMITH_STATE_ALIENCE = 1782, //Blacksmith map state (ALIENCE) BG_AB_OP_BLACKSMITH_STATE_HORDE = 1783, //Blacksmith map state (HORDE) @@ -59,11 +56,8 @@ enum BG_AB_WorldStates BG_AB_OP_GOLDMINE_STATE_CON_HOR = 1790, //Gold Mine map state (CON HORDE) */ }; - const uint32 BG_AB_OP_NODESTATES[5] = {1767, 1782, 1772, 1792, 1787}; - const uint32 BG_AB_OP_NODEICONS[5] = {1842, 1846, 1845, 1844, 1843}; - /* Note: code uses that these IDs follow each other */ enum BG_AB_NodeObjectId { @@ -73,7 +67,6 @@ enum BG_AB_NodeObjectId BG_AB_OBJECTID_NODE_BANNER_3 = 180090, // Lumber mill banner BG_AB_OBJECTID_NODE_BANNER_4 = 180091 // Gold mine banner }; - enum BG_AB_ObjectType { // for all 5 node points 8*5=40 objects @@ -106,7 +99,6 @@ enum BG_AB_ObjectType BG_AB_OBJECT_BERSERKBUFF_GOLD_MINE = 56, BG_AB_OBJECT_MAX = 57, }; - /* Object id templates from DB */ enum BG_AB_ObjectTypes { @@ -114,26 +106,21 @@ enum BG_AB_ObjectTypes BG_AB_OBJECTID_BANNER_CONT_A = 180059, BG_AB_OBJECTID_BANNER_H = 180060, BG_AB_OBJECTID_BANNER_CONT_H = 180061, - BG_AB_OBJECTID_AURA_A = 180100, BG_AB_OBJECTID_AURA_H = 180101, BG_AB_OBJECTID_AURA_C = 180102, - BG_AB_OBJECTID_GATE_A = 180255, BG_AB_OBJECTID_GATE_H = 180256 }; - enum BG_AB_Timers { BG_AB_FLAG_CAPTURING_TIME = 60000, }; - enum BG_AB_Score { BG_AB_WARNING_NEAR_VICTORY_SCORE = 1800, BG_AB_MAX_TEAM_SCORE = 2000 }; - /* do NOT change the order, else wrong behaviour */ enum BG_AB_BattleGroundNodes { @@ -142,15 +129,11 @@ enum BG_AB_BattleGroundNodes BG_AB_NODE_FARM = 2, BG_AB_NODE_LUMBER_MILL = 3, BG_AB_NODE_GOLD_MINE = 4, - BG_AB_DYNAMIC_NODES_COUNT = 5, // dynamic nodes that can be captured - BG_AB_SPIRIT_ALIANCE = 5, BG_AB_SPIRIT_HORDE = 6, - BG_AB_ALL_NODES_COUNT = 7, // all nodes (dynamic and static) }; - enum BG_AB_NodeStatus { BG_AB_NODE_TYPE_NEUTRAL = 0, @@ -161,7 +144,6 @@ enum BG_AB_NodeStatus BG_AB_NODE_STATUS_ALLY_OCCUPIED = 3, BG_AB_NODE_STATUS_HORDE_OCCUPIED = 4 }; - enum BG_AB_Sounds { BG_AB_SOUND_NODE_CLAIMED = 8192, @@ -171,12 +153,10 @@ enum BG_AB_Sounds BG_AB_SOUND_NODE_ASSAULTED_HORDE = 8174, BG_AB_SOUND_NEAR_VICTORY = 8456 }; - #define BG_AB_NotABBGWeekendHonorTicks 330 #define BG_AB_ABBGWeekendHonorTicks 200 #define BG_AB_NotABBGWeekendReputationTicks 200 #define BG_AB_ABBGWeekendReputationTicks 150 - // x, y, z, o const float BG_AB_NodePositions[BG_AB_DYNAMIC_NODES_COUNT][4] = { {1166.785f, 1200.132f, -56.70859f, 0.9075713f}, // stables @@ -185,20 +165,16 @@ const float BG_AB_NodePositions[BG_AB_DYNAMIC_NODES_COUNT][4] = { {856.1419f, 1148.902f, 11.18469f, -2.303835f}, // lumber mill {1146.923f, 848.1782f, -110.917f, -0.7330382f} // gold mine }; - // x, y, z, o, rot0, rot1, rot2, rot3 const float BG_AB_DoorPositions[2][8] = { {1284.597f, 1281.167f, -15.97792f, 0.7068594f, 0.012957f, -0.060288f, 0.344959f, 0.93659f}, {708.0903f, 708.4479f, -17.8342f, -2.391099f, 0.050291f, 0.015127f, 0.929217f, -0.365784f} }; - // Tick intervals and given points: case 0,1,2,3,4,5 captured nodes const uint32 BG_AB_TickIntervals[6] = {0, 12000, 9000, 6000, 3000, 1000}; const uint32 BG_AB_TickPoints[6] = {0, 10, 10, 10, 10, 30}; - // WorldSafeLocs ids for 5 nodes, and for ally, and horde starting location const uint32 BG_AB_GraveyardIds[BG_AB_ALL_NODES_COUNT] = {895, 894, 893, 897, 896, 898, 899}; - // x, y, z, o const float BG_AB_BuffPositions[BG_AB_DYNAMIC_NODES_COUNT][4] = { {1185.71f, 1185.24f, -56.36f, 2.56f}, // stables @@ -207,7 +183,6 @@ const float BG_AB_BuffPositions[BG_AB_DYNAMIC_NODES_COUNT][4] = { {807.46f, 1189.16f, 11.92f, 5.44f}, // lumber mill {1146.62f, 816.94f, -98.49f, 6.14f} // gold mine }; - // x, y, z, o const float BG_AB_SpiritGuidePos[BG_AB_ALL_NODES_COUNT][4] = { {1200.03f, 1171.09f, -56.47f, 5.15f}, // stables @@ -218,14 +193,12 @@ const float BG_AB_SpiritGuidePos[BG_AB_ALL_NODES_COUNT][4] = { {1354.05f, 1275.48f, -11.30f, 4.77f}, // alliance starting base {714.61f, 646.15f, -10.87f, 4.34f} // horde starting base }; - struct BG_AB_BannerTimer { uint32 timer; uint8 type; uint8 teamIndex; }; - class BattleGroundABScore : public BattleGroundScore { public: @@ -234,15 +207,12 @@ class BattleGroundABScore : public BattleGroundScore uint32 BasesAssaulted; uint32 BasesDefended; }; - class BattleGroundAB : public BattleGround { friend class BattleGroundMgr; - public: BattleGroundAB(); ~BattleGroundAB(); - void Update(uint32 diff); void AddPlayer(Player *plr); virtual void StartingEventCloseDoors(); @@ -253,15 +223,11 @@ class BattleGroundAB : public BattleGround virtual void Reset(); void EndBattleGround(uint32 winner); virtual WorldSafeLocsEntry const* GetClosestGraveYard(Player* player); - /* Scorekeeping */ virtual void UpdatePlayerScore(Player *Source, uint32 type, uint32 value); - virtual void FillInitialWorldStates(WorldPacket& data); - /* Nodes occupying */ virtual void EventPlayerClickedOnFlag(Player *source, GameObject* target_obj); - /* achievement req. */ bool IsAllNodesConrolledByTeam(uint32 team) const; // overwrited bool IsTeamScores500Disadvantage(uint32 team) const { return m_TeamScores500Disadvantage[GetTeamIndexByTeamId(team)]; } @@ -270,14 +236,11 @@ class BattleGroundAB : public BattleGround void _CreateBanner(uint8 node, uint8 type, uint8 teamIndex, bool delay); void _DelBanner(uint8 node, uint8 type, uint8 teamIndex); void _SendNodeUpdate(uint8 node); - /* Creature spawning/despawning */ // TODO: working, scripted peons spawning void _NodeOccupied(uint8 node,Team team); void _NodeDeOccupied(uint8 node); - int32 _GetNodeNameId(uint8 node); - /* Nodes info: 0: neutral 1: ally contested diff --git a/src/game/BattleGroundAV.cpp b/src/game/BattleGroundAV.cpp index 42d15a6ce84..4db2f4b3df2 100644 --- a/src/game/BattleGroundAV.cpp +++ b/src/game/BattleGroundAV.cpp @@ -17,10 +17,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "ObjectMgr.h" #include "WorldPacket.h" - #include "BattleGround.h" #include "BattleGroundAV.h" #include "Formulas.h" @@ -28,36 +26,29 @@ #include "Language.h" #include "Player.h" #include "SpellAuras.h" - BattleGroundAV::BattleGroundAV() { m_BgObjects.resize(BG_AV_OBJECT_MAX); m_BgCreatures.resize(AV_CPLACE_MAX+AV_STATICCPLACE_MAX); - m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_AV_START_TWO_MINUTES; m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_AV_START_ONE_MINUTE; m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_AV_START_HALF_MINUTE; m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_AV_HAS_BEGUN; } - BattleGroundAV::~BattleGroundAV() { } - const uint16 BattleGroundAV::GetBonusHonor(uint8 kills) //TODO: move this function to Battleground.cpp (needs to find a way to get m_MaxLevel) { return Trinity::Honor::hk_honor_at_level(m_MaxLevel, kills); } - void BattleGroundAV::HandleKillPlayer(Player *player, Player *killer) { if(GetStatus() != STATUS_IN_PROGRESS) return; - BattleGround::HandleKillPlayer(player, killer); UpdateScore(player->GetTeam(),-1); } - void BattleGroundAV::HandleKillUnit(Creature *unit, Player *killer) { sLog.outDebug("bg_av HandleKillUnit %i",unit->GetEntry()); @@ -95,7 +86,6 @@ void BattleGroundAV::HandleKillUnit(Creature *unit, Player *killer) Creature* creature = GetBGCreature(AV_CPLACE_HERALD); if(creature) YellToAll(creature,GetTrinityString(LANG_BG_AV_A_CAPTAIN_DEAD),LANG_UNIVERSAL); - } else if ( entry == BG_AV_CreatureInfo[AV_NPC_H_CAPTAIN][0] ) { @@ -120,7 +110,6 @@ void BattleGroundAV::HandleKillUnit(Creature *unit, Player *killer) else if ( entry == BG_AV_CreatureInfo[AV_NPC_S_MINE_N_4][0] || entry == BG_AV_CreatureInfo[AV_NPC_S_MINE_A_4][0] || entry == BG_AV_CreatureInfo[AV_NPC_S_MINE_H_4][0]) ChangeMineOwner(AV_SOUTH_MINE,killer->GetTeam()); } - void BattleGroundAV::HandleQuestComplete(uint32 questid, Player *player) { if (GetStatus() != STATUS_IN_PROGRESS) @@ -224,13 +213,11 @@ void BattleGroundAV::HandleQuestComplete(uint32 questid, Player *player) } } - void BattleGroundAV::UpdateScore(uint16 team, int16 points ) { //note: to remove reinforcementpoints points must be negative, for adding reinforcements points must be positive assert( team == ALLIANCE || team == HORDE); uint8 teamindex = GetTeamIndexByTeamId(team); //0=ally 1=horde m_Team_Scores[teamindex] += points; - UpdateWorldState(((teamindex==BG_TEAM_HORDE)?AV_Horde_Score:AV_Alliance_Score), m_Team_Scores[teamindex]); if( points < 0) { @@ -247,7 +234,6 @@ void BattleGroundAV::UpdateScore(uint16 team, int16 points ) } } } - Creature* BattleGroundAV::AddAVCreature(uint16 cinfoid, uint16 type ) { uint32 level; @@ -271,7 +257,6 @@ Creature* BattleGroundAV::AddAVCreature(uint16 cinfoid, uint16 type ) return NULL; if(creature->GetEntry() == BG_AV_CreatureInfo[AV_NPC_A_CAPTAIN][0] || creature->GetEntry() == BG_AV_CreatureInfo[AV_NPC_H_CAPTAIN][0]) creature->SetRespawnDelay(RESPAWN_ONE_DAY); // TODO: look if this can be done by database + also add this for the wingcommanders - if((isStatic && cinfoid>=10 && cinfoid<=14) || (!isStatic && ((cinfoid >= AV_NPC_A_GRAVEDEFENSE0 && cinfoid<=AV_NPC_A_GRAVEDEFENSE3) || (cinfoid>=AV_NPC_H_GRAVEDEFENSE0 && cinfoid<=AV_NPC_H_GRAVEDEFENSE3)))) { @@ -289,17 +274,14 @@ Creature* BattleGroundAV::AddAVCreature(uint16 cinfoid, uint16 type ) //TODO: find a way to add a motionmaster without killing the creature (i //just copied this code from a gm-command } - if(level != 0) level += m_MaxLevel-60; //maybe we can do this more generic for custom level-range.. actually it's blizzlike creature->SetLevel(level); return creature; } - void BattleGroundAV::Update(uint32 diff) { BattleGround::Update(diff); - if(GetStatus() == STATUS_IN_PROGRESS) { for(uint8 i=0; i<=1;i++)//0=alliance, 1=horde @@ -335,7 +317,6 @@ void BattleGroundAV::Update(uint32 diff) { if( m_Mine_Timer <= 0) UpdateScore(m_Mine_Owner[mine],1); - if(m_Mine_Reclaim_Timer[mine] > diff) m_Mine_Reclaim_Timer[mine] -= diff; else{ //we don't need to set this timer to 0 cause this codepart wont get called when this thing is 0 @@ -345,7 +326,6 @@ void BattleGroundAV::Update(uint32 diff) } if( m_Mine_Timer <= 0) m_Mine_Timer=AV_MINE_TICK_TIMER; //this is at the end, cause we need to update both mines - //looks for all timers of the nodes and destroy the building (for graveyards the building wont get destroyed, it goes just to the other team for(BG_AV_Nodes i = BG_AV_NODES_FIRSTAID_STATION; i < BG_AV_NODES_MAX; ++i) if(m_Nodes[i].State == POINT_ASSAULTED) //maybe remove this @@ -357,13 +337,11 @@ void BattleGroundAV::Update(uint32 diff) } } } - void BattleGroundAV::StartingEventCloseDoors() { DoorClose(BG_AV_OBJECT_DOOR_A); DoorClose(BG_AV_OBJECT_DOOR_H); } - void BattleGroundAV::StartingEventOpenDoors() { sLog.outDebug("BG_AV: start spawning mine stuff"); @@ -373,14 +351,11 @@ void BattleGroundAV::StartingEventOpenDoors() SpawnBGObject(i,RESPAWN_IMMEDIATELY); for(uint8 mine = AV_NORTH_MINE; mine <= AV_SOUTH_MINE; mine++) //mine population ChangeMineOwner(mine, AV_NEUTRAL_TEAM,true); - UpdateWorldState(AV_SHOW_H_SCORE, 1); UpdateWorldState(AV_SHOW_A_SCORE, 1); - DoorOpen(BG_AV_OBJECT_DOOR_H); DoorOpen(BG_AV_OBJECT_DOOR_A); } - void BattleGroundAV::AddPlayer(Player *plr) { BattleGround::AddPlayer(plr); @@ -389,9 +364,7 @@ void BattleGroundAV::AddPlayer(Player *plr) m_PlayerScores[plr->GetGUID()] = sc; if(m_MaxLevel==0) m_MaxLevel=(plr->getLevel()%10 == 0)? plr->getLevel() : (plr->getLevel()-(plr->getLevel()%10))+10; //TODO: just look at the code \^_^/ --but queue-info should provide this information.. - } - void BattleGroundAV::EndBattleGround(uint32 winner) { //calculate bonuskills for both teams: @@ -414,7 +387,6 @@ void BattleGroundAV::EndBattleGround(uint32 winner) } } } - for(int i=0; i<=1; i++) //0=ally 1=horde { if(m_CaptainAlive[i]) @@ -427,11 +399,9 @@ void BattleGroundAV::EndBattleGround(uint32 winner) if(kills[i] != 0) RewardHonorToTeam(GetBonusHonor(kills[i]),(i == 0)?ALLIANCE:HORDE); } - //TODO add enterevademode for all attacking creatures BattleGround::EndBattleGround(winner); } - void BattleGroundAV::RemovePlayer(Player* plr,uint64 /*guid*/) { if(!plr) @@ -445,13 +415,11 @@ void BattleGroundAV::RemovePlayer(Player* plr,uint64 /*guid*/) plr->RemoveAurasDueToSpell(AV_BUFF_H_CAPTAIN); } - void BattleGroundAV::HandleAreaTrigger(Player *Source, uint32 Trigger) { // this is wrong way to implement these things. On official it done by gameobject spell cast. if (GetStatus() != STATUS_IN_PROGRESS) return; - uint32 SpellId = 0; switch(Trigger) { @@ -481,18 +449,14 @@ void BattleGroundAV::HandleAreaTrigger(Player *Source, uint32 Trigger) // Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger); break; } - if (SpellId) Source->CastSpell(Source, SpellId, true); } - void BattleGroundAV::UpdatePlayerScore(Player* Source, uint32 type, uint32 value) { - BattleGroundScoreMap::iterator itr = m_PlayerScores.find(Source->GetGUID()); if(itr == m_PlayerScores.end()) // player not found... return; - switch(type) { case SCORE_GRAVEYARDS_ASSAULTED: @@ -522,19 +486,14 @@ void BattleGroundAV::UpdatePlayerScore(Player* Source, uint32 type, uint32 value } } - - void BattleGroundAV::EventPlayerDestroyedPoint(BG_AV_Nodes node) { - uint32 object = GetObjectThroughNode(node); sLog.outDebug("bg_av: player destroyed point node %i object %i",node,object); - //despawn banner SpawnBGObject(object, RESPAWN_ONE_DAY); DestroyNode(node); UpdateNodeWorldState(node); - uint32 owner = m_Nodes[node].Owner; if( IsTower(node) ) { @@ -547,11 +506,9 @@ void BattleGroundAV::EventPlayerDestroyedPoint(BG_AV_Nodes node) //spawn destroyed aura for(uint8 i=0; i<=9; i++) SpawnBGObject(BG_AV_OBJECT_BURN_DUNBALDAR_SOUTH + i + (tmp * 10),RESPAWN_IMMEDIATELY); - UpdateScore((owner == ALLIANCE) ? HORDE : ALLIANCE, (-1)*BG_AV_RES_TOWER); RewardReputationToTeam((owner == ALLIANCE)?730:729,BG_AV_REP_TOWER,owner); RewardHonorToTeam(GetBonusHonor(BG_AV_KILL_TOWER),owner); - SpawnBGObject(BG_AV_OBJECT_TAURA_A_DUNBALDAR_SOUTH+GetTeamIndexByTeamId(owner)+(2*tmp),RESPAWN_ONE_DAY); SpawnBGObject(BG_AV_OBJECT_TFLAG_A_DUNBALDAR_SOUTH+GetTeamIndexByTeamId(owner)+(2*tmp),RESPAWN_ONE_DAY); } @@ -579,12 +536,10 @@ void BattleGroundAV::EventPlayerDestroyedPoint(BG_AV_Nodes node) sprintf(buf, GetTrinityString(LANG_BG_AV_TOWER_TAKEN) , GetNodeName(node),( owner == ALLIANCE ) ? GetTrinityString(LANG_BG_AV_ALLY) : GetTrinityString(LANG_BG_AV_HORDE) ); else sprintf(buf, GetTrinityString(LANG_BG_AV_GRAVE_TAKEN) , GetNodeName(node),( owner == ALLIANCE ) ? GetTrinityString(LANG_BG_AV_ALLY) :GetTrinityString(LANG_BG_AV_HORDE) ); - Creature* creature = GetBGCreature(AV_CPLACE_HERALD); if(creature) YellToAll(creature,buf,LANG_UNIVERSAL); } - void BattleGroundAV::ChangeMineOwner(uint8 mine, uint32 team, bool initial) { //mine=0 northmine mine=1 southmin //changing the owner results in setting respawntim to infinite for current creatures, spawning new mine owners creatures and changing the chest-objects so that the current owning team can use them @@ -593,12 +548,10 @@ void BattleGroundAV::ChangeMineOwner(uint8 mine, uint32 team, bool initial) team = AV_NEUTRAL_TEAM; else PlaySoundToAll((team==ALLIANCE)?AV_SOUND_ALLIANCE_GOOD:AV_SOUND_HORDE_GOOD); - if(m_Mine_Owner[mine] == team && !initial) return; m_Mine_PrevOwner[mine] = m_Mine_Owner[mine]; m_Mine_Owner[mine] = team; - if(!initial) { sLog.outDebug("bg_av depopulating mine %i (0=north,1=south)",mine); @@ -611,7 +564,6 @@ void BattleGroundAV::ChangeMineOwner(uint8 mine, uint32 team, bool initial) DelCreature(i); //TODO here also } SendMineWorldStates(mine); - sLog.outDebug("bg_av populating mine %i (0=north,1=south)",mine); uint16 miner; //also neutral team exists.. after a big time, the neutral team tries to conquer the mine @@ -674,7 +626,6 @@ void BattleGroundAV::ChangeMineOwner(uint8 mine, uint32 team, bool initial) } return; } - bool BattleGroundAV::PlayerCanDoMineQuest(int32 GOId,uint32 team) { if(GOId == BG_AV_OBJECTID_MINE_N) @@ -683,12 +634,10 @@ bool BattleGroundAV::PlayerCanDoMineQuest(int32 GOId,uint32 team) return (m_Mine_Owner[AV_SOUTH_MINE]==team); return true; //cause it's no mine'object it is ok if this is true } - void BattleGroundAV::PopulateNode(BG_AV_Nodes node) { uint32 owner = m_Nodes[node].Owner; assert(owner); - uint32 c_place = AV_CPLACE_DEFENSE_STORM_AID + ( 4 * node ); uint32 creatureid; if(IsTower(node)) @@ -709,7 +658,6 @@ void BattleGroundAV::PopulateNode(BG_AV_Nodes node) DelCreature(node); if( !AddSpiritGuide(node, BG_AV_CreaturePos[node][0], BG_AV_CreaturePos[node][1], BG_AV_CreaturePos[node][2], BG_AV_CreaturePos[node][3], owner)) sLog.outError("AV: couldn't spawn spiritguide at node %i",node); - } for(uint8 i=0; i<4; i++) { @@ -727,7 +675,6 @@ void BattleGroundAV::DePopulateNode(BG_AV_Nodes node) DelCreature(node); } - const BG_AV_Nodes BattleGroundAV::GetNodeThroughObject(uint32 object) { sLog.outDebug("bg_AV getnodethroughobject %i",object); @@ -749,7 +696,6 @@ const BG_AV_Nodes BattleGroundAV::GetNodeThroughObject(uint32 object) assert(false); return BG_AV_Nodes(0); } - const uint32 BattleGroundAV::GetObjectThroughNode(BG_AV_Nodes node) { //this function is the counterpart to GetNodeThroughObject() sLog.outDebug("bg_AV GetObjectThroughNode %i",node); @@ -786,9 +732,7 @@ const uint32 BattleGroundAV::GetObjectThroughNode(BG_AV_Nodes node) return 0; } - //called when using banner - void BattleGroundAV::EventPlayerClickedOnFlag(Player *source, GameObject* target_obj) { if(GetStatus() != STATUS_IN_PROGRESS) @@ -816,15 +760,12 @@ void BattleGroundAV::EventPlayerClickedOnFlag(Player *source, GameObject* target break; } } - void BattleGroundAV::EventPlayerDefendsPoint(Player* player, uint32 object) { assert(GetStatus() == STATUS_IN_PROGRESS); BG_AV_Nodes node = GetNodeThroughObject(object); - uint32 owner = m_Nodes[node].Owner; //maybe should name it prevowner uint32 team = player->GetTeam(); - if(owner == player->GetTeam() || m_Nodes[node].State != POINT_ASSAULTED) return; if(m_Nodes[node].TotalOwner == AV_NEUTRAL_TEAM) @@ -840,13 +781,11 @@ void BattleGroundAV::EventPlayerDefendsPoint(Player* player, uint32 object) return; } - //spawn new go :) if(m_Nodes[node].Owner == ALLIANCE) SpawnBGObject(object+22, RESPAWN_IMMEDIATELY); //spawn horde banner else SpawnBGObject(object-22, RESPAWN_IMMEDIATELY); //spawn alliance banner - if(!IsTower(node)) { SpawnBGObject(BG_AV_OBJECT_AURA_N_FIRSTAID_STATION+3*node,RESPAWN_ONE_DAY); @@ -854,11 +793,9 @@ void BattleGroundAV::EventPlayerDefendsPoint(Player* player, uint32 object) } // despawn old go SpawnBGObject(object, RESPAWN_ONE_DAY); - DefendNode(node,team); PopulateNode(node); UpdateNodeWorldState(node); - if(IsTower(node)) { //spawn big flag+aura on top of tower @@ -888,11 +825,9 @@ void BattleGroundAV::EventPlayerDefendsPoint(Player* player, uint32 object) else PlaySoundToAll((team==ALLIANCE)?AV_SOUND_ALLIANCE_GOOD:AV_SOUND_HORDE_GOOD); } - void BattleGroundAV::EventPlayerAssaultsPoint(Player* player, uint32 object) { assert(GetStatus() == STATUS_IN_PROGRESS); - BG_AV_Nodes node = GetNodeThroughObject(object); uint32 owner = m_Nodes[node].Owner; //maybe name it prevowner uint32 team = player->GetTeam(); @@ -900,7 +835,6 @@ void BattleGroundAV::EventPlayerAssaultsPoint(Player* player, uint32 object) if(owner == team || team == m_Nodes[node].TotalOwner) return; //surely a gm used this object - if(node == BG_AV_NODES_SNOWFALL_GRAVE) //snowfall is a bit special in capping + it gets eyecandy stuff { if(object == BG_AV_OBJECT_FLAG_N_SNOWFALL_GRAVE) //initial capping @@ -938,7 +872,6 @@ void BattleGroundAV::EventPlayerAssaultsPoint(Player* player, uint32 object) SpawnBGObject(spawn+i,RESPAWN_IMMEDIATELY); } } - //if snowfall gots capped it can be handled like all other graveyards if( m_Nodes[node].TotalOwner != AV_NEUTRAL_TEAM) { @@ -980,11 +913,9 @@ void BattleGroundAV::EventPlayerAssaultsPoint(Player* player, uint32 object) } DePopulateNode(node); } - SpawnBGObject(object, RESPAWN_ONE_DAY); //delete old banner AssaultNode(node,team); UpdateNodeWorldState(node); - //send a nice message to all :) char buf[256]; sprintf(buf, ( IsTower(node) ) ? GetTrinityString(LANG_BG_AV_TOWER_ASSAULTED) : GetTrinityString(LANG_BG_AV_GRAVE_ASSAULTED), GetNodeName(node), ( team == ALLIANCE ) ? GetTrinityString(LANG_BG_AV_ALLY) : GetTrinityString(LANG_BG_AV_HORDE )); @@ -995,7 +926,6 @@ void BattleGroundAV::EventPlayerAssaultsPoint(Player* player, uint32 object) UpdatePlayerScore(player, ( IsTower(node) ) ? SCORE_TOWERS_ASSAULTED : SCORE_GRAVEYARDS_ASSAULTED, 1); PlaySoundToAll((team==ALLIANCE)?AV_SOUND_ALLIANCE_ASSAULTS:AV_SOUND_HORDE_ASSAULTS); } - void BattleGroundAV::FillInitialWorldStates(WorldPacket& data) { bool stateok; @@ -1009,7 +939,6 @@ void BattleGroundAV::FillInitialWorldStates(WorldPacket& data) data << uint32(BG_AV_NodeWorldStates[i][GetWorldStateType(j,HORDE)]) << uint32((m_Nodes[i].Owner == HORDE && stateok)?1:0); } } - //towers for (uint8 i = BG_AV_NODES_DUNBALDAR_SOUTH; i <= BG_AV_NODES_MAX; i++) for (uint8 j =1; j <= 3; j+=2) @@ -1034,7 +963,6 @@ void BattleGroundAV::FillInitialWorldStates(WorldPacket& data) SendMineWorldStates(AV_NORTH_MINE); SendMineWorldStates(AV_SOUTH_MINE); } - const uint8 BattleGroundAV::GetWorldStateType(uint8 state, uint16 team) //this is used for node worldstates and returns values which fit good into the worldstatesarray { //neutral stuff cant get handled (currently its only snowfall) @@ -1057,7 +985,6 @@ const uint8 BattleGroundAV::GetWorldStateType(uint8 state, uint16 team) //this i sLog.outError("BG_AV: should update a strange worldstate state:%i team:%i",state,team); return 5; //this will crash the game, but i want to know if something is wrong here } - void BattleGroundAV::UpdateNodeWorldState(BG_AV_Nodes node) { UpdateWorldState(BG_AV_NodeWorldStates[node][GetWorldStateType(m_Nodes[node].State,m_Nodes[node].Owner)],1); @@ -1066,14 +993,12 @@ void BattleGroundAV::UpdateNodeWorldState(BG_AV_Nodes node) else UpdateWorldState(BG_AV_NodeWorldStates[node][GetWorldStateType(m_Nodes[node].PrevState,m_Nodes[node].PrevOwner)],0); } - void BattleGroundAV::SendMineWorldStates(uint32 mine) { assert(mine == AV_NORTH_MINE || mine==AV_SOUTH_MINE); // currently i'm sure, that this works (: // assert(m_Mine_PrevOwner[mine] == ALLIANCE || m_Mine_PrevOwner[mine] == HORDE || m_Mine_PrevOwner[mine] == AV_NEUTRAL_TEAM); // assert(m_Mine_Owner[mine] == ALLIANCE || m_Mine_Owner[mine] == HORDE || m_Mine_Owner[mine] == AV_NEUTRAL_TEAM); - uint8 owner,prevowner,mine2; //those variables are needed to access the right worldstate in the BG_AV_MineWorldStates array mine2 = (mine==AV_NORTH_MINE)?0:1; if(m_Mine_PrevOwner[mine] == ALLIANCE) @@ -1088,13 +1013,11 @@ void BattleGroundAV::SendMineWorldStates(uint32 mine) owner = 2; else owner = 1; - UpdateWorldState(BG_AV_MineWorldStates[mine2][owner],1); if( prevowner != owner) UpdateWorldState(BG_AV_MineWorldStates[mine2][prevowner],0); } - WorldSafeLocsEntry const* BattleGroundAV::GetClosestGraveYard(Player* player) { WorldSafeLocsEntry const* good_entry = NULL; @@ -1120,11 +1043,9 @@ WorldSafeLocsEntry const* BattleGroundAV::GetClosestGraveYard(Player* player) // If not, place ghost on starting location if( !good_entry ) good_entry = sWorldSafeLocsStore.LookupEntry( BG_AV_GraveyardIds[GetTeamIndexByTeamId(player->GetTeam())+7] ); - return good_entry; } - bool BattleGroundAV::SetupBattleGround() { // Create starting objects @@ -1137,7 +1058,6 @@ bool BattleGroundAV::SetupBattleGround() sLog.outErrorDb("BatteGroundAV: Failed to spawn some object BattleGround not created!1"); return false; } - //spawn node-objects for (uint8 i = BG_AV_NODES_FIRSTAID_STATION ; i < BG_AV_NODES_MAX; ++i) { @@ -1232,7 +1152,6 @@ bool BattleGroundAV::SetupBattleGround() return false; } } - if(!AddObject(BG_AV_OBJECT_FLAG_N_SNOWFALL_GRAVE, BG_AV_OBJECTID_BANNER_SNOWFALL_N ,BG_AV_ObjectPos[BG_AV_NODES_SNOWFALL_GRAVE][0],BG_AV_ObjectPos[BG_AV_NODES_SNOWFALL_GRAVE][1],BG_AV_ObjectPos[BG_AV_NODES_SNOWFALL_GRAVE][2],BG_AV_ObjectPos[BG_AV_NODES_SNOWFALL_GRAVE][3],0,0,sin(BG_AV_ObjectPos[BG_AV_NODES_SNOWFALL_GRAVE][3]/2), cos(BG_AV_ObjectPos[BG_AV_NODES_SNOWFALL_GRAVE][3]/2), RESPAWN_ONE_DAY)) { sLog.outError("BatteGroundAV: Failed to spawn some object BattleGround not created!8"); @@ -1249,7 +1168,6 @@ bool BattleGroundAV::SetupBattleGround() return false; } } - uint16 i; sLog.outDebug("Alterac Valley: entering state STATUS_WAIT_JOIN ..."); // Initial Nodes @@ -1280,7 +1198,6 @@ bool BattleGroundAV::SetupBattleGround() for(i = BG_AV_OBJECT_FLAG_N_SNOWFALL_GRAVE; i <= BG_AV_OBJECT_DOOR_A; i++) SpawnBGObject(i, RESPAWN_IMMEDIATELY); SpawnBGObject(BG_AV_OBJECT_AURA_N_SNOWFALL_GRAVE,RESPAWN_IMMEDIATELY); - //creatures sLog.outDebug("BG_AV start poputlating nodes"); for(BG_AV_Nodes i= BG_AV_NODES_FIRSTAID_STATION; i < BG_AV_NODES_MAX; ++i ) @@ -1303,7 +1220,6 @@ bool BattleGroundAV::SetupBattleGround() AddAVCreature(AV_NPC_HERALD,AV_CPLACE_HERALD); return true; } - const char* BattleGroundAV::GetNodeName(BG_AV_Nodes node) { switch (node) @@ -1331,7 +1247,6 @@ const char* BattleGroundAV::GetNodeName(BG_AV_Nodes node) } } } - void BattleGroundAV::AssaultNode(BG_AV_Nodes node, uint16 team) { if (m_Nodes[node].TotalOwner == team) @@ -1361,18 +1276,15 @@ void BattleGroundAV::AssaultNode(BG_AV_Nodes node, uint16 team) m_Nodes[node].PrevState = m_Nodes[node].State; m_Nodes[node].State = POINT_ASSAULTED; } - void BattleGroundAV::DestroyNode(BG_AV_Nodes node) { assert(m_Nodes[node].State == POINT_ASSAULTED); - m_Nodes[node].TotalOwner = m_Nodes[node].Owner; m_Nodes[node].PrevOwner = m_Nodes[node].Owner; m_Nodes[node].PrevState = m_Nodes[node].State; m_Nodes[node].State = (m_Nodes[node].Tower)? POINT_DESTROYED : POINT_CONTROLED; m_Nodes[node].Timer = 0; } - void BattleGroundAV::InitNode(BG_AV_Nodes node, uint16 team, bool tower) { m_Nodes[node].TotalOwner = team; @@ -1384,7 +1296,6 @@ void BattleGroundAV::InitNode(BG_AV_Nodes node, uint16 team, bool tower) m_Nodes[node].Timer = 0; m_Nodes[node].Tower = tower; } - void BattleGroundAV::DefendNode(BG_AV_Nodes node, uint16 team) { assert(m_Nodes[node].TotalOwner == team); @@ -1396,7 +1307,6 @@ void BattleGroundAV::DefendNode(BG_AV_Nodes node, uint16 team) m_Nodes[node].State = POINT_CONTROLED; m_Nodes[node].Timer = 0; } - void BattleGroundAV::ResetBGSubclass() { m_MaxLevel=0; @@ -1420,12 +1330,9 @@ void BattleGroundAV::ResetBGSubclass() for(BG_AV_Nodes i = BG_AV_NODES_ICEBLOOD_TOWER; i <= BG_AV_NODES_FROSTWOLF_WTOWER; ++i) //horde towers InitNode(i,HORDE,true); InitNode(BG_AV_NODES_SNOWFALL_GRAVE,AV_NEUTRAL_TEAM,false); //give snowfall neutral owner - m_Mine_Timer=AV_MINE_TICK_TIMER; for(uint16 i = 0; i < AV_CPLACE_MAX+AV_STATICCPLACE_MAX; i++) if(m_BgCreatures[i]) DelCreature(i); - } - diff --git a/src/game/BattleGroundAV.h b/src/game/BattleGroundAV.h index 306c513ae95..7e5bd367b70 100644 --- a/src/game/BattleGroundAV.h +++ b/src/game/BattleGroundAV.h @@ -17,44 +17,32 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef __BATTLEGROUNDAV_H #define __BATTLEGROUNDAV_H - class BattleGround; - #define LANG_BG_AV_A_CAPTAIN_BUFF "Begone. Uncouth scum! The Alliance shall prevail in Alterac Valley!" #define LANG_BG_AV_H_CAPTAIN_BUFF "Now is the time to attack! For the Horde!" #define LANG_BG_AV_S_MINE_BOSS_CLAIMS "Snivvle is here! Snivvle claims the Coldtooth Mine!" - #define BG_AV_CAPTIME 240000 //4:00 #define BG_AV_SNOWFALL_FIRSTCAP 300000 //5:00 but i also have seen 4:05 - #define BG_AV_SCORE_INITIAL_POINTS 600 #define SEND_MSG_NEAR_LOSE 120 - #define BG_AV_KILL_BOSS 4 #define BG_AV_REP_BOSS 350 - #define BG_AV_KILL_CAPTAIN 3 #define BG_AV_REP_CAPTAIN 125 #define BG_AV_RES_CAPTAIN 100 - #define BG_AV_KILL_TOWER 3 #define BG_AV_REP_TOWER 12 #define BG_AV_RES_TOWER 75 - #define BG_AV_GET_COMMANDER 1 //for a safely returned wingcommander //bonushonor at the end #define BG_AV_KILL_SURVIVING_TOWER 2 #define BG_AV_REP_SURVIVING_TOWER 12 - #define BG_AV_KILL_SURVIVING_CAPTAIN 2 #define BG_AV_REP_SURVIVING_CAPTAIN 125 - enum BG_AV_Sounds { //TODO: get out if there comes a sound when neutral team captures mine - /* 8212: alliance grave assault @@ -62,7 +50,6 @@ enum BG_AV_Sounds drek "mlanzenabschaum! In meiner Burg?! Toetet sie all" - nicht immer der sound 8333: galv "sterbt fuer euch ist kein platz hier" - 8332: bal "Verschwinde, dreckiger Abschaum! Die Allianz wird im Alteractal " 8174: @@ -85,21 +72,16 @@ horde: mine capture horde wins */ - AV_SOUND_NEAR_VICTORY = 8456, //not confirmed yet - AV_SOUND_ALLIANCE_ASSAULTS = 8212, //tower,grave + enemy boss if someone tries to attack him AV_SOUND_HORDE_ASSAULTS = 8174, AV_SOUND_ALLIANCE_GOOD = 8173, //if something good happens for the team: wins(maybe only through killing the boss), captures mine or grave, destroys tower and defends grave AV_SOUND_HORDE_GOOD = 8213, AV_SOUND_BOTH_TOWER_DEFEND = 8192, - AV_SOUND_ALLIANCE_CAPTAIN = 8232, //gets called when someone attacks them and at the beginning after 3min+rand(x)*10sec (maybe buff) AV_SOUND_HORDE_CAPTAIN = 8333, - }; - enum BG_AV_OTHER_VALUES { AV_STATICCPLACE_MAX = 123, @@ -118,25 +100,21 @@ enum BG_AV_ObjectIds BG_AV_OBJECTID_BANNER_H = 178943, // can only be used by alliance BG_AV_OBJECTID_BANNER_CONT_A = 178940, // can only be used by horde BG_AV_OBJECTID_BANNER_CONT_H = 179435, // can only be used by alliance - BG_AV_OBJECTID_BANNER_A_B = 178365, BG_AV_OBJECTID_BANNER_H_B = 178364, BG_AV_OBJECTID_BANNER_CONT_A_B = 179286, BG_AV_OBJECTID_BANNER_CONT_H_B = 179287, BG_AV_OBJECTID_BANNER_SNOWFALL_N = 180418, - //snowfall eyecandy banner: BG_AV_OBJECTID_SNOWFALL_CANDY_A = 179044, BG_AV_OBJECTID_SNOWFALL_CANDY_PA = 179424, BG_AV_OBJECTID_SNOWFALL_CANDY_H = 179064, BG_AV_OBJECTID_SNOWFALL_CANDY_PH = 179425, - //banners on top of towers: BG_AV_OBJECTID_TOWER_BANNER_A = 178927, //[PH] Alliance A1 Tower Banner BIG BG_AV_OBJECTID_TOWER_BANNER_H = 178955, //[PH] Horde H1 Tower Banner BIG BG_AV_OBJECTID_TOWER_BANNER_PA = 179446, //[PH] Alliance H1 Tower Pre-Banner BIG BG_AV_OBJECTID_TOWER_BANNER_PH = 179436, //[PH] Horde A1 Tower Pre-Banner BIG - //Auras BG_AV_OBJECTID_AURA_A = 180421, BG_AV_OBJECTID_AURA_H = 180422, @@ -144,18 +122,14 @@ enum BG_AV_ObjectIds BG_AV_OBJECTID_AURA_A_S = 180100, BG_AV_OBJECTID_AURA_H_S = 180101, BG_AV_OBJECTID_AURA_N_S = 180102, - BG_AV_OBJECTID_GATE_A = 180424, BG_AV_OBJECTID_GATE_H = 180424, - //mine supplies BG_AV_OBJECTID_MINE_N = 178785, BG_AV_OBJECTID_MINE_S = 178784, - BG_AV_OBJECTID_FIRE = 179065, BG_AV_OBJECTID_SMOKE = 179066 }; - enum BG_AV_Nodes { BG_AV_NODES_FIRSTAID_STATION = 0, @@ -173,10 +147,8 @@ enum BG_AV_Nodes BG_AV_NODES_TOWER_POINT = 12, BG_AV_NODES_FROSTWOLF_ETOWER = 13, BG_AV_NODES_FROSTWOLF_WTOWER = 14, - BG_AV_NODES_MAX = 15 }; - enum BG_AV_ObjectTypes { BG_AV_OBJECT_FLAG_A_FIRSTAID_STATION = 0, @@ -190,7 +162,6 @@ enum BG_AV_ObjectTypes BG_AV_OBJECT_FLAG_A_DUNBALDAR_NORTH = 8, BG_AV_OBJECT_FLAG_A_ICEWING_BUNKER = 9, BG_AV_OBJECT_FLAG_A_STONEHEART_BUNKER = 10, - BG_AV_OBJECT_FLAG_C_A_FIRSTAID_STATION = 11, BG_AV_OBJECT_FLAG_C_A_STORMPIKE_GRAVE = 12, BG_AV_OBJECT_FLAG_C_A_STONEHEART_GRAVE = 13, @@ -202,7 +173,6 @@ enum BG_AV_ObjectTypes BG_AV_OBJECT_FLAG_C_A_TOWER_POINT = 19, BG_AV_OBJECT_FLAG_C_A_FROSTWOLF_ETOWER = 20, BG_AV_OBJECT_FLAG_C_A_FROSTWOLF_WTOWER = 21, - BG_AV_OBJECT_FLAG_C_H_FIRSTAID_STATION = 22, BG_AV_OBJECT_FLAG_C_H_STORMPIKE_GRAVE = 23, BG_AV_OBJECT_FLAG_C_H_STONEHEART_GRAVE = 24, @@ -214,7 +184,6 @@ enum BG_AV_ObjectTypes BG_AV_OBJECT_FLAG_C_H_DUNBALDAR_NORTH = 30, BG_AV_OBJECT_FLAG_C_H_ICEWING_BUNKER = 31, BG_AV_OBJECT_FLAG_C_H_STONEHEART_BUNKER = 32, - BG_AV_OBJECT_FLAG_H_FIRSTAID_STATION = 33, BG_AV_OBJECT_FLAG_H_STORMPIKE_GRAVE = 34, BG_AV_OBJECT_FLAG_H_STONEHEART_GRAVE = 35, @@ -226,9 +195,7 @@ enum BG_AV_ObjectTypes BG_AV_OBJECT_FLAG_H_TOWER_POINT = 41, BG_AV_OBJECT_FLAG_H_FROSTWOLF_ETOWER = 42, BG_AV_OBJECT_FLAG_H_FROSTWOLF_WTOWER = 43, - BG_AV_OBJECT_FLAG_N_SNOWFALL_GRAVE = 44, - BG_AV_OBJECT_DOOR_H = 45, BG_AV_OBJECT_DOOR_A = 46, //auras for graveyards (3auras per graveyard neutral,alliance,horde) @@ -253,7 +220,6 @@ enum BG_AV_ObjectTypes BG_AV_OBJECT_AURA_N_FROSTWOLF_HUT = 65, BG_AV_OBJECT_AURA_A_FROSTWOLF_HUT = 66, BG_AV_OBJECT_AURA_H_FROSTWOLF_HUT = 67, - //big flags on top of towers 2 flags on each (contested,(alliance | horde)) + 2 auras BG_AV_OBJECT_TFLAG_A_DUNBALDAR_SOUTH = 67, BG_AV_OBJECT_TFLAG_H_DUNBALDAR_SOUTH = 68, @@ -287,7 +253,6 @@ enum BG_AV_ObjectTypes BG_AV_OBJECT_TAURA_H_FROSTWOLF_ETOWER = 96, BG_AV_OBJECT_TAURA_A_FROSTWOLF_WTOWER = 97, BG_AV_OBJECT_TAURA_H_FROSTWOLF_WTOWER = 98, - BG_AV_OBJECT_BURN_DUNBALDAR_SOUTH = 99, BG_AV_OBJECT_BURN_DUNBALDAR_NORTH = 109, BG_AV_OBJECT_BURN_ICEWING_BUNKER = 119, @@ -306,12 +271,9 @@ enum BG_AV_ObjectTypes BG_AV_OBJECT_MINE_SUPPLY_N_MAX = 224, BG_AV_OBJECT_MINE_SUPPLY_S_MIN = 225, BG_AV_OBJECT_MINE_SUPPLY_S_MAX = 236, - BG_AV_OBJECT_MAX = 237 }; - - enum BG_AV_OBJECTS { AV_OPLACE_FIRSTAID_STATION = 0, @@ -337,7 +299,6 @@ enum BG_AV_OBJECTS AV_OPLACE_BIGBANNER_TOWER_POINT = 20, AV_OPLACE_BIGBANNER_FROSTWOLF_ETOWER = 21, AV_OPLACE_BIGBANNER_FROSTWOLF_WTOWER = 22, - AV_OPLACE_BURN_DUNBALDAR_SOUTH = 23, AV_OPLACE_BURN_DUNBALDAR_NORTH = 33, AV_OPLACE_BURN_ICEWING_BUNKER = 43, @@ -356,7 +317,6 @@ enum BG_AV_OBJECTS AV_OPLACE_MINE_SUPPLY_N_MAX = 136, AV_OPLACE_MINE_SUPPLY_S_MIN = 137, AV_OPLACE_MINE_SUPPLY_S_MAX = 148, - AV_OPLACE_MAX = 149 }; const float BG_AV_ObjectPos[AV_OPLACE_MAX][4] = { @@ -473,7 +433,6 @@ const float BG_AV_ObjectPos[AV_OPLACE_MAX][4] = { {-1295.55f,-263.865f,105.033f,0.925024f}, {-1294.71f,-281.466f,107.664f,-1.50098f}, {-1289.69f,-259.521f,107.612f,-2.19912f}, - //the two buildings of the captains //alliance {-64.4987f,-289.33f,33.4616f,-2.82743f}, @@ -497,7 +456,6 @@ const float BG_AV_ObjectPos[AV_OPLACE_MAX][4] = { {-568.04f,-188.707f,81.55f,0}, {-501.775f,-151.581f,81.2027f,0}, {-509.975f,-191.652f,83.2978f,0}, - //snowfall eyecandy {-191.153f,-129.868f,78.5595f,-1.25664f }, {-201.282f,-134.319f,78.6753f,-0.942478f }, @@ -529,13 +487,11 @@ const float BG_AV_ObjectPos[AV_OPLACE_MAX][4] = { {-947.642f,-208.807f,77.0101f,1.36136f}, {-951.394f,-193.695f,67.634f,0.802851f} }; - const float BG_AV_DoorPositons[2][4] = { {780.487f, -493.024f, 99.9553f, 3.0976f}, //alliance {-1375.193f, -538.981f, 55.2824f, 0.72178f} //horde }; - //creaturestuff starts here //is related to BG_AV_CreaturePos enum BG_AV_CreaturePlace @@ -557,7 +513,6 @@ enum BG_AV_CreaturePlace AV_CPLACE_DEFENSE_FROSTWOLF = 25, AV_CPLACE_DEFENSE_ICE_GRAVE = 29, AV_CPLACE_DEFENSE_FROST_HUT = 33, - AV_CPLACE_DEFENSE_DUN_S = 37, AV_CPLACE_DEFENSE_DUN_N = 41, AV_CPLACE_DEFENSE_ICEWING = 45, @@ -566,7 +521,6 @@ enum BG_AV_CreaturePlace AV_CPLACE_DEFENSE_TOWERPOINT = 57, AV_CPLACE_DEFENSE_FROST_E = 61, AV_CPLACE_DEFENSE_FROST_t = 65, - AV_CPLACE_A_MARSHAL_SOUTH = 69, AV_CPLACE_A_MARSHAL_NORTH = 70, AV_CPLACE_A_MARSHAL_ICE = 71, @@ -596,13 +550,10 @@ enum BG_AV_CreaturePlace AV_CPLACE_MINE_S_S_MAX = 299, //boss AV_CPLACE_MINE_S_3 = 300, - //herald AV_CPLACE_HERALD = 301, - AV_CPLACE_MAX = 302 }; - //x, y, z, o const float BG_AV_CreaturePos[AV_CPLACE_MAX][4] = { //spiritguides @@ -692,7 +643,6 @@ const float BG_AV_CreaturePos[AV_CPLACE_MAX][4] = { {-1302.41f,-259.256f,114.065f,1.67602f}, {-1287.97f,-262.087f,114.165f,6.18264f}, {-1291.59f,-271.166f,114.151f,5.28257f}, - //alliance marshall {721.104f,-7.64155f,50.7046f,3.45575f},// south {723.058f,-14.1548f,50.7046f,3.40339f},// north @@ -703,7 +653,6 @@ const float BG_AV_CreaturePos[AV_CPLACE_MAX][4] = { {-1370.96f,-223.532f,98.4266f,4.93012f}, {-1378.37f,-228.614f,99.3546f,5.38565f}, {-1358.02f,-228.998f,98.868f,3.87768f}, - //irondeep mine //Irondeep Trogg {971.671f,-442.657f,57.6951f,3.1765f}, @@ -939,13 +888,10 @@ const float BG_AV_CreaturePos[AV_CPLACE_MAX][4] = { {-848.902f,-92.931f,68.6325f,3.33350}, //herald {-48.459f,-288.802f,55.47f,1.0} - }; - enum BG_AV_CreatureIds { - AV_NPC_A_GRAVEDEFENSE0 = 0, // stormpike Defender AV_NPC_A_GRAVEDEFENSE1 = 1, // seasoned defender AV_NPC_A_GRAVEDEFENSE2 = 2, // veteran defender @@ -953,7 +899,6 @@ enum BG_AV_CreatureIds AV_NPC_A_TOWERDEFENSE = 4, // stormpike bowman AV_NPC_A_CAPTAIN = 5, // balinda AV_NPC_A_BOSS = 6, // vanndar - AV_NPC_H_GRAVEDEFENSE0 = 7, // frostwolf guardian AV_NPC_H_GRAVEDEFENSE1 = 8, // seasoned guardian AV_NPC_H_GRAVEDEFENSE2 = 9, // veteran guardian @@ -961,7 +906,6 @@ enum BG_AV_CreatureIds AV_NPC_H_TOWERDEFENSE = 11, // frostwolf bowman AV_NPC_H_CAPTAIN = 12, // galvangar AV_NPC_H_BOSS = 13, // drek thar - AV_NPC_A_MARSHAL_SOUTH = 14, AV_NPC_MARSHAL_NORTH = 15, AV_NPC_A_MARSHAL_ICE = 16, @@ -997,9 +941,7 @@ enum BG_AV_CreatureIds AV_NPC_S_MINE_H_4 = 46, AV_NPC_HERALD = 47, AV_NPC_INFO_MAX = 48 - }; - //entry, team, minlevel, maxlevel //TODO this array should be removed, the only needed things are the entrys (for spawning(?) and handlekillunit) const uint32 BG_AV_CreatureInfo[AV_NPC_INFO_MAX][4] = { @@ -1021,46 +963,37 @@ const uint32 BG_AV_CreatureInfo[AV_NPC_INFO_MAX][4] = { { 14762, 1534, 60, 60 }, //Dun Baldar North Marshal { 14764, 1534, 60, 60 }, //Icewing Marshal { 14765, 1534, 60, 60 }, //Stonehearth Marshal - { 14773, 1214, 60, 60 }, //Iceblood Warmaster { 14776, 1214, 60, 60 }, //Tower Point Warmaster { 14772, 1214, 60, 60 }, //East Frostwolf Warmaster { 14777, 1214, 60, 60 }, //West Frostwolf Warmaster - { 10987, 59, 52, 53 }, //Irondeep Trogg { 11600, 59, 53, 54 }, //Irondeep Shaman { 11602, 59, 54, 55 }, //Irondeep Skullthumper { 11657, 59, 58, 58 }, //Morloch - {13396,469,52,53}, //irondeep alliance TODO: get the right ids {13080,469,53,54}, {13098,469,54,55}, {13078,469,58,58}, - {13397,67,52,53}, //irondeep horde {13099,67,53,54}, {13081,67,54,55}, {13079,67,58,58}, - { 11603, 59, 52, 53 }, //south mine neutral { 11604, 59, 53, 54 }, { 11605, 59, 54, 55 }, { 11677, 59, 58, 58 }, { 10982, 59, 52, 53 }, //vermin - {13317,469,52,53}, //alliance {13096,469,54,55}, //explorer {13087,469,54,55}, //invader {13086,469,58,58}, - {13316,67,52,53}, //horde {13097,67,54,55}, //surveypr {13089,67,54,55}, //guard {13088,67,58,58}, {14848,67,58,58} //Herald - }; - //x,y,z,o,static_creature_info-id const float BG_AV_StaticCreaturePos[AV_STATICCPLACE_MAX][5] = { //static creatures {-1235.31f,-340.777f,60.5088f,3.31613f,0 },//2225 - Zora Guthrek @@ -1186,9 +1119,7 @@ const float BG_AV_StaticCreaturePos[AV_STATICCPLACE_MAX][5] = { //static creatur {773.651f,-497.482f,99.0408f,2.11185f,46 },//14284 - Stormpike Battleguard {949.1f,-506.913f,95.4237f,3.31613f,46 },//14284 - Stormpike Battleguard {-1370.9f,-219.793f,98.4258f,5.04381f,47}, //drek thar - }; - const uint32 BG_AV_StaticCreatureInfo[51][4] = { { 2225, 1215, 55, 55 }, //Zora Guthrek { 3343, 1215, 55, 55 }, //Grelkor @@ -1242,7 +1173,6 @@ const uint32 BG_AV_StaticCreatureInfo[51][4] = { { 11947, 1214, 61, 61 }, //Captain Galvangar { 11949, 1216, 61, 61 } //Captain Balinda Stonehearth }; - enum BG_AV_Graveyards { AV_GRAVE_STORM_AID = 751, @@ -1256,8 +1186,6 @@ enum BG_AV_Graveyards AV_GRAVE_MAIN_HORDE = 610 }; - - const uint32 BG_AV_GraveyardIds[9]= { AV_GRAVE_STORM_AID, AV_GRAVE_STORM_GRAVE, @@ -1269,7 +1197,6 @@ const uint32 BG_AV_GraveyardIds[9]= { AV_GRAVE_MAIN_ALLIANCE, AV_GRAVE_MAIN_HORDE }; - enum BG_AV_BUFF { //TODO add all other buffs here AV_BUFF_ARMOR = 21163, @@ -1283,19 +1210,15 @@ enum BG_AV_States POINT_DESTROYED = 2, POINT_CONTROLED = 3 }; - enum BG_AV_WorldStates { AV_Alliance_Score = 3127, AV_Horde_Score = 3128, AV_SHOW_H_SCORE = 3133, AV_SHOW_A_SCORE = 3134, - /* //the comments behind the state shows which icon overlaps the other.. but is, until now, unused and maybe not a good solution (but give few performance (: ) - // Graves - // Alliance //Stormpike first aid station AV_AID_A_C = 1325, @@ -1338,7 +1261,6 @@ enum BG_AV_WorldStates AV_FROSTWOLFHUT_H_C = 1330, AV_FROSTWOLFHUT_H_A = 1332, //over ac - //Towers //Alliance //Dunbaldar South Bunker @@ -1374,38 +1296,30 @@ enum BG_AV_WorldStates AV_FROSTWOLFE_CONTROLLED = 1383, AV_FROSTWOLFE_DESTROYED = 1366, AV_FROSTWOLFE_ASSAULTED = 1388, - //mines - AV_N_MINE_N = 1360, AV_N_MINE_A = 1358, AV_N_MINE_H = 1359, - AV_S_MINE_N = 1357, AV_S_MINE_A = 1355, AV_S_MINE_H = 1356, - //towers assaulted by own team (unused) AV_STONEH_UNUSED = 1377, AV_ICEWING_UNUSED = 1376, AV_DUNS_UNUSED = 1375, AV_DUNN_UNUSED = 1374, - AV_ICEBLOOD_UNUSED = 1395, AV_TOWERPOINT_UNUSED = 1394, AV_FROSTWOLFE_UNUSED = 1393, AV_FROSTWOLFW_UNUSED = 1392 */ - }; - //alliance_control neutral_control horde_control const uint32 BG_AV_MineWorldStates[2][3] = { {1358, 1360,1359}, {1355, 1357,1356} }; - //alliance_control alliance_assault h_control h_assault const uint32 BG_AV_NodeWorldStates[16][4] = { //Stormpike first aid station @@ -1439,7 +1353,6 @@ const uint32 BG_AV_NodeWorldStates[16][4] = { //Frostwolf West {1365,1387,1382,1392}, }; - enum BG_AV_QuestIds { AV_QUEST_A_SCRAPS1 = 7223, @@ -1465,7 +1378,6 @@ enum BG_AV_QuestIds AV_QUEST_A_RIDER_TAME = 7027, AV_QUEST_H_RIDER_TAME = 7001 }; - struct BG_AV_NodeInfo { uint16 TotalOwner; @@ -1476,9 +1388,7 @@ struct BG_AV_NodeInfo int Timer; bool Tower; }; - inline BG_AV_Nodes &operator++(BG_AV_Nodes &i){ return i = BG_AV_Nodes(i + 1); } - class BattleGroundAVScore : public BattleGroundScore { public: @@ -1492,30 +1402,24 @@ class BattleGroundAVScore : public BattleGroundScore uint32 LeadersKilled; uint32 SecondaryObjectives; }; - class BattleGroundAV : public BattleGround { friend class BattleGroundMgr; - public: BattleGroundAV(); ~BattleGroundAV(); void Update(uint32 diff); - /* inherited from BattlegroundClass */ virtual void AddPlayer(Player *plr); virtual void StartingEventCloseDoors(); virtual void StartingEventOpenDoors(); - void RemovePlayer(Player *plr,uint64 guid); void HandleAreaTrigger(Player *Source, uint32 Trigger); bool SetupBattleGround(); virtual void ResetBGSubclass(); - /*general stuff*/ void UpdateScore(uint16 team, int16 points); void UpdatePlayerScore(Player *Source, uint32 type, uint32 value); - /*handlestuff*/ //these are functions which get called from extern virtual void EventPlayerClickedOnFlag(Player *source, GameObject* target_obj); void HandleKillPlayer(Player* player, Player *killer); @@ -1523,62 +1427,47 @@ class BattleGroundAV : public BattleGround void HandleQuestComplete(uint32 questid, Player *player); bool PlayerCanDoMineQuest(int32 GOId,uint32 team); - void EndBattleGround(uint32 winner); - virtual WorldSafeLocsEntry const* GetClosestGraveYard(Player* player); - private: /* Nodes occupying */ void EventPlayerAssaultsPoint(Player* player, uint32 object); void EventPlayerDefendsPoint(Player* player, uint32 object); void EventPlayerDestroyedPoint(BG_AV_Nodes node); - void AssaultNode(BG_AV_Nodes node,uint16 team); void DestroyNode(BG_AV_Nodes node); void InitNode(BG_AV_Nodes node, uint16 team, bool tower); void DefendNode(BG_AV_Nodes node, uint16 team); - void PopulateNode(BG_AV_Nodes node); void DePopulateNode(BG_AV_Nodes node); - const BG_AV_Nodes GetNodeThroughObject(uint32 object); const uint32 GetObjectThroughNode(BG_AV_Nodes node); const char* GetNodeName(BG_AV_Nodes node); const bool IsTower(BG_AV_Nodes node) { return m_Nodes[node].Tower; } - /*mine*/ void ChangeMineOwner(uint8 mine, uint32 team, bool initial=false); - /*worldstates*/ void FillInitialWorldStates(WorldPacket& data); const uint8 GetWorldStateType(uint8 state, uint16 team); void SendMineWorldStates(uint32 mine); void UpdateNodeWorldState(BG_AV_Nodes node); - /*general */ Creature* AddAVCreature(uint16 cinfoid, uint16 type); const uint16 GetBonusHonor(uint8 kills); //TODO remove this when mangos handles this right - /*variables */ int32 m_Team_Scores[2]; uint32 m_Team_QuestStatus[2][9]; //[x][y] x=team y=questcounter - BG_AV_NodeInfo m_Nodes[BG_AV_NODES_MAX]; - uint32 m_Mine_Owner[2]; uint32 m_Mine_PrevOwner[2]; //only for worldstates needed int32 m_Mine_Timer; //ticks for both teams uint32 m_Mine_Reclaim_Timer[2]; uint32 m_CaptainBuffTimer[2]; bool m_CaptainAlive[2]; - uint8 m_MaxLevel; //TODO remove this when battleground-getmaxlevel() returns something usefull bool m_IsInformedNearVictory[2]; - }; - #endif diff --git a/src/game/BattleGroundBE.cpp b/src/game/BattleGroundBE.cpp index 05475328b01..e79d2b606ff 100644 --- a/src/game/BattleGroundBE.cpp +++ b/src/game/BattleGroundBE.cpp @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "BattleGround.h" #include "BattleGroundBE.h" #include "Language.h" @@ -25,11 +24,9 @@ #include "ObjectMgr.h" #include "Player.h" #include "WorldPacket.h" - BattleGroundBE::BattleGroundBE() { m_BgObjects.resize(BG_BE_OBJECT_MAX); - m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M; m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S; m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S; @@ -40,94 +37,72 @@ BattleGroundBE::BattleGroundBE() m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS; m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN; } - BattleGroundBE::~BattleGroundBE() { - } - void BattleGroundBE::Update(uint32 diff) { BattleGround::Update(diff); - /*if (GetStatus() == STATUS_IN_PROGRESS) { // update something }*/ } - void BattleGroundBE::StartingEventCloseDoors() { for(uint32 i = BG_BE_OBJECT_DOOR_1; i <= BG_BE_OBJECT_DOOR_4; ++i) SpawnBGObject(i, RESPAWN_IMMEDIATELY); - for(uint32 i = BG_BE_OBJECT_BUFF_1; i <= BG_BE_OBJECT_BUFF_2; ++i) SpawnBGObject(i, RESPAWN_ONE_DAY); } - void BattleGroundBE::StartingEventOpenDoors() { for(uint32 i = BG_BE_OBJECT_DOOR_1; i <= BG_BE_OBJECT_DOOR_2; ++i) DoorOpen(i); - for(uint32 i = BG_BE_OBJECT_BUFF_1; i <= BG_BE_OBJECT_BUFF_2; ++i) SpawnBGObject(i, 60); } - void BattleGroundBE::AddPlayer(Player *plr) { BattleGround::AddPlayer(plr); //create score and add it to map, default values are set in constructor BattleGroundBEScore* sc = new BattleGroundBEScore; - m_PlayerScores[plr->GetGUID()] = sc; - UpdateWorldState(0x9f1, GetAlivePlayersCountByTeam(ALLIANCE)); UpdateWorldState(0x9f0, GetAlivePlayersCountByTeam(HORDE)); } - void BattleGroundBE::RemovePlayer(Player* /*plr*/, uint64 /*guid*/) { if (GetStatus() == STATUS_WAIT_LEAVE) return; - UpdateWorldState(0x9f1, GetAlivePlayersCountByTeam(ALLIANCE)); UpdateWorldState(0x9f0, GetAlivePlayersCountByTeam(HORDE)); - CheckArenaWinConditions(); } - void BattleGroundBE::HandleKillPlayer(Player *player, Player *killer) { if (GetStatus() != STATUS_IN_PROGRESS) return; - if (!killer) { sLog.outError("Killer player not found"); return; } - BattleGround::HandleKillPlayer(player,killer); - UpdateWorldState(0x9f1, GetAlivePlayersCountByTeam(ALLIANCE)); UpdateWorldState(0x9f0, GetAlivePlayersCountByTeam(HORDE)); - CheckArenaWinConditions(); } - bool BattleGroundBE::HandlePlayerUnderMap(Player *player) { player->TeleportTo(GetMapId(),6238.930176,262.963470,0.889519,player->GetOrientation(),false); return true; } - void BattleGroundBE::HandleAreaTrigger(Player *Source, uint32 Trigger) { // this is wrong way to implement these things. On official it done by gameobject spell cast. if (GetStatus() != STATUS_IN_PROGRESS) return; - //uint32 SpellId = 0; //uint64 buff_guid = 0; switch(Trigger) @@ -143,24 +118,20 @@ void BattleGroundBE::HandleAreaTrigger(Player *Source, uint32 Trigger) Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger); break; } - //if (buff_guid) // HandleTriggerBuff(buff_guid,Source); } - void BattleGroundBE::FillInitialWorldStates(WorldPacket &data) { data << uint32(0x9f1) << uint32(GetAlivePlayersCountByTeam(ALLIANCE)); // 7 data << uint32(0x9f0) << uint32(GetAlivePlayersCountByTeam(HORDE)); // 8 data << uint32(0x9f3) << uint32(1); // 9 } - void BattleGroundBE::Reset() { //call parent's class reset BattleGround::Reset(); } - bool BattleGroundBE::SetupBattleGround() { // gates @@ -175,22 +146,16 @@ bool BattleGroundBE::SetupBattleGround() sLog.outErrorDb("BatteGroundBE: Failed to spawn some object!"); return false; } - return true; } - void BattleGroundBE::UpdatePlayerScore(Player* Source, uint32 type, uint32 value) { - BattleGroundScoreMap::iterator itr = m_PlayerScores.find(Source->GetGUID()); if(itr == m_PlayerScores.end()) // player not found... return; - //there is nothing special in this score BattleGround::UpdatePlayerScore(Source,type,value); - } - /* 21:45:46 id:231310 [S2C] SMSG_INIT_WORLD_STATES (706 = 0x02C2) len: 86 0000: 32 02 00 00 76 0e 00 00 00 00 00 00 09 00 f3 09 | 2...v........... @@ -199,7 +164,6 @@ void BattleGroundBE::UpdatePlayerScore(Player* Source, uint32 type, uint32 value 0030: 00 00 00 00 00 00 d7 08 00 00 00 00 00 00 d6 08 | ................ 0040: 00 00 00 00 00 00 d5 08 00 00 00 00 00 00 d3 08 | ................ 0050: 00 00 00 00 00 00 | ...... - spell 32724 - Gold Team spell 32725 - Green Team 35774 Gold Team diff --git a/src/game/BattleGroundBE.h b/src/game/BattleGroundBE.h index e75e332f44f..b3996498e53 100644 --- a/src/game/BattleGroundBE.h +++ b/src/game/BattleGroundBE.h @@ -19,9 +19,7 @@ */ #ifndef __BATTLEGROUNDBE_H #define __BATTLEGROUNDBE_H - class BattleGround; - enum BattleGroundBEObjectTypes { BG_BE_OBJECT_DOOR_1 = 0, @@ -32,7 +30,6 @@ enum BattleGroundBEObjectTypes BG_BE_OBJECT_BUFF_2 = 5, BG_BE_OBJECT_MAX = 6 }; - enum BattleGroundBEObjects { BG_BE_OBJECT_TYPE_DOOR_1 = 183971, @@ -42,28 +39,23 @@ enum BattleGroundBEObjects BG_BE_OBJECT_TYPE_BUFF_1 = 184663, BG_BE_OBJECT_TYPE_BUFF_2 = 184664 }; - class BattleGroundBEScore : public BattleGroundScore { public: BattleGroundBEScore() {}; virtual ~BattleGroundBEScore() {}; }; - class BattleGroundBE : public BattleGround { friend class BattleGroundMgr; - public: BattleGroundBE(); ~BattleGroundBE(); void Update(uint32 diff); - /* inherited from BattlegroundClass */ virtual void AddPlayer(Player *plr); virtual void StartingEventCloseDoors(); virtual void StartingEventOpenDoors(); - void RemovePlayer(Player *plr, uint64 guid); void HandleAreaTrigger(Player *Source, uint32 Trigger); bool SetupBattleGround(); @@ -71,7 +63,6 @@ class BattleGroundBE : public BattleGround virtual void FillInitialWorldStates(WorldPacket &d); void HandleKillPlayer(Player* player, Player *killer); bool HandlePlayerUnderMap(Player * plr); - /* Scorekeeping */ void UpdatePlayerScore(Player *Source, uint32 type, uint32 value); }; diff --git a/src/game/BattleGroundDS.cpp b/src/game/BattleGroundDS.cpp index 0be870be175..e133bc740b0 100644 --- a/src/game/BattleGroundDS.cpp +++ b/src/game/BattleGroundDS.cpp @@ -15,15 +15,12 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "BattleGround.h" #include "BattleGroundDS.h" #include "Language.h" #include "Player.h" - BattleGroundDS::BattleGroundDS() { - m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M; m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S; m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S; @@ -34,47 +31,36 @@ BattleGroundDS::BattleGroundDS() m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS; m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN; } - BattleGroundDS::~BattleGroundDS() { - } - void BattleGroundDS::Update(uint32 diff) { BattleGround::Update(diff); } - void BattleGroundDS::StartingEventCloseDoors() { } - void BattleGroundDS::StartingEventOpenDoors() { } - void BattleGroundDS::AddPlayer(Player *plr) { BattleGround::AddPlayer(plr); //create score and add it to map, default values are set in constructor BattleGroundDSScore* sc = new BattleGroundDSScore; - m_PlayerScores[plr->GetGUID()] = sc; } - void BattleGroundDS::RemovePlayer(Player * /*plr*/, uint64 /*guid*/) { } - void BattleGroundDS::HandleKillPlayer(Player* player, Player* killer) { BattleGround::HandleKillPlayer(player, killer); } - void BattleGroundDS::HandleAreaTrigger(Player * /*Source*/, uint32 /*Trigger*/) { } - bool BattleGroundDS::SetupBattleGround() { return true; diff --git a/src/game/BattleGroundDS.h b/src/game/BattleGroundDS.h index 44a6cfbd33a..8b310a67da0 100644 --- a/src/game/BattleGroundDS.h +++ b/src/game/BattleGroundDS.h @@ -17,9 +17,7 @@ */ #ifndef __BATTLEGROUNDDS_H #define __BATTLEGROUNDDS_H - class BattleGround; - class BattleGroundDSScore : public BattleGroundScore { public: @@ -27,21 +25,17 @@ class BattleGroundDSScore : public BattleGroundScore virtual ~BattleGroundDSScore() {}; //TODO fix me }; - class BattleGroundDS : public BattleGround { friend class BattleGroundMgr; - public: BattleGroundDS(); ~BattleGroundDS(); void Update(uint32 diff); - /* inherited from BattlegroundClass */ virtual void AddPlayer(Player *plr); virtual void StartingEventCloseDoors(); virtual void StartingEventOpenDoors(); - void RemovePlayer(Player *plr, uint64 guid); void HandleAreaTrigger(Player *Source, uint32 Trigger); bool SetupBattleGround(); diff --git a/src/game/BattleGroundEY.cpp b/src/game/BattleGroundEY.cpp index 0c7ea66388b..5678eeec494 100644 --- a/src/game/BattleGroundEY.cpp +++ b/src/game/BattleGroundEY.cpp @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "ObjectMgr.h" #include "World.h" #include "WorldPacket.h" @@ -29,13 +28,11 @@ #include "Object.h" #include "Player.h" #include "Util.h" - // these variables aren't used outside of this file, so declare them only here uint32 BG_EY_HonorScoreTicks[BG_HONOR_MODE_NUM] = { 330, // normal honor 200 // holiday }; - BattleGroundEY::BattleGroundEY() { m_BuffChange = true; @@ -45,21 +42,17 @@ BattleGroundEY::BattleGroundEY() m_Points_Trigger[BLOOD_ELF] = TR_BLOOD_ELF_BUFF; m_Points_Trigger[DRAENEI_RUINS] = TR_DRAENEI_RUINS_BUFF; m_Points_Trigger[MAGE_TOWER] = TR_MAGE_TOWER_BUFF; - m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_EY_START_TWO_MINUTES; m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_EY_START_ONE_MINUTE; m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_EY_START_HALF_MINUTE; m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_EY_HAS_BEGUN; } - BattleGroundEY::~BattleGroundEY() { } - void BattleGroundEY::Update(uint32 diff) { BattleGround::Update(diff); - if (GetStatus() == STATUS_IN_PROGRESS) { m_PointAddingTimer -= diff; @@ -71,11 +64,9 @@ void BattleGroundEY::Update(uint32 diff) if (m_TeamPointsCount[BG_TEAM_HORDE] > 0) AddPoints(HORDE, BG_EY_TickPoints[m_TeamPointsCount[BG_TEAM_HORDE] - 1]); } - if (m_FlagState == BG_EY_FLAG_STATE_WAIT_RESPAWN || m_FlagState == BG_EY_FLAG_STATE_ON_GROUND) { m_FlagsTimer -= diff; - if (m_FlagsTimer < 0) { m_FlagsTimer = 0; @@ -85,7 +76,6 @@ void BattleGroundEY::Update(uint32 diff) RespawnFlagAfterDrop(); } } - m_TowerCapCheckTimer -= diff; if (m_TowerCapCheckTimer <= 0) { @@ -101,21 +91,17 @@ void BattleGroundEY::Update(uint32 diff) } } } - void BattleGroundEY::StartingEventCloseDoors() { SpawnBGObject(BG_EY_OBJECT_DOOR_A, RESPAWN_IMMEDIATELY); SpawnBGObject(BG_EY_OBJECT_DOOR_H, RESPAWN_IMMEDIATELY); - for(uint32 i = BG_EY_OBJECT_A_BANNER_FEL_REALVER_CENTER; i < BG_EY_OBJECT_MAX; ++i) SpawnBGObject(i, RESPAWN_ONE_DAY); } - void BattleGroundEY::StartingEventOpenDoors() { SpawnBGObject(BG_EY_OBJECT_DOOR_A, RESPAWN_ONE_DAY); SpawnBGObject(BG_EY_OBJECT_DOOR_H, RESPAWN_ONE_DAY); - for(uint32 i = BG_EY_OBJECT_N_BANNER_FEL_REALVER_CENTER; i <= BG_EY_OBJECT_FLAG_NETHERSTORM; ++i) SpawnBGObject(i, RESPAWN_IMMEDIATELY); for(uint32 i = 0; i < EY_POINTS_MAX; ++i) @@ -125,7 +111,6 @@ void BattleGroundEY::StartingEventOpenDoors() SpawnBGObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REALVER + buff + i * 3, RESPAWN_IMMEDIATELY); } } - void BattleGroundEY::AddPoints(uint32 Team, uint32 Points) { BattleGroundTeamId team_index = GetTeamIndexByTeamId(Team); @@ -138,7 +123,6 @@ void BattleGroundEY::AddPoints(uint32 Team, uint32 Points) } UpdateTeamScore(Team); } - void BattleGroundEY::CheckSomeoneJoinedPoint() { GameObject *obj = NULL; @@ -175,7 +159,6 @@ void BattleGroundEY::CheckSomeoneJoinedPoint() } } } - void BattleGroundEY::CheckSomeoneLeftPoint() { //reset current point counts @@ -217,7 +200,6 @@ void BattleGroundEY::CheckSomeoneLeftPoint() } } } - void BattleGroundEY::UpdatePointStatuses() { for(uint8 point = 0; point < EY_POINTS_MAX; ++point) @@ -226,14 +208,12 @@ void BattleGroundEY::UpdatePointStatuses() continue; //count new point bar status: m_PointBarStatus[point] += (m_CurrentPointPlayersCount[2 * point] - m_CurrentPointPlayersCount[2 * point + 1] < BG_EY_POINT_MAX_CAPTURERS_COUNT) ? m_CurrentPointPlayersCount[2 * point] - m_CurrentPointPlayersCount[2 * point + 1] : BG_EY_POINT_MAX_CAPTURERS_COUNT; - if (m_PointBarStatus[point] > BG_EY_PROGRESS_BAR_ALI_CONTROLLED) //point is fully alliance's m_PointBarStatus[point] = BG_EY_PROGRESS_BAR_ALI_CONTROLLED; if (m_PointBarStatus[point] < BG_EY_PROGRESS_BAR_HORDE_CONTROLLED) //point is fully horde's m_PointBarStatus[point] = BG_EY_PROGRESS_BAR_HORDE_CONTROLLED; - uint32 pointOwnerTeamId = 0; //find which team should own this point if (m_PointBarStatus[point] <= BG_EY_PROGRESS_BAR_NEUTRAL_LOW) @@ -242,7 +222,6 @@ void BattleGroundEY::UpdatePointStatuses() pointOwnerTeamId = ALLIANCE; else pointOwnerTeamId = EY_POINT_NO_OWNER; - for (uint8 i = 0; i < m_PlayersNearPoint[point].size(); ++i) { Player *plr = objmgr.GetPlayer(m_PlayersNearPoint[point][i]); @@ -255,7 +234,6 @@ void BattleGroundEY::UpdatePointStatuses() //point was uncontrolled and player is from team which captured point if (m_PointState[point] == EY_POINT_STATE_UNCONTROLLED && plr->GetTeam() == pointOwnerTeamId) this->EventTeamCapturedPoint(plr, point); - //point was under control and player isn't from team which controlled it if (m_PointState[point] == EY_POINT_UNDER_CONTROL && plr->GetTeam() != m_PointOwnedByTeam[point]) this->EventTeamLostPoint(plr, point); @@ -264,7 +242,6 @@ void BattleGroundEY::UpdatePointStatuses() } } } - void BattleGroundEY::UpdateTeamScore(uint32 Team) { uint32 score = GetTeamScore(Team); @@ -278,19 +255,16 @@ void BattleGroundEY::UpdateTeamScore(uint32 Team) PlaySoundToAll(BG_EY_SOUND_NEAR_VICTORY); m_IsInformedNearVictory = true; }*/ - if (score >= BG_EY_MAX_TEAM_SCORE) { score = BG_EY_MAX_TEAM_SCORE; EndBattleGround(Team); } - if (Team == ALLIANCE) UpdateWorldState(EY_ALLIANCE_RESOURCES, score); else UpdateWorldState(EY_HORDE_RESOURCES, score); } - void BattleGroundEY::EndBattleGround(uint32 winner) { //win reward @@ -301,10 +275,8 @@ void BattleGroundEY::EndBattleGround(uint32 winner) //complete map reward RewardHonorToTeam(GetBonusHonorFromKill(1), ALLIANCE); RewardHonorToTeam(GetBonusHonorFromKill(1), HORDE); - BattleGround::EndBattleGround(winner); } - void BattleGroundEY::UpdatePointsCount(uint32 Team) { if (Team == ALLIANCE) @@ -312,7 +284,6 @@ void BattleGroundEY::UpdatePointsCount(uint32 Team) else UpdateWorldState(EY_HORDE_BASE, m_TeamPointsCount[BG_TEAM_HORDE]); } - void BattleGroundEY::UpdatePointsIcons(uint32 Team, uint32 Point) { //we MUST firstly send 0, after that we can send 1!!! @@ -333,18 +304,14 @@ void BattleGroundEY::UpdatePointsIcons(uint32 Team, uint32 Point) UpdateWorldState(m_PointsIconStruct[Point].WorldStateControlIndex, 1); } } - void BattleGroundEY::AddPlayer(Player *plr) { BattleGround::AddPlayer(plr); //create score and add it to map BattleGroundEYScore* sc = new BattleGroundEYScore; - m_PlayersNearPoint[EY_POINTS_MAX].push_back(plr->GetGUID()); - m_PlayerScores[plr->GetGUID()] = sc; } - void BattleGroundEY::RemovePlayer(Player *plr, uint64 guid) { // sometimes flag aura not removed :( @@ -368,15 +335,12 @@ void BattleGroundEY::RemovePlayer(Player *plr, uint64 guid) } } } - void BattleGroundEY::HandleAreaTrigger(Player *Source, uint32 Trigger) { if (GetStatus() != STATUS_IN_PROGRESS) return; - if(!Source->isAlive()) //hack code, must be removed later return; - switch(Trigger) { case TR_BLOOD_ELF_POINT: @@ -416,7 +380,6 @@ void BattleGroundEY::HandleAreaTrigger(Player *Source, uint32 Trigger) break; } } - bool BattleGroundEY::SetupBattleGround() { // doors @@ -477,7 +440,6 @@ bool BattleGroundEY::SetupBattleGround() sLog.outErrorDb("BatteGroundEY: Failed to spawn some object BattleGround not created!"); return false; } - //buffs for (int i = 0; i < EY_POINTS_MAX; ++i) { @@ -493,7 +455,6 @@ bool BattleGroundEY::SetupBattleGround() ) sLog.outError("BattleGroundEY: Cannot spawn buff"); } - WorldSafeLocsEntry const *sg = NULL; sg = sWorldSafeLocsStore.LookupEntry(EY_GRAVEYARD_MAIN_ALLIANCE); if (!sg || !AddSpiritGuide(EY_SPIRIT_MAIN_ALLIANCE, sg->x, sg->y, sg->z, 3.124139f, ALLIANCE)) @@ -501,22 +462,18 @@ bool BattleGroundEY::SetupBattleGround() sLog.outErrorDb("BatteGroundEY: Failed to spawn spirit guide! BattleGround not created!"); return false; } - sg = sWorldSafeLocsStore.LookupEntry(EY_GRAVEYARD_MAIN_HORDE); if (!sg || !AddSpiritGuide(EY_SPIRIT_MAIN_HORDE, sg->x, sg->y, sg->z, 3.193953f, HORDE)) { sLog.outErrorDb("BatteGroundEY: Failed to spawn spirit guide! BattleGround not created!"); return false; } - return true; } - void BattleGroundEY::Reset() { //call parent's class reset BattleGround::Reset(); - m_TeamScores[BG_TEAM_ALLIANCE] = 0; m_TeamScores[BG_TEAM_HORDE] = 0; m_TeamPointsCount[BG_TEAM_ALLIANCE] = 0; @@ -531,7 +488,6 @@ void BattleGroundEY::Reset() m_TowerCapCheckTimer = 0; bool isBGWeekend = sBattleGroundMgr.IsBGWeekend(GetTypeID()); m_HonorTics = (isBGWeekend) ? BG_EY_EYWeekendHonorTicks : BG_EY_NotEYWeekendHonorTicks; - for(uint8 i = 0; i < EY_POINTS_MAX; ++i) { m_PointOwnedByTeam[i] = EY_POINT_NO_OWNER; @@ -543,47 +499,37 @@ void BattleGroundEY::Reset() m_PlayersNearPoint[EY_PLAYERS_OUT_OF_POINTS].clear(); m_PlayersNearPoint[EY_PLAYERS_OUT_OF_POINTS].reserve(30); } - void BattleGroundEY::RespawnFlag(bool send_message) { if (m_FlagCapturedBgObjectType > 0) SpawnBGObject(m_FlagCapturedBgObjectType, RESPAWN_ONE_DAY); - m_FlagCapturedBgObjectType = 0; m_FlagState = BG_EY_FLAG_STATE_ON_BASE; SpawnBGObject(BG_EY_OBJECT_FLAG_NETHERSTORM, RESPAWN_IMMEDIATELY); - if (send_message) { SendMessageToAll(LANG_BG_EY_RESETED_FLAG, CHAT_MSG_BG_SYSTEM_NEUTRAL); PlaySoundToAll(BG_EY_SOUND_FLAG_RESET); // flags respawned sound... } - UpdateWorldState(NETHERSTORM_FLAG, 1); } - void BattleGroundEY::RespawnFlagAfterDrop() { RespawnFlag(true); - GameObject *obj = HashMapHolder::Find(GetDroppedFlagGUID()); if (obj) obj->Delete(); else sLog.outError("BattleGroundEY: Unknown dropped flag guid: %u",GUID_LOPART(GetDroppedFlagGUID())); - SetDroppedFlagGUID(0); } - void BattleGroundEY::HandleKillPlayer(Player *player, Player *killer) { if (GetStatus() != STATUS_IN_PROGRESS) return; - BattleGround::HandleKillPlayer(player, killer); EventPlayerDroppedFlag(player); } - void BattleGroundEY::EventPlayerDroppedFlag(Player *Source) { if (GetStatus() != STATUS_IN_PROGRESS) @@ -597,13 +543,10 @@ void BattleGroundEY::EventPlayerDroppedFlag(Player *Source) } return; } - if (!IsFlagPickedup()) return; - if (GetFlagPickerGUID() != Source->GetGUID()) return; - SetFlagPicker(0); Source->RemoveAurasDueToSpell(BG_EY_NETHERSTORM_FLAG_SPELL); m_FlagState = BG_EY_FLAG_STATE_ON_GROUND; @@ -613,18 +556,15 @@ void BattleGroundEY::EventPlayerDroppedFlag(Player *Source) //this does not work correctly :( (it should remove flag carrier name) UpdateWorldState(NETHERSTORM_FLAG_STATE_HORDE, BG_EY_FLAG_STATE_WAIT_RESPAWN); UpdateWorldState(NETHERSTORM_FLAG_STATE_ALLIANCE, BG_EY_FLAG_STATE_WAIT_RESPAWN); - if (Source->GetTeam() == ALLIANCE) SendMessageToAll(LANG_BG_EY_DROPPED_FLAG, CHAT_MSG_BG_SYSTEM_ALLIANCE, NULL); else SendMessageToAll(LANG_BG_EY_DROPPED_FLAG, CHAT_MSG_BG_SYSTEM_HORDE, NULL); } - void BattleGroundEY::EventPlayerClickedOnFlag(Player *Source, GameObject* target_obj) { if (GetStatus() != STATUS_IN_PROGRESS || IsFlagPickedup() || !Source->IsWithinDistInMap(target_obj, 10)) return; - if (Source->GetTeam() == ALLIANCE) { UpdateWorldState(NETHERSTORM_FLAG_STATE_ALLIANCE, BG_EY_FLAG_STATE_ON_PLAYER); @@ -635,34 +575,27 @@ void BattleGroundEY::EventPlayerClickedOnFlag(Player *Source, GameObject* target UpdateWorldState(NETHERSTORM_FLAG_STATE_HORDE, BG_EY_FLAG_STATE_ON_PLAYER); PlaySoundToAll(BG_EY_SOUND_FLAG_PICKED_UP_HORDE); } - if (m_FlagState == BG_EY_FLAG_STATE_ON_BASE) UpdateWorldState(NETHERSTORM_FLAG, 0); m_FlagState = BG_EY_FLAG_STATE_ON_PLAYER; - SpawnBGObject(BG_EY_OBJECT_FLAG_NETHERSTORM, RESPAWN_ONE_DAY); SetFlagPicker(Source->GetGUID()); //get flag aura on player Source->CastSpell(Source, BG_EY_NETHERSTORM_FLAG_SPELL, true); Source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT); - if (Source->GetTeam() == ALLIANCE) PSendMessageToAll(LANG_BG_EY_HAS_TAKEN_FLAG, CHAT_MSG_BG_SYSTEM_ALLIANCE, NULL, Source->GetName()); else PSendMessageToAll(LANG_BG_EY_HAS_TAKEN_FLAG, CHAT_MSG_BG_SYSTEM_HORDE, NULL, Source->GetName()); } - void BattleGroundEY::EventTeamLostPoint(Player *Source, uint32 Point) { if (GetStatus() != STATUS_IN_PROGRESS) return; - //Natural point uint32 Team = m_PointOwnedByTeam[Point]; - if (!Team) return; - if (Team == ALLIANCE) { m_TeamPointsCount[BG_TEAM_ALLIANCE]--; @@ -677,36 +610,27 @@ void BattleGroundEY::EventTeamLostPoint(Player *Source, uint32 Point) SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeHorde + 1, RESPAWN_ONE_DAY); SpawnBGObject(m_LoosingPointTypes[Point].DespawnObjectTypeHorde + 2, RESPAWN_ONE_DAY); } - SpawnBGObject(m_LoosingPointTypes[Point].SpawnNeutralObjectType, RESPAWN_IMMEDIATELY); SpawnBGObject(m_LoosingPointTypes[Point].SpawnNeutralObjectType + 1, RESPAWN_IMMEDIATELY); SpawnBGObject(m_LoosingPointTypes[Point].SpawnNeutralObjectType + 2, RESPAWN_IMMEDIATELY); - //buff isn't despawned - m_PointOwnedByTeam[Point] = EY_POINT_NO_OWNER; m_PointState[Point] = EY_POINT_NO_OWNER; - if (Team == ALLIANCE) SendMessageToAll(m_LoosingPointTypes[Point].MessageIdAlliance,CHAT_MSG_BG_SYSTEM_ALLIANCE, Source); else SendMessageToAll(m_LoosingPointTypes[Point].MessageIdHorde,CHAT_MSG_BG_SYSTEM_HORDE, Source); - UpdatePointsIcons(Team, Point); UpdatePointsCount(Team); } - void BattleGroundEY::EventTeamCapturedPoint(Player *Source, uint32 Point) { if (GetStatus() != STATUS_IN_PROGRESS) return; - uint32 Team = Source->GetTeam(); - SpawnBGObject(m_CapturingPointTypes[Point].DespawnNeutralObjectType, RESPAWN_ONE_DAY); SpawnBGObject(m_CapturingPointTypes[Point].DespawnNeutralObjectType + 1, RESPAWN_ONE_DAY); SpawnBGObject(m_CapturingPointTypes[Point].DespawnNeutralObjectType + 2, RESPAWN_ONE_DAY); - if (Team == ALLIANCE) { m_TeamPointsCount[BG_TEAM_ALLIANCE]++; @@ -721,53 +645,39 @@ void BattleGroundEY::EventTeamCapturedPoint(Player *Source, uint32 Point) SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeHorde + 1, RESPAWN_IMMEDIATELY); SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeHorde + 2, RESPAWN_IMMEDIATELY); } - //buff isn't respawned - m_PointOwnedByTeam[Point] = Team; m_PointState[Point] = EY_POINT_UNDER_CONTROL; - if (Team == ALLIANCE) SendMessageToAll(m_CapturingPointTypes[Point].MessageIdAlliance,CHAT_MSG_BG_SYSTEM_ALLIANCE, Source); else SendMessageToAll(m_CapturingPointTypes[Point].MessageIdHorde,CHAT_MSG_BG_SYSTEM_HORDE, Source); - if (m_BgCreatures[Point]) DelCreature(Point); - WorldSafeLocsEntry const *sg = NULL; sg = sWorldSafeLocsStore.LookupEntry(m_CapturingPointTypes[Point].GraveYardId); if (!sg || !AddSpiritGuide(Point, sg->x, sg->y, sg->z, 3.124139f, Team)) sLog.outError("BatteGroundEY: Failed to spawn spirit guide! point: %u, team: %u, graveyard_id: %u", Point, Team, m_CapturingPointTypes[Point].GraveYardId); - // SpawnBGCreature(Point,RESPAWN_IMMEDIATELY); - UpdatePointsIcons(Team, Point); UpdatePointsCount(Team); } - void BattleGroundEY::EventPlayerCapturedFlag(Player *Source, uint32 BgObjectType) { if (GetStatus() != STATUS_IN_PROGRESS || GetFlagPickerGUID() != Source->GetGUID()) return; - SetFlagPicker(0); m_FlagState = BG_EY_FLAG_STATE_WAIT_RESPAWN; Source->RemoveAurasDueToSpell(BG_EY_NETHERSTORM_FLAG_SPELL); - Source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT); - if (Source->GetTeam() == ALLIANCE) PlaySoundToAll(BG_EY_SOUND_FLAG_CAPTURED_ALLIANCE); else PlaySoundToAll(BG_EY_SOUND_FLAG_CAPTURED_HORDE); - SpawnBGObject(BgObjectType, RESPAWN_IMMEDIATELY); - m_FlagsTimer = BG_EY_FLAG_RESPAWN_TIME; m_FlagCapturedBgObjectType = BgObjectType; - uint8 team_id = 0; if (Source->GetTeam() == ALLIANCE) { @@ -779,19 +689,15 @@ void BattleGroundEY::EventPlayerCapturedFlag(Player *Source, uint32 BgObjectType team_id = BG_TEAM_HORDE; SendMessageToAll(LANG_BG_EY_CAPTURED_FLAG_H, CHAT_MSG_BG_SYSTEM_HORDE, Source); } - if (m_TeamPointsCount[team_id] > 0) AddPoints(Source->GetTeam(), BG_EY_FlagPoints[m_TeamPointsCount[team_id] - 1]); - UpdatePlayerScore(Source, SCORE_FLAG_CAPTURES, 1); } - void BattleGroundEY::UpdatePlayerScore(Player *Source, uint32 type, uint32 value) { BattleGroundScoreMap::iterator itr = m_PlayerScores.find(Source->GetGUID()); if(itr == m_PlayerScores.end()) // player not found return; - switch(type) { case SCORE_FLAG_CAPTURES: // flags captured @@ -802,7 +708,6 @@ void BattleGroundEY::UpdatePlayerScore(Player *Source, uint32 type, uint32 value break; } } - void BattleGroundEY::FillInitialWorldStates(WorldPacket& data) { data << uint32(EY_HORDE_BASE) << uint32(m_TeamPointsCount[BG_TEAM_HORDE]); @@ -815,33 +720,19 @@ void BattleGroundEY::FillInitialWorldStates(WorldPacket& data) data << uint32(0xab1) << uint32(0x0); data << uint32(0xab0) << uint32(0x0); data << uint32(0xaaf) << uint32(0x0); - data << uint32(DRAENEI_RUINS_HORDE_CONTROL) << uint32(m_PointOwnedByTeam[DRAENEI_RUINS] == HORDE && m_PointState[DRAENEI_RUINS] == EY_POINT_UNDER_CONTROL); - data << uint32(DRAENEI_RUINS_ALLIANCE_CONTROL) << uint32(m_PointOwnedByTeam[DRAENEI_RUINS] == ALLIANCE && m_PointState[DRAENEI_RUINS] == EY_POINT_UNDER_CONTROL); - data << uint32(DRAENEI_RUINS_UNCONTROL) << uint32(m_PointState[DRAENEI_RUINS] != EY_POINT_UNDER_CONTROL); - data << uint32(MAGE_TOWER_ALLIANCE_CONTROL) << uint32(m_PointOwnedByTeam[MAGE_TOWER] == ALLIANCE && m_PointState[MAGE_TOWER] == EY_POINT_UNDER_CONTROL); - data << uint32(MAGE_TOWER_HORDE_CONTROL) << uint32(m_PointOwnedByTeam[MAGE_TOWER] == HORDE && m_PointState[MAGE_TOWER] == EY_POINT_UNDER_CONTROL); - data << uint32(MAGE_TOWER_UNCONTROL) << uint32(m_PointState[MAGE_TOWER] != EY_POINT_UNDER_CONTROL); - data << uint32(FEL_REAVER_HORDE_CONTROL) << uint32(m_PointOwnedByTeam[FEL_REALVER] == HORDE && m_PointState[FEL_REALVER] == EY_POINT_UNDER_CONTROL); - data << uint32(FEL_REAVER_ALLIANCE_CONTROL) << uint32(m_PointOwnedByTeam[FEL_REALVER] == ALLIANCE && m_PointState[FEL_REALVER] == EY_POINT_UNDER_CONTROL); - data << uint32(FEL_REAVER_UNCONTROL) << uint32(m_PointState[FEL_REALVER] != EY_POINT_UNDER_CONTROL); - data << uint32(BLOOD_ELF_HORDE_CONTROL) << uint32(m_PointOwnedByTeam[BLOOD_ELF] == HORDE && m_PointState[BLOOD_ELF] == EY_POINT_UNDER_CONTROL); - data << uint32(BLOOD_ELF_ALLIANCE_CONTROL) << uint32(m_PointOwnedByTeam[BLOOD_ELF] == ALLIANCE && m_PointState[BLOOD_ELF] == EY_POINT_UNDER_CONTROL); - data << uint32(BLOOD_ELF_UNCONTROL) << uint32(m_PointState[BLOOD_ELF] != EY_POINT_UNDER_CONTROL); - data << uint32(NETHERSTORM_FLAG) << uint32(m_FlagState == BG_EY_FLAG_STATE_ON_BASE); - data << uint32(0xad2) << uint32(0x1); data << uint32(0xad1) << uint32(0x1); data << uint32(0xabe) << uint32(GetTeamScore(HORDE)); @@ -852,39 +743,31 @@ void BattleGroundEY::FillInitialWorldStates(WorldPacket& data) data << uint32(0xa9e) << uint32(0x0); data << uint32(0xc0d) << uint32(0x17b); } - WorldSafeLocsEntry const *BattleGroundEY::GetClosestGraveYard(Player* player) { uint32 g_id = 0; - switch(player->GetTeam()) { case ALLIANCE: g_id = EY_GRAVEYARD_MAIN_ALLIANCE; break; case HORDE: g_id = EY_GRAVEYARD_MAIN_HORDE; break; default: return NULL; } - float distance, nearestDistance; - WorldSafeLocsEntry const* entry = NULL; WorldSafeLocsEntry const* nearestEntry = NULL; entry = sWorldSafeLocsStore.LookupEntry(g_id); nearestEntry = entry; - if (!entry) { sLog.outError("BattleGroundEY: Not found the main team graveyard. Graveyard system isn't working!"); return NULL; } - float plr_x = player->GetPositionX(); float plr_y = player->GetPositionY(); float plr_z = player->GetPositionZ(); - distance = (entry->x - plr_x)*(entry->x - plr_x) + (entry->y - plr_y)*(entry->y - plr_y) + (entry->z - plr_z)*(entry->z - plr_z); nearestDistance = distance; - for(uint8 i = 0; i < EY_POINTS_MAX; ++i) { if (m_PointOwnedByTeam[i]==player->GetTeam() && m_PointState[i]==EY_POINT_UNDER_CONTROL) @@ -903,16 +786,13 @@ WorldSafeLocsEntry const *BattleGroundEY::GetClosestGraveYard(Player* player) } } } - return nearestEntry; } - bool BattleGroundEY::IsAllNodesConrolledByTeam(uint32 team) const { uint32 count = 0; for(int i = 0; i < EY_POINTS_MAX; ++i) if (m_PointOwnedByTeam[i] == team && m_PointState[i] == EY_POINT_UNDER_CONTROL) ++count; - return count == EY_POINTS_MAX; } diff --git a/src/game/BattleGroundEY.h b/src/game/BattleGroundEY.h index 3385a06bfb0..086c4d79fbd 100644 --- a/src/game/BattleGroundEY.h +++ b/src/game/BattleGroundEY.h @@ -17,17 +17,12 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef __BATTLEGROUNDEY_H #define __BATTLEGROUNDEY_H - #include "Language.h" - class BattleGround; - #define BG_EY_FLAG_RESPAWN_TIME (10*IN_MILISECONDS) //10 seconds #define BG_EY_FPOINTS_TICK_TIME (2*IN_MILISECONDS) //2 seconds - enum BG_EY_WorldStates { EY_ALLIANCE_RESOURCES = 2749, @@ -54,7 +49,6 @@ enum BG_EY_WorldStates NETHERSTORM_FLAG_STATE_ALLIANCE = 2769, NETHERSTORM_FLAG_STATE_HORDE = 2770 }; - enum BG_EY_ProgressBarConsts { BG_EY_POINT_MAX_CAPTURERS_COUNT = 5, @@ -68,7 +62,6 @@ enum BG_EY_ProgressBarConsts BG_EY_PROGRESS_BAR_NEUTRAL_HIGH = 70, BG_EY_PROGRESS_BAR_ALI_CONTROLLED = 100 }; - enum BG_EY_Sounds { //strange ids, but sure about them @@ -78,13 +71,11 @@ enum BG_EY_Sounds BG_EY_SOUND_FLAG_CAPTURED_ALLIANCE = 8173, BG_EY_SOUND_FLAG_RESET = 8192 }; - enum BG_EY_Spells { BG_EY_NETHERSTORM_FLAG_SPELL = 34976, BG_EY_PLAYER_DROPPED_FLAG_SPELL = 34991 }; - enum EYBattleGroundObjectEntry { BG_OBJECT_A_DOOR_EY_ENTRY = 184719, //Alliance door @@ -100,7 +91,6 @@ enum EYBattleGroundObjectEntry BG_OBJECT_HU_TOWER_CAP_EY_ENTRY = 184082, //Human Tower Cap Pt BG_OBJECT_DR_TOWER_CAP_EY_ENTRY = 184083 //Draenei Tower Cap Pt }; - enum EYBattleGroundPointsTrigger { TR_BLOOD_ELF_POINT = 4476, @@ -112,7 +102,6 @@ enum EYBattleGroundPointsTrigger TR_MAGE_TOWER_BUFF = 4570, TR_DRAENEI_RUINS_BUFF = 4571 }; - enum EYBattleGroundGaveyards { EY_GRAVEYARD_MAIN_ALLIANCE = 1103, @@ -122,18 +111,15 @@ enum EYBattleGroundGaveyards EY_GRAVEYARD_DRAENEI_RUINS = 1107, EY_GRAVEYARD_MAGE_TOWER = 1108 }; - enum EYBattleGroundPoints { FEL_REALVER = 0, BLOOD_ELF = 1, DRAENEI_RUINS = 2, MAGE_TOWER = 3, - EY_PLAYERS_OUT_OF_POINTS = 4, EY_POINTS_MAX = 4 }; - enum EYBattleGroundCreaturesTypes { EY_SPIRIT_FEL_REALVER = 0, @@ -142,10 +128,8 @@ enum EYBattleGroundCreaturesTypes EY_SPIRIT_MAGE_TOWER = 3, EY_SPIRIT_MAIN_ALLIANCE = 4, EY_SPIRIT_MAIN_HORDE = 5, - BG_EY_CREATURES_MAX = 6 }; - enum EYBattleGroundObjectTypes { BG_EY_OBJECT_DOOR_A = 0, @@ -210,16 +194,13 @@ enum EYBattleGroundObjectTypes BG_EY_OBJECT_BERSERKBUFF_MAGE_TOWER = 58, BG_EY_OBJECT_MAX = 59 }; - #define BG_EY_NotEYWeekendHonorTicks 330 #define BG_EY_EYWeekendHonorTicks 200 - enum BG_EY_Score { BG_EY_WARNING_NEAR_VICTORY_SCORE = 1800, BG_EY_MAX_TEAM_SCORE = 2000 }; - enum BG_EY_FlagState { BG_EY_FLAG_STATE_ON_BASE = 0, @@ -227,14 +208,12 @@ enum BG_EY_FlagState BG_EY_FLAG_STATE_ON_PLAYER = 2, BG_EY_FLAG_STATE_ON_GROUND = 3 }; - enum EYBattleGroundPointState { EY_POINT_NO_OWNER = 0, EY_POINT_STATE_UNCONTROLLED = 0, EY_POINT_UNDER_CONTROL = 3 }; - struct BattleGroundEYPointIconsStruct { BattleGroundEYPointIconsStruct(uint32 _WorldStateControlIndex, uint32 _WorldStateAllianceControlledIndex, uint32 _WorldStateHordeControlledIndex) @@ -243,7 +222,6 @@ struct BattleGroundEYPointIconsStruct uint32 WorldStateAllianceControlledIndex; uint32 WorldStateHordeControlledIndex; }; - struct BattleGroundEYLoosingPointStruct { BattleGroundEYLoosingPointStruct(uint32 _SpawnNeutralObjectType, uint32 _DespawnObjectTypeAlliance, uint32 _MessageIdAlliance, uint32 _DespawnObjectTypeHorde, uint32 _MessageIdHorde) @@ -251,14 +229,12 @@ struct BattleGroundEYLoosingPointStruct DespawnObjectTypeAlliance(_DespawnObjectTypeAlliance), MessageIdAlliance(_MessageIdAlliance), DespawnObjectTypeHorde(_DespawnObjectTypeHorde), MessageIdHorde(_MessageIdHorde) {} - uint32 SpawnNeutralObjectType; uint32 DespawnObjectTypeAlliance; uint32 MessageIdAlliance; uint32 DespawnObjectTypeHorde; uint32 MessageIdHorde; }; - struct BattleGroundEYCapturingPointStruct { BattleGroundEYCapturingPointStruct(uint32 _DespawnNeutralObjectType, uint32 _SpawnObjectTypeAlliance, uint32 _MessageIdAlliance, uint32 _SpawnObjectTypeHorde, uint32 _MessageIdHorde, uint32 _GraveYardId) @@ -267,7 +243,6 @@ struct BattleGroundEYCapturingPointStruct SpawnObjectTypeHorde(_SpawnObjectTypeHorde), MessageIdHorde(_MessageIdHorde), GraveYardId(_GraveYardId) {} - uint32 DespawnNeutralObjectType; uint32 SpawnObjectTypeAlliance; uint32 MessageIdAlliance; @@ -275,10 +250,8 @@ struct BattleGroundEYCapturingPointStruct uint32 MessageIdHorde; uint32 GraveYardId; }; - const uint8 BG_EY_TickPoints[EY_POINTS_MAX] = {1, 2, 5, 10}; const uint32 BG_EY_FlagPoints[EY_POINTS_MAX] = {75, 85, 100, 500}; - //constant arrays: const BattleGroundEYPointIconsStruct m_PointsIconStruct[EY_POINTS_MAX] = { @@ -301,7 +274,6 @@ const BattleGroundEYCapturingPointStruct m_CapturingPointTypes[EY_POINTS_MAX] = BattleGroundEYCapturingPointStruct(BG_EY_OBJECT_N_BANNER_DRAENEI_RUINS_CENTER, BG_EY_OBJECT_A_BANNER_DRAENEI_RUINS_CENTER, LANG_BG_EY_HAS_TAKEN_A_D_RUINS, BG_EY_OBJECT_H_BANNER_DRAENEI_RUINS_CENTER, LANG_BG_EY_HAS_TAKEN_H_D_RUINS, EY_GRAVEYARD_DRAENEI_RUINS), BattleGroundEYCapturingPointStruct(BG_EY_OBJECT_N_BANNER_MAGE_TOWER_CENTER, BG_EY_OBJECT_A_BANNER_MAGE_TOWER_CENTER, LANG_BG_EY_HAS_TAKEN_A_M_TOWER, BG_EY_OBJECT_H_BANNER_MAGE_TOWER_CENTER, LANG_BG_EY_HAS_TAKEN_H_M_TOWER, EY_GRAVEYARD_MAGE_TOWER) }; - class BattleGroundEYScore : public BattleGroundScore { public: @@ -309,21 +281,17 @@ class BattleGroundEYScore : public BattleGroundScore virtual ~BattleGroundEYScore() {}; uint32 FlagCaptures; }; - class BattleGroundEY : public BattleGround { friend class BattleGroundMgr; - public: BattleGroundEY(); ~BattleGroundEY(); void Update(uint32 diff); - /* inherited from BattlegroundClass */ virtual void AddPlayer(Player *plr); virtual void StartingEventCloseDoors(); virtual void StartingEventOpenDoors(); - /* BG Flags */ uint64 GetFlagPickerGUID() const { return m_FlagKeeper; } void SetFlagPicker(uint64 guid) { m_FlagKeeper = guid; } @@ -331,7 +299,6 @@ class BattleGroundEY : public BattleGround uint8 GetFlagState() const { return m_FlagState; } void RespawnFlag(bool send_message); void RespawnFlagAfterDrop(); - void RemovePlayer(Player *plr,uint64 guid); void HandleBuffUse(uint64 const& buff_guid); void HandleAreaTrigger(Player *Source, uint32 Trigger); @@ -345,11 +312,9 @@ class BattleGroundEY : public BattleGround virtual void FillInitialWorldStates(WorldPacket& data); void SetDroppedFlagGUID(uint64 guid) { m_DroppedFlagGUID = guid;} uint64 GetDroppedFlagGUID() const { return m_DroppedFlagGUID;} - /* Battleground Events */ virtual void EventPlayerClickedOnFlag(Player *Source, GameObject* target_obj); virtual void EventPlayerDroppedFlag(Player *Source); - /* achievement req. */ bool IsAllNodesConrolledByTeam(uint32 team) const; private: @@ -358,38 +323,30 @@ class BattleGroundEY : public BattleGround void EventTeamLostPoint(Player *Source, uint32 Point); void UpdatePointsCount(uint32 Team); void UpdatePointsIcons(uint32 Team, uint32 Point); - /* Point status updating procedures */ void CheckSomeoneLeftPoint(); void CheckSomeoneJoinedPoint(); void UpdatePointStatuses(); - /* Scorekeeping */ uint32 GetTeamScore(uint32 Team) const { return m_TeamScores[GetTeamIndexByTeamId(Team)]; } void AddPoints(uint32 Team, uint32 Points); - void RemovePoint(uint32 TeamID, uint32 Points = 1) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] -= Points; } void SetTeamPoint(uint32 TeamID, uint32 Points = 0) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] = Points; } - uint32 m_HonorScoreTics[2]; uint32 m_TeamPointsCount[2]; - uint32 m_Points_Trigger[EY_POINTS_MAX]; - uint64 m_FlagKeeper; // keepers guid uint64 m_DroppedFlagGUID; uint32 m_FlagCapturedBgObjectType; // type that should be despawned when flag is captured uint8 m_FlagState; // for checking flag state int32 m_FlagsTimer; int32 m_TowerCapCheckTimer; - uint32 m_PointOwnedByTeam[EY_POINTS_MAX]; uint8 m_PointState[EY_POINTS_MAX]; int32 m_PointBarStatus[EY_POINTS_MAX]; typedef std::vector PlayersNearPointType; PlayersNearPointType m_PlayersNearPoint[EY_POINTS_MAX + 1]; uint8 m_CurrentPointPlayersCount[2*EY_POINTS_MAX]; - int32 m_PointAddingTimer; uint32 m_HonorTics; }; diff --git a/src/game/BattleGroundHandler.cpp b/src/game/BattleGroundHandler.cpp index 3e7c453e300..1e685ec1f3a 100644 --- a/src/game/BattleGroundHandler.cpp +++ b/src/game/BattleGroundHandler.cpp @@ -17,13 +17,11 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "Common.h" #include "ObjectAccessor.h" #include "ObjectMgr.h" #include "WorldPacket.h" #include "WorldSession.h" - #include "ArenaTeam.h" #include "BattleGroundMgr.h" #include "BattleGroundWS.h" @@ -34,42 +32,33 @@ #include "Player.h" #include "Object.h" #include "Opcodes.h" - void WorldSession::HandleBattlemasterHelloOpcode( WorldPacket & recv_data ) { uint64 guid; recv_data >> guid; sLog.outDebug( "WORLD: Recvd CMSG_BATTLEMASTER_HELLO Message from (GUID: %u TypeId:%u)", GUID_LOPART(guid),GuidHigh2TypeId(GUID_HIPART(guid))); - Creature *unit = GetPlayer()->GetMap()->GetCreature(guid); if (!unit) return; - if(!unit->isBattleMaster()) // it's not battlemaster return; - // Stop the npc if moving unit->StopMoving(); - BattleGroundTypeId bgTypeId = sBattleGroundMgr.GetBattleMasterBG(unit->GetEntry()); - if (!_player->GetBGAccessByLevel(bgTypeId)) { // temp, must be gossip message... SendNotification(LANG_YOUR_BG_LEVEL_REQ_ERROR); return; } - SendBattlegGroundList(guid, bgTypeId); } - void WorldSession::SendBattlegGroundList( uint64 guid, BattleGroundTypeId bgTypeId ) { WorldPacket data; sBattleGroundMgr.BuildBattleGroundListPacket(&data, guid, _player, bgTypeId, 0); SendPacket( &data ); } - void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data ) { uint64 guid; @@ -78,40 +67,31 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data ) uint8 joinAsGroup; bool isPremade = false; Group * grp; - recv_data >> guid; // battlemaster guid recv_data >> bgTypeId_; // battleground type id (DBC id) recv_data >> instanceId; // instance id, 0 if First Available selected recv_data >> joinAsGroup; // join as group - if (!sBattlemasterListStore.LookupEntry(bgTypeId_)) { sLog.outError("Battleground: invalid bgtype (%u) received. possible cheater? player guid %u",bgTypeId_,_player->GetGUIDLow()); return; } - BattleGroundTypeId bgTypeId = BattleGroundTypeId(bgTypeId_); - sLog.outDebug( "WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from (GUID: %u TypeId:%u)", GUID_LOPART(guid), GuidHigh2TypeId(GUID_HIPART(guid))); - // can do this, since it's battleground, not arena BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, 0); - // ignore if player is already in BG if (_player->InBattleGround()) return; - // get bg instance or bg template if instance not found BattleGround *bg = NULL; if (instanceId) bg = sBattleGroundMgr.GetBattleGroundThroughClientInstance(instanceId, bgTypeId); - if (!bg && !(bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId))) { sLog.outError("Battleground: no available bg / template found"); return; } - // check queueing conditions if (!joinAsGroup) { @@ -146,7 +126,6 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data ) } } // if we're here, then the conditions to join a bg are met. We can proceed in joining. - // _player->GetGroup() was already checked, grp is already initialized GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, 0, false, isPremade, 0); uint32 avgTime = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundQueueIdFromLevel(bgTypeId)); @@ -157,9 +136,7 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data ) { Player *member = itr->getSource(); if(!member) continue; // this should never happen - uint32 queueSlot = member->AddBattleGroundQueueId(bgQueueTypeId); // add to queue - WorldPacket data; // send status packet (in queue) sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->ArenaType); @@ -175,12 +152,10 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data ) { // already checked if queueSlot is valid, now just get it uint32 queueSlot = _player->AddBattleGroundQueueId(bgQueueTypeId); - WorldPacket data; // send status packet (in queue) sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->ArenaType); SendPacket(&data); - sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddPlayer(_player, ginfo); sLog.outDebug("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,_player->GetGUIDLow(), _player->GetName()); } @@ -188,31 +163,25 @@ void WorldSession::HandleBattlemasterJoinOpcode( WorldPacket & recv_data ) if (!ginfo->IsInvitedToBGInstanceGUID) sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AnnounceWorld(ginfo, _player->GetGUID(), true); } - void WorldSession::HandleBattleGroundPlayerPositionsOpcode( WorldPacket & /*recv_data*/ ) { // empty opcode sLog.outDebug("WORLD: Recvd MSG_BATTLEGROUND_PLAYER_POSITIONS Message"); - BattleGround *bg = _player->GetBattleGround(); if(!bg) // can't be received if player not in battleground return; - switch( bg->GetTypeID() ) { case BATTLEGROUND_WS: { uint32 count1 = 0; //always constant zero? uint32 count2 = 0; //count of next fields - Player *ali_plr = objmgr.GetPlayer(((BattleGroundWS*)bg)->GetAllianceFlagPickerGUID()); if (ali_plr) ++count2; - Player *horde_plr = objmgr.GetPlayer(((BattleGroundWS*)bg)->GetHordeFlagPickerGUID()); if (horde_plr) ++count2; - WorldPacket data(MSG_BATTLEGROUND_PLAYER_POSITIONS, (4+4+16*count1+16*count2)); data << count1; // alliance flag holders count - obsolete, now always 0 /*for(uint8 i = 0; i < count1; ++i) @@ -234,7 +203,6 @@ void WorldSession::HandleBattleGroundPlayerPositionsOpcode( WorldPacket & /*recv data << (float)horde_plr->GetPositionX(); data << (float)horde_plr->GetPositionY(); } - SendPacket(&data); } break; @@ -256,57 +224,44 @@ void WorldSession::HandleBattleGroundPlayerPositionsOpcode( WorldPacket & /*recv break; } } - void WorldSession::HandlePVPLogDataOpcode( WorldPacket & /*recv_data*/ ) { sLog.outDebug( "WORLD: Recvd MSG_PVP_LOG_DATA Message"); - BattleGround *bg = _player->GetBattleGround(); if (!bg) return; - WorldPacket data; sBattleGroundMgr.BuildPvpLogDataPacket(&data, bg); SendPacket(&data); - sLog.outDebug( "WORLD: Sent MSG_PVP_LOG_DATA Message"); } - void WorldSession::HandleBattlefieldListOpcode( WorldPacket &recv_data ) { sLog.outDebug( "WORLD: Recvd CMSG_BATTLEFIELD_LIST Message"); - uint32 bgTypeId; recv_data >> bgTypeId; // id from DBC - uint8 fromWhere; recv_data >> fromWhere; // 0 - battlemaster, 1 - UI - BattlemasterListEntry const* bl = sBattlemasterListStore.LookupEntry(bgTypeId); if (!bl) { sLog.outError("Battleground: invalid bgtype received."); return; } - WorldPacket data; sBattleGroundMgr.BuildBattleGroundListPacket(&data, 0, _player, BattleGroundTypeId(bgTypeId), fromWhere); SendPacket( &data ); } - void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data ) { sLog.outDebug( "WORLD: Recvd CMSG_BATTLEFIELD_PORT Message"); - uint8 type; // arenatype if arena uint8 unk2; // unk, can be 0x0 (may be if was invited?) and 0x1 uint32 instanceId; uint32 bgTypeId_; // type id from dbc uint16 unk; // 0x1F90 constant? uint8 action; // enter battle 0x1, leave queue 0x0 - recv_data >> type >> unk2 >> bgTypeId_ >> unk >> action; - if (!sBattlemasterListStore.LookupEntry(bgTypeId_)) { sLog.outError("Battleground: invalid bgtype (%u) received.", bgTypeId_); @@ -327,12 +282,10 @@ void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data ) // if the player is not in queue, continue or no group information - this should never happen if (itrPlayerStatus == qpMap.end() || !itrPlayerStatus->second.GroupInfo) continue; - BattleGround * bg = NULL; // get possibly needed data from groupinfo uint8 arenatype = itrPlayerStatus->second.GroupInfo->ArenaType; uint8 status = 0; - if (!itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID) { // not invited to bg, get template @@ -345,11 +298,9 @@ void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data ) bg = sBattleGroundMgr.GetBattleGround(itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID, bgTypeId); status = STATUS_WAIT_JOIN; } - // if bg not found, then continue, don't invite if already in the instance if (!bg || (_player->InBattleGround() && _player->GetBattleGround() && _player->GetBattleGround()->GetInstanceID() == bg->GetInstanceID())) continue; - // re - invite player with proper data WorldPacket data; sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, i, status, INVITE_ACCEPT_WAIT_TIME, 0, arenatype); @@ -358,7 +309,6 @@ void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data ) } return; } - //get GroupQueueInfo from BattleGroundQueue BattleGroundTypeId bgTypeId = BattleGroundTypeId(bgTypeId_); BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, type); @@ -369,7 +319,6 @@ void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data ) sLog.outError("Battleground: itrplayerstatus not found."); return; } - instanceId = itrPlayerStatus->second.GroupInfo->IsInvitedToBGInstanceGUID; // if action == 1, then instanceId is required if (!instanceId && action == 1) @@ -377,9 +326,7 @@ void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data ) sLog.outError("Battleground: instance not found."); return; } - BattleGround *bg = sBattleGroundMgr.GetBattleGround(instanceId, bgTypeId); - // bg template might and must be used in case of leaving queue, when instance is not created yet if (!bg && action == 0) bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId); @@ -388,7 +335,6 @@ void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data ) sLog.outError("Battleground: bg_template not found for type id %u.", bgTypeId); return; } - if (_player->InBattleGroundQueue()) { //we must use temporary variables, because GroupQueueInfo pointer can be deleted in BattleGroundQueue::RemovePlayer() function! @@ -397,7 +343,6 @@ void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data ) uint32 isRated = itrPlayerStatus->second.GroupInfo->IsRated; uint32 rating = itrPlayerStatus->second.GroupInfo->ArenaTeamRating; uint32 opponentsRating = itrPlayerStatus->second.GroupInfo->OpponentsTeamRating; - //some checks if player isn't cheating - it is not exactly cheating, but we cannot allow it if (action == 1 && arenaType == 0) { @@ -425,9 +370,7 @@ void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data ) case 1: // port to battleground if (!_player->IsInvitedForBattleGroundQueueType(bgQueueTypeId)) return; // cheating? - _player->SetBattleGroundEntryPoint(); - // resurrect the player if (!_player->isAlive()) { @@ -439,9 +382,7 @@ void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data ) { _player->GetMotionMaster()->MovementExpired(); _player->CleanupAfterTaxiFlight(); - } - sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime(), bg->GetArenaType()); _player->GetSession()->SendPacket(&data); // remove battleground queue status from BGmgr @@ -450,7 +391,6 @@ void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data ) // also this is required to prevent stuck at old battleground after SetBattleGroundId set to new if (BattleGround *currentBg = _player->GetBattleGround()) currentBg->RemovePlayerAtLeave(_player->GetGUID(), false, true); - // set the destination instance id _player->SetBattleGroundId(bg->GetInstanceID(), bgTypeId); // set the destination team @@ -491,34 +431,26 @@ void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data ) } } } - void WorldSession::HandleLeaveBattlefieldOpcode( WorldPacket & /*recv_data*/ ) { sLog.outDebug( "WORLD: Recvd CMSG_LEAVE_BATTLEFIELD Message"); - //uint8 unk1, unk2; //uint32 bgTypeId; // id from DBC //uint16 unk3; - //recv_data >> unk1 >> unk2 >> bgTypeId >> unk3; - no used currently - //if(bgTypeId >= MAX_BATTLEGROUND_TYPES) // cheating? but not important in this case // return; - // not allow leave battleground in combat if (_player->isInCombat()) if (BattleGround* bg = _player->GetBattleGround()) if (bg->GetStatus() != STATUS_WAIT_LEAVE) return; - _player->LeaveBattleground(); } - void WorldSession::HandleBattlefieldStatusOpcode( WorldPacket & /*recv_data*/ ) { // empty opcode sLog.outDebug( "WORLD: Battleground status" ); - WorldPacket data; // we must update all queues here BattleGround *bg = NULL; @@ -571,76 +503,56 @@ void WorldSession::HandleBattlefieldStatusOpcode( WorldPacket & /*recv_data*/ ) } } } - void WorldSession::HandleAreaSpiritHealerQueryOpcode( WorldPacket & recv_data ) { sLog.outDebug("WORLD: CMSG_AREA_SPIRIT_HEALER_QUERY"); - BattleGround *bg = _player->GetBattleGround(); if (!bg) return; - uint64 guid; recv_data >> guid; - Creature *unit = GetPlayer()->GetMap()->GetCreature(guid); if (!unit) return; - if(!unit->isSpiritService()) // it's not spirit service return; - sBattleGroundMgr.SendAreaSpiritHealerQueryOpcode(_player, bg, guid); } - void WorldSession::HandleAreaSpiritHealerQueueOpcode( WorldPacket & recv_data ) { sLog.outDebug("WORLD: CMSG_AREA_SPIRIT_HEALER_QUEUE"); - BattleGround *bg = _player->GetBattleGround(); if (!bg) return; - uint64 guid; recv_data >> guid; - Creature *unit = GetPlayer()->GetMap()->GetCreature(guid); if (!unit) return; - if(!unit->isSpiritService()) // it's not spirit service return; - bg->AddPlayerToResurrectQueue(guid, _player->GetGUID()); } - void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data ) { sLog.outDebug("WORLD: CMSG_BATTLEMASTER_JOIN_ARENA"); //recv_data.hexlike(); - uint64 guid; // arena Battlemaster guid uint8 arenaslot; // 2v2, 3v3 or 5v5 uint8 asGroup; // asGroup uint8 isRated; // isRated Group * grp; - recv_data >> guid >> arenaslot >> asGroup >> isRated; - // ignore if we already in BG or BG queue if (_player->InBattleGround()) return; - Creature *unit = GetPlayer()->GetMap()->GetCreature(guid); if (!unit) return; - if(!unit->isBattleMaster()) // it's not battle master return; - uint8 arenatype = 0; uint32 arenaRating = 0; - switch(arenaslot) { case 0: @@ -656,7 +568,6 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data ) sLog.outError("Unknown arena slot %u at HandleBattlemasterJoinArena()", arenaslot); return; } - //check existance BattleGround* bg = NULL; if (!(bg = sBattleGroundMgr.GetBattleGroundTemplate(BATTLEGROUND_AA))) @@ -664,10 +575,8 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data ) sLog.outError("Battleground: template bg (all arenas) not found"); return; } - BattleGroundTypeId bgTypeId = bg->GetTypeID(); BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, arenatype); - // check queueing conditions if (!asGroup) { @@ -692,9 +601,7 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data ) return; } } - uint32 ateamId = 0; - if (isRated) { ateamId = _player->GetArenaTeamId(arenaslot); @@ -713,19 +620,15 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data ) for(GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) { Player *member = itr->getSource(); - // calc avg personal rating avg_pers_rating += member->GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (arenaslot*6) + 5); } - if (arenatype) avg_pers_rating /= arenatype; - // if avg personal rating is more than 150 points below the teams rating, the team will be queued against an opponent matching or similar to the average personal rating if (avg_pers_rating + 150 < arenaRating) arenaRating = avg_pers_rating; } - GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, arenatype, isRated, false, arenaRating, ateamId); uint32 avgTime = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].GetAverageQueueWaitTime(ginfo, _player->GetBattleGroundQueueIdFromLevel(bgTypeId)); if (asGroup) @@ -738,14 +641,11 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data ) } else bg->SetRated(false); - for(GroupReference *itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) { Player *member = itr->getSource(); if(!member) continue; - uint32 queueSlot = member->AddBattleGroundQueueId(bgQueueTypeId);// add to queue - WorldPacket data; // send status packet (in queue) sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype); @@ -762,7 +662,6 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data ) else { uint32 queueSlot = _player->AddBattleGroundQueueId(bgQueueTypeId); - WorldPacket data; // send status packet (in queue) sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype); @@ -772,24 +671,19 @@ void WorldSession::HandleBattlemasterJoinArena( WorldPacket & recv_data ) } sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel(bgTypeId), arenatype, isRated, arenaRating); } - void WorldSession::HandleReportPvPAFK( WorldPacket & recv_data ) { uint64 playerGuid; recv_data >> playerGuid; Player *reportedPlayer = objmgr.GetPlayer(playerGuid); - if (!reportedPlayer) { sLog.outDebug("WorldSession::HandleReportPvPAFK: player not found"); return; } - sLog.outDebug("WorldSession::HandleReportPvPAFK: %s reported %s", _player->GetName(), reportedPlayer->GetName()); - reportedPlayer->ReportedAfkBy(_player); } - void WorldSession::SendBattleGroundOrArenaJoinError(uint8 err) { WorldPacket data; diff --git a/src/game/BattleGroundMgr.cpp b/src/game/BattleGroundMgr.cpp index f2143de5bdc..99339a835a6 100644 --- a/src/game/BattleGroundMgr.cpp +++ b/src/game/BattleGroundMgr.cpp @@ -17,13 +17,11 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "Common.h" #include "ObjectMgr.h" #include "World.h" #include "WorldPacket.h" #include "Policies/SingletonImp.h" - #include "ArenaTeam.h" #include "BattleGroundMgr.h" #include "BattleGroundAV.h" @@ -45,13 +43,10 @@ #include "GameEventMgr.h" #include "ProgressBar.h" #include "SharedDefines.h" - INSTANTIATE_SINGLETON_1( BattleGroundMgr ); - /*********************************************************/ /*** BATTLEGROUND QUEUE SYSTEM ***/ /*********************************************************/ - BattleGroundQueue::BattleGroundQueue() { for(uint32 i = 0; i < BG_TEAMS_COUNT; i++) @@ -65,7 +60,6 @@ BattleGroundQueue::BattleGroundQueue() } } } - BattleGroundQueue::~BattleGroundQueue() { m_QueuedPlayers.clear(); @@ -79,18 +73,15 @@ BattleGroundQueue::~BattleGroundQueue() } } } - /*********************************************************/ /*** BATTLEGROUND QUEUE SELECTION POOLS ***/ /*********************************************************/ - // selection pool initialization, used to clean up from prev selection void BattleGroundQueue::SelectionPool::Init() { SelectedGroups.clear(); PlayerCount = 0; } - // remove group info from selection pool // returns true when we need to try to add new group to selection pool // returns false when selection pool is ok or when we kicked smaller group than we need to kick @@ -123,7 +114,6 @@ bool BattleGroundQueue::SelectionPool::KickGroup(uint32 size) } return true; } - // add group to selection pool // used when building selection pools // returns true if we can invite more players, or when we added group to selection pool @@ -142,16 +132,13 @@ bool BattleGroundQueue::SelectionPool::AddGroup(GroupQueueInfo *ginfo, uint32 de return true; return false; } - /*********************************************************/ /*** BATTLEGROUND QUEUES ***/ /*********************************************************/ - // add group to bg queue with the given leader and bg specifications GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, BattleGroundTypeId BgTypeId, uint8 ArenaType, bool isRated, bool isPremade, uint32 arenaRating, uint32 arenateamid) { BGQueueIdBasedOnLevel queue_id = leader->GetBattleGroundQueueIdFromLevel(BgTypeId); - // create new ginfo // cannot use the method like in addplayer, because that could modify an in-queue group's stats // (e.g. leader leaving queue then joining as individual again) @@ -166,9 +153,7 @@ GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, BattleGroundTypeId ginfo->Team = leader->GetTeam(); ginfo->ArenaTeamRating = arenaRating; ginfo->OpponentsTeamRating = 0; - ginfo->Players.clear(); - //compute index (if group is premade or joined a rated match) to queues uint32 index = 0; if (!isRated && !isPremade) @@ -176,13 +161,10 @@ GroupQueueInfo * BattleGroundQueue::AddGroup(Player *leader, BattleGroundTypeId if (ginfo->Team == HORDE) index++; sLog.outDebug("Adding Group to BattleGroundQueue bgTypeId : %u, queue_id : %u, index : %u", BgTypeId, queue_id, index); - m_QueuedGroups[queue_id][index].push_back(ginfo); - // return ginfo, because it is needed to add players to this group info return ginfo; } - //add player to playermap void BattleGroundQueue::AddPlayer(Player *plr, GroupQueueInfo *ginfo) { @@ -190,11 +172,9 @@ void BattleGroundQueue::AddPlayer(Player *plr, GroupQueueInfo *ginfo) PlayerQueueInfo& info = m_QueuedPlayers[plr->GetGUID()]; info.LastOnlineTime = getMSTime(); info.GroupInfo = ginfo; - // add the pinfo to ginfo's list ginfo->Players[plr->GetGUID()] = &info; } - void BattleGroundQueue::PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id) { uint32 timeInQueue = getMSTimeDiff(ginfo->JoinTime, getMSTime()); @@ -209,7 +189,6 @@ void BattleGroundQueue::PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* g if (ginfo->IsRated) team_index = BG_TEAM_HORDE; //for rated arenas use BG_TEAM_HORDE } - //store pointer to arrayindex of player that was added first uint32* lastPlayerAddedPointer = &(m_WaitTimeLastPlayer[team_index][queue_id]); //remove his time from sum @@ -222,7 +201,6 @@ void BattleGroundQueue::PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* g (*lastPlayerAddedPointer)++; (*lastPlayerAddedPointer) %= COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME; } - uint32 BattleGroundQueue::GetAverageQueueWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id) { uint8 team_index = BG_TEAM_ALLIANCE; //default set to BG_TEAM_ALLIANCE - or non rated arenas! @@ -243,15 +221,12 @@ uint32 BattleGroundQueue::GetAverageQueueWaitTime(GroupQueueInfo* ginfo, BGQueue //if there aren't enough values return 0 - not available return 0; } - //remove player from queue and from group info, if group info is empty then remove it too void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCount) { //Player *plr = objmgr.GetPlayer(guid); - int32 queue_id = -1; // signed for proper for-loop finish QueuedPlayersMap::iterator itr; - //remove player from map, if he's there itr = m_QueuedPlayers.find(guid); if (itr == m_QueuedPlayers.end()) @@ -259,14 +234,12 @@ void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCou sLog.outError("BattleGroundQueue: couldn't find player to remove GUID: %u", GUID_LOPART(guid)); return; } - GroupQueueInfo* group = itr->second.GroupInfo; GroupsQueueType::iterator group_itr, group_itr_tmp; // mostly people with the highest levels are in battlegrounds, thats why // we count from MAX_BATTLEGROUND_QUEUES - 1 to 0 // variable index removes useless searching in other team's queue uint32 index = (group->Team == HORDE) ? BG_TEAM_HORDE : BG_TEAM_ALLIANCE; - for (int32 queue_id_tmp = MAX_BATTLEGROUND_QUEUES - 1; queue_id_tmp >= 0 && queue_id == -1; --queue_id_tmp) { //we must check premade and normal team's queue - because when players from premade are joining bg, @@ -293,17 +266,14 @@ void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCou return; } sLog.outDebug("BattleGroundQueue: Removing player GUID %u, from queue_id %u", GUID_LOPART(guid), (uint32)queue_id); - // ALL variables are correctly set // We can ignore leveling up in queue - it should not cause crash // remove player from group // if only one player there, remove group - // remove player queue info from group queue info std::map::iterator pitr = group->Players.find(guid); if (pitr != group->Players.end()) group->Players.erase(pitr); - // if invited to bg, and should decrease invited count, then do it if (decreaseInvitedCount && group->IsInvitedToBGInstanceGUID) { @@ -311,14 +281,11 @@ void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCou if (bg) bg->DecreaseInvitedCount(group->Team); } - // remove player queue info m_QueuedPlayers.erase(itr); - //if we left BG queue(not porting) OR if arena team left queue for rated match if ((decreaseInvitedCount && !group->ArenaType) || (group->ArenaType && group->IsRated && group->Players.empty())) AnnounceWorld(group, guid, false); - //if player leaves queue and he is invited to rated arena match, then he have to loose if (group->IsInvitedToBGInstanceGUID && group->IsRated && decreaseInvitedCount) { @@ -334,7 +301,6 @@ void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCou at->SaveToDB(); } } - // remove group queue info if needed if (group->Players.empty()) { @@ -363,7 +329,6 @@ void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCou RemovePlayer(group->Players.begin()->first, decreaseInvitedCount); } } - //Announce world message void BattleGroundQueue::AnnounceWorld(GroupQueueInfo *ginfo, const uint64& playerGUID, bool isAddedToQueue) { @@ -374,7 +339,6 @@ void BattleGroundQueue::AnnounceWorld(GroupQueueInfo *ginfo, const uint64& playe BattleGround* bg = sBattleGroundMgr.GetBattleGroundTemplate(ginfo->BgTypeId); if (!bg) return; - char const* bgName = bg->GetName(); if (isAddedToQueue) { @@ -406,7 +370,6 @@ void BattleGroundQueue::AnnounceWorld(GroupQueueInfo *ginfo, const uint64& playe BattleGround* bg = sBattleGroundMgr.GetBattleGroundTemplate(ginfo->BgTypeId); if (!bg || !plr) return; - BGQueueIdBasedOnLevel queue_id = plr->GetBattleGroundQueueIdFromLevel(bg->GetTypeID()); char const* bgName = bg->GetName(); uint32 MinPlayers = bg->GetMinPlayersPerTeam(); @@ -421,7 +384,6 @@ void BattleGroundQueue::AnnounceWorld(GroupQueueInfo *ginfo, const uint64& playe for(itr = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_HORDE].begin(); itr != m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_HORDE].end(); ++itr) if (!(*itr)->IsInvitedToBGInstanceGUID) qHorde += (*itr)->Players.size(); - // Show queue status to player only (when joining queue) if (sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY)) { @@ -437,13 +399,11 @@ void BattleGroundQueue::AnnounceWorld(GroupQueueInfo *ginfo, const uint64& playe } } } - bool BattleGroundQueue::InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * bg, uint32 side) { // set side if needed if (side) ginfo->Team = side; - if (!ginfo->IsInvitedToBGInstanceGUID) { // not yet invited @@ -452,13 +412,10 @@ bool BattleGroundQueue::InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * b BattleGroundTypeId bgTypeId = bg->GetTypeID(); BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, bg->GetArenaType()); BGQueueIdBasedOnLevel queue_id = bg->GetQueueId(); - // set ArenaTeamId for rated matches if (bg->isArena() && bg->isRated()) bg->SetArenaTeamIdForTeam(ginfo->Team, ginfo->ArenaTeamId); - ginfo->RemoveInviteTime = getMSTime() + INVITE_ACCEPT_WAIT_TIME; - // loop through the players for(std::map::iterator itr = ginfo->Players.begin(); itr != ginfo->Players.end(); ++itr) { @@ -467,39 +424,29 @@ bool BattleGroundQueue::InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * b // if offline, skip him, this should not happen - player is removed from queue when he logs out if (!plr) continue; - // invite the player PlayerInvitedToBGUpdateAverageWaitTime(ginfo, queue_id); //sBattleGroundMgr.InvitePlayer(plr, bg, ginfo->Team); - // set invited player counters bg->IncreaseInvitedCount(ginfo->Team); - plr->SetInviteForBattleGroundQueueType(bgQueueTypeId, ginfo->IsInvitedToBGInstanceGUID); - // create remind invite events BGQueueInviteEvent* inviteEvent = new BGQueueInviteEvent(plr->GetGUID(), ginfo->IsInvitedToBGInstanceGUID, bgTypeId, ginfo->RemoveInviteTime); plr->m_Events.AddEvent(inviteEvent, plr->m_Events.CalculateTime(INVITATION_REMIND_TIME)); // create automatic remove events BGQueueRemoveEvent* removeEvent = new BGQueueRemoveEvent(plr->GetGUID(), ginfo->IsInvitedToBGInstanceGUID, bgTypeId, bgQueueTypeId, ginfo->RemoveInviteTime); plr->m_Events.AddEvent(removeEvent, plr->m_Events.CalculateTime(INVITE_ACCEPT_WAIT_TIME)); - WorldPacket data; - uint32 queueSlot = plr->GetBattleGroundQueueIndex(bgQueueTypeId); - sLog.outDebug("Battleground: invited plr %s (%u) to BG instance %u queueindex %u bgtype %u, I can't help it if they don't press the enter battle button.",plr->GetName(),plr->GetGUIDLow(),bg->GetInstanceID(),queueSlot,bg->GetTypeID()); - // send status packet sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME, 0, ginfo->ArenaType); plr->GetSession()->SendPacket(&data); } return true; } - return false; } - /* This function is inviting players to already running battlegrounds Invitation type is based on config file @@ -509,7 +456,6 @@ void BattleGroundQueue::FillPlayersToBG(BattleGround* bg, BGQueueIdBasedOnLevel { int32 hordeFree = bg->GetFreeSlotsForTeam(HORDE); int32 aliFree = bg->GetFreeSlotsForTeam(ALLIANCE); - //iterator for iterating through bg queue GroupsQueueType::const_iterator Ali_itr = m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE].begin(); //count of groups in queue - used to stop cycles @@ -524,11 +470,9 @@ void BattleGroundQueue::FillPlayersToBG(BattleGround* bg, BGQueueIdBasedOnLevel uint32 hordeIndex = 0; for (; hordeIndex < hordeCount && m_SelectionPools[BG_TEAM_HORDE].AddGroup((*Horde_itr), hordeFree); hordeIndex++) ++Horde_itr; - //if ofc like BG queue invitation is set in config, then we are happy if (sWorld.getConfig(CONFIG_BATTLEGROUND_INVITATION_TYPE) == 0) return; - /* if we reached this code, then we have to solve NP - complete problem called Subset sum problem So one solution is to check all possible invitation subgroups, or we can use these conditions: @@ -536,7 +480,6 @@ void BattleGroundQueue::FillPlayersToBG(BattleGround* bg, BGQueueIdBasedOnLevel that we will invite now whole queue, because only 1 change has been made to queues from the last BattleGroundQueue::Update call 2. Other thing we should consider is group order in queue */ - // At first we need to compare free space in bg and our selection pool int32 diffAli = aliFree - int32(m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount()); int32 diffHorde = hordeFree - int32(m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount()); @@ -579,7 +522,6 @@ void BattleGroundQueue::FillPlayersToBG(BattleGround* bg, BGQueueIdBasedOnLevel diffHorde = hordeFree - int32(m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount()); } } - // this method checks if premade versus premade battleground is possible // then after 30 mins (default) in queue it moves premade group to normal queue // it tries to invite as much players as it can - to MaxPlayersPerTeam, because premade groups have more than MinPlayersPerTeam players @@ -597,7 +539,6 @@ bool BattleGroundQueue::CheckPremadeMatch(BGQueueIdBasedOnLevel queue_id, uint32 for( horde_group = m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].begin(); horde_group != m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].end(); ++horde_group) if (!(*horde_group)->IsInvitedToBGInstanceGUID) break; - if (ali_group != m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].end() && horde_group != m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].end()) { m_SelectionPools[BG_TEAM_ALLIANCE].AddGroup((*ali_group), MaxPlayersPerTeam); @@ -639,7 +580,6 @@ bool BattleGroundQueue::CheckPremadeMatch(BGQueueIdBasedOnLevel queue_id, uint32 //selection pools are not set return false; } - // this method tries to create battleground or arena with MinPlayersPerTeam against MinPlayersPerTeam bool BattleGroundQueue::CheckNormalMatch(BattleGround* bg_template, BGQueueIdBasedOnLevel queue_id, uint32 minPlayers, uint32 maxPlayers) { @@ -682,7 +622,6 @@ bool BattleGroundQueue::CheckNormalMatch(BattleGround* bg_template, BGQueueIdBas //return true if there are enough players in selection pools - enable to work .debug bg command correctly return m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount() >= minPlayers && m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount() >= minPlayers; } - // this method will check if we can invite players to same faction skirmish match bool BattleGroundQueue::CheckSkirmishForSameFaction(BGQueueIdBasedOnLevel queue_id, uint32 minPlayersPerTeam) { @@ -719,7 +658,6 @@ bool BattleGroundQueue::CheckSkirmishForSameFaction(BGQueueIdBasedOnLevel queue_ } if (m_SelectionPools[otherTeam].GetPlayerCount() != minPlayersPerTeam) return false; - //here we have correct 2 selections and we need to change one teams team and move selection pool teams to other team's queue for(GroupsQueueType::iterator itr = m_SelectionPools[otherTeam].SelectedGroups.begin(); itr != m_SelectionPools[otherTeam].SelectedGroups.end(); ++itr) { @@ -741,7 +679,6 @@ bool BattleGroundQueue::CheckSkirmishForSameFaction(BGQueueIdBasedOnLevel queue_ } return true; } - /* this method is called when group is inserted, or player / group is removed from BG Queue - there is only one player's status changed, so we don't use while(true) cycles to invite whole queue it must be called after fully adding the members of a group to ensure group joining @@ -755,7 +692,6 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_ALLIANCE].empty() && m_QueuedGroups[queue_id][BG_QUEUE_NORMAL_HORDE].empty() ) return; - //battleground with free slot for player should be always in the beggining of the queue // maybe it would be better to create bgfreeslotqueue for each queue_id_based_on_level BGFreeSlotQueueType::iterator itr, next; @@ -769,20 +705,16 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve { BattleGround* bg = *itr; //we have to store battleground pointer here, because when battleground is full, it is removed from free queue (not yet implemented!!) // and iterator is invalid - // clear selection pools m_SelectionPools[BG_TEAM_ALLIANCE].Init(); m_SelectionPools[BG_TEAM_HORDE].Init(); - // call a function that does the job for us FillPlayersToBG(bg, queue_id); - // now everything is set, invite players for(GroupsQueueType::const_iterator citr = m_SelectionPools[BG_TEAM_ALLIANCE].SelectedGroups.begin(); citr != m_SelectionPools[BG_TEAM_ALLIANCE].SelectedGroups.end(); ++citr) InviteGroupToBG((*citr), bg, (*citr)->Team); for(GroupsQueueType::const_iterator citr = m_SelectionPools[BG_TEAM_HORDE].SelectedGroups.begin(); citr != m_SelectionPools[BG_TEAM_HORDE].SelectedGroups.end(); ++citr) InviteGroupToBG((*citr), bg, (*citr)->Team); - if (!bg->HasFreeSlots()) { // remove BG from BGFreeSlotQueue @@ -790,9 +722,7 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve } } } - // finished iterating through the bgs with free slots, maybe we need to create a new bg - BattleGround * bg_template = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId); if (!bg_template) { @@ -833,10 +763,8 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve }*/ } } - m_SelectionPools[BG_TEAM_ALLIANCE].Init(); m_SelectionPools[BG_TEAM_HORDE].Init(); - if (bg_template->isBattleGround()) { //check if there is premade against premade match @@ -860,7 +788,6 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve m_SelectionPools[BG_TEAM_HORDE].Init(); } } - // now check if there are in queues enough players to start new game of (normal battleground, or non-rated arena) if (!isRated) { @@ -875,7 +802,6 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve sLog.outError("BattleGroundQueue::Update - Cannot create battleground: %u", bgTypeId); return; } - // invite those selection pools for(uint32 i = 0; i < BG_TEAMS_COUNT; i++) for(GroupsQueueType::const_iterator citr = m_SelectionPools[BG_TEAM_ALLIANCE + i].SelectedGroups.begin(); citr != m_SelectionPools[BG_TEAM_ALLIANCE + i].SelectedGroups.end(); ++citr) @@ -911,7 +837,6 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve else if (!front1 && !front2) return; //queues are empty } - //set rating range uint32 arenaMinRating = (arenaRating <= sBattleGroundMgr.GetMaxRatingDifference()) ? 0 : arenaRating - sBattleGroundMgr.GetMaxRatingDifference(); uint32 arenaMaxRating = arenaRating + sBattleGroundMgr.GetMaxRatingDifference(); @@ -920,13 +845,9 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve // the discard time is current_time - time_to_discard, teams that joined after that, will have their ratings taken into account // else leave the discard time on 0, this way all ratings will be discarded uint32 discardTime = getMSTime() - sBattleGroundMgr.GetRatingDiscardTimer(); - // we need to find 2 teams which will play next game - GroupsQueueType::iterator itr_team[BG_TEAMS_COUNT]; - //optimalization : --- we dont need to use selection_pools - each update we select max 2 groups - for(uint32 i = BG_QUEUE_PREMADE_ALLIANCE; i < BG_QUEUE_NORMAL_ALLIANCE; i++) { // take the group that joined first @@ -979,7 +900,6 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve } } } - //if we have 2 teams, then start new arena and invite players! if (m_SelectionPools[BG_TEAM_ALLIANCE].GetPlayerCount() && m_SelectionPools[BG_TEAM_HORDE].GetPlayerCount()) { @@ -989,7 +909,6 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve sLog.outError("BattlegroundQueue::Update couldn't create arena instance for rated arena match!"); return; } - (*(itr_team[BG_TEAM_ALLIANCE]))->OpponentsTeamRating = (*(itr_team[BG_TEAM_HORDE]))->ArenaTeamRating; sLog.outDebug("setting oposite teamrating for team %u to %u", (*(itr_team[BG_TEAM_ALLIANCE]))->ArenaTeamId, (*(itr_team[BG_TEAM_ALLIANCE]))->OpponentsTeamRating); (*(itr_team[BG_TEAM_HORDE]))->OpponentsTeamRating = (*(itr_team[BG_TEAM_ALLIANCE]))->ArenaTeamRating; @@ -1009,33 +928,26 @@ void BattleGroundQueue::Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLeve m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_ALLIANCE].erase(itr_team[BG_TEAM_HORDE]); itr_team[BG_TEAM_HORDE] = m_QueuedGroups[queue_id][BG_QUEUE_PREMADE_HORDE].begin(); } - InviteGroupToBG(*(itr_team[BG_TEAM_ALLIANCE]), arena, ALLIANCE); InviteGroupToBG(*(itr_team[BG_TEAM_HORDE]), arena, HORDE); - sLog.outDebug("Starting rated arena match!"); - arena->StartBattleGround(); } } } - /*********************************************************/ /*** BATTLEGROUND QUEUE EVENTS ***/ /*********************************************************/ - bool BGQueueInviteEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) { Player* plr = objmgr.GetPlayer( m_PlayerGuid ); // player logged off (we should do nothing, he is correctly removed from queue in another procedure) if (!plr) return true; - BattleGround* bg = sBattleGroundMgr.GetBattleGround(m_BgInstanceGUID, m_BgTypeId); //if battleground ended and its instance deleted - do nothing if (!bg) return true; - BattleGroundQueueTypeId bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType()); uint32 queueSlot = plr->GetBattleGroundQueueIndex(bgQueueTypeId); if( queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES ) // player is in queue or in battleground @@ -1054,12 +966,10 @@ bool BGQueueInviteEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) } return true; //event will be deleted } - void BGQueueInviteEvent::Abort(uint64 /*e_time*/) { //do nothing } - /* this event has many possibilities when it is executed: 1. player is in battleground ( he clicked enter on invitation window ) @@ -1075,11 +985,9 @@ bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) if (!plr) // player logged off (we should do nothing, he is correctly removed from queue in another procedure) return true; - BattleGround* bg = sBattleGroundMgr.GetBattleGround(m_BgInstanceGUID, m_BgTypeId); //battleground can be deleted already when we are removing queue info //bg pointer can be NULL! so use it carefully! - uint32 queueSlot = plr->GetBattleGroundQueueIndex(m_BgQueueTypeId); if( queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES ) // player is in queue, or in Battleground { @@ -1091,32 +999,26 @@ bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) && qMapItr->second.GroupInfo->RemoveInviteTime == m_RemoveTime ) { sLog.outDebug("Battleground: removing player %u from bg queue for instance %u because of not pressing enter battle in time.",plr->GetGUIDLow(),m_BgInstanceGUID); - plr->RemoveBattleGroundQueueId(m_BgQueueTypeId); sBattleGroundMgr.m_BattleGroundQueues[m_BgQueueTypeId].RemovePlayer(m_PlayerGuid, true); //update queues if battleground isn't ended if (bg) sBattleGroundMgr.ScheduleQueueUpdate(m_BgQueueTypeId, m_BgTypeId, bg->GetQueueId()); - WorldPacket data; sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0); plr->GetSession()->SendPacket(&data); } } - //event will be deleted return true; } - void BGQueueRemoveEvent::Abort(uint64 /*e_time*/) { //do nothing } - /*********************************************************/ /*** BATTLEGROUND MANAGER ***/ /*********************************************************/ - BattleGroundMgr::BattleGroundMgr() : m_AutoDistributionTimeChecker(0), m_ArenaTesting(false) { for(uint32 i = BATTLEGROUND_TYPE_NONE; i < MAX_BATTLEGROUND_TYPE_ID; i++) @@ -1124,12 +1026,10 @@ BattleGroundMgr::BattleGroundMgr() : m_AutoDistributionTimeChecker(0), m_ArenaTe m_NextRatingDiscardUpdate = sWorld.getConfig(CONFIG_ARENA_RATING_DISCARD_TIMER); m_Testing=false; } - BattleGroundMgr::~BattleGroundMgr() { DeleteAllBattleGrounds(); } - void BattleGroundMgr::DeleteAllBattleGrounds() { for(uint32 i = BATTLEGROUND_TYPE_NONE; i < MAX_BATTLEGROUND_TYPE_ID; i++) @@ -1143,7 +1043,6 @@ void BattleGroundMgr::DeleteAllBattleGrounds() delete bg; } } - // destroy template battlegrounds that listed only in queues (other already terminated) for(uint32 bgTypeId = 0; bgTypeId < MAX_BATTLEGROUND_TYPE_ID; ++bgTypeId) { @@ -1152,7 +1051,6 @@ void BattleGroundMgr::DeleteAllBattleGrounds() delete BGFreeSlotQueue[bgTypeId].front(); } } - // used to update running battlegrounds, and delete finished ones void BattleGroundMgr::Update(uint32 diff) { @@ -1180,7 +1078,6 @@ void BattleGroundMgr::Update(uint32 diff) } } } - // update scheduled queues if (!m_QueueUpdateScheduler.empty()) { @@ -1198,7 +1095,6 @@ void BattleGroundMgr::Update(uint32 diff) m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, queue_id); } } - // if rating difference counts, maybe force-update queues if (sWorld.getConfig(CONFIG_ARENA_MAX_RATING_DIFFERENCE) && sWorld.getConfig(CONFIG_ARENA_RATING_DISCARD_TIMER)) { @@ -1234,11 +1130,9 @@ void BattleGroundMgr::Update(uint32 diff) m_AutoDistributionTimeChecker -= diff; } } - void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGround *bg, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2, uint8 arenatype) { // we can be in 3 queues in same time... - if (StatusID == 0 || !bg) { data->Initialize(SMSG_BATTLEFIELD_STATUS, 4*3); @@ -1246,7 +1140,6 @@ void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGro *data << uint64(0); return; } - data->Initialize(SMSG_BATTLEFIELD_STATUS, (4+1+1+4+2+4+1+4+4+4)); *data << uint32(QueueSlot); // queue id (0...2) - player can be in 3 queues in time // uint64 in client @@ -1295,15 +1188,12 @@ void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGro *data << uint8(0); break; } - if (bg->isArena() && (StatusID == STATUS_WAIT_QUEUE)) *data << uint32(BATTLEGROUND_AA); // all arenas I don't think so. else *data << uint32(bg->GetTypeID()); // BG id from DBC - *data << uint16(0x1F90); // unk value 8080 *data << uint32(bg->GetInstanceID()); // instance id - *data << uint8(bg->isArena()); // minimap-icon 0=faction 1=arena */ *data << uint32(StatusID); // status @@ -1328,14 +1218,12 @@ void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGro break; } } - void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg) { uint8 type = (bg->isArena() ? 1 : 0); // last check on 3.0.3 data->Initialize(MSG_PVP_LOG_DATA, (1+1+4+40*bg->GetPlayerScoresSize())); *data << uint8(type); // type (battleground=0/arena=1) - if(type) // arena { // it seems this must be according to BG_WINNER_A/H and _NOT_ BG_TEAM_A/H @@ -1356,7 +1244,6 @@ void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg) *data << (uint8)0; } } - if (bg->GetStatus() != STATUS_WAIT_LEAVE) { *data << uint8(0); // bg not ended @@ -1366,9 +1253,7 @@ void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg) *data << uint8(1); // bg ended *data << uint8(bg->GetWinner()); // who win } - *data << (int32)(bg->GetPlayerScoresSize()); - for(BattleGround::BattleGroundScoreMap::const_iterator itr = bg->GetPlayerScoresBegin(); itr != bg->GetPlayerScoresEnd(); ++itr) { *data << (uint64)itr->first; @@ -1432,7 +1317,6 @@ void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg) } } } - void BattleGroundMgr::BuildGroupJoinedBattlegroundPacket(WorldPacket *data, BattleGroundTypeId bgTypeId) { /*bgTypeId is: @@ -1447,32 +1331,27 @@ void BattleGroundMgr::BuildGroupJoinedBattlegroundPacket(WorldPacket *data, Batt data->Initialize(SMSG_GROUP_JOINED_BATTLEGROUND, 4); *data << uint32(bgTypeId); } - void BattleGroundMgr::BuildUpdateWorldStatePacket(WorldPacket *data, uint32 field, uint32 value) { data->Initialize(SMSG_UPDATE_WORLD_STATE, 4+4); *data << uint32(field); *data << uint32(value); } - void BattleGroundMgr::BuildPlaySoundPacket(WorldPacket *data, uint32 soundid) { data->Initialize(SMSG_PLAY_SOUND, 4); *data << uint32(soundid); } - void BattleGroundMgr::BuildPlayerLeftBattleGroundPacket(WorldPacket *data, const uint64& guid) { data->Initialize(SMSG_BATTLEGROUND_PLAYER_LEFT, 8); *data << uint64(guid); } - void BattleGroundMgr::BuildPlayerJoinedBattleGroundPacket(WorldPacket *data, Player *plr) { data->Initialize(SMSG_BATTLEGROUND_PLAYER_JOINED, 8); *data << uint64(plr->GetGUID()); } - BattleGround * BattleGroundMgr::GetBattleGroundThroughClientInstance(uint32 instanceId, BattleGroundTypeId bgTypeId) { //cause at HandleBattleGroundJoinOpcode the clients sends the instanceid he gets from @@ -1480,10 +1359,8 @@ BattleGround * BattleGroundMgr::GetBattleGroundThroughClientInstance(uint32 inst BattleGround* bg = GetBattleGroundTemplate(bgTypeId); if (!bg) return NULL; - if (bg->isArena()) return GetBattleGround(instanceId, bgTypeId); - for(BattleGroundSet::iterator itr = m_BattleGrounds[bgTypeId].begin(); itr != m_BattleGrounds[bgTypeId].end(); ++itr) { if (itr->second->GetClientInstanceID() == instanceId) @@ -1491,7 +1368,6 @@ BattleGround * BattleGroundMgr::GetBattleGroundThroughClientInstance(uint32 inst } return NULL; } - BattleGround * BattleGroundMgr::GetBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId) { if (!InstanceID) @@ -1511,18 +1387,15 @@ BattleGround * BattleGroundMgr::GetBattleGround(uint32 InstanceID, BattleGroundT itr = m_BattleGrounds[bgTypeId].find(InstanceID); return ( (itr != m_BattleGrounds[bgTypeId].end()) ? itr->second : NULL ); } - BattleGround * BattleGroundMgr::GetBattleGroundTemplate(BattleGroundTypeId bgTypeId) { //map is sorted and we can be sure that lowest instance id has only BG template return m_BattleGrounds[bgTypeId].empty() ? NULL : m_BattleGrounds[bgTypeId].begin()->second; } - uint32 BattleGroundMgr::CreateClientVisibleInstanceId(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id) { if (IsArenaType(bgTypeId)) return 0; //arenas don't have client-instanceids - // we create here an instanceid, which is just for // displaying this to the client and without any other use.. // the client-instanceIds are unique for each battleground-type @@ -1539,7 +1412,6 @@ uint32 BattleGroundMgr::CreateClientVisibleInstanceId(BattleGroundTypeId bgTypeI m_ClientBattleGroundIds[bgTypeId][queue_id].insert(lastId + 1); return lastId + 1; } - // create a new battleground that will really be used to play BattleGround * BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id, uint8 arenaType, bool isRated) { @@ -1550,7 +1422,6 @@ BattleGround * BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeI sLog.outError("BattleGround: CreateNewBattleGround - bg template not found for %u", bgTypeId); return NULL; } - //for arenas there is random map used if (bg_template->isArena()) { @@ -1564,7 +1435,6 @@ BattleGround * BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeI return NULL; } } - BattleGround *bg = NULL; // create a copy of the BG template switch(bgTypeId) @@ -1606,23 +1476,18 @@ BattleGround * BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeI //error, but it is handled few lines above return 0; } - // generate a new instance id bg->SetInstanceID(MapManager::Instance().GenerateInstanceId()); // set instance id bg->SetClientInstanceID(CreateClientVisibleInstanceId(bgTypeId, queue_id)); - // reset the new bg (set status to status_wait_queue from status_none) bg->Reset(); - // start the joining of the bg bg->SetStatus(STATUS_WAIT_JOIN); bg->SetQueueId(queue_id); bg->SetArenaType(arenaType); bg->SetRated(isRated); - return bg; } - // used to create the BG templates uint32 BattleGroundMgr::CreateBattleGround(BattleGroundTypeId bgTypeId, bool IsArena, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam, uint32 LevelMin, uint32 LevelMax, char* BattleGroundName, uint32 MapID, float Team1StartLocX, float Team1StartLocY, float Team1StartLocZ, float Team1StartLocO, float Team2StartLocX, float Team2StartLocY, float Team2StartLocZ, float Team2StartLocO) { @@ -1643,7 +1508,6 @@ uint32 BattleGroundMgr::CreateBattleGround(BattleGroundTypeId bgTypeId, bool IsA case BATTLEGROUND_RV: bg = new BattleGroundRV; break; default:bg = new BattleGround; break; // placeholder for non implemented BG } - bg->SetMapId(MapID); bg->SetTypeID(bgTypeId); bg->SetInstanceID(0); @@ -1656,14 +1520,11 @@ uint32 BattleGroundMgr::CreateBattleGround(BattleGroundTypeId bgTypeId, bool IsA bg->SetTeamStartLoc(ALLIANCE, Team1StartLocX, Team1StartLocY, Team1StartLocZ, Team1StartLocO); bg->SetTeamStartLoc(HORDE, Team2StartLocX, Team2StartLocY, Team2StartLocZ, Team2StartLocO); bg->SetLevelRange(LevelMin, LevelMax); - // add bg to update list AddBattleGround(bg->GetInstanceID(), bg->GetTypeID(), bg); - // return some not-null value, bgTypeId is good enough for me return bgTypeId; } - void BattleGroundMgr::CreateInitialBattleGrounds() { float AStartLoc[4]; @@ -1672,32 +1533,23 @@ void BattleGroundMgr::CreateInitialBattleGrounds() BattlemasterListEntry const *bl; WorldSafeLocsEntry const *start; bool IsArena; - uint32 count = 0; - // 0 1 2 3 4 5 6 7 8 QueryResult *result = WorldDatabase.Query("SELECT id, MinPlayersPerTeam,MaxPlayersPerTeam,MinLvl,MaxLvl,AllianceStartLoc,AllianceStartO,HordeStartLoc,HordeStartO FROM battleground_template"); - if (!result) { barGoLink bar(1); - bar.step(); - sLog.outString(); sLog.outErrorDb(">> Loaded 0 battlegrounds. DB table `battleground_template` is empty."); return; } - barGoLink bar(result->GetRowCount()); - do { Field *fields = result->Fetch(); bar.step(); - uint32 bgTypeID_ = fields[0].GetUInt32(); - // can be overwrite by values from DB bl = sBattlemasterListStore.LookupEntry(bgTypeID_); if (!bl) @@ -1705,9 +1557,7 @@ void BattleGroundMgr::CreateInitialBattleGrounds() sLog.outError("Battleground ID %u not found in BattlemasterList.dbc. Battleground not created.", bgTypeID_); continue; } - BattleGroundTypeId bgTypeID = BattleGroundTypeId(bgTypeID_); - IsArena = (bl->type == TYPE_ARENA); MinPlayersPerTeam = fields[1].GetUInt32(); MaxPlayersPerTeam = fields[2].GetUInt32(); @@ -1724,9 +1574,7 @@ void BattleGroundMgr::CreateInitialBattleGrounds() MinLvl = bl->minlvl; MaxLvl = bl->maxlvl; } - start1 = fields[5].GetUInt32(); - start = sWorldSafeLocsStore.LookupEntry(start1); if (start) { @@ -1747,9 +1595,7 @@ void BattleGroundMgr::CreateInitialBattleGrounds() sLog.outErrorDb("Table `battleground_template` for id %u have non-existed WorldSafeLocs.dbc id %u in field `AllianceStartLoc`. BG not created.", bgTypeID, start1); continue; } - start2 = fields[7].GetUInt32(); - start = sWorldSafeLocsStore.LookupEntry(start2); if (start) { @@ -1770,20 +1616,15 @@ void BattleGroundMgr::CreateInitialBattleGrounds() sLog.outErrorDb("Table `battleground_template` for id %u have non-existed WorldSafeLocs.dbc id %u in field `HordeStartLoc`. BG not created.", bgTypeID, start2); continue; } - //sLog.outDetail("Creating battleground %s, %u-%u", bl->name[sWorld.GetDBClang()], MinLvl, MaxLvl); if (!CreateBattleGround(bgTypeID, IsArena, MinPlayersPerTeam, MaxPlayersPerTeam, MinLvl, MaxLvl, bl->name[sWorld.GetDefaultDbcLocale()], bl->mapid[0], AStartLoc[0], AStartLoc[1], AStartLoc[2], AStartLoc[3], HStartLoc[0], HStartLoc[1], HStartLoc[2], HStartLoc[3])) continue; - ++count; } while (result->NextRow()); - delete result; - sLog.outString(); sLog.outString( ">> Loaded %u battlegrounds", count ); } - void BattleGroundMgr::InitAutomaticArenaPointDistribution() { if (sWorld.getConfig(CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS)) @@ -1804,22 +1645,17 @@ void BattleGroundMgr::InitAutomaticArenaPointDistribution() sLog.outDebug("Automatic Arena Point Distribution initialized."); } } - void BattleGroundMgr::DistributeArenaPoints() { // used to distribute arena points based on last week's stats sWorld.SendWorldText(LANG_DIST_ARENA_POINTS_START); - sWorld.SendWorldText(LANG_DIST_ARENA_POINTS_ONLINE_START); - //temporary structure for storing maximum points to add values for all players std::map PlayerPoints; - //at first update all points for all team members for(ObjectMgr::ArenaTeamMap::iterator team_itr = objmgr.GetArenaTeamMapBegin(); team_itr != objmgr.GetArenaTeamMapEnd(); ++team_itr) if (ArenaTeam * at = team_itr->second) at->UpdateArenaPointsHelper(PlayerPoints); - //cycle that gives points to all players for (std::map::iterator plr_itr = PlayerPoints.begin(); plr_itr != PlayerPoints.end(); ++plr_itr) { @@ -1837,11 +1673,8 @@ void BattleGroundMgr::DistributeArenaPoints() std::min(int32(plr_itr->second),int32(sWorld.getConfig(CONFIG_MAX_ARENA_POINTS)))); } } - PlayerPoints.clear(); - sWorld.SendWorldText(LANG_DIST_ARENA_POINTS_ONLINE_END); - sWorld.SendWorldText(LANG_DIST_ARENA_POINTS_TEAM_START); for(ObjectMgr::ArenaTeamMap::iterator titr = objmgr.GetArenaTeamMapBegin(); titr != objmgr.GetArenaTeamMapEnd(); ++titr) { @@ -1852,20 +1685,15 @@ void BattleGroundMgr::DistributeArenaPoints() at->NotifyStatsChanged(); // notify the players of the changes } } - sWorld.SendWorldText(LANG_DIST_ARENA_POINTS_TEAM_END); - sWorld.SendWorldText(LANG_DIST_ARENA_POINTS_END); } - void BattleGroundMgr::BuildBattleGroundListPacket(WorldPacket *data, const uint64& guid, Player* plr, BattleGroundTypeId bgTypeId, uint8 fromWhere) { if (!plr) return; - uint32 PlayerLevel = 10; PlayerLevel = plr->getLevel(); - data->Initialize(SMSG_BATTLEFIELD_LIST); *data << uint64(guid); // battlemaster guid *data << uint8(fromWhere); // from where you joined @@ -1878,11 +1706,9 @@ void BattleGroundMgr::BuildBattleGroundListPacket(WorldPacket *data, const uint6 else // battleground { *data << uint8(0x00); // unk, different for each bg type - size_t count_pos = data->wpos(); uint32 count = 0; *data << uint32(0x00); // number of bg instances - uint32 queue_id = plr->GetBattleGroundQueueIdFromLevel(bgTypeId); for(std::set::iterator itr = m_ClientBattleGroundIds[bgTypeId][queue_id].begin(); itr != m_ClientBattleGroundIds[bgTypeId][queue_id].end();++itr) { @@ -1892,7 +1718,6 @@ void BattleGroundMgr::BuildBattleGroundListPacket(WorldPacket *data, const uint6 data->put( count_pos , count); } } - void BattleGroundMgr::SendToBattleGround(Player *pl, uint32 instanceId, BattleGroundTypeId bgTypeId) { BattleGround *bg = GetBattleGround(instanceId, bgTypeId); @@ -1904,7 +1729,6 @@ void BattleGroundMgr::SendToBattleGround(Player *pl, uint32 instanceId, BattleGr if (team==0) team = pl->GetTeam(); bg->GetTeamStartLoc(team, x, y, z, O); - sLog.outDetail("BATTLEGROUND: Sending %s to map %u, X %f, Y %f, Z %f, O %f", pl->GetName(), mapid, x, y, z, O); pl->TeleportTo(mapid, x, y, z, O); } @@ -1913,7 +1737,6 @@ void BattleGroundMgr::SendToBattleGround(Player *pl, uint32 instanceId, BattleGr sLog.outError("player %u trying to port to non-existent bg instance %u",pl->GetGUIDLow(), instanceId); } } - void BattleGroundMgr::SendAreaSpiritHealerQueryOpcode(Player *pl, BattleGround *bg, const uint64& guid) { WorldPacket data(SMSG_AREA_SPIRIT_HEALER_TIME, 12); @@ -1923,7 +1746,6 @@ void BattleGroundMgr::SendAreaSpiritHealerQueryOpcode(Player *pl, BattleGround * data << guid << time_; pl->GetSession()->SendPacket(&data); } - bool BattleGroundMgr::IsArenaType(BattleGroundTypeId bgTypeId) { return ( bgTypeId == BATTLEGROUND_AA || @@ -1931,7 +1753,6 @@ bool BattleGroundMgr::IsArenaType(BattleGroundTypeId bgTypeId) bgTypeId == BATTLEGROUND_NA || bgTypeId == BATTLEGROUND_RL ); } - BattleGroundQueueTypeId BattleGroundMgr::BGQueueTypeId(BattleGroundTypeId bgTypeId, uint8 arenaType) { switch(bgTypeId) @@ -1967,7 +1788,6 @@ BattleGroundQueueTypeId BattleGroundMgr::BGQueueTypeId(BattleGroundTypeId bgType return BATTLEGROUND_QUEUE_NONE; } } - BattleGroundTypeId BattleGroundMgr::BGTemplateId(BattleGroundQueueTypeId bgQueueTypeId) { switch(bgQueueTypeId) @@ -1990,7 +1810,6 @@ BattleGroundTypeId BattleGroundMgr::BGTemplateId(BattleGroundQueueTypeId bgQueue return BattleGroundTypeId(0); // used for unknown template (it existed and do nothing) } } - uint8 BattleGroundMgr::BGArenaType(BattleGroundQueueTypeId bgQueueTypeId) { switch(bgQueueTypeId) @@ -2005,7 +1824,6 @@ uint8 BattleGroundMgr::BGArenaType(BattleGroundQueueTypeId bgQueueTypeId) return 0; } } - void BattleGroundMgr::ToggleTesting() { m_Testing = !m_Testing; @@ -2014,7 +1832,6 @@ void BattleGroundMgr::ToggleTesting() else sWorld.SendWorldText(LANG_DEBUG_BG_OFF); } - void BattleGroundMgr::ToggleArenaTesting() { m_ArenaTesting = !m_ArenaTesting; @@ -2023,7 +1840,6 @@ void BattleGroundMgr::ToggleArenaTesting() else sWorld.SendWorldText(LANG_DEBUG_ARENA_OFF); } - void BattleGroundMgr::SetHolidayWeekends(uint32 mask) { for(uint32 bgtype = 1; bgtype < MAX_BATTLEGROUND_TYPE_ID; ++bgtype) @@ -2034,7 +1850,6 @@ void BattleGroundMgr::SetHolidayWeekends(uint32 mask) } } } - void BattleGroundMgr::ScheduleQueueUpdate(BattleGroundQueueTypeId bgQueueTypeId, BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id) { //This method must be atomic, TODO add mutex @@ -2052,7 +1867,6 @@ void BattleGroundMgr::ScheduleQueueUpdate(BattleGroundQueueTypeId bgQueueTypeId, if (!found) m_QueueUpdateScheduler.push_back(schedule_id); } - uint32 BattleGroundMgr::GetMaxRatingDifference() const { // this is for stupid people who can't use brain and set max rating difference to 0 @@ -2061,44 +1875,33 @@ uint32 BattleGroundMgr::GetMaxRatingDifference() const diff = 5000; return diff; } - uint32 BattleGroundMgr::GetRatingDiscardTimer() const { return sWorld.getConfig(CONFIG_ARENA_RATING_DISCARD_TIMER); } - uint32 BattleGroundMgr::GetPrematureFinishTime() const { return sWorld.getConfig(CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER); } - void BattleGroundMgr::LoadBattleMastersEntry() { mBattleMastersMap.clear(); // need for reload case - QueryResult *result = WorldDatabase.Query( "SELECT entry,bg_template FROM battlemaster_entry" ); - uint32 count = 0; - if (!result) { barGoLink bar( 1 ); bar.step(); - sLog.outString(); sLog.outString( ">> Loaded 0 battlemaster entries - table is empty!" ); return; } - barGoLink bar( result->GetRowCount() ); - do { ++count; bar.step(); - Field *fields = result->Fetch(); - uint32 entry = fields[0].GetUInt32(); uint32 bgTypeId = fields[1].GetUInt32(); if (!sBattlemasterListStore.LookupEntry(bgTypeId)) @@ -2106,13 +1909,9 @@ void BattleGroundMgr::LoadBattleMastersEntry() sLog.outErrorDb("Table `battlemaster_entry` contain entry %u for not existed battleground type %u, ignored.",entry,bgTypeId); continue; } - mBattleMastersMap[entry] = BattleGroundTypeId(bgTypeId); - } while( result->NextRow() ); - delete result; - sLog.outString(); sLog.outString( ">> Loaded %u battlemaster entries", count ); } diff --git a/src/game/BattleGroundMgr.h b/src/game/BattleGroundMgr.h index 9100142ebd0..2de067d3639 100644 --- a/src/game/BattleGroundMgr.h +++ b/src/game/BattleGroundMgr.h @@ -17,32 +17,23 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef __BATTLEGROUNDMGR_H #define __BATTLEGROUNDMGR_H - #include "Common.h" #include "Policies/Singleton.h" - #include "BattleGround.h" - typedef std::map BattleGroundSet; - //this container can't be deque, because deque doesn't like removing the last element - if you remove it, it invalidates next iterator and crash appears typedef std::list BGFreeSlotQueueType; - typedef UNORDERED_MAP BattleMastersMap; - #define BATTLEGROUND_ARENA_POINT_DISTRIBUTION_DAY 86400 // seconds in a day #define COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME 10 - struct GroupQueueInfo; // type predefinition struct PlayerQueueInfo // stores information for players in queue { uint32 LastOnlineTime; // for tracking and removing offline players from queue after 5 minutes GroupQueueInfo * GroupInfo; // pointer to the associated groupqueueinfo }; - struct GroupQueueInfo // stores information about the group in queue (also used when joined as solo!) { std::map Players; // player queue info map @@ -57,7 +48,6 @@ struct GroupQueueInfo // stores informatio uint32 ArenaTeamRating; // if rated match, inited to the rating of the team uint32 OpponentsTeamRating; // for rated arena matches }; - enum BattleGroundQueueGroupTypes { BG_QUEUE_PREMADE_ALLIANCE = 0, @@ -66,16 +56,13 @@ enum BattleGroundQueueGroupTypes BG_QUEUE_NORMAL_HORDE = 3 }; #define BG_QUEUE_GROUP_TYPES_COUNT 4 - class BattleGround; class BattleGroundQueue { public: BattleGroundQueue(); ~BattleGroundQueue(); - void Update(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id, uint8 arenaType = 0, bool isRated = false, uint32 minRating = 0); - void FillPlayersToBG(BattleGround* bg, BGQueueIdBasedOnLevel queue_id); bool CheckPremadeMatch(BGQueueIdBasedOnLevel queue_id, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam); bool CheckNormalMatch(BattleGround* bg_template, BGQueueIdBasedOnLevel queue_id, uint32 minPlayers, uint32 maxPlayers); @@ -85,16 +72,12 @@ class BattleGroundQueue void RemovePlayer(const uint64& guid, bool decreaseInvitedCount); void PlayerInvitedToBGUpdateAverageWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id); uint32 GetAverageQueueWaitTime(GroupQueueInfo* ginfo, BGQueueIdBasedOnLevel queue_id); - void DecreaseGroupLength(uint32 queueId, uint32 AsGroup); void AnnounceWorld(GroupQueueInfo *ginfo, const uint64& playerGUID, bool isAddedToQueue); - typedef std::map QueuedPlayersMap; QueuedPlayersMap m_QueuedPlayers; - //we need constant add to begin and constant remove / add from the end, therefore deque suits our problem well typedef std::list GroupsQueueType; - /* This two dimensional array is used to store All queued groups First dimension specifies the bgTypeId @@ -105,7 +88,6 @@ class BattleGroundQueue BG_QUEUE_NORMAL_HORDE is used for normal (or small) horde groups or non-rated arena matches */ GroupsQueueType m_QueuedGroups[MAX_BATTLEGROUND_QUEUES][BG_QUEUE_GROUP_TYPES_COUNT]; - // class to select and invite groups to bg class SelectionPool { @@ -119,18 +101,14 @@ class BattleGroundQueue private: uint32 PlayerCount; }; - //one selection pool for horde, other one for alliance SelectionPool m_SelectionPools[BG_TEAMS_COUNT]; - private: - bool InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * bg, uint32 side); uint32 m_WaitTimes[BG_TEAMS_COUNT][MAX_BATTLEGROUND_QUEUES][COUNT_OF_PLAYERS_TO_AVERAGE_WAIT_TIME]; uint32 m_WaitTimeLastPlayer[BG_TEAMS_COUNT][MAX_BATTLEGROUND_QUEUES]; uint32 m_SumOfWaitTimes[BG_TEAMS_COUNT][MAX_BATTLEGROUND_QUEUES]; }; - /* This class is used to invite player to BG again, when minute lasts from his first invitation it is capable to solve all possibilities @@ -143,7 +121,6 @@ class BGQueueInviteEvent : public BasicEvent { }; virtual ~BGQueueInviteEvent() {}; - virtual bool Execute(uint64 e_time, uint32 p_time); virtual void Abort(uint64 e_time); private: @@ -152,7 +129,6 @@ class BGQueueInviteEvent : public BasicEvent BattleGroundTypeId m_BgTypeId; uint32 m_RemoveTime; }; - /* This class is used to remove player from BG queue after 1 minute 20 seconds from first invitation We must store removeInvite time in case player left queue and joined and is invited again @@ -164,9 +140,7 @@ class BGQueueRemoveEvent : public BasicEvent BGQueueRemoveEvent(const uint64& pl_guid, uint32 bgInstanceGUID, BattleGroundTypeId BgTypeId, BattleGroundQueueTypeId bgQueueTypeId, uint32 removeTime) : m_PlayerGuid(pl_guid), m_BgInstanceGUID(bgInstanceGUID), m_RemoveTime(removeTime), m_BgTypeId(BgTypeId), m_BgQueueTypeId(bgQueueTypeId) {} - virtual ~BGQueueRemoveEvent() {} - virtual bool Execute(uint64 e_time, uint32 p_time); virtual void Abort(uint64 e_time); private: @@ -176,7 +150,6 @@ class BGQueueRemoveEvent : public BasicEvent BattleGroundTypeId m_BgTypeId; BattleGroundQueueTypeId m_BgQueueTypeId; }; - class BattleGroundMgr { public: @@ -184,7 +157,6 @@ class BattleGroundMgr BattleGroundMgr(); ~BattleGroundMgr(); void Update(uint32 diff); - /* Packet Building */ void BuildPlayerJoinedBattleGroundPacket(WorldPacket *data, Player *plr); void BuildPlayerLeftBattleGroundPacket(WorldPacket *data, const uint64& guid); @@ -195,41 +167,30 @@ class BattleGroundMgr void BuildBattleGroundStatusPacket(WorldPacket *data, BattleGround *bg, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2, uint8 arenatype); void BuildPlaySoundPacket(WorldPacket *data, uint32 soundid); void SendAreaSpiritHealerQueryOpcode(Player *pl, BattleGround *bg, const uint64& guid); - /* Battlegrounds */ BattleGround* GetBattleGroundThroughClientInstance(uint32 instanceId, BattleGroundTypeId bgTypeId); BattleGround* GetBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId); //there must be uint32 because MAX_BATTLEGROUND_TYPE_ID means unknown - BattleGround* GetBattleGroundTemplate(BattleGroundTypeId bgTypeId); BattleGround* CreateNewBattleGround(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id, uint8 arenaType, bool isRated); - uint32 CreateBattleGround(BattleGroundTypeId bgTypeId, bool IsArena, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam, uint32 LevelMin, uint32 LevelMax, char* BattleGroundName, uint32 MapID, float Team1StartLocX, float Team1StartLocY, float Team1StartLocZ, float Team1StartLocO, float Team2StartLocX, float Team2StartLocY, float Team2StartLocZ, float Team2StartLocO); - void AddBattleGround(uint32 InstanceID, BattleGroundTypeId bgTypeId, BattleGround* BG) { m_BattleGrounds[bgTypeId][InstanceID] = BG; }; void RemoveBattleGround(uint32 instanceID, BattleGroundTypeId bgTypeId) { m_BattleGrounds[bgTypeId].erase(instanceID); } uint32 CreateClientVisibleInstanceId(BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id); - void CreateInitialBattleGrounds(); void DeleteAllBattleGrounds(); - void SendToBattleGround(Player *pl, uint32 InstanceID, BattleGroundTypeId bgTypeId); - /* Battleground queues */ //these queues are instantiated when creating BattlegroundMrg BattleGroundQueue m_BattleGroundQueues[MAX_BATTLEGROUND_QUEUE_TYPES]; // public, because we need to access them in BG handler code - BGFreeSlotQueueType BGFreeSlotQueue[MAX_BATTLEGROUND_TYPE_ID]; - void ScheduleQueueUpdate(BattleGroundQueueTypeId bgQueueTypeId, BattleGroundTypeId bgTypeId, BGQueueIdBasedOnLevel queue_id); uint32 GetMaxRatingDifference() const; uint32 GetRatingDiscardTimer() const; uint32 GetPrematureFinishTime() const; - void InitAutomaticArenaPointDistribution(); void DistributeArenaPoints(); void ToggleArenaTesting(); void ToggleTesting(); - void SetHolidayWeekends(uint32 mask); void LoadBattleMastersEntry(); BattleGroundTypeId GetBattleMasterBG(uint32 entry) const @@ -239,20 +200,16 @@ class BattleGroundMgr return itr->second; return BATTLEGROUND_WS; } - bool isArenaTesting() const { return m_ArenaTesting; } bool isTesting() const { return m_Testing; } - static bool IsArenaType(BattleGroundTypeId bgTypeId); static bool IsBattleGroundType(BattleGroundTypeId bgTypeId) { return !BattleGroundMgr::IsArenaType(bgTypeId); } static BattleGroundQueueTypeId BGQueueTypeId(BattleGroundTypeId bgTypeId, uint8 arenaType); static BattleGroundTypeId BGTemplateId(BattleGroundQueueTypeId bgQueueTypeId); static uint8 BGArenaType(BattleGroundQueueTypeId bgQueueTypeId); - static bool IsBGWeekend(BattleGroundTypeId bgTypeId); private: BattleMastersMap mBattleMastersMap; - /* Battlegrounds */ BattleGroundSet m_BattleGrounds[MAX_BATTLEGROUND_TYPE_ID]; std::vectorm_QueueUpdateScheduler; @@ -263,7 +220,6 @@ class BattleGroundMgr bool m_ArenaTesting; bool m_Testing; }; - #define sBattleGroundMgr Trinity::Singleton::Instance() #endif diff --git a/src/game/BattleGroundNA.cpp b/src/game/BattleGroundNA.cpp index 92e71c1c283..b9f85117f1a 100644 --- a/src/game/BattleGroundNA.cpp +++ b/src/game/BattleGroundNA.cpp @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "BattleGround.h" #include "BattleGroundNA.h" #include "Language.h" @@ -25,11 +24,9 @@ #include "ObjectMgr.h" #include "Player.h" #include "WorldPacket.h" - BattleGroundNA::BattleGroundNA() { m_BgObjects.resize(BG_NA_OBJECT_MAX); - m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M; m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S; m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S; @@ -40,90 +37,69 @@ BattleGroundNA::BattleGroundNA() m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS; m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN; } - BattleGroundNA::~BattleGroundNA() { - } - void BattleGroundNA::Update(uint32 diff) { BattleGround::Update(diff); - /*if (GetStatus() == STATUS_IN_PROGRESS) { // update something }*/ } - void BattleGroundNA::StartingEventCloseDoors() { for(uint32 i = BG_NA_OBJECT_DOOR_1; i <= BG_NA_OBJECT_DOOR_4; ++i) SpawnBGObject(i, RESPAWN_IMMEDIATELY); } - void BattleGroundNA::StartingEventOpenDoors() { for(uint32 i = BG_NA_OBJECT_DOOR_1; i <= BG_NA_OBJECT_DOOR_2; ++i) DoorOpen(i); - for(uint32 i = BG_NA_OBJECT_BUFF_1; i <= BG_NA_OBJECT_BUFF_2; ++i) SpawnBGObject(i, 60); } - void BattleGroundNA::AddPlayer(Player *plr) { BattleGround::AddPlayer(plr); //create score and add it to map, default values are set in constructor BattleGroundNAScore* sc = new BattleGroundNAScore; - m_PlayerScores[plr->GetGUID()] = sc; - UpdateWorldState(0xa0f, GetAlivePlayersCountByTeam(ALLIANCE)); UpdateWorldState(0xa10, GetAlivePlayersCountByTeam(HORDE)); } - void BattleGroundNA::RemovePlayer(Player* /*plr*/, uint64 /*guid*/) { if (GetStatus() == STATUS_WAIT_LEAVE) return; - UpdateWorldState(0xa0f, GetAlivePlayersCountByTeam(ALLIANCE)); UpdateWorldState(0xa10, GetAlivePlayersCountByTeam(HORDE)); - CheckArenaWinConditions(); } - void BattleGroundNA::HandleKillPlayer(Player *player, Player *killer) { if (GetStatus() != STATUS_IN_PROGRESS) return; - if (!killer) { sLog.outError("BattleGroundNA: Killer player not found"); return; } - BattleGround::HandleKillPlayer(player,killer); - UpdateWorldState(0xa0f, GetAlivePlayersCountByTeam(ALLIANCE)); UpdateWorldState(0xa10, GetAlivePlayersCountByTeam(HORDE)); - CheckArenaWinConditions(); } - bool BattleGroundNA::HandlePlayerUnderMap(Player *player) { player->TeleportTo(GetMapId(),4055.504395,2919.660645,13.611241,player->GetOrientation(),false); return true; } - void BattleGroundNA::HandleAreaTrigger(Player *Source, uint32 Trigger) { if (GetStatus() != STATUS_IN_PROGRESS) return; - //uint32 SpellId = 0; //uint64 buff_guid = 0; switch(Trigger) @@ -136,24 +112,20 @@ void BattleGroundNA::HandleAreaTrigger(Player *Source, uint32 Trigger) Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger); break; } - //if (buff_guid) // HandleTriggerBuff(buff_guid,Source); } - void BattleGroundNA::FillInitialWorldStates(WorldPacket &data) { data << uint32(0xa0f) << uint32(GetAlivePlayersCountByTeam(ALLIANCE)); // 7 data << uint32(0xa10) << uint32(GetAlivePlayersCountByTeam(HORDE)); // 8 data << uint32(0xa11) << uint32(1); // 9 } - void BattleGroundNA::Reset() { //call parent's class reset BattleGround::Reset(); } - bool BattleGroundNA::SetupBattleGround() { // gates @@ -168,10 +140,8 @@ bool BattleGroundNA::SetupBattleGround() sLog.outErrorDb("BatteGroundNA: Failed to spawn some object!"); return false; } - return true; } - /* 20:12:14 id:036668 [S2C] SMSG_INIT_WORLD_STATES (706 = 0x02C2) len: 86 0000: 2f 02 00 00 72 0e 00 00 00 00 00 00 09 00 11 0a | /...r........... diff --git a/src/game/BattleGroundNA.h b/src/game/BattleGroundNA.h index 56e2cf373c4..00d2e554d7e 100644 --- a/src/game/BattleGroundNA.h +++ b/src/game/BattleGroundNA.h @@ -19,9 +19,7 @@ */ #ifndef __BATTLEGROUNDNA_H #define __BATTLEGROUNDNA_H - class BattleGround; - enum BattleGroundNAObjectTypes { BG_NA_OBJECT_DOOR_1 = 0, @@ -32,7 +30,6 @@ enum BattleGroundNAObjectTypes BG_NA_OBJECT_BUFF_2 = 5, BG_NA_OBJECT_MAX = 6 }; - enum BattleGroundNAObjects { BG_NA_OBJECT_TYPE_DOOR_1 = 183978, @@ -42,7 +39,6 @@ enum BattleGroundNAObjects BG_NA_OBJECT_TYPE_BUFF_1 = 184663, BG_NA_OBJECT_TYPE_BUFF_2 = 184664 }; - class BattleGroundNAScore : public BattleGroundScore { public: @@ -50,21 +46,17 @@ class BattleGroundNAScore : public BattleGroundScore virtual ~BattleGroundNAScore() {}; //TODO fix me }; - class BattleGroundNA : public BattleGround { friend class BattleGroundMgr; - public: BattleGroundNA(); ~BattleGroundNA(); void Update(uint32 diff); - /* inherited from BattlegroundClass */ virtual void AddPlayer(Player *plr); virtual void StartingEventCloseDoors(); virtual void StartingEventOpenDoors(); - void RemovePlayer(Player *plr, uint64 guid); void HandleAreaTrigger(Player *Source, uint32 Trigger); bool SetupBattleGround(); diff --git a/src/game/BattleGroundRL.cpp b/src/game/BattleGroundRL.cpp index b9f9943bbf2..c4ca4b1b66f 100644 --- a/src/game/BattleGroundRL.cpp +++ b/src/game/BattleGroundRL.cpp @@ -18,7 +18,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "BattleGround.h" #include "BattleGroundRL.h" #include "Language.h" @@ -26,11 +25,9 @@ #include "ObjectMgr.h" #include "Player.h" #include "WorldPacket.h" - BattleGroundRL::BattleGroundRL() { m_BgObjects.resize(BG_RL_OBJECT_MAX); - m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M; m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S; m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S; @@ -41,91 +38,70 @@ BattleGroundRL::BattleGroundRL() m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS; m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN; } - BattleGroundRL::~BattleGroundRL() { - } - void BattleGroundRL::Update(uint32 diff) { BattleGround::Update(diff); - /*if (GetStatus() == STATUS_IN_PROGRESS) { // update something }*/ } - void BattleGroundRL::StartingEventCloseDoors() { for(uint32 i = BG_RL_OBJECT_DOOR_1; i <= BG_RL_OBJECT_DOOR_2; ++i) SpawnBGObject(i, RESPAWN_IMMEDIATELY); } - void BattleGroundRL::StartingEventOpenDoors() { for(uint32 i = BG_RL_OBJECT_DOOR_1; i <= BG_RL_OBJECT_DOOR_2; ++i) DoorOpen(i); - for(uint32 i = BG_RL_OBJECT_BUFF_1; i <= BG_RL_OBJECT_BUFF_2; ++i) SpawnBGObject(i, 60); } - void BattleGroundRL::AddPlayer(Player *plr) { BattleGround::AddPlayer(plr); //create score and add it to map, default values are set in constructor BattleGroundRLScore* sc = new BattleGroundRLScore; - m_PlayerScores[plr->GetGUID()] = sc; - UpdateWorldState(0xbb8, GetAlivePlayersCountByTeam(ALLIANCE)); UpdateWorldState(0xbb9, GetAlivePlayersCountByTeam(HORDE)); } - void BattleGroundRL::RemovePlayer(Player* /*plr*/, uint64 /*guid*/) { if (GetStatus() == STATUS_WAIT_LEAVE) return; - UpdateWorldState(0xbb8, GetAlivePlayersCountByTeam(ALLIANCE)); UpdateWorldState(0xbb9, GetAlivePlayersCountByTeam(HORDE)); - CheckArenaWinConditions(); } - void BattleGroundRL::HandleKillPlayer(Player *player, Player *killer) { if (GetStatus() != STATUS_IN_PROGRESS) return; - if (!killer) { sLog.outError("Killer player not found"); return; } - BattleGround::HandleKillPlayer(player,killer); - UpdateWorldState(0xbb8, GetAlivePlayersCountByTeam(ALLIANCE)); UpdateWorldState(0xbb9, GetAlivePlayersCountByTeam(HORDE)); - CheckArenaWinConditions(); } - bool BattleGroundRL::HandlePlayerUnderMap(Player *player) { player->TeleportTo(GetMapId(),1285.810547,1667.896851,39.957642,player->GetOrientation(),false); return true; } - void BattleGroundRL::HandleAreaTrigger(Player *Source, uint32 Trigger) { // this is wrong way to implement these things. On official it done by gameobject spell cast. if (GetStatus() != STATUS_IN_PROGRESS) return; - //uint32 SpellId = 0; //uint64 buff_guid = 0; switch(Trigger) @@ -138,24 +114,20 @@ void BattleGroundRL::HandleAreaTrigger(Player *Source, uint32 Trigger) Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger); break; } - //if (buff_guid) // HandleTriggerBuff(buff_guid,Source); } - void BattleGroundRL::FillInitialWorldStates(WorldPacket &data) { data << uint32(0xbb8) << uint32(GetAlivePlayersCountByTeam(ALLIANCE)); // 7 data << uint32(0xbb9) << uint32(GetAlivePlayersCountByTeam(HORDE)); // 8 data << uint32(0xbba) << uint32(1); // 9 } - void BattleGroundRL::Reset() { //call parent's reset BattleGround::Reset(); } - bool BattleGroundRL::SetupBattleGround() { // gates @@ -168,10 +140,8 @@ bool BattleGroundRL::SetupBattleGround() sLog.outErrorDb("BatteGroundRL: Failed to spawn some object!"); return false; } - return true; } - /* Packet S->C, id 600, SMSG_INIT_WORLD_STATES (706), len 86 0000: 3C 02 00 00 80 0F 00 00 00 00 00 00 09 00 BA 0B | <............... diff --git a/src/game/BattleGroundRL.h b/src/game/BattleGroundRL.h index 772c9dd0879..7fb7ef60c2d 100644 --- a/src/game/BattleGroundRL.h +++ b/src/game/BattleGroundRL.h @@ -19,9 +19,7 @@ */ #ifndef __BATTLEGROUNDRL_H #define __BATTLEGROUNDRL_H - class BattleGround; - enum BattleGroundRLObjectTypes { BG_RL_OBJECT_DOOR_1 = 0, @@ -30,7 +28,6 @@ enum BattleGroundRLObjectTypes BG_RL_OBJECT_BUFF_2 = 3, BG_RL_OBJECT_MAX = 4 }; - enum BattleGroundRLObjects { BG_RL_OBJECT_TYPE_DOOR_1 = 185918, @@ -38,7 +35,6 @@ enum BattleGroundRLObjects BG_RL_OBJECT_TYPE_BUFF_1 = 184663, BG_RL_OBJECT_TYPE_BUFF_2 = 184664 }; - class BattleGroundRLScore : public BattleGroundScore { public: @@ -46,23 +42,19 @@ class BattleGroundRLScore : public BattleGroundScore virtual ~BattleGroundRLScore() {}; //TODO fix me }; - class BattleGroundRL : public BattleGround { friend class BattleGroundMgr; - public: BattleGroundRL(); ~BattleGroundRL(); void Update(uint32 diff); - /* inherited from BattlegroundClass */ virtual void AddPlayer(Player *plr); virtual void Reset(); virtual void FillInitialWorldStates(WorldPacket &d); virtual void StartingEventCloseDoors(); virtual void StartingEventOpenDoors(); - void RemovePlayer(Player *plr, uint64 guid); void HandleAreaTrigger(Player *Source, uint32 Trigger); bool SetupBattleGround(); diff --git a/src/game/BattleGroundRV.cpp b/src/game/BattleGroundRV.cpp index 54070961018..a0fc8377eaf 100644 --- a/src/game/BattleGroundRV.cpp +++ b/src/game/BattleGroundRV.cpp @@ -15,15 +15,12 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "BattleGround.h" #include "BattleGroundRV.h" #include "Language.h" #include "Player.h" - BattleGroundRV::BattleGroundRV() { - m_StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M; m_StartDelayTimes[BG_STARTING_EVENT_SECOND] = BG_START_DELAY_30S; m_StartDelayTimes[BG_STARTING_EVENT_THIRD] = BG_START_DELAY_15S; @@ -34,47 +31,36 @@ BattleGroundRV::BattleGroundRV() m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_ARENA_FIFTEEN_SECONDS; m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_ARENA_HAS_BEGUN; } - BattleGroundRV::~BattleGroundRV() { - } - void BattleGroundRV::Update(uint32 diff) { BattleGround::Update(diff); } - void BattleGroundRV::StartingEventCloseDoors() { } - void BattleGroundRV::StartingEventOpenDoors() { } - void BattleGroundRV::AddPlayer(Player *plr) { BattleGround::AddPlayer(plr); //create score and add it to map, default values are set in constructor BattleGroundRVScore* sc = new BattleGroundRVScore; - m_PlayerScores[plr->GetGUID()] = sc; } - void BattleGroundRV::RemovePlayer(Player * /*plr*/, uint64 /*guid*/) { } - void BattleGroundRV::HandleKillPlayer(Player* player, Player* killer) { BattleGround::HandleKillPlayer(player, killer); } - void BattleGroundRV::HandleAreaTrigger(Player * /*Source*/, uint32 /*Trigger*/) { } - bool BattleGroundRV::SetupBattleGround() { return true; diff --git a/src/game/BattleGroundRV.h b/src/game/BattleGroundRV.h index e3e94baf101..4cfa8940bc3 100644 --- a/src/game/BattleGroundRV.h +++ b/src/game/BattleGroundRV.h @@ -17,9 +17,7 @@ */ #ifndef __BATTLEGROUNDRV_H #define __BATTLEGROUNDRV_H - class BattleGround; - class BattleGroundRVScore : public BattleGroundScore { public: @@ -27,21 +25,17 @@ class BattleGroundRVScore : public BattleGroundScore virtual ~BattleGroundRVScore() {}; //TODO fix me }; - class BattleGroundRV : public BattleGround { friend class BattleGroundMgr; - public: BattleGroundRV(); ~BattleGroundRV(); void Update(uint32 diff); - /* inherited from BattlegroundClass */ virtual void AddPlayer(Player *plr); virtual void StartingEventCloseDoors(); virtual void StartingEventOpenDoors(); - void RemovePlayer(Player *plr, uint64 guid); void HandleAreaTrigger(Player *Source, uint32 Trigger); bool SetupBattleGround(); diff --git a/src/game/BattleGroundSA.cpp b/src/game/BattleGroundSA.cpp index acf16ad3af0..ce5688b7706 100644 --- a/src/game/BattleGroundSA.cpp +++ b/src/game/BattleGroundSA.cpp @@ -15,12 +15,10 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "BattleGround.h" #include "BattleGroundSA.h" #include "Language.h" #include "Player.h" - BattleGroundSA::BattleGroundSA() { //TODO FIX ME! @@ -29,52 +27,39 @@ BattleGroundSA::BattleGroundSA() m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_WS_START_HALF_MINUTE; m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_WS_HAS_BEGUN; } - BattleGroundSA::~BattleGroundSA() { - } - void BattleGroundSA::Update(uint32 diff) { BattleGround::Update(diff); } - void BattleGroundSA::StartingEventCloseDoors() { } - void BattleGroundSA::StartingEventOpenDoors() { } - void BattleGroundSA::AddPlayer(Player *plr) { BattleGround::AddPlayer(plr); //create score and add it to map, default values are set in constructor BattleGroundSAScore* sc = new BattleGroundSAScore; - m_PlayerScores[plr->GetGUID()] = sc; } - void BattleGroundSA::RemovePlayer(Player* /*plr*/,uint64 /*guid*/) { - } - void BattleGroundSA::HandleAreaTrigger(Player * /*Source*/, uint32 /*Trigger*/) { // this is wrong way to implement these things. On official it done by gameobject spell cast. if (GetStatus() != STATUS_IN_PROGRESS) return; } - void BattleGroundSA::UpdatePlayerScore(Player* Source, uint32 type, uint32 value) { - BattleGroundScoreMap::iterator itr = m_PlayerScores.find(Source->GetGUID()); if(itr == m_PlayerScores.end()) // player not found... return; - BattleGround::UpdatePlayerScore(Source,type,value); } diff --git a/src/game/BattleGroundSA.h b/src/game/BattleGroundSA.h index 3ba23d02656..81b87b6e3e7 100644 --- a/src/game/BattleGroundSA.h +++ b/src/game/BattleGroundSA.h @@ -15,40 +15,31 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef __BATTLEGROUNDSA_H #define __BATTLEGROUNDSA_H - class BattleGround; - class BattleGroundSAScore : public BattleGroundScore { public: BattleGroundSAScore() {}; virtual ~BattleGroundSAScore() {}; }; - class BattleGroundSA : public BattleGround { friend class BattleGroundMgr; - public: BattleGroundSA(); ~BattleGroundSA(); void Update(uint32 diff); - /* inherited from BattlegroundClass */ virtual void AddPlayer(Player *plr); virtual void StartingEventCloseDoors(); virtual void StartingEventOpenDoors(); - void RemovePlayer(Player *plr,uint64 guid); void HandleAreaTrigger(Player *Source, uint32 Trigger); //bool SetupBattleGround(); - /* Scorekeeping */ void UpdatePlayerScore(Player *Source, uint32 type, uint32 value); - private: }; #endif diff --git a/src/game/BattleGroundWS.cpp b/src/game/BattleGroundWS.cpp index ec19308e71f..5edae297872 100644 --- a/src/game/BattleGroundWS.cpp +++ b/src/game/BattleGroundWS.cpp @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "BattleGround.h" #include "BattleGroundWS.h" #include "Creature.h" @@ -29,7 +28,6 @@ #include "Player.h" #include "World.h" #include "WorldPacket.h" - // these variables aren't used outside of this file, so declare them only here enum BG_WSG_Rewards { @@ -38,42 +36,34 @@ enum BG_WSG_Rewards BG_WSG_MAP_COMPLETE, BG_WSG_REWARD_NUM }; - uint32 BG_WSG_Honor[BG_HONOR_MODE_NUM][BG_WSG_REWARD_NUM] = { {20,40,40}, // normal honor {60,40,80} // holiday }; - uint32 BG_WSG_Reputation[BG_HONOR_MODE_NUM][BG_WSG_REWARD_NUM] = { {0,35,0}, // normal honor {0,45,0} // holiday }; - BattleGroundWS::BattleGroundWS() { m_BgObjects.resize(BG_WS_OBJECT_MAX); m_BgCreatures.resize(BG_CREATURES_MAX_WS); - m_StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_WS_START_TWO_MINUTES; m_StartMessageIds[BG_STARTING_EVENT_SECOND] = LANG_BG_WS_START_ONE_MINUTE; m_StartMessageIds[BG_STARTING_EVENT_THIRD] = LANG_BG_WS_START_HALF_MINUTE; m_StartMessageIds[BG_STARTING_EVENT_FOURTH] = LANG_BG_WS_HAS_BEGUN; } - BattleGroundWS::~BattleGroundWS() { } - void BattleGroundWS::Update(uint32 diff) { BattleGround::Update(diff); - if (GetStatus() == STATUS_IN_PROGRESS) { if (m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_WAIT_RESPAWN) { m_FlagsTimer[BG_TEAM_ALLIANCE] -= diff; - if (m_FlagsTimer[BG_TEAM_ALLIANCE] < 0) { m_FlagsTimer[BG_TEAM_ALLIANCE] = 0; @@ -83,7 +73,6 @@ void BattleGroundWS::Update(uint32 diff) if (m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_GROUND) { m_FlagsDropTimer[BG_TEAM_ALLIANCE] -= diff; - if (m_FlagsDropTimer[BG_TEAM_ALLIANCE] < 0) { m_FlagsDropTimer[BG_TEAM_ALLIANCE] = 0; @@ -94,7 +83,6 @@ void BattleGroundWS::Update(uint32 diff) if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_WAIT_RESPAWN) { m_FlagsTimer[BG_TEAM_HORDE] -= diff; - if (m_FlagsTimer[BG_TEAM_HORDE] < 0) { m_FlagsTimer[BG_TEAM_HORDE] = 0; @@ -104,7 +92,6 @@ void BattleGroundWS::Update(uint32 diff) if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_ON_GROUND) { m_FlagsDropTimer[BG_TEAM_HORDE] -= diff; - if (m_FlagsDropTimer[BG_TEAM_HORDE] < 0) { m_FlagsDropTimer[BG_TEAM_HORDE] = 0; @@ -145,7 +132,6 @@ void BattleGroundWS::Update(uint32 diff) } } } - void BattleGroundWS::StartingEventCloseDoors() { for(uint32 i = BG_WS_OBJECT_DOOR_A_1; i <= BG_WS_OBJECT_DOOR_H_4; ++i) @@ -156,32 +142,26 @@ void BattleGroundWS::StartingEventCloseDoors() for(uint32 i = BG_WS_OBJECT_A_FLAG; i <= BG_WS_OBJECT_BERSERKBUFF_2; ++i) SpawnBGObject(i, RESPAWN_ONE_DAY); } - void BattleGroundWS::StartingEventOpenDoors() { for(uint32 i = BG_WS_OBJECT_DOOR_A_1; i <= BG_WS_OBJECT_DOOR_A_4; ++i) DoorOpen(i); for(uint32 i = BG_WS_OBJECT_DOOR_H_1; i <= BG_WS_OBJECT_DOOR_H_2; ++i) DoorOpen(i); - SpawnBGObject(BG_WS_OBJECT_DOOR_A_5, RESPAWN_ONE_DAY); SpawnBGObject(BG_WS_OBJECT_DOOR_A_6, RESPAWN_ONE_DAY); SpawnBGObject(BG_WS_OBJECT_DOOR_H_3, RESPAWN_ONE_DAY); SpawnBGObject(BG_WS_OBJECT_DOOR_H_4, RESPAWN_ONE_DAY); - for(uint32 i = BG_WS_OBJECT_A_FLAG; i <= BG_WS_OBJECT_BERSERKBUFF_2; ++i) SpawnBGObject(i, RESPAWN_IMMEDIATELY); } - void BattleGroundWS::AddPlayer(Player *plr) { BattleGround::AddPlayer(plr); //create score and add it to map, default values are set in constructor BattleGroundWGScore* sc = new BattleGroundWGScore; - m_PlayerScores[plr->GetGUID()] = sc; } - void BattleGroundWS::RespawnFlag(uint32 Team, bool captured) { if (Team == ALLIANCE) @@ -194,7 +174,6 @@ void BattleGroundWS::RespawnFlag(uint32 Team, bool captured) sLog.outDebug("Respawn Horde flag"); m_FlagState[BG_TEAM_HORDE] = BG_WS_FLAG_STATE_ON_BASE; } - if (captured) { //when map_update will be allowed for battlegrounds this code will be useless @@ -205,12 +184,10 @@ void BattleGroundWS::RespawnFlag(uint32 Team, bool captured) } m_BothFlagsKept = false; } - void BattleGroundWS::RespawnFlagAfterDrop(uint32 team) { if (GetStatus() != STATUS_IN_PROGRESS) return; - RespawnFlag(team,false); if (team == ALLIANCE) { @@ -222,26 +199,20 @@ void BattleGroundWS::RespawnFlagAfterDrop(uint32 team) SpawnBGObject(BG_WS_OBJECT_H_FLAG, RESPAWN_IMMEDIATELY); SendMessageToAll(LANG_BG_WS_HORDE_FLAG_RESPAWNED, CHAT_MSG_BG_SYSTEM_NEUTRAL); } - PlaySoundToAll(BG_WS_SOUND_FLAGS_RESPAWNED); - GameObject *obj = HashMapHolder::Find(GetDroppedFlagGUID(team)); if (obj) obj->Delete(); else sLog.outError("unknown droped flag bg, guid: %u",GUID_LOPART(GetDroppedFlagGUID(team))); - SetDroppedFlagGUID(0,team); m_BothFlagsKept = false; } - void BattleGroundWS::EventPlayerCapturedFlag(Player *Source) { if (GetStatus() != STATUS_IN_PROGRESS) return; - uint32 winner = 0; - Source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT); if (Source->GetTeam() == ALLIANCE) { @@ -281,33 +252,26 @@ void BattleGroundWS::EventPlayerCapturedFlag(Player *Source) } //for flag capture is reward 2 honorable kills RewardHonorToTeam(GetBonusHonorFromKill(2), Source->GetTeam()); - SpawnBGObject(BG_WS_OBJECT_H_FLAG, BG_WS_FLAG_RESPAWN_TIME); SpawnBGObject(BG_WS_OBJECT_A_FLAG, BG_WS_FLAG_RESPAWN_TIME); - if (Source->GetTeam() == ALLIANCE) SendMessageToAll(LANG_BG_WS_CAPTURED_HF, CHAT_MSG_BG_SYSTEM_ALLIANCE, Source); else SendMessageToAll(LANG_BG_WS_CAPTURED_AF, CHAT_MSG_BG_SYSTEM_HORDE, Source); - UpdateFlagState(Source->GetTeam(), 1); // flag state none UpdateTeamScore(Source->GetTeam()); // only flag capture should be updated UpdatePlayerScore(Source, SCORE_FLAG_CAPTURES, 1); // +1 flag captures - if (GetTeamScore(ALLIANCE) == BG_WS_MAX_TEAM_SCORE) winner = ALLIANCE; - if (GetTeamScore(HORDE) == BG_WS_MAX_TEAM_SCORE) winner = HORDE; - if (winner) { UpdateWorldState(BG_WS_FLAG_UNK_ALLIANCE, 0); UpdateWorldState(BG_WS_FLAG_UNK_HORDE, 0); UpdateWorldState(BG_WS_FLAG_STATE_ALLIANCE, 1); UpdateWorldState(BG_WS_FLAG_STATE_HORDE, 1); - RewardHonorToTeam(BG_WSG_Honor[m_HonorMode][BG_WSG_WIN], winner); EndBattleGround(winner); } @@ -316,7 +280,6 @@ void BattleGroundWS::EventPlayerCapturedFlag(Player *Source) m_FlagsTimer[GetTeamIndexByTeamId(Source->GetTeam()) ? 0 : 1] = BG_WS_FLAG_RESPAWN_TIME; } } - void BattleGroundWS::EventPlayerDroppedFlag(Player *Source) { if (GetStatus() != STATUS_IN_PROGRESS) @@ -345,9 +308,7 @@ void BattleGroundWS::EventPlayerDroppedFlag(Player *Source) } return; } - bool set = false; - if (Source->GetTeam() == ALLIANCE) { if (!IsHordeFlagPickedup()) @@ -382,12 +343,10 @@ void BattleGroundWS::EventPlayerDroppedFlag(Player *Source) set = true; } } - if (set) { Source->CastSpell(Source, SPELL_RECENTLY_DROPPED_FLAG, true); UpdateFlagState(Source->GetTeam(), 1); - if (Source->GetTeam() == ALLIANCE) { SendMessageToAll(LANG_BG_WS_DROPPED_HF, CHAT_MSG_BG_SYSTEM_HORDE, Source); @@ -398,19 +357,15 @@ void BattleGroundWS::EventPlayerDroppedFlag(Player *Source) SendMessageToAll(LANG_BG_WS_DROPPED_AF, CHAT_MSG_BG_SYSTEM_ALLIANCE, Source); UpdateWorldState(BG_WS_FLAG_UNK_ALLIANCE, uint32(-1)); } - m_FlagsDropTimer[GetTeamIndexByTeamId(Source->GetTeam()) ? 0 : 1] = BG_WS_FLAG_DROP_TIME; } } - void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target_obj) { if (GetStatus() != STATUS_IN_PROGRESS) return; - int32 message_id = 0; ChatMsg type; - //alliance flag picked up from base if(Source->GetTeam() == HORDE && this->GetFlagState(ALLIANCE) == BG_WS_FLAG_STATE_ON_BASE && this->m_BgObjects[BG_WS_OBJECT_A_FLAG] == target_obj->GetGUID()) @@ -428,7 +383,6 @@ void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target if(m_FlagState[1] == BG_WS_FLAG_STATE_ON_PLAYER) m_BothFlagsKept = true; } - //horde flag picked up from base if (Source->GetTeam() == ALLIANCE && this->GetFlagState(HORDE) == BG_WS_FLAG_STATE_ON_BASE && this->m_BgObjects[BG_WS_OBJECT_H_FLAG] == target_obj->GetGUID()) @@ -446,7 +400,6 @@ void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target if(m_FlagState[0] == BG_WS_FLAG_STATE_ON_PLAYER) m_BothFlagsKept = true; } - //Alliance flag on ground(not in base) (returned or picked up again from ground!) if (GetFlagState(ALLIANCE) == BG_WS_FLAG_STATE_ON_GROUND && Source->IsWithinDistInMap(target_obj, 10)) { @@ -480,7 +433,6 @@ void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target //called in HandleGameObjectUseOpcode: //target_obj->Delete(); } - //Horde flag on ground(not in base) (returned or picked up again) if (GetFlagState(HORDE) == BG_WS_FLAG_STATE_ON_GROUND && Source->IsWithinDistInMap(target_obj, 10)) { @@ -514,14 +466,11 @@ void BattleGroundWS::EventPlayerClickedOnFlag(Player *Source, GameObject* target //called in HandleGameObjectUseOpcode: //target_obj->Delete(); } - if (!message_id) return; - SendMessageToAll(message_id, type, Source); Source->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT); } - void BattleGroundWS::RemovePlayer(Player *plr, uint64 guid) { // sometimes flag aura not removed :( @@ -548,7 +497,6 @@ void BattleGroundWS::RemovePlayer(Player *plr, uint64 guid) this->EventPlayerDroppedFlag(plr); } } - void BattleGroundWS::UpdateFlagState(uint32 team, uint32 value) { if (team == ALLIANCE) @@ -556,7 +504,6 @@ void BattleGroundWS::UpdateFlagState(uint32 team, uint32 value) else UpdateWorldState(BG_WS_FLAG_STATE_HORDE, value); } - void BattleGroundWS::UpdateTeamScore(uint32 team) { if (team == ALLIANCE) @@ -564,13 +511,11 @@ void BattleGroundWS::UpdateTeamScore(uint32 team) else UpdateWorldState(BG_WS_FLAG_CAPTURES_HORDE, GetTeamScore(team)); } - void BattleGroundWS::HandleAreaTrigger(Player *Source, uint32 Trigger) { // this is wrong way to implement these things. On official it done by gameobject spell cast. if (GetStatus() != STATUS_IN_PROGRESS) return; - //uint32 SpellId = 0; //uint64 buff_guid = 0; switch(Trigger) @@ -613,11 +558,9 @@ void BattleGroundWS::HandleAreaTrigger(Player *Source, uint32 Trigger) Source->GetSession()->SendAreaTriggerMessage("Warning: Unhandled AreaTrigger in Battleground: %u", Trigger); break; } - //if (buff_guid) // HandleTriggerBuff(buff_guid,Source); } - bool BattleGroundWS::SetupBattleGround() { // flags @@ -647,31 +590,25 @@ bool BattleGroundWS::SetupBattleGround() sLog.outErrorDb("BatteGroundWS: Failed to spawn some object BattleGround not created!"); return false; } - WorldSafeLocsEntry const *sg = sWorldSafeLocsStore.LookupEntry(WS_GRAVEYARD_MAIN_ALLIANCE); if (!sg || !AddSpiritGuide(WS_SPIRIT_MAIN_ALLIANCE, sg->x, sg->y, sg->z, 3.124139f, ALLIANCE)) { sLog.outErrorDb("BatteGroundWS: Failed to spawn Alliance spirit guide! BattleGround not created!"); return false; } - sg = sWorldSafeLocsStore.LookupEntry(WS_GRAVEYARD_MAIN_HORDE); if (!sg || !AddSpiritGuide(WS_SPIRIT_MAIN_HORDE, sg->x, sg->y, sg->z, 3.193953f, HORDE)) { sLog.outErrorDb("BatteGroundWS: Failed to spawn Horde spirit guide! BattleGround not created!"); return false; } - sLog.outDebug("BatteGroundWS: BG objects and spirit guides spawned"); - return true; } - void BattleGroundWS::Reset() { //call parent's class reset BattleGround::Reset(); - m_FlagKeepers[BG_TEAM_ALLIANCE] = 0; m_FlagKeepers[BG_TEAM_HORDE] = 0; m_DroppedFlagGUID[BG_TEAM_ALLIANCE] = 0; @@ -684,7 +621,6 @@ void BattleGroundWS::Reset() m_ReputationCapture = (isBGWeekend) ? 45 : 35; m_HonorWinKills = (isBGWeekend) ? 3 : 1; m_HonorEndKills = (isBGWeekend) ? 4 : 2; - /* Spirit nodes is static at this BG and then not required deleting at BG reset. if (m_BgCreatures[WS_SPIRIT_MAIN_ALLIANCE]) DelCreature(WS_SPIRIT_MAIN_ALLIANCE); @@ -692,7 +628,6 @@ void BattleGroundWS::Reset() DelCreature(WS_SPIRIT_MAIN_HORDE); */ } - void BattleGroundWS::EndBattleGround(uint32 winner) { //win reward @@ -703,27 +638,20 @@ void BattleGroundWS::EndBattleGround(uint32 winner) //complete map_end rewards (even if no team wins) RewardHonorToTeam(GetBonusHonorFromKill(m_HonorEndKills), ALLIANCE); RewardHonorToTeam(GetBonusHonorFromKill(m_HonorEndKills), HORDE); - BattleGround::EndBattleGround(winner); } - void BattleGroundWS::HandleKillPlayer(Player *player, Player *killer) { if (GetStatus() != STATUS_IN_PROGRESS) return; - EventPlayerDroppedFlag(player); - BattleGround::HandleKillPlayer(player, killer); } - void BattleGroundWS::UpdatePlayerScore(Player *Source, uint32 type, uint32 value) { - BattleGroundScoreMap::iterator itr = m_PlayerScores.find(Source->GetGUID()); if(itr == m_PlayerScores.end()) // player not found return; - switch(type) { case SCORE_FLAG_CAPTURES: // flags captured @@ -737,7 +665,6 @@ void BattleGroundWS::UpdatePlayerScore(Player *Source, uint32 type, uint32 value break; } } - WorldSafeLocsEntry const* BattleGroundWS::GetClosestGraveYard(Player* player) { //if status in progress, it returns main graveyards with spiritguides @@ -760,37 +687,30 @@ WorldSafeLocsEntry const* BattleGroundWS::GetClosestGraveYard(Player* player) return sWorldSafeLocsStore.LookupEntry(WS_GRAVEYARD_FLAGROOM_HORDE); } } - void BattleGroundWS::FillInitialWorldStates(WorldPacket& data) { data << uint32(BG_WS_FLAG_CAPTURES_ALLIANCE) << uint32(GetTeamScore(ALLIANCE)); data << uint32(BG_WS_FLAG_CAPTURES_HORDE) << uint32(GetTeamScore(HORDE)); - if (m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_GROUND) data << uint32(BG_WS_FLAG_UNK_ALLIANCE) << uint32(-1); else if (m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_PLAYER) data << uint32(BG_WS_FLAG_UNK_ALLIANCE) << uint32(1); else data << uint32(BG_WS_FLAG_UNK_ALLIANCE) << uint32(0); - if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_ON_GROUND) data << uint32(BG_WS_FLAG_UNK_HORDE) << uint32(-1); else if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_ON_PLAYER) data << uint32(BG_WS_FLAG_UNK_HORDE) << uint32(1); else data << uint32(BG_WS_FLAG_UNK_HORDE) << uint32(0); - data << uint32(BG_WS_FLAG_CAPTURES_MAX) << uint32(BG_WS_MAX_TEAM_SCORE); - if (m_FlagState[BG_TEAM_HORDE] == BG_WS_FLAG_STATE_ON_PLAYER) data << uint32(BG_WS_FLAG_STATE_ALLIANCE) << uint32(2); else data << uint32(BG_WS_FLAG_STATE_ALLIANCE) << uint32(1); - if (m_FlagState[BG_TEAM_ALLIANCE] == BG_WS_FLAG_STATE_ON_PLAYER) data << uint32(BG_WS_FLAG_STATE_HORDE) << uint32(2); else data << uint32(BG_WS_FLAG_STATE_HORDE) << uint32(1); - } diff --git a/src/game/BattleGroundWS.h b/src/game/BattleGroundWS.h index 16631afecdc..0b616af24b1 100644 --- a/src/game/BattleGroundWS.h +++ b/src/game/BattleGroundWS.h @@ -17,12 +17,9 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef __BATTLEGROUNDWS_H #define __BATTLEGROUNDWS_H - #include "BattleGround.h" - enum BG_WS_TimerOrScore { BG_WS_MAX_TEAM_SCORE = 3, @@ -31,7 +28,6 @@ enum BG_WS_TimerOrScore BG_WS_SPELL_FORCE_TIME = 600000, BG_WS_SPELL_BRUTAL_TIME = 900000 }; - enum BG_WS_Sound { BG_WS_SOUND_FLAG_CAPTURED_ALLIANCE = 8173, @@ -42,7 +38,6 @@ enum BG_WS_Sound BG_WS_SOUND_ALLIANCE_FLAG_PICKED_UP = 8174, BG_WS_SOUND_FLAGS_RESPAWNED = 8232 }; - enum BG_WS_SpellId { BG_WS_SPELL_WARSONG_FLAG = 23333, @@ -52,7 +47,6 @@ enum BG_WS_SpellId BG_WS_SPELL_FOCUSED_ASSAULT = 46392, BG_WS_SPELL_BRUTAL_ASSAULT = 46393 }; - enum BG_WS_WorldStates { BG_WS_FLAG_UNK_ALLIANCE = 1545, @@ -64,7 +58,6 @@ enum BG_WS_WorldStates BG_WS_FLAG_STATE_HORDE = 2338, BG_WS_FLAG_STATE_ALLIANCE = 2339 }; - enum BG_WS_ObjectTypes { BG_WS_OBJECT_DOOR_A_1 = 0, @@ -87,7 +80,6 @@ enum BG_WS_ObjectTypes BG_WS_OBJECT_BERSERKBUFF_2 = 17, BG_WS_OBJECT_MAX = 18 }; - enum BG_WS_ObjectEntry { BG_OBJECT_DOOR_A_1_WS_ENTRY = 179918, @@ -105,7 +97,6 @@ enum BG_WS_ObjectEntry BG_OBJECT_A_FLAG_GROUND_WS_ENTRY = 179785, BG_OBJECT_H_FLAG_GROUND_WS_ENTRY = 179786 }; - enum BG_WS_FlagState { BG_WS_FLAG_STATE_ON_BASE = 0, @@ -113,7 +104,6 @@ enum BG_WS_FlagState BG_WS_FLAG_STATE_ON_PLAYER = 2, BG_WS_FLAG_STATE_ON_GROUND = 3 }; - enum BG_WS_Graveyards { WS_GRAVEYARD_FLAGROOM_ALLIANCE = 769, @@ -121,21 +111,17 @@ enum BG_WS_Graveyards WS_GRAVEYARD_MAIN_ALLIANCE = 771, WS_GRAVEYARD_MAIN_HORDE = 772 }; - enum BG_WS_CreatureTypes { WS_SPIRIT_MAIN_ALLIANCE = 0, WS_SPIRIT_MAIN_HORDE = 1, - BG_CREATURES_MAX_WS = 2 }; - enum BG_WS_CarrierDebuffs { WS_SPELL_FOCUSED_ASSAULT = 46392, WS_SPELL_BRUTAL_ASSAULT = 46393 }; - class BattleGroundWGScore : public BattleGroundScore { public: @@ -144,22 +130,18 @@ class BattleGroundWGScore : public BattleGroundScore uint32 FlagCaptures; uint32 FlagReturns; }; - class BattleGroundWS : public BattleGround { friend class BattleGroundMgr; - public: /* Construction */ BattleGroundWS(); ~BattleGroundWS(); void Update(uint32 diff); - /* inherited from BattlegroundClass */ virtual void AddPlayer(Player *plr); virtual void StartingEventCloseDoors(); virtual void StartingEventOpenDoors(); - /* BG Flags */ uint64 GetAllianceFlagPickerGUID() const { return m_FlagKeepers[BG_TEAM_ALLIANCE]; } uint64 GetHordeFlagPickerGUID() const { return m_FlagKeepers[BG_TEAM_HORDE]; } @@ -174,12 +156,10 @@ class BattleGroundWS : public BattleGround void RemoveTimedAura(uint32 aura); bool IsBrutalTimerDone; bool IsForceTimerDone; - /* Battleground Events */ virtual void EventPlayerDroppedFlag(Player *Source); virtual void EventPlayerClickedOnFlag(Player *Source, GameObject* target_obj); virtual void EventPlayerCapturedFlag(Player *Source); - void RemovePlayer(Player *plr, uint64 guid); void HandleAreaTrigger(Player *Source, uint32 Trigger); void HandleKillPlayer(Player *player, Player *killer); @@ -187,14 +167,12 @@ class BattleGroundWS : public BattleGround virtual void Reset(); void EndBattleGround(uint32 winner); virtual WorldSafeLocsEntry const* GetClosestGraveYard(Player* player); - void UpdateFlagState(uint32 team, uint32 value); void UpdateTeamScore(uint32 team); void UpdatePlayerScore(Player *Source, uint32 type, uint32 value); void SetDroppedFlagGUID(uint64 guid, uint32 TeamID) { m_DroppedFlagGUID[GetTeamIndexByTeamId(TeamID)] = guid;} uint64 GetDroppedFlagGUID(uint32 TeamID) { return m_DroppedFlagGUID[GetTeamIndexByTeamId(TeamID)];} virtual void FillInitialWorldStates(WorldPacket& data); - /* Scorekeeping */ uint32 GetTeamScore(uint32 TeamID) const { return m_TeamScores[GetTeamIndexByTeamId(TeamID)]; } void AddPoint(uint32 TeamID, uint32 Points = 1) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] += Points; } @@ -206,7 +184,6 @@ class BattleGroundWS : public BattleGround uint8 m_FlagState[2]; // for checking flag state int32 m_FlagsTimer[2]; int32 m_FlagsDropTimer[2]; - uint32 m_ReputationCapture; uint32 m_HonorWinKills; uint32 m_HonorEndKills; diff --git a/src/game/Calendar.h b/src/game/Calendar.h index 7a86afa7db7..41f75c7aa28 100644 --- a/src/game/Calendar.h +++ b/src/game/Calendar.h @@ -15,12 +15,9 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef MANGOS_CALENDAR_H #define MANGOS_CALENDAR_H - class Calendar { - }; #endif diff --git a/src/game/CalendarHandler.cpp b/src/game/CalendarHandler.cpp index 93d3b7eae26..747f2e9f309 100644 --- a/src/game/CalendarHandler.cpp +++ b/src/game/CalendarHandler.cpp @@ -15,36 +15,27 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "Common.h" #include "WorldPacket.h" #include "WorldSession.h" - #include "InstanceSaveMgr.h" #include "Log.h" #include "Opcodes.h" #include "Player.h" - void WorldSession::HandleCalendarGetCalendar(WorldPacket &recv_data) { sLog.outDebug("WORLD: CMSG_CALENDAR_GET_CALENDAR"); // empty - time_t cur_time = time(NULL); - WorldPacket data(SMSG_CALENDAR_SEND_CALENDAR,4+4*0+4+4*0+4+4); - // TODO: calendar invite event output data << (uint32) 0; //invite node count // TODO: calendar event output data << (uint32) 0; //event count - data << (uint32) 0; //wtf?? data << (uint32) secsToTimeBitFields(cur_time); // current time - uint32 counter = 0; size_t p_counter = data.wpos(); data << uint32(counter); // instance save count - for(int i = 0; i < TOTAL_DIFFICULTIES; ++i) { for (Player::BoundInstancesMap::const_iterator itr = _player->m_boundInstances[i].begin(); itr != _player->m_boundInstances[i].end(); ++itr) @@ -61,7 +52,6 @@ void WorldSession::HandleCalendarGetCalendar(WorldPacket &recv_data) } } data.put(p_counter,counter); - data << (uint32) 1135753200; //wtf?? (28.12.2005 12:00) data << (uint32) 0; // unk counter 4 data << (uint32) 0; // unk counter 5 @@ -69,14 +59,12 @@ void WorldSession::HandleCalendarGetCalendar(WorldPacket &recv_data) //data.hexlike(); SendPacket(&data); } - void WorldSession::HandleCalendarGetEvent(WorldPacket &recv_data) { sLog.outDebug("WORLD: CMSG_CALENDAR_GET_EVENT"); recv_data.hexlike(); recv_data.read_skip(); // unk } - void WorldSession::HandleCalendarGuildFilter(WorldPacket &recv_data) { sLog.outDebug("WORLD: CMSG_CALENDAR_GUILD_FILTER"); @@ -85,24 +73,20 @@ void WorldSession::HandleCalendarGuildFilter(WorldPacket &recv_data) recv_data.read_skip(); // unk2 recv_data.read_skip(); // unk3 } - void WorldSession::HandleCalendarArenaTeam(WorldPacket &recv_data) { sLog.outDebug("WORLD: CMSG_CALENDAR_ARENA_TEAM"); recv_data.hexlike(); recv_data.read_skip(); // unk } - void WorldSession::HandleCalendarAddEvent(WorldPacket &recv_data) { sLog.outDebug("WORLD: CMSG_CALENDAR_ADD_EVENT"); recv_data.hexlike(); recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam - //std::string unk1, unk2; //recv_data >> (std::string)unk1; //recv_data >> (std::string)unk2; - //uint8 unk3, unk4; //uint32 unk5, unk6, unk7, unk8, unk9, count = 0; //recv_data >> (uint8)unk3; @@ -128,13 +112,11 @@ void WorldSession::HandleCalendarAddEvent(WorldPacket &recv_data) // } //} } - void WorldSession::HandleCalendarUpdateEvent(WorldPacket &recv_data) { sLog.outDebug("WORLD: CMSG_CALENDAR_UPDATE_EVENT"); recv_data.hexlike(); recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam - //recv_data >> uint64 //recv_data >> uint64 //recv_data >> std::string @@ -147,110 +129,88 @@ void WorldSession::HandleCalendarUpdateEvent(WorldPacket &recv_data) //recv_data >> uint32 //recv_data >> uint32 } - void WorldSession::HandleCalendarRemoveEvent(WorldPacket &recv_data) { sLog.outDebug("WORLD: CMSG_CALENDAR_REMOVE_EVENT"); recv_data.hexlike(); recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam - //recv_data >> uint64 //recv_data >> uint64 //recv_data >> uint32 - } - void WorldSession::HandleCalendarCopyEvent(WorldPacket &recv_data) { sLog.outDebug("WORLD: CMSG_CALENDAR_COPY_EVENT"); recv_data.hexlike(); recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam - //recv_data >> uint64 //recv_data >> uint64 //recv_data >> uint32 - } - void WorldSession::HandleCalendarEventInvite(WorldPacket &recv_data) { sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_INVITE"); recv_data.hexlike(); recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam - //recv_data >> uint64 //recv_data >> uint64 //recv_data >> std::string //recv_data >> uint8 //recv_data >> uint8 - } - void WorldSession::HandleCalendarEventRsvp(WorldPacket &recv_data) { sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_RSVP"); recv_data.hexlike(); recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam - //recv_data >> uint64 //recv_data >> uint64 //recv_data >> uint32 - } - void WorldSession::HandleCalendarEventRemoveInvite(WorldPacket &recv_data) { sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_REMOVE_INVITE"); recv_data.hexlike(); recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam - //recv_data.readPackGUID(guid) //recv_data >> uint64 //recv_data >> uint64 //recv_data >> uint64 } - void WorldSession::HandleCalendarEventStatus(WorldPacket &recv_data) { sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_STATUS"); recv_data.hexlike(); recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam - //recv_data.readPackGUID(guid) //recv_data >> uint64 //recv_data >> uint64 //recv_data >> uint64 //recv_data >> uint32 } - void WorldSession::HandleCalendarEventModeratorStatus(WorldPacket &recv_data) { sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_MODERATOR_STATUS"); recv_data.hexlike(); recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam - //recv_data.readPackGUID(guid) //recv_data >> uint64 //recv_data >> uint64 //recv_data >> uint64 //recv_data >> uint32 } - void WorldSession::HandleCalendarComplain(WorldPacket &recv_data) { sLog.outDebug("WORLD: CMSG_CALENDAR_COMPLAIN"); recv_data.hexlike(); recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam - //recv_data >> uint64 //recv_data >> uint64 //recv_data >> uint64 } - void WorldSession::HandleCalendarGetNumPending(WorldPacket & /*recv_data*/) { sLog.outDebug("WORLD: CMSG_CALENDAR_GET_NUM_PENDING"); // empty - WorldPacket data(SMSG_CALENDAR_SEND_NUM_PENDING, 4); data << uint32(0); // 0 - no pending invites, 1 - some pending invites SendPacket(&data); diff --git a/src/game/Cell.h b/src/game/Cell.h index 9baf4104080..7145df0aacc 100644 --- a/src/game/Cell.h +++ b/src/game/Cell.h @@ -17,20 +17,14 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef TRINITY_CELL_H #define TRINITY_CELL_H - #include - #include "GameSystem/TypeContainer.h" #include "GameSystem/TypeContainerVisitor.h" - #include "GridDefines.h" - class Map; class WorldObject; - enum District { UPPER_DISTRICT = 1, @@ -44,15 +38,12 @@ enum District LOWER_RIGHT_DISTRICT = (LOWER_DISTRICT | RIGHT_DISTRICT), ALL_DISTRICT = (UPPER_DISTRICT | LOWER_DISTRICT | LEFT_DISTRICT | RIGHT_DISTRICT | CENTER_DISTRICT) }; - template struct CellLock; - struct TRINITY_DLL_DECL CellArea { CellArea() : right_offset(0), left_offset(0), upper_offset(0), lower_offset(0) {} CellArea(int right, int left, int upper, int lower) : right_offset(right), left_offset(left), upper_offset(upper), lower_offset(lower) {} bool operator!() const { return !right_offset && !left_offset && !upper_offset && !lower_offset; } - void ResizeBorders(CellPair& begin_cell, CellPair& end_cell) const { begin_cell << left_offset; @@ -60,20 +51,17 @@ struct TRINITY_DLL_DECL CellArea end_cell >> right_offset; end_cell += upper_offset; } - int right_offset; int left_offset; int upper_offset; int lower_offset; }; - struct TRINITY_DLL_DECL Cell { Cell() { data.All = 0; } Cell(const Cell &cell) { data.All = cell.data.All; } explicit Cell(CellPair const& p); - void operator|=(Cell &cell) { data.Part.reserved = 0; @@ -81,14 +69,12 @@ struct TRINITY_DLL_DECL Cell uint32 x, y, old_x, old_y; Compute(x, y); cell.Compute(old_x, old_y); - if( std::abs(int(x-old_x)) > 1 || std::abs(int(y-old_y)) > 1) { data.Part.reserved = ALL_DISTRICT; cell.data.Part.reserved = ALL_DISTRICT; return; } - if( x < old_x ) { data.Part.reserved |= LEFT_DISTRICT; @@ -110,45 +96,38 @@ struct TRINITY_DLL_DECL Cell cell.data.Part.reserved |= UPPER_DISTRICT; } } - void Compute(uint32 &x, uint32 &y) const { x = data.Part.grid_x*MAX_NUMBER_OF_CELLS + data.Part.cell_x; y = data.Part.grid_y*MAX_NUMBER_OF_CELLS + data.Part.cell_y; } - bool DiffCell(const Cell &cell) const { return( data.Part.cell_x != cell.data.Part.cell_x || data.Part.cell_y != cell.data.Part.cell_y ); } - bool DiffGrid(const Cell &cell) const { return( data.Part.grid_x != cell.data.Part.grid_x || data.Part.grid_y != cell.data.Part.grid_y ); } - uint32 CellX() const { return data.Part.cell_x; } uint32 CellY() const { return data.Part.cell_y; } uint32 GridX() const { return data.Part.grid_x; } uint32 GridY() const { return data.Part.grid_y; } bool NoCreate() const { return data.Part.nocreate; } void SetNoCreate() { data.Part.nocreate = 1; } - CellPair cellPair() const { return CellPair( data.Part.grid_x*MAX_NUMBER_OF_CELLS+data.Part.cell_x, data.Part.grid_y*MAX_NUMBER_OF_CELLS+data.Part.cell_y); } - Cell& operator=(const Cell &cell) { this->data.All = cell.data.All; return *this; } - bool operator==(const Cell &cell) const { return (data.All == cell.data.All); } bool operator!=(const Cell &cell) const { return !operator==(cell); } union @@ -164,17 +143,13 @@ struct TRINITY_DLL_DECL Cell } Part; uint32 All; } data; - template void Visit(const CellLock &, TypeContainerVisitor &visitor, Map &) const; template void Visit(const CellLock &, TypeContainerVisitor &visitor, Map &m, const WorldObject &obj, float radius) const; template void Visit(const CellLock &, TypeContainerVisitor &visitor, Map &, float radius, float x_off, float y_off) const; - static CellArea CalculateCellArea(const WorldObject &obj, float radius); - private: template void VisitCircle(const CellLock &, TypeContainerVisitor &, Map &, const CellPair& , const CellPair& ) const; }; - template struct TRINITY_DLL_DECL CellLock { diff --git a/src/game/CellImpl.h b/src/game/CellImpl.h index ff2b0343c69..659ffd48eb6 100644 --- a/src/game/CellImpl.h +++ b/src/game/CellImpl.h @@ -17,16 +17,12 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef TRINITY_CELLIMPL_H #define TRINITY_CELLIMPL_H - #include - #include "Cell.h" #include "Map.h" #include "Object.h" - inline Cell::Cell(CellPair const& p) { data.Part.grid_x = p.x_coord / MAX_NUMBER_OF_CELLS; @@ -36,7 +32,6 @@ inline Cell::Cell(CellPair const& p) data.Part.nocreate = 0; data.Part.reserved = 0; } - template inline void Cell::Visit(const CellLock &l, TypeContainerVisitor &visitor, Map &m) const @@ -44,19 +39,16 @@ Cell::Visit(const CellLock &l, TypeContainerVisitor &vi const CellPair &standing_cell = l.i_cellPair; if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP) return; - uint16 district = (District)this->data.Part.reserved; if(district == CENTER_DISTRICT) { m.Visit(l, visitor); return; } - // set up the cell range based on the district // the overloaded operators handle range checking CellPair begin_cell = standing_cell; CellPair end_cell = standing_cell; - switch( district ) { case ALL_DISTRICT: @@ -117,7 +109,6 @@ Cell::Visit(const CellLock &l, TypeContainerVisitor &vi break; } } - // loop the cell range for(uint32 x = begin_cell.x_coord; x <= end_cell.x_coord; x++) { @@ -131,7 +122,6 @@ Cell::Visit(const CellLock &l, TypeContainerVisitor &vi } } } - template inline void Cell::Visit(const CellLock &l, TypeContainerVisitor &visitor, Map &m, float radius, float x_off, float y_off) const @@ -139,9 +129,7 @@ Cell::Visit(const CellLock &l, TypeContainerVisitor &vi const CellPair &standing_cell = l.i_cellPair; if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP) return; - int left = 0, right = 0, upper = 0, lower = 0; - // Origin = (CENTER_GRID_CELL_OFFSET, CENTER_GRID_CELL_OFFSET) if(CENTER_GRID_CELL_OFFSET - x_off < radius) ++right; @@ -151,21 +139,17 @@ Cell::Visit(const CellLock &l, TypeContainerVisitor &vi ++upper; if(CENTER_GRID_CELL_OFFSET + y_off < radius) ++lower; - if(!left && !right && !upper && !lower) { m.Visit(l, visitor); return; } - CellPair begin_cell = standing_cell; CellPair end_cell = standing_cell; - begin_cell << left; //note: need change << if left > 1 begin_cell -= lower; end_cell >> right; end_cell += upper; - // loop the cell range for(uint32 x = begin_cell.x_coord; x <= end_cell.x_coord; x++) { @@ -179,20 +163,16 @@ Cell::Visit(const CellLock &l, TypeContainerVisitor &vi } } } - inline int CellHelper(const float radius) { if(radius < 1.0f) return 0; - return (int)ceilf(radius/SIZE_OF_GRID_CELL); } - inline CellArea Cell::CalculateCellArea(const WorldObject &obj, float radius) { if(radius <= 0.0f) return CellArea(); - //we should increase search radius by object's radius, otherwise //we could have problems with huge creatures, which won't attack nearest players etc radius += obj.GetObjectSize(); @@ -200,23 +180,18 @@ inline CellArea Cell::CalculateCellArea(const WorldObject &obj, float radius) //TODO: add more correct/generic method for this task const float x_offset = (obj.GetPositionX() - CENTER_GRID_CELL_OFFSET)/SIZE_OF_GRID_CELL; const float y_offset = (obj.GetPositionY() - CENTER_GRID_CELL_OFFSET)/SIZE_OF_GRID_CELL; - const float x_val = floor(x_offset + CENTER_GRID_CELL_ID + 0.5f); const float y_val = floor(y_offset + CENTER_GRID_CELL_ID + 0.5f); - const float x_off = (x_offset - x_val + CENTER_GRID_CELL_ID) * SIZE_OF_GRID_CELL; const float y_off = (y_offset - y_val + CENTER_GRID_CELL_ID) * SIZE_OF_GRID_CELL; - const float tmp_diff = radius - CENTER_GRID_CELL_OFFSET; //lets calculate upper/lower/right/left corners for cell search int right = CellHelper(tmp_diff + x_off); int left = CellHelper(tmp_diff - x_off); int upper = CellHelper(tmp_diff + y_off); int lower = CellHelper(tmp_diff - y_off); - return CellArea(right, left, upper, lower); } - template inline void Cell::Visit(const CellLock &l, TypeContainerVisitor &visitor, Map &m, const WorldObject &obj, float radius) const @@ -224,7 +199,6 @@ Cell::Visit(const CellLock &l, TypeContainerVisitor &vi const CellPair &standing_cell = l.i_cellPair; if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP) return; - //no jokes here... Actually placing ASSERT() here was good idea, but //we had some problems with DynamicObjects, which pass radius = 0.0f (DB issue?) //maybe it is better to just return when radius <= 0.0f? @@ -236,7 +210,6 @@ Cell::Visit(const CellLock &l, TypeContainerVisitor &vi //lets limit the upper value for search radius if(radius > 333.0f) radius = 333.0f; - //lets calculate object coord offsets from cell borders. CellArea area = Cell::CalculateCellArea(obj, radius); //if radius fits inside standing cell @@ -245,10 +218,8 @@ Cell::Visit(const CellLock &l, TypeContainerVisitor &vi m.Visit(l, visitor); return; } - CellPair begin_cell = standing_cell; CellPair end_cell = standing_cell; - area.ResizeBorders(begin_cell, end_cell); //visit all cells, found in CalculateCellArea() //if radius is known to reach cell area more than 4x4 then we should call optimized VisitCircle @@ -259,11 +230,9 @@ Cell::Visit(const CellLock &l, TypeContainerVisitor &vi VisitCircle(l, visitor, m, begin_cell, end_cell); return; } - //ALWAYS visit standing cell first!!! Since we deal with small radiuses //it is very essential to call visitor for standing cell firstly... m.Visit(l, visitor); - // loop the cell range for(uint32 x = begin_cell.x_coord; x <= end_cell.x_coord; x++) { @@ -281,7 +250,6 @@ Cell::Visit(const CellLock &l, TypeContainerVisitor &vi } } } - template inline void Cell::VisitCircle(const CellLock &l, TypeContainerVisitor &visitor, Map &m, const CellPair& begin_cell, const CellPair& end_cell) const @@ -291,7 +259,6 @@ Cell::VisitCircle(const CellLock &l, TypeContainerVisitor &l, TypeContainerVisitor &l, TypeContainerVisitordata.Part.nocreate; CellLock lock_left(r_zone_left, cell_pair_left); m.Visit(lock_left, visitor); - //right trapezoid cell visit CellPair cell_pair_right(x_end + step, y); Cell r_zone_right(cell_pair_right); diff --git a/src/game/Channel.cpp b/src/game/Channel.cpp index 72e35a6e777..5ff403b9484 100644 --- a/src/game/Channel.cpp +++ b/src/game/Channel.cpp @@ -17,12 +17,10 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "Channel.h" #include "ObjectMgr.h" #include "SocialMgr.h" #include "World.h" - Channel::Channel(const std::string& name, uint32 channel_id, uint32 Team) : m_name(name), m_announce(true), m_moderate(false), m_channelId(channel_id), m_ownerGUID(0), m_password(""), m_flags(0) { @@ -33,20 +31,16 @@ Channel::Channel(const std::string& name, uint32 channel_id, uint32 Team) { channel_id = ch->ChannelID; // built-in channel m_announce = false; // no join/leave announces - m_flags |= CHANNEL_FLAG_GENERAL; // for all built-in channels - if(ch->flags & CHANNEL_DBC_FLAG_TRADE) // for trade channel m_flags |= CHANNEL_FLAG_TRADE; - if(ch->flags & CHANNEL_DBC_FLAG_CITY_ONLY2) // for city only channels m_flags |= CHANNEL_FLAG_CITY; - if(ch->flags & CHANNEL_DBC_FLAG_LFG) // for LFG channel m_flags |= CHANNEL_FLAG_LFG; else // for all other channels m_flags |= CHANNEL_FLAG_NOT_LFG; - m_IsSaved = false; + m_IsSaved = false; } else // it's custom channel { @@ -62,9 +56,7 @@ Channel::Channel(const std::string& name, uint32 channel_id, uint32 Team) m_moderate = fields[3].GetBool(); m_password = fields[4].GetString(); const char* db_BannedList = fields[5].GetString(); - m_IsSaved = true; - if(db_BannedList) { Tokens tokens = StrSplit(db_BannedList, " "); @@ -87,11 +79,10 @@ Channel::Channel(const std::string& name, uint32 channel_id, uint32 Team) { sLog.outDebug("New Channel(%s) saved", name.c_str()); m_IsSaved = true; - } + } } } } - void Channel::Join(uint64 p, const char *pass) { WorldPacket data; @@ -104,23 +95,19 @@ void Channel::Join(uint64 p, const char *pass) } return; } - if(IsBanned(p)) { MakeBanned(&data); SendToOne(&data, p); return; } - if(m_password.length() > 0 && strcmp(pass, m_password.c_str())) { MakeWrongPassword(&data); SendToOne(&data, p); return; } - Player *plr = objmgr.GetPlayer(p); - if(plr) { if(HasFlag(CHANNEL_FLAG_LFG) && @@ -131,36 +118,28 @@ void Channel::Join(uint64 p, const char *pass) SendToOne(&data, p); return; } - if(plr->GetGuildId() && (GetFlags() == 0x38)) return; - plr->JoinedChannel(this); } - if(m_announce && (!plr || plr->GetSession()->GetSecurity() < SEC_GAMEMASTER || !sWorld.getConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL) )) { MakeJoined(&data, p); SendToAll(&data); } - data.clear(); - PlayerInfo pinfo; pinfo.player = p; pinfo.flags = MEMBER_FLAG_NONE; players[p] = pinfo; - MakeYouJoined(&data); SendToOne(&data, p); - JoinNotify(p); - // if no owner first logged will become if(!IsConstant() && !m_ownerGUID) { SetOwner(p, (players.size() > 1 ? true : false)); - players[p].SetModerator(true); + players[p].SetModerator(true); } /* else if(!IsConstant() && m_ownerGUID && plr && m_ownerGUID == plr->GetGUID() )) @@ -169,7 +148,6 @@ void Channel::Join(uint64 p, const char *pass) players[p].SetModerator(true); }*/ } - void Channel::Leave(uint64 p, bool send) { if(!IsOn(p)) @@ -184,7 +162,6 @@ void Channel::Leave(uint64 p, bool send) else { Player *plr = objmgr.GetPlayer(p); - if(send) { WorldPacket data; @@ -194,9 +171,7 @@ void Channel::Leave(uint64 p, bool send) plr->LeftChannel(this); data.clear(); } - bool changeowner = players[p].IsOwner(); - players.erase(p); if(m_announce && (!plr || plr->GetSession()->GetSecurity() < SEC_GAMEMASTER || !sWorld.getConfig(CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL) )) { @@ -204,9 +179,7 @@ void Channel::Leave(uint64 p, bool send) MakeLeft(&data, p); SendToAll(&data); } - LeaveNotify(p); - if(changeowner) { uint64 newowner = !players.empty() ? players.begin()->second.player : 0; @@ -215,14 +188,12 @@ void Channel::Leave(uint64 p, bool send) } } } - void Channel::KickOrBan(uint64 good, const char *badname, bool ban) { AccountTypes sec = SEC_PLAYER; Player *gplr = objmgr.GetPlayer(good); if(gplr) sec = gplr->GetSession()->GetSecurity(); - if(!IsOn(good)) { WorldPacket data; @@ -253,9 +224,7 @@ void Channel::KickOrBan(uint64 good, const char *badname, bool ban) else { bool changeowner = (m_ownerGUID == bad->GetGUID()); - WorldPacket data; - if(ban && !IsBanned(bad->GetGUID())) { banned.insert(bad->GetGUID()); @@ -274,17 +243,14 @@ void Channel::KickOrBan(uint64 good, const char *badname, bool ban) if(CharacterDatabase.PExecute( ss.str( ).c_str( ) )) { sLog.outDebug("Channel(%s) BannedList saved", m_name.c_str()); - } + } } - } else MakePlayerKicked(&data, bad->GetGUID(), good); - SendToAll(&data); players.erase(bad->GetGUID()); bad->LeftChannel(this); - if(changeowner) { uint64 newowner = !players.empty() ? good : false; @@ -294,14 +260,12 @@ void Channel::KickOrBan(uint64 good, const char *badname, bool ban) } } } - void Channel::UnBan(uint64 good, const char *badname) { uint32 sec = 0; Player *gplr = objmgr.GetPlayer(good); if(gplr) sec = gplr->GetSession()->GetSecurity(); - if(!IsOn(good)) { WorldPacket data; @@ -326,7 +290,6 @@ void Channel::UnBan(uint64 good, const char *badname) else { banned.erase(bad->GetGUID()); - WorldPacket data; MakePlayerUnbanned(&data, bad->GetGUID(), good); SendToAll(&data); @@ -344,19 +307,17 @@ void Channel::UnBan(uint64 good, const char *badname) if(CharacterDatabase.PExecute( ss.str( ).c_str( ) )) { sLog.outDebug("Channel(%s) BannedList saved", m_name.c_str()); - } + } } } } } - void Channel::Password(uint64 p, const char *pass) { uint32 sec = 0; Player *plr = objmgr.GetPlayer(p); if(plr) sec = plr->GetSession()->GetSecurity(); - if(!IsOn(p)) { WorldPacket data; @@ -372,7 +333,6 @@ void Channel::Password(uint64 p, const char *pass) else { m_password = pass; - WorldPacket data; MakePasswordChanged(&data, p); SendToAll(&data); @@ -383,19 +343,16 @@ void Channel::Password(uint64 p, const char *pass) if(CharacterDatabase.PExecute( ss.str( ).c_str( ) )) { sLog.outDebug("Channel(%s) password saved", m_name.c_str()); - } + } } } } - void Channel::SetMode(uint64 p, const char *p2n, bool mod, bool set) { Player *plr = objmgr.GetPlayer(p); if (!plr) return; - uint32 sec = plr->GetSession()->GetSecurity(); - if(!IsOn(p)) { WorldPacket data; @@ -418,11 +375,9 @@ void Channel::SetMode(uint64 p, const char *p2n, bool mod, bool set) SendToOne(&data, p); return; } - PlayerInfo inf = players[newp->GetGUID()]; if(p == m_ownerGUID && newp->GetGUID() == m_ownerGUID && mod) return; - if(!IsOn(newp->GetGUID())) { WorldPacket data; @@ -430,7 +385,6 @@ void Channel::SetMode(uint64 p, const char *p2n, bool mod, bool set) SendToOne(&data, p); return; } - // allow make moderator from another team only if both is GMs // at this moment this only way to show channel post for GM from another team if( (plr->GetSession()->GetSecurity() < SEC_GAMEMASTER || newp->GetSession()->GetSecurity() < SEC_GAMEMASTER) && @@ -441,7 +395,6 @@ void Channel::SetMode(uint64 p, const char *p2n, bool mod, bool set) SendToOne(&data, p); return; } - if(m_ownerGUID == newp->GetGUID() && m_ownerGUID != p) { WorldPacket data; @@ -449,22 +402,18 @@ void Channel::SetMode(uint64 p, const char *p2n, bool mod, bool set) SendToOne(&data, p); return; } - if(mod) SetModerator(newp->GetGUID(), set); else SetMute(newp->GetGUID(), set); } } - void Channel::SetOwner(uint64 p, const char *newname) { Player *plr = objmgr.GetPlayer(p); if (!plr) return; - uint32 sec = plr->GetSession()->GetSecurity(); - if(!IsOn(p)) { WorldPacket data; @@ -472,7 +421,6 @@ void Channel::SetOwner(uint64 p, const char *newname) SendToOne(&data, p); return; } - if(sec < SEC_GAMEMASTER && p != m_ownerGUID) { WorldPacket data; @@ -480,7 +428,6 @@ void Channel::SetOwner(uint64 p, const char *newname) SendToOne(&data, p); return; } - Player *newp = objmgr.GetPlayer(newname); if(newp == NULL || !IsOn(newp->GetGUID())) { @@ -489,7 +436,6 @@ void Channel::SetOwner(uint64 p, const char *newname) SendToOne(&data, p); return; } - if(newp->GetTeam() != plr->GetTeam() && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL)) { WorldPacket data; @@ -497,11 +443,9 @@ void Channel::SetOwner(uint64 p, const char *newname) SendToOne(&data, p); return; } - players[newp->GetGUID()].SetModerator(true); SetOwner(newp->GetGUID()); } - void Channel::SendWhoOwner(uint64 p) { if(!IsOn(p)) @@ -517,11 +461,9 @@ void Channel::SendWhoOwner(uint64 p) SendToOne(&data, p); } } - void Channel::List(Player* player) { uint64 p = player->GetGUID(); - if(!IsOn(p)) { WorldPacket data; @@ -534,17 +476,13 @@ void Channel::List(Player* player) data << uint8(1); // channel type? data << GetName(); // channel name data << uint8(GetFlags()); // channel flags? - size_t pos = data.wpos(); data << uint32(0); // size of list, placeholder - uint32 gmLevelInWhoList = sWorld.getConfig(CONFIG_GM_LEVEL_IN_WHO_LIST); - uint32 count = 0; for(PlayerList::const_iterator i = players.begin(); i != players.end(); ++i) { Player *plr = objmgr.GetPlayer(i->first); - // PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters // MODERATOR, GAME MASTER, ADMINISTRATOR can see all if (plr && (player->GetSession()->GetSecurity() > SEC_PLAYER || plr->GetSession()->GetSecurity() <= gmLevelInWhoList) && @@ -555,20 +493,16 @@ void Channel::List(Player* player) ++count; } } - data.put(pos,count); - SendToOne(&data, p); } } - void Channel::Announce(uint64 p) { uint32 sec = 0; Player *plr = objmgr.GetPlayer(p); if(plr) sec = plr->GetSession()->GetSecurity(); - if(!IsOn(p)) { WorldPacket data; @@ -584,7 +518,6 @@ void Channel::Announce(uint64 p) else { m_announce = !m_announce; - WorldPacket data; if(m_announce) MakeAnnouncementsOn(&data, p); @@ -598,19 +531,16 @@ void Channel::Announce(uint64 p) if(CharacterDatabase.PExecute( ss.str( ).c_str( ) )) { sLog.outDebug("Channel(%s) announce saved", m_name.c_str()); - } + } } - } } - void Channel::Moderate(uint64 p) { uint32 sec = 0; Player *plr = objmgr.GetPlayer(p); if(plr) sec = plr->GetSession()->GetSecurity(); - if(!IsOn(p)) { WorldPacket data; @@ -626,7 +556,6 @@ void Channel::Moderate(uint64 p) else { m_moderate = !m_moderate; - WorldPacket data; if(m_moderate) MakeModerationOn(&data, p); @@ -640,23 +569,20 @@ void Channel::Moderate(uint64 p) if(CharacterDatabase.PExecute( ss.str( ).c_str( ) )) { sLog.outDebug("Channel(%s) moderate saved", m_name.c_str()); - } + } } } } - void Channel::Say(uint64 p, const char *what, uint32 lang) { if(!what) return; if (sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL)) lang = LANG_UNIVERSAL; - uint32 sec = 0; Player *plr = objmgr.GetPlayer(p); if(plr) sec = plr->GetSession()->GetSecurity(); - if(!IsOn(p)) { WorldPacket data; @@ -678,7 +604,6 @@ void Channel::Say(uint64 p, const char *what, uint32 lang) else { uint32 messageLength = strlen(what) + 1; - WorldPacket data(SMSG_MESSAGECHAT, 1+4+8+4+m_name.size()+1+8+4+messageLength+1); data << (uint8)CHAT_MSG_CHANNEL; data << (uint32)lang; @@ -689,11 +614,9 @@ void Channel::Say(uint64 p, const char *what, uint32 lang) data << messageLength; data << what; data << uint8(plr ? plr->chatTag() : 0); - SendToAll(&data, !players[p].IsModerator() ? p : false); } } - void Channel::Invite(uint64 p, const char *newname) { if(!IsOn(p)) @@ -703,7 +626,6 @@ void Channel::Invite(uint64 p, const char *newname) SendToOne(&data, p); return; } - Player *newp = objmgr.GetPlayer(newname); if(!newp) { @@ -712,11 +634,9 @@ void Channel::Invite(uint64 p, const char *newname) SendToOne(&data, p); return; } - Player *plr = objmgr.GetPlayer(p); if (!plr) return; - if (newp->GetTeam() != plr->GetTeam() && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL)) { WorldPacket data; @@ -724,7 +644,6 @@ void Channel::Invite(uint64 p, const char *newname) SendToOne(&data, p); return; } - if(IsOn(newp->GetGUID())) { WorldPacket data; @@ -732,7 +651,6 @@ void Channel::Invite(uint64 p, const char *newname) SendToOne(&data, p); return; } - WorldPacket data; if(!newp->GetSocial()->HasIgnore(GUID_LOPART(p))) { @@ -743,7 +661,6 @@ void Channel::Invite(uint64 p, const char *newname) MakePlayerInvited(&data, newp->GetName()); SendToOne(&data, p); } - void Channel::SetOwner(uint64 guid, bool exclaim) { if(m_ownerGUID) @@ -753,18 +670,15 @@ void Channel::SetOwner(uint64 guid, bool exclaim) if(p_itr != players.end()) p_itr->second.SetOwner(false); } - m_ownerGUID = guid; if(m_ownerGUID) { uint8 oldFlag = GetPlayerFlags(m_ownerGUID); players[m_ownerGUID].SetModerator(true); players[m_ownerGUID].SetOwner(true); - WorldPacket data; MakeModeChange(&data, m_ownerGUID, oldFlag); SendToAll(&data); - if(exclaim) { MakeOwnerChanged(&data, m_ownerGUID); @@ -777,12 +691,10 @@ void Channel::SetOwner(uint64 guid, bool exclaim) if(CharacterDatabase.PExecute( ss.str( ).c_str( ) )) { sLog.outDebug("Channel(%s) owner saved", m_name.c_str()); - } + } }*/ - } } - void Channel::SendToAll(WorldPacket *data, uint64 p) { for(PlayerList::const_iterator i = players.begin(); i != players.end(); ++i) @@ -795,7 +707,6 @@ void Channel::SendToAll(WorldPacket *data, uint64 p) } } } - void Channel::SendToAllButOne(WorldPacket *data, uint64 who) { for(PlayerList::const_iterator i = players.begin(); i != players.end(); ++i) @@ -808,24 +719,18 @@ void Channel::SendToAllButOne(WorldPacket *data, uint64 who) } } } - void Channel::SendToOne(WorldPacket *data, uint64 who) { Player *plr = objmgr.GetPlayer(who); if(plr) plr->GetSession()->SendPacket(data); } - void Channel::Voice(uint64 /*guid1*/, uint64 /*guid2*/) { - } - void Channel::DeVoice(uint64 /*guid1*/, uint64 /*guid2*/) { - } - // done void Channel::MakeNotifyPacket(WorldPacket *data, uint8 notify_type) { @@ -833,21 +738,18 @@ void Channel::MakeNotifyPacket(WorldPacket *data, uint8 notify_type) *data << uint8(notify_type); *data << m_name; } - // done 0x00 void Channel::MakeJoined(WorldPacket *data, uint64 guid) { MakeNotifyPacket(data, CHAT_JOINED_NOTICE); *data << uint64(guid); } - // done 0x01 void Channel::MakeLeft(WorldPacket *data, uint64 guid) { MakeNotifyPacket(data, CHAT_LEFT_NOTICE); *data << uint64(guid); } - // done 0x02 void Channel::MakeYouJoined(WorldPacket *data) { @@ -856,7 +758,6 @@ void Channel::MakeYouJoined(WorldPacket *data) *data << uint32(GetChannelId()); *data << uint32(0); } - // done 0x03 void Channel::MakeYouLeft(WorldPacket *data) { @@ -864,64 +765,53 @@ void Channel::MakeYouLeft(WorldPacket *data) *data << uint32(GetChannelId()); *data << uint8(0); // can be 0x00 and 0x01 } - // done 0x04 void Channel::MakeWrongPassword(WorldPacket *data) { MakeNotifyPacket(data, CHAT_WRONG_PASSWORD_NOTICE); } - // done 0x05 void Channel::MakeNotMember(WorldPacket *data) { MakeNotifyPacket(data, CHAT_NOT_MEMBER_NOTICE); } - // done 0x06 void Channel::MakeNotModerator(WorldPacket *data) { MakeNotifyPacket(data, CHAT_NOT_MODERATOR_NOTICE); } - // done 0x07 void Channel::MakePasswordChanged(WorldPacket *data, uint64 guid) { MakeNotifyPacket(data, CHAT_PASSWORD_CHANGED_NOTICE); *data << uint64(guid); } - // done 0x08 void Channel::MakeOwnerChanged(WorldPacket *data, uint64 guid) { MakeNotifyPacket(data, CHAT_OWNER_CHANGED_NOTICE); *data << uint64(guid); } - // done 0x09 void Channel::MakePlayerNotFound(WorldPacket *data, const std::string& name) { MakeNotifyPacket(data, CHAT_PLAYER_NOT_FOUND_NOTICE); *data << name; } - // done 0x0A void Channel::MakeNotOwner(WorldPacket *data) { MakeNotifyPacket(data, CHAT_NOT_OWNER_NOTICE); } - // done 0x0B void Channel::MakeChannelOwner(WorldPacket *data) { std::string name = ""; - if(!objmgr.GetPlayerNameByGUID(m_ownerGUID, name) || name.empty()) name = "PLAYER_NOT_FOUND"; - MakeNotifyPacket(data, CHAT_CHANNEL_OWNER_NOTICE); *data << ((IsConstant() || !m_ownerGUID) ? "Nobody" : name); } - // done 0x0C void Channel::MakeModeChange(WorldPacket *data, uint64 guid, uint8 oldflags) { @@ -930,41 +820,35 @@ void Channel::MakeModeChange(WorldPacket *data, uint64 guid, uint8 oldflags) *data << uint8(oldflags); *data << uint8(GetPlayerFlags(guid)); } - // done 0x0D void Channel::MakeAnnouncementsOn(WorldPacket *data, uint64 guid) { MakeNotifyPacket(data, CHAT_ANNOUNCEMENTS_ON_NOTICE); *data << uint64(guid); } - // done 0x0E void Channel::MakeAnnouncementsOff(WorldPacket *data, uint64 guid) { MakeNotifyPacket(data, CHAT_ANNOUNCEMENTS_OFF_NOTICE); *data << uint64(guid); } - // done 0x0F void Channel::MakeModerationOn(WorldPacket *data, uint64 guid) { MakeNotifyPacket(data, CHAT_MODERATION_ON_NOTICE); *data << uint64(guid); } - // done 0x10 void Channel::MakeModerationOff(WorldPacket *data, uint64 guid) { MakeNotifyPacket(data, CHAT_MODERATION_OFF_NOTICE); *data << uint64(guid); } - // done 0x11 void Channel::MakeMuted(WorldPacket *data) { MakeNotifyPacket(data, CHAT_MUTED_NOTICE); } - // done 0x12 void Channel::MakePlayerKicked(WorldPacket *data, uint64 bad, uint64 good) { @@ -972,13 +856,11 @@ void Channel::MakePlayerKicked(WorldPacket *data, uint64 bad, uint64 good) *data << uint64(bad); *data << uint64(good); } - // done 0x13 void Channel::MakeBanned(WorldPacket *data) { MakeNotifyPacket(data, CHAT_BANNED_NOTICE); } - // done 0x14 void Channel::MakePlayerBanned(WorldPacket *data, uint64 bad, uint64 good) { @@ -986,7 +868,6 @@ void Channel::MakePlayerBanned(WorldPacket *data, uint64 bad, uint64 good) *data << uint64(bad); *data << uint64(good); } - // done 0x15 void Channel::MakePlayerUnbanned(WorldPacket *data, uint64 bad, uint64 good) { @@ -994,107 +875,90 @@ void Channel::MakePlayerUnbanned(WorldPacket *data, uint64 bad, uint64 good) *data << uint64(bad); *data << uint64(good); } - // done 0x16 void Channel::MakePlayerNotBanned(WorldPacket *data, uint64 guid) { MakeNotifyPacket(data, CHAT_PLAYER_NOT_BANNED_NOTICE); *data << uint64(guid); } - // done 0x17 void Channel::MakePlayerAlreadyMember(WorldPacket *data, uint64 guid) { MakeNotifyPacket(data, CHAT_PLAYER_ALREADY_MEMBER_NOTICE); *data << uint64(guid); } - // done 0x18 void Channel::MakeInvite(WorldPacket *data, uint64 guid) { MakeNotifyPacket(data, CHAT_INVITE_NOTICE); *data << uint64(guid); } - // done 0x19 void Channel::MakeInviteWrongFaction(WorldPacket *data) { MakeNotifyPacket(data, CHAT_INVITE_WRONG_FACTION_NOTICE); } - // done 0x1A void Channel::MakeWrongFaction(WorldPacket *data) { MakeNotifyPacket(data, CHAT_WRONG_FACTION_NOTICE); } - // done 0x1B void Channel::MakeInvalidName(WorldPacket *data) { MakeNotifyPacket(data, CHAT_INVALID_NAME_NOTICE); } - // done 0x1C void Channel::MakeNotModerated(WorldPacket *data) { MakeNotifyPacket(data, CHAT_NOT_MODERATED_NOTICE); } - // done 0x1D void Channel::MakePlayerInvited(WorldPacket *data, const std::string& name) { MakeNotifyPacket(data, CHAT_PLAYER_INVITED_NOTICE); *data << name; } - // done 0x1E void Channel::MakePlayerInviteBanned(WorldPacket *data, uint64 guid) { MakeNotifyPacket(data, CHAT_PLAYER_INVITE_BANNED_NOTICE); *data << uint64(guid); } - // done 0x1F void Channel::MakeThrottled(WorldPacket *data) { MakeNotifyPacket(data, CHAT_THROTTLED_NOTICE); } - // done 0x20 void Channel::MakeNotInArea(WorldPacket *data) { MakeNotifyPacket(data, CHAT_NOT_IN_AREA_NOTICE); } - // done 0x21 void Channel::MakeNotInLfg(WorldPacket *data) { MakeNotifyPacket(data, CHAT_NOT_IN_LFG_NOTICE); } - // done 0x22 void Channel::MakeVoiceOn(WorldPacket *data, uint64 guid) { MakeNotifyPacket(data, CHAT_VOICE_ON_NOTICE); *data << uint64(guid); } - // done 0x23 void Channel::MakeVoiceOff(WorldPacket *data, uint64 guid) { MakeNotifyPacket(data, CHAT_VOICE_OFF_NOTICE); *data << uint64(guid); } - void Channel::JoinNotify(uint64 guid) { WorldPacket data; - if(IsConstant()) data.Initialize(SMSG_USERLIST_ADD, 8+1+1+4+GetName().size()+1); else data.Initialize(SMSG_USERLIST_UPDATE, 8+1+1+4+GetName().size()+1); - data << uint64(guid); data << uint8(GetPlayerFlags(guid)); data << uint8(GetFlags()); @@ -1102,7 +966,6 @@ void Channel::JoinNotify(uint64 guid) data << GetName(); SendToAll(&data); } - void Channel::LeaveNotify(uint64 guid) { WorldPacket data(SMSG_USERLIST_REMOVE, 8+1+4+GetName().size()+1); diff --git a/src/game/Channel.h b/src/game/Channel.h index 69a1e2f66f6..b97acd52360 100644 --- a/src/game/Channel.h +++ b/src/game/Channel.h @@ -17,20 +17,15 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef _CHANNEL_H #define _CHANNEL_H - #include #include #include - #include "Common.h" - #include "Opcodes.h" #include "Player.h" #include "WorldPacket.h" - enum ChatNotify { CHAT_JOINED_NOTICE = 0x00, //+ "%s joined channel."; @@ -72,7 +67,6 @@ enum ChatNotify CHAT_VOICE_ON_NOTICE = 0x22, //+ "[%s] Channel voice enabled by %s."; CHAT_VOICE_OFF_NOTICE = 0x23, //+ "[%s] Channel voice disabled by %s."; }; - enum ChannelFlags { CHANNEL_FLAG_NONE = 0x00, @@ -90,7 +84,6 @@ enum ChannelFlags // GuildRecruitment 0x38 = 0x20 | 0x10 | 0x08 // LookingForGroup 0x50 = 0x40 | 0x10 }; - enum ChannelDBCFlags { CHANNEL_DBC_FLAG_NONE = 0x00000, @@ -104,7 +97,6 @@ enum ChannelDBCFlags CHANNEL_DBC_FLAG_GUILD_REQ = 0x20000, // GuildRecruitment CHANNEL_DBC_FLAG_LFG = 0x40000 // LookingForGroup }; - enum ChannelMemberFlags { MEMBER_FLAG_NONE = 0x00, @@ -117,14 +109,12 @@ enum ChannelMemberFlags // 0x40 // 0x80 }; - class Channel { struct PlayerInfo { uint64 player; uint8 flags; - bool HasFlag(uint8 flag) { return flags & flag; } void SetFlag(uint8 flag) { if(!HasFlag(flag)) flags |= flag; } bool IsOwner() { return flags & MEMBER_FLAG_OWNER; } @@ -146,7 +136,6 @@ class Channel else flags &= ~MEMBER_FLAG_MUTED; } }; - typedef std::map PlayerList; PlayerList players; typedef std::set BannedList; @@ -159,7 +148,6 @@ class Channel uint32 m_channelId; uint64 m_ownerGUID; bool m_IsSaved; - private: // initial packet data (notify type and channel name) void MakeNotifyPacket(WorldPacket *data, uint8 notify_type); @@ -200,49 +188,40 @@ class Channel void MakeNotInLfg(WorldPacket *data); //? 0x21 void MakeVoiceOn(WorldPacket *data, uint64 guid); //+ 0x22 void MakeVoiceOff(WorldPacket *data, uint64 guid); //+ 0x23 - void SendToAll(WorldPacket *data, uint64 p = 0); void SendToAllButOne(WorldPacket *data, uint64 who); void SendToOne(WorldPacket *data, uint64 who); - bool IsOn(uint64 who) const { return players.find(who) != players.end(); } bool IsBanned(uint64 guid) const { return banned.find(guid) != banned.end(); } - uint8 GetPlayerFlags(uint64 p) const { PlayerList::const_iterator p_itr = players.find(p); if(p_itr == players.end()) return 0; - return p_itr->second.flags; } - void SetModerator(uint64 p, bool set) { if(players[p].IsModerator() != set) { uint8 oldFlag = GetPlayerFlags(p); players[p].SetModerator(set); - WorldPacket data; MakeModeChange(&data, p, oldFlag); SendToAll(&data); } } - void SetMute(uint64 p, bool set) { if(players[p].IsMuted() != set) { uint8 oldFlag = GetPlayerFlags(p); players[p].SetMuted(set); - WorldPacket data; MakeModeChange(&data, p, oldFlag); SendToAll(&data); } } - public: uint32 m_Team; Channel(const std::string& name, uint32 channel_id, uint32 Team = 0); @@ -257,7 +236,6 @@ class Channel uint32 GetNumPlayers() const { return players.size(); } uint8 GetFlags() const { return m_flags; } bool HasFlag(uint8 flag) { return m_flags & flag; } - void Join(uint64 p, const char *pass); void Leave(uint64 p, bool send = true); void KickOrBan(uint64 good, const char *badname, bool ban); diff --git a/src/game/ChannelHandler.cpp b/src/game/ChannelHandler.cpp index abf73e0e274..d50c579cd9b 100644 --- a/src/game/ChannelHandler.cpp +++ b/src/game/ChannelHandler.cpp @@ -18,26 +18,19 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "Policies/SingletonImp.h" - #include "ObjectMgr.h" // for normalizePlayerName #include "ChannelMgr.h" - void WorldSession::HandleJoinChannel(WorldPacket& recvPacket) { sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); - uint32 channel_id; uint8 unknown1, unknown2; std::string channelname, pass; - recvPacket >> channel_id >> unknown1 >> unknown2; recvPacket >> channelname; - if(channelname.empty()) return; - recvPacket >> pass; if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) { @@ -46,20 +39,16 @@ void WorldSession::HandleJoinChannel(WorldPacket& recvPacket) chn->Join(_player->GetGUID(), pass.c_str()); } } - void WorldSession::HandleLeaveChannel(WorldPacket& recvPacket) { sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); //recvPacket.hexlike(); - uint32 unk; std::string channelname; recvPacket >> unk; // channel id? recvPacket >> channelname; - if(channelname.empty()) return; - if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) { if(Channel *chn = cMgr->GetChannel(channelname, _player)) @@ -67,50 +56,40 @@ void WorldSession::HandleLeaveChannel(WorldPacket& recvPacket) cMgr->LeftChannel(channelname); } } - void WorldSession::HandleChannelList(WorldPacket& recvPacket) { sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); //recvPacket.hexlike(); std::string channelname; recvPacket >> channelname; - if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) if(Channel *chn = cMgr->GetChannel(channelname, _player)) chn->List(_player); } - void WorldSession::HandleChannelPassword(WorldPacket& recvPacket) { sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); //recvPacket.hexlike(); std::string channelname, pass; recvPacket >> channelname; - recvPacket >> pass; - if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) if(Channel *chn = cMgr->GetChannel(channelname, _player)) chn->Password(_player->GetGUID(), pass.c_str()); } - void WorldSession::HandleChannelSetOwner(WorldPacket& recvPacket) { sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); //recvPacket.hexlike(); std::string channelname, newp; recvPacket >> channelname; - recvPacket >> newp; - if(!normalizePlayerName(newp)) return; - if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) if(Channel *chn = cMgr->GetChannel(channelname, _player)) chn->SetOwner(_player->GetGUID(), newp.c_str()); } - void WorldSession::HandleChannelOwner(WorldPacket& recvPacket) { sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); @@ -121,144 +100,110 @@ void WorldSession::HandleChannelOwner(WorldPacket& recvPacket) if(Channel *chn = cMgr->GetChannel(channelname, _player)) chn->SendWhoOwner(_player->GetGUID()); } - void WorldSession::HandleChannelModerator(WorldPacket& recvPacket) { sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); //recvPacket.hexlike(); std::string channelname, otp; recvPacket >> channelname; - recvPacket >> otp; - if(!normalizePlayerName(otp)) return; - if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) if(Channel *chn = cMgr->GetChannel(channelname, _player)) chn->SetModerator(_player->GetGUID(), otp.c_str()); } - void WorldSession::HandleChannelUnmoderator(WorldPacket& recvPacket) { sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); //recvPacket.hexlike(); std::string channelname, otp; recvPacket >> channelname; - recvPacket >> otp; - if(!normalizePlayerName(otp)) return; - if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) if(Channel *chn = cMgr->GetChannel(channelname, _player)) chn->UnsetModerator(_player->GetGUID(), otp.c_str()); } - void WorldSession::HandleChannelMute(WorldPacket& recvPacket) { sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); //recvPacket.hexlike(); std::string channelname, otp; recvPacket >> channelname; - recvPacket >> otp; - if(!normalizePlayerName(otp)) return; - if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) if(Channel *chn = cMgr->GetChannel(channelname, _player)) chn->SetMute(_player->GetGUID(), otp.c_str()); } - void WorldSession::HandleChannelUnmute(WorldPacket& recvPacket) { sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); //recvPacket.hexlike(); - std::string channelname, otp; recvPacket >> channelname; - recvPacket >> otp; - if(!normalizePlayerName(otp)) return; - if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) if(Channel *chn = cMgr->GetChannel(channelname, _player)) chn->UnsetMute(_player->GetGUID(), otp.c_str()); } - void WorldSession::HandleChannelInvite(WorldPacket& recvPacket) { sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); //recvPacket.hexlike(); std::string channelname, otp; recvPacket >> channelname; - recvPacket >> otp; - if(!normalizePlayerName(otp)) return; - if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) if(Channel *chn = cMgr->GetChannel(channelname, _player)) chn->Invite(_player->GetGUID(), otp.c_str()); } - void WorldSession::HandleChannelKick(WorldPacket& recvPacket) { sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); //recvPacket.hexlike(); std::string channelname, otp; recvPacket >> channelname; - recvPacket >> otp; if(!normalizePlayerName(otp)) return; - if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) if(Channel *chn = cMgr->GetChannel(channelname, _player)) chn->Kick(_player->GetGUID(), otp.c_str()); } - void WorldSession::HandleChannelBan(WorldPacket& recvPacket) { sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); //recvPacket.hexlike(); std::string channelname, otp; recvPacket >> channelname; - recvPacket >> otp; - if(!normalizePlayerName(otp)) return; - if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) if(Channel *chn = cMgr->GetChannel(channelname, _player)) chn->Ban(_player->GetGUID(), otp.c_str()); } - void WorldSession::HandleChannelUnban(WorldPacket& recvPacket) { sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); //recvPacket.hexlike(); - std::string channelname, otp; recvPacket >> channelname; - recvPacket >> otp; - if(!normalizePlayerName(otp)) return; - if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) if(Channel *chn = cMgr->GetChannel(channelname, _player)) chn->UnBan(_player->GetGUID(), otp.c_str()); } - void WorldSession::HandleChannelAnnouncements(WorldPacket& recvPacket) { sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); @@ -269,7 +214,6 @@ void WorldSession::HandleChannelAnnouncements(WorldPacket& recvPacket) if(Channel *chn = cMgr->GetChannel(channelname, _player)) chn->Announce(_player->GetGUID()); } - void WorldSession::HandleChannelModerate(WorldPacket& recvPacket) { sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); @@ -280,7 +224,6 @@ void WorldSession::HandleChannelModerate(WorldPacket& recvPacket) if(Channel *chn = cMgr->GetChannel(channelname, _player)) chn->Moderate(_player->GetGUID()); } - void WorldSession::HandleChannelDisplayListQuery(WorldPacket &recvPacket) { sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); @@ -291,7 +234,6 @@ void WorldSession::HandleChannelDisplayListQuery(WorldPacket &recvPacket) if(Channel *chn = cMgr->GetChannel(channelname, _player)) chn->List(_player); } - void WorldSession::HandleGetChannelMemberCount(WorldPacket &recvPacket) { sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); @@ -310,7 +252,6 @@ void WorldSession::HandleGetChannelMemberCount(WorldPacket &recvPacket) } } } - void WorldSession::HandleSetChannelWatch(WorldPacket &recvPacket) { sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); diff --git a/src/game/ChannelMgr.cpp b/src/game/ChannelMgr.cpp index 09d172155cc..8994d84b23f 100644 --- a/src/game/ChannelMgr.cpp +++ b/src/game/ChannelMgr.cpp @@ -15,35 +15,27 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "ChannelMgr.h" #include "Policies/SingletonImp.h" #include "World.h" - INSTANTIATE_SINGLETON_1( AllianceChannelMgr ); INSTANTIATE_SINGLETON_1( HordeChannelMgr ); - ChannelMgr* channelMgr(uint32 team) { if (sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL)) return &MaNGOS::Singleton::Instance(); // cross-faction - if(team == ALLIANCE) return &MaNGOS::Singleton::Instance(); if(team == HORDE) return &MaNGOS::Singleton::Instance(); - return NULL; } - ChannelMgr::~ChannelMgr() { for(ChannelMap::iterator itr = channels.begin();itr!=channels.end(); ++itr) delete itr->second; - channels.clear(); } - Channel *ChannelMgr::GetJoinChannel(std::string name, uint32 channel_id) { if (channels.find(name) == channels.end()) @@ -51,14 +43,11 @@ Channel *ChannelMgr::GetJoinChannel(std::string name, uint32 channel_id) Channel *nchan = new Channel(name,channel_id, team); channels[name] = nchan; } - return channels[name]; } - Channel *ChannelMgr::GetChannel(std::string name, Player *p, bool pkt) { ChannelMap::const_iterator i = channels.find(name); - if(i == channels.end()) { if(pkt) @@ -67,29 +56,23 @@ Channel *ChannelMgr::GetChannel(std::string name, Player *p, bool pkt) MakeNotOnPacket(&data,name); p->GetSession()->SendPacket(&data); } - return NULL; } else return i->second; } - void ChannelMgr::LeftChannel(std::string name) { ChannelMap::const_iterator i = channels.find(name); - if(i == channels.end()) return; - Channel* channel = i->second; - if(channel->GetNumPlayers() == 0 && !channel->IsConstant()) { channels.erase(name); delete channel; } } - void ChannelMgr::MakeNotOnPacket(WorldPacket *data, std::string name) { data->Initialize(SMSG_CHANNEL_NOTIFY, (1+10)); // we guess size diff --git a/src/game/ChannelMgr.h b/src/game/ChannelMgr.h index f65a8520648..5bf07d609b9 100644 --- a/src/game/ChannelMgr.h +++ b/src/game/ChannelMgr.h @@ -19,19 +19,14 @@ */ #ifndef MANGOSSERVER_CHANNELMGR_H #define MANGOSSERVER_CHANNELMGR_H - #include "Common.h" #include "Channel.h" #include "Policies/Singleton.h" - #include #include - #include "Policies/Singleton.h" - #include "Channel.h" #include "World.h" - class ChannelMgr { public: @@ -39,7 +34,6 @@ class ChannelMgr typedef std::map ChannelMap; ChannelMgr() {team = 0;} ~ChannelMgr(); - Channel *GetJoinChannel(std::string name, uint32 channel_id); Channel *GetChannel(std::string name, Player *p, bool pkt = true); void LeftChannel(std::string name); @@ -47,11 +41,8 @@ class ChannelMgr ChannelMap channels; void MakeNotOnPacket(WorldPacket *data, std::string name); }; - class AllianceChannelMgr : public ChannelMgr {}; class HordeChannelMgr : public ChannelMgr {}; - ChannelMgr* channelMgr(uint32 team); - #endif diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index e1e6eae86a3..e348d3b6f55 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "Common.h" #include "ObjectAccessor.h" #include "ObjectMgr.h" @@ -28,7 +27,6 @@ #include "Auth/md5.h" #include "Database/DatabaseEnv.h" #include "Database/DatabaseImpl.h" - #include "ArenaTeam.h" #include "Chat.h" #include "Group.h" @@ -43,7 +41,6 @@ #include "UpdateMask.h" #include "Util.h" #include "ScriptCalls.h" - class LoginQueryHolder : public SqlQueryHolder { private: @@ -56,13 +53,10 @@ class LoginQueryHolder : public SqlQueryHolder uint32 GetAccountId() const { return m_accountId; } bool Initialize(); }; - bool LoginQueryHolder::Initialize() { SetSize(MAX_PLAYER_LOGIN_QUERY); - bool res = true; - // NOTE: all fields in `characters` must be read to prevent lost character data at next save in case wrong DB structure. // !!! NOTE: including unused `zone`,`online` res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADFROM, "SELECT guid, account, data, name, race, class, gender, level, xp, money, playerBytes, playerBytes2, playerFlags, position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeon_difficulty, arena_pending_points, instance_id, speccount, activespec FROM characters WHERE guid = '%u'", GUID_LOPART(m_guid)); @@ -92,10 +86,8 @@ bool LoginQueryHolder::Initialize() res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGLYPHS, "SELECT spec, glyph1, glyph2, glyph3, glyph4, glyph5, glyph6 FROM character_glyphs WHERE guid='%u'", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADTALENTS, "SELECT spell, spec FROM character_talent WHERE guid='%u'", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADACCOUNTDATA, "SELECT type, time, data FROM character_account_data WHERE guid='%u'", GUID_LOPART(m_guid)); - return res; } - // don't call WorldSession directly // it may get deleted before the query callbacks get executed // instead pass an account id to this handler @@ -124,15 +116,11 @@ class CharacterHandler session->HandlePlayerLogin((LoginQueryHolder*)holder); } } chrHandler; - void WorldSession::HandleCharEnum(QueryResult * result) { WorldPacket data(SMSG_CHAR_ENUM, 100); // we guess size - uint8 num = 0; - data << num; - if( result ) { do @@ -143,15 +131,11 @@ void WorldSession::HandleCharEnum(QueryResult * result) ++num; } while( result->NextRow() ); - delete result; } - data.put(0, num); - SendPacket( &data ); } - void WorldSession::HandleCharEnumOpcode( WorldPacket & /*recv_data*/ ) { /// get all the data necessary for loading all characters (along with their pets) on the account @@ -181,32 +165,25 @@ void WorldSession::HandleCharEnumOpcode( WorldPacket & /*recv_data*/ ) "WHERE characters.account = '%u' ORDER BY characters.guid", PET_SAVE_AS_CURRENT,GetAccountId()); } - void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) { std::string name; uint8 race_,class_; - recv_data >> name; - recv_data >> race_; recv_data >> class_; - WorldPacket data(SMSG_CHAR_CREATE, 1); // returned with diff.values in all cases - if(GetSecurity() == SEC_PLAYER) { if(uint32 mask = sWorld.getConfig(CONFIG_CHARACTERS_CREATING_DISABLED)) { bool disabled = false; - uint32 team = Player::TeamForRace(race_); switch(team) { case ALLIANCE: disabled = mask & (1<<0); break; case HORDE: disabled = mask & (1<<1); break; } - if(disabled) { data << (uint8)CHAR_CREATE_DISABLED; @@ -215,10 +192,8 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) } } } - ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(class_); ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(race_); - if( !classEntry || !raceEntry ) { data << (uint8)CHAR_CREATE_FAILED; @@ -226,7 +201,6 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) sLog.outError("Class: %u or Race %u not found in DBC (Wrong DBC files?) or Cheater?", class_, race_); return; } - // prevent character creating Expansion race without Expansion account if (raceEntry->addon > Expansion()) { @@ -235,7 +209,6 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) SendPacket( &data ); return; } - // prevent character creating Expansion class without Expansion account if (classEntry->addon > Expansion()) { @@ -244,7 +217,6 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) SendPacket( &data ); return; } - // prevent character creating with invalid name if (!normalizePlayerName(name)) { @@ -253,7 +225,6 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) sLog.outError("Account:[%d] but tried to Create character with empty [name] ",GetAccountId()); return; } - // check name limitations uint8 res = ObjectMgr::CheckPlayerName(name,true); if (res != CHAR_NAME_SUCCESS) @@ -262,28 +233,24 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) SendPacket( &data ); return; } - if (GetSecurity() == SEC_PLAYER && objmgr.IsReservedName(name)) { data << (uint8)CHAR_NAME_RESERVED; SendPacket( &data ); return; } - if (objmgr.GetPlayerGUIDByName(name)) { data << (uint8)CHAR_CREATE_NAME_IN_USE; SendPacket( &data ); return; } - QueryResult *resultacct = loginDatabase.PQuery("SELECT SUM(numchars) FROM realmcharacters WHERE acctid = '%d'", GetAccountId()); if (resultacct) { Field *fields=resultacct->Fetch(); uint32 acctcharcount = fields[0].GetUInt32(); delete resultacct; - if (acctcharcount >= sWorld.getConfig(CONFIG_CHARACTERS_PER_ACCOUNT)) { data << (uint8)CHAR_CREATE_ACCOUNT_LIMIT; @@ -291,7 +258,6 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) return; } } - QueryResult *result = CharacterDatabase.PQuery("SELECT COUNT(guid) FROM characters WHERE account = '%d'", GetAccountId()); uint8 charcount = 0; if ( result ) @@ -299,7 +265,6 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) Field *fields=result->Fetch(); charcount = fields[0].GetUInt8(); delete result; - if (charcount >= sWorld.getConfig(CONFIG_CHARACTERS_PER_REALM)) { data << (uint8)CHAR_CREATE_SERVER_LIMIT; @@ -307,7 +272,6 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) return; } } - // speedup check for heroic class disabled case uint32 heroic_free_slots = sWorld.getConfig(CONFIG_HEROIC_CHARACTERS_PER_REALM); if(heroic_free_slots==0 && GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT) @@ -316,7 +280,6 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) SendPacket( &data ); return; } - // speedup check for heroic class disabled case uint32 req_level_for_heroic = sWorld.getConfig(CONFIG_MIN_LEVEL_FOR_HEROIC_CHARACTER_CREATING); if(GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT && req_level_for_heroic > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)) @@ -325,15 +288,11 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) SendPacket( &data ); return; } - bool AllowTwoSideAccounts = !sWorld.IsPvPRealm() || sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || GetSecurity() > SEC_PLAYER; uint32 skipCinematics = sWorld.getConfig(CONFIG_SKIP_CINEMATICS); - bool have_same_race = false; - // if 0 then allowed creating without any characters bool have_req_level_for_heroic = (req_level_for_heroic==0); - if(!AllowTwoSideAccounts || skipCinematics == 1 || class_ == CLASS_DEATH_KNIGHT) { QueryResult *result2 = CharacterDatabase.PQuery("SELECT level,race,class FROM characters WHERE account = '%u' %s", @@ -341,10 +300,8 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) if(result2) { uint32 team_= Player::TeamForRace(race_); - Field* field = result2->Fetch(); uint8 acc_race = field[1].GetUInt32(); - if(GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT) { uint8 acc_class = field[2].GetUInt32(); @@ -352,7 +309,6 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) { if(heroic_free_slots > 0) --heroic_free_slots; - if(heroic_free_slots==0) { data << (uint8)CHAR_CREATE_UNIQUE_CLASS_LIMIT; @@ -360,7 +316,6 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) return; } } - if(!have_req_level_for_heroic) { uint32 acc_level = field[0].GetUInt32(); @@ -368,7 +323,6 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) have_req_level_for_heroic = true; } } - // need to check team only for first character // TODO: what to if account already has characters of both races? if (!AllowTwoSideAccounts) @@ -376,7 +330,6 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) uint32 acc_team=0; if(acc_race > 0) acc_team = Player::TeamForRace(acc_race); - if(acc_team != team_) { data << (uint8)CHAR_CREATE_PVP_TEAMS_VIOLATION; @@ -385,20 +338,16 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) return; } } - // search same race for cinematic or same class if need // TODO: check if cinematic already shown? (already logged in?; cinematic field) while ((skipCinematics == 1 && !have_same_race) || class_ == CLASS_DEATH_KNIGHT) { if(!result2->NextRow()) break; - field = result2->Fetch(); acc_race = field[1].GetUInt32(); - if(!have_same_race) have_same_race = race_ == acc_race; - if(GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT) { uint8 acc_class = field[2].GetUInt32(); @@ -406,7 +355,6 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) { if(heroic_free_slots > 0) --heroic_free_slots; - if(heroic_free_slots==0) { data << (uint8)CHAR_CREATE_UNIQUE_CLASS_LIMIT; @@ -414,7 +362,6 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) return; } } - if(!have_req_level_for_heroic) { uint32 acc_level = field[0].GetUInt32(); @@ -426,14 +373,12 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) delete result2; } } - if(GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT && !have_req_level_for_heroic) { data << (uint8)CHAR_CREATE_LEVEL_REQUIREMENT; SendPacket( &data ); return; } - // extract other data required for player creating uint8 gender, skin, face, hairStyle, hairColor, facialHair, outfitId; recv_data >> gender; @@ -443,58 +388,44 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data ) recv_data >> hairColor; recv_data >> facialHair; recv_data >> outfitId; - if(recv_data.rpos() < recv_data.wpos()) { uint8 unk; recv_data >> unk; sLog.outDebug("Character creation %s (account %u) has unhandled tail data: [%u]", name.c_str(), GetAccountId(), unk); } - Player * pNewChar = new Player(this); if(!pNewChar->Create( objmgr.GenerateLowGuid(HIGHGUID_PLAYER), name, race_, class_, gender, skin, face, hairStyle, hairColor, facialHair, outfitId )) { // Player not create (race/class problem?) delete pNewChar; - data << (uint8)CHAR_CREATE_ERROR; SendPacket( &data ); - return; } - if ((have_same_race && skipCinematics == 1) || skipCinematics == 2) pNewChar->setCinematic(1); // not show intro - // Player created, save it now pNewChar->SaveToDB(); charcount+=1; - loginDatabase.PExecute("DELETE FROM realmcharacters WHERE acctid= '%d' AND realmid = '%d'", GetAccountId(), realmID); loginDatabase.PExecute("INSERT INTO realmcharacters (numchars, acctid, realmid) VALUES (%u, %u, %u)", charcount, GetAccountId(), realmID); - delete pNewChar; // created only to call SaveToDB() - data << (uint8)CHAR_CREATE_SUCCESS; SendPacket( &data ); - std::string IP_str = GetRemoteAddress(); sLog.outDetail("Account: %d (IP: %s) Create Character:[%s]",GetAccountId(),IP_str.c_str(),name.c_str()); sLog.outChar("Account: %d (IP: %s) Create Character:[%s]",GetAccountId(),IP_str.c_str(),name.c_str()); } - void WorldSession::HandleCharDeleteOpcode( WorldPacket & recv_data ) { uint64 guid; recv_data >> guid; - // can't delete loaded character if(objmgr.GetPlayer(guid)) return; - uint32 accountId = 0; std::string name; - // is guild leader if(objmgr.GetGuildByLeader(guid)) { @@ -503,7 +434,6 @@ void WorldSession::HandleCharDeleteOpcode( WorldPacket & recv_data ) SendPacket( &data ); return; } - // is arena team captain if(objmgr.GetArenaTeamByCaptain(guid)) { @@ -512,7 +442,6 @@ void WorldSession::HandleCharDeleteOpcode( WorldPacket & recv_data ) SendPacket( &data ); return; } - QueryResult *result = CharacterDatabase.PQuery("SELECT account,name FROM characters WHERE guid='%u'", GUID_LOPART(guid)); if(result) { @@ -521,28 +450,22 @@ void WorldSession::HandleCharDeleteOpcode( WorldPacket & recv_data ) name = fields[1].GetCppString(); delete result; } - // prevent deleting other players' characters using cheating tools if(accountId != GetAccountId()) return; - std::string IP_str = GetRemoteAddress(); sLog.outDetail("Account: %d (IP: %s) Delete Character:[%s] (guid: %u)",GetAccountId(),IP_str.c_str(),name.c_str(),GUID_LOPART(guid)); sLog.outChar("Account: %d (IP: %s) Delete Character:[%s] (guid: %u)",GetAccountId(),IP_str.c_str(),name.c_str(),GUID_LOPART(guid)); - if(sLog.IsOutCharDump()) // optimize GetPlayerDump call { std::string dump = PlayerDumpWriter().GetDump(GUID_LOPART(guid)); sLog.outCharDump(dump.c_str(),GetAccountId(),GUID_LOPART(guid),name.c_str()); } - Player::DeleteFromDB(guid, GetAccountId()); - WorldPacket data(SMSG_CHAR_DELETE, 1); data << (uint8)CHAR_DELETE_SUCCESS; SendPacket( &data ); } - void WorldSession::HandlePlayerLoginOpcode( WorldPacket & recv_data ) { if(PlayerLoading() || GetPlayer() != NULL) @@ -550,14 +473,10 @@ void WorldSession::HandlePlayerLoginOpcode( WorldPacket & recv_data ) sLog.outError("Player tryes to login again, AccountId = %d",GetAccountId()); return; } - m_playerLoading = true; uint64 playerGuid = 0; - DEBUG_LOG( "WORLD: Recvd Player Logon Message" ); - recv_data >> playerGuid; - LoginQueryHolder *holder = new LoginQueryHolder(GetAccountId(), playerGuid); if(!holder->Initialize()) { @@ -565,18 +484,14 @@ void WorldSession::HandlePlayerLoginOpcode( WorldPacket & recv_data ) m_playerLoading = false; return; } - CharacterDatabase.DelayQueryHolder(&chrHandler, &CharacterHandler::HandlePlayerLoginCallback, holder); } - void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) { uint64 playerGuid = holder->GetGuid(); - Player* pCurrChar = new Player(this); // for send server info and strings (config) ChatHandler chH = ChatHandler(pCurrChar); - // "GetAccountId()==db stored account id" checked in LoadFromDB (prevent login not own character using cheating tools) if(!pCurrChar->LoadFromDB(GUID_LOPART(playerGuid), holder)) { @@ -586,13 +501,9 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) m_playerLoading = false; return; } - pCurrChar->GetMotionMaster()->Initialize(); - SetPlayer(pCurrChar); - pCurrChar->SendDungeonDifficulty(false); - WorldPacket data( SMSG_LOGIN_VERIFY_WORLD, 20 ); data << pCurrChar->GetMapId(); data << pCurrChar->GetPositionX(); @@ -600,25 +511,20 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) data << pCurrChar->GetPositionZ(); data << pCurrChar->GetOrientation(); SendPacket(&data); - // load player specific part before send times LoadAccountData(holder->GetResult(PLAYER_LOGIN_QUERY_LOADACCOUNTDATA),PER_CHARACTER_CACHE_MASK); SendAccountDataTimes(); - data.Initialize(SMSG_FEATURE_SYSTEM_STATUS, 2); // added in 2.2.0 data << uint8(2); // unknown value data << uint8(0); // enable(1)/disable(0) voice chat interface in client SendPacket(&data); - // Send MOTD { data.Initialize(SMSG_MOTD, 50); // new in 2.0.1 data << (uint32)0; - uint32 linecount=0; std::string str_motd = sWorld.GetMotd(); std::string::size_type pos, nextpos; - pos = 0; while ( (nextpos= str_motd.find('@',pos)) != std::string::npos ) { @@ -629,33 +535,25 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) } pos = nextpos+1; } - if (posGetGUIDLow()); QueryResult *resultGuild = holder->GetResult(PLAYER_LOGIN_QUERY_LOADGUILD); - if(resultGuild) { Field *fields = resultGuild->Fetch(); @@ -668,7 +566,6 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) pCurrChar->SetInGuild(0); pCurrChar->SetRank(0); } - if(pCurrChar->GetGuildId() != 0) { Guild* guild = objmgr.GetGuildById(pCurrChar->GetGuildId()); @@ -680,7 +577,6 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) data << guild->GetMOTD(); SendPacket(&data); DEBUG_LOG( "WORLD: Sent guild-motd (SMSG_GUILD_EVENT)" ); - data.Initialize(SMSG_GUILD_EVENT, (5+10)); // we guess size data<<(uint8)GE_SIGNED_ON; data<<(uint8)1; @@ -688,7 +584,6 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) data<GetGUID(); guild->BroadcastPacket(&data); DEBUG_LOG( "WORLD: Sent guild-signed-on (SMSG_GUILD_EVENT)" ); - // Increment online members of the guild guild->IncOnlineMemberCount(); } @@ -699,30 +594,24 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) pCurrChar->SetInGuild(0); } } - if(!pCurrChar->isAlive()) pCurrChar->SendCorpseReclaimDelay(true); - pCurrChar->SendInitialPacketsBeforeAddToMap(); - //Show cinematic at the first time that player login if( !pCurrChar->getCinematic() ) { pCurrChar->setCinematic(1); - if(ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(pCurrChar->getClass())) { if (cEntry->CinematicSequence) pCurrChar->SendCinematicStart(cEntry->CinematicSequence); else if (ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace())) pCurrChar->SendCinematicStart(rEntry->CinematicSequence); - // send new char string if not empty if (!sWorld.GetNewCharString().empty()) chH.PSendSysMessage(sWorld.GetNewCharString().c_str()); } } - if (!pCurrChar->GetMap()->Add(pCurrChar)) { AreaTrigger const* at = objmgr.GetGoBackTrigger(pCurrChar->GetMapId()); @@ -731,29 +620,22 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) else pCurrChar->TeleportTo(pCurrChar->m_homebindMapId, pCurrChar->m_homebindX, pCurrChar->m_homebindY, pCurrChar->m_homebindZ, pCurrChar->GetOrientation()); } - ObjectAccessor::Instance().AddObject(pCurrChar); //sLog.outDebug("Player %s added to Map.",pCurrChar->GetName()); - pCurrChar->SendInitialPacketsAfterAddToMap(); - CharacterDatabase.PExecute("UPDATE characters SET online = 1 WHERE guid = '%u'", pCurrChar->GetGUIDLow()); loginDatabase.PExecute("UPDATE account SET online = 1 WHERE id = '%u'", GetAccountId()); pCurrChar->SetInGameTime( getMSTime() ); - // announce group about member online (must be after add to player list to receive announce to self) if(Group *group = pCurrChar->GetGroup()) { //pCurrChar->groupInfo.group->SendInit(this); // useless group->SendUpdate(); } - // friend status sSocialMgr.SendFriendStatus(pCurrChar, FRIEND_ONLINE, pCurrChar->GetGUIDLow(), true); - // Place character in world (and load zone) before some object loading pCurrChar->LoadCorpse(); - // setting Ghost+speed if dead if (pCurrChar->m_deathState != ALIVE) { @@ -761,78 +643,57 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) if(pCurrChar->getRace() == RACE_NIGHTELF) pCurrChar->CastSpell(pCurrChar, SPELL_ID_NE_GHOST, true, 0);// auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form) pCurrChar->CastSpell(pCurrChar, SPELL_ID_GHOST, true, 0); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?) - pCurrChar->SetMovement(MOVE_WATER_WALK); } - pCurrChar->ContinueTaxiFlight(); - // reset for all pets before pet loading if(pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_PET_TALENTS)) Pet::resetTalentsForAllPetsOf(pCurrChar); - // Load pet if any (if player not alive and in taxi flight or another then pet will remember as temporary unsummoned) pCurrChar->LoadPet(); - // Set FFA PvP for non GM in non-rest mode if(sWorld.IsFFAPvPRealm() && !pCurrChar->isGameMaster() && !pCurrChar->HasFlag(PLAYER_FLAGS,PLAYER_FLAGS_RESTING) ) pCurrChar->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); - if(pCurrChar->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_CONTESTED_PVP)) pCurrChar->SetContestedPvP(); - // Apply at_login requests if(pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_SPELLS)) { pCurrChar->resetSpells(); SendNotification(LANG_RESET_SPELLS); } - if(pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_TALENTS)) { pCurrChar->resetTalents(true); pCurrChar->SendTalentsInfoData(false); // original talents send already in to SendInitialPacketsBeforeAddToMap, resend reset state SendNotification(LANG_RESET_TALENTS); } - // show time before shutdown if shutdown planned. if(sWorld.IsShutdowning()) sWorld.ShutdownMsg(true,pCurrChar); - if(sWorld.getConfig(CONFIG_ALL_TAXI_PATHS)) pCurrChar->SetTaxiCheater(true); - if(pCurrChar->isGameMaster()) SendNotification(LANG_GM_ON); - std::string IP_str = GetRemoteAddress(); sLog.outChar("Account: %d (IP: %s) Login Character:[%s] (guid:%u)", GetAccountId(),IP_str.c_str(),pCurrChar->GetName() ,pCurrChar->GetGUIDLow()); - if(!pCurrChar->IsStandState() && !pCurrChar->hasUnitState(UNIT_STAT_STUNNED)) pCurrChar->SetStandState(UNIT_STAND_STATE_STAND); - m_playerLoading = false; - //Hook for OnLogin Event Script->OnLogin(pCurrChar); - delete holder; } - void WorldSession::HandleSetFactionAtWar( WorldPacket & recv_data ) { DEBUG_LOG( "WORLD: Received CMSG_SET_FACTION_ATWAR" ); - uint32 repListID; uint8 flag; - recv_data >> repListID; recv_data >> flag; - GetPlayer()->GetReputationMgr().SetAtWar(repListID,flag); } - //I think this function is never used :/ I dunno, but i guess this opcode not exists void WorldSession::HandleSetFactionCheat( WorldPacket & /*recv_data*/ ) { @@ -840,12 +701,9 @@ void WorldSession::HandleSetFactionCheat( WorldPacket & /*recv_data*/ ) /* uint32 FactionID; uint32 Standing; - recv_data >> FactionID; recv_data >> Standing; - std::list::iterator itr; - for(itr = GetPlayer()->factions.begin(); itr != GetPlayer()->factions.end(); ++itr) { if(itr->ReputationListID == FactionID) @@ -858,19 +716,15 @@ void WorldSession::HandleSetFactionCheat( WorldPacket & /*recv_data*/ ) */ GetPlayer()->GetReputationMgr().SendStates(); } - void WorldSession::HandleMeetingStoneInfo( WorldPacket & /*recv_data*/ ) { DEBUG_LOG( "WORLD: Received CMSG_MEETING_STONE_INFO" ); - SendLfgUpdate(0, 0, 0); } - void WorldSession::HandleTutorialFlag( WorldPacket & recv_data ) { uint32 iFlag; recv_data >> iFlag; - uint32 wInt = (iFlag / 32); if (wInt >= 8) { @@ -878,26 +732,21 @@ void WorldSession::HandleTutorialFlag( WorldPacket & recv_data ) return; } uint32 rInt = (iFlag % 32); - uint32 tutflag = GetTutorialInt( wInt ); tutflag |= (1 << rInt); SetTutorialInt( wInt, tutflag ); - //sLog.outDebug("Received Tutorial Flag Set {%u}.", iFlag); } - void WorldSession::HandleTutorialClear( WorldPacket & /*recv_data*/ ) { for (int i = 0; i < 8; ++i) SetTutorialInt( i, 0xFFFFFFFF ); } - void WorldSession::HandleTutorialReset( WorldPacket & /*recv_data*/ ) { for (int i = 0; i < 8; ++i) SetTutorialInt( i, 0x00000000 ); } - void WorldSession::HandleSetWatchedFactionOpcode(WorldPacket & recv_data) { DEBUG_LOG("WORLD: Received CMSG_SET_WATCHED_FACTION"); @@ -905,37 +754,30 @@ void WorldSession::HandleSetWatchedFactionOpcode(WorldPacket & recv_data) recv_data >> fact; GetPlayer()->SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, fact); } - void WorldSession::HandleSetFactionInactiveOpcode(WorldPacket & recv_data) { DEBUG_LOG("WORLD: Received CMSG_SET_FACTION_INACTIVE"); uint32 replistid; uint8 inactive; recv_data >> replistid >> inactive; - _player->GetReputationMgr().SetInactive(replistid, inactive); } - void WorldSession::HandleShowingHelmOpcode( WorldPacket & /*recv_data*/ ) { DEBUG_LOG("CMSG_SHOWING_HELM for %s", _player->GetName()); _player->ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_HELM); } - void WorldSession::HandleShowingCloakOpcode( WorldPacket & /*recv_data*/ ) { DEBUG_LOG("CMSG_SHOWING_CLOAK for %s", _player->GetName()); _player->ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_CLOAK); } - void WorldSession::HandleCharRenameOpcode(WorldPacket& recv_data) { uint64 guid; std::string newname; - recv_data >> guid; recv_data >> newname; - // prevent character rename to invalid name if (!normalizePlayerName(newname)) { @@ -944,7 +786,6 @@ void WorldSession::HandleCharRenameOpcode(WorldPacket& recv_data) SendPacket( &data ); return; } - uint8 res = ObjectMgr::CheckPlayerName(newname,true); if (res != CHAR_NAME_SUCCESS) { @@ -953,7 +794,6 @@ void WorldSession::HandleCharRenameOpcode(WorldPacket& recv_data) SendPacket( &data ); return; } - // check name limitations if (GetSecurity() == SEC_PLAYER && objmgr.IsReservedName(newname)) { @@ -962,10 +802,8 @@ void WorldSession::HandleCharRenameOpcode(WorldPacket& recv_data) SendPacket( &data ); return; } - std::string escaped_newname = newname; CharacterDatabase.escape_string(escaped_newname); - // make sure that the character belongs to the current account, that rename at login is enabled // and that there is no character with the desired new name CharacterDatabase.AsyncPQuery(&WorldSession::HandleChangePlayerNameOpcodeCallBack, @@ -974,7 +812,6 @@ void WorldSession::HandleCharRenameOpcode(WorldPacket& recv_data) GUID_LOPART(guid), GetAccountId(), AT_LOGIN_RENAME, AT_LOGIN_RENAME, escaped_newname.c_str() ); } - void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResult *result, uint32 accountId, std::string newname) { WorldSession * session = sWorld.FindSession(accountId); @@ -983,7 +820,6 @@ void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResult *result, uin if(result) delete result; return; } - if (!result) { WorldPacket data(SMSG_CHAR_RENAME, 1); @@ -991,31 +827,23 @@ void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResult *result, uin session->SendPacket( &data ); return; } - uint32 guidLow = result->Fetch()[0].GetUInt32(); uint64 guid = MAKE_NEW_GUID(guidLow, 0, HIGHGUID_PLAYER); std::string oldname = result->Fetch()[1].GetCppString(); - delete result; - CharacterDatabase.PExecute("UPDATE characters set name = '%s', at_login = at_login & ~ %u WHERE guid ='%u'", newname.c_str(), uint32(AT_LOGIN_RENAME), guidLow); CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid ='%u'", guidLow); - sLog.outChar("Account: %d (IP: %s) Character:[%s] (guid:%u) Changed name to: %s", session->GetAccountId(), session->GetRemoteAddress().c_str(), oldname.c_str(), guidLow, newname.c_str()); - WorldPacket data(SMSG_CHAR_RENAME, 1+8+(newname.size()+1)); data << uint8(RESPONSE_SUCCESS); data << uint64(guid); data << newname; session->SendPacket(&data); } - void WorldSession::HandleSetPlayerDeclinedNames(WorldPacket& recv_data) { uint64 guid; - recv_data >> guid; - // not accept declined names for unsupported languages std::string name; if(!objmgr.GetPlayerNameByGUID(guid, name)) @@ -1026,7 +854,6 @@ void WorldSession::HandleSetPlayerDeclinedNames(WorldPacket& recv_data) SendPacket(&data); return; } - std::wstring wname; if(!Utf8toWStr(name, wname)) { @@ -1036,7 +863,6 @@ void WorldSession::HandleSetPlayerDeclinedNames(WorldPacket& recv_data) SendPacket(&data); return; } - if(!isCyrillicCharacter(wname[0])) // name already stored as only single alphabet using { WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8); @@ -1045,12 +871,9 @@ void WorldSession::HandleSetPlayerDeclinedNames(WorldPacket& recv_data) SendPacket(&data); return; } - std::string name2; DeclinedName declinedname; - recv_data >> name2; - if(name2 != name) // character have different name { WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8); @@ -1059,7 +882,6 @@ void WorldSession::HandleSetPlayerDeclinedNames(WorldPacket& recv_data) SendPacket(&data); return; } - for(int i = 0; i < MAX_DECLINED_NAME_CASES; ++i) { recv_data >> declinedname.name[i]; @@ -1072,7 +894,6 @@ void WorldSession::HandleSetPlayerDeclinedNames(WorldPacket& recv_data) return; } } - if(!ObjectMgr::CheckDeclinedNames(GetMainPartOfName(wname, 0), declinedname)) { WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8); @@ -1081,41 +902,30 @@ void WorldSession::HandleSetPlayerDeclinedNames(WorldPacket& recv_data) SendPacket(&data); return; } - for(int i = 0; i < MAX_DECLINED_NAME_CASES; ++i) CharacterDatabase.escape_string(declinedname.name[i]); - CharacterDatabase.BeginTransaction(); CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid = '%u'", GUID_LOPART(guid)); CharacterDatabase.PExecute("INSERT INTO character_declinedname (guid, genitive, dative, accusative, instrumental, prepositional) VALUES ('%u','%s','%s','%s','%s','%s')", GUID_LOPART(guid), declinedname.name[0].c_str(), declinedname.name[1].c_str(), declinedname.name[2].c_str(), declinedname.name[3].c_str(), declinedname.name[4].c_str()); CharacterDatabase.CommitTransaction(); - WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8); data << uint32(0); // OK data << uint64(guid); SendPacket(&data); } - void WorldSession::HandleAlterAppearance( WorldPacket & recv_data ) { sLog.outDebug("CMSG_ALTER_APPEARANCE"); - uint32 Hair, Color, FacialHair; recv_data >> Hair >> Color >> FacialHair; - BarberShopStyleEntry const* bs_hair = sBarberShopStyleStore.LookupEntry(Hair); - if(!bs_hair || bs_hair->type != 0 || bs_hair->race != _player->getRace() || bs_hair->gender != _player->getGender()) return; - BarberShopStyleEntry const* bs_facialHair = sBarberShopStyleStore.LookupEntry(FacialHair); - if(!bs_facialHair || bs_facialHair->type != 2 || bs_facialHair->race != _player->getRace() || bs_facialHair->gender != _player->getGender()) return; - uint32 Cost = _player->GetBarberShopCost(bs_hair->hair_id, Color, bs_facialHair->hair_id); - // 0 - ok // 1,3 - not enough money // 2 - you have to seat on barber chair @@ -1132,30 +942,23 @@ void WorldSession::HandleAlterAppearance( WorldPacket & recv_data ) data << uint32(0); // ok SendPacket(&data); } - _player->ModifyMoney(-int32(Cost)); // it isn't free _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER, Cost); - _player->SetByteValue(PLAYER_BYTES, 2, uint8(bs_hair->hair_id)); _player->SetByteValue(PLAYER_BYTES, 3, uint8(Color)); _player->SetByteValue(PLAYER_BYTES_2, 0, uint8(bs_facialHair->hair_id)); - _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP, 1); - _player->SetStandState(0); // stand up } - void WorldSession::HandleRemoveGlyph( WorldPacket & recv_data ) { uint32 slot; recv_data >> slot; - if(slot >= MAX_GLYPH_SLOT_INDEX) { sLog.outDebug("Client sent wrong glyph slot number in opcode CMSG_REMOVE_GLYPH %u", slot); return; } - if(uint32 glyph = _player->GetGlyph(slot)) { if(GlyphPropertiesEntry const *gp = sGlyphPropertiesStore.LookupEntry(glyph)) @@ -1166,18 +969,14 @@ void WorldSession::HandleRemoveGlyph( WorldPacket & recv_data ) } } } - void WorldSession::HandleCharCustomize(WorldPacket& recv_data) { uint64 guid; std::string newname; - recv_data >> guid; recv_data >> newname; - uint8 gender, skin, face, hairStyle, hairColor, facialHair; recv_data >> gender >> skin >> hairColor >> hairStyle >> facialHair >> face; - QueryResult *result = CharacterDatabase.PQuery("SELECT at_login FROM characters WHERE guid ='%u'", GUID_LOPART(guid)); if (!result) { @@ -1186,11 +985,9 @@ void WorldSession::HandleCharCustomize(WorldPacket& recv_data) SendPacket( &data ); return; } - Field *fields = result->Fetch(); uint32 at_loginFlags = fields[0].GetUInt32(); delete result; - if (!(at_loginFlags & AT_LOGIN_CUSTOMIZE)) { WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1); @@ -1198,7 +995,6 @@ void WorldSession::HandleCharCustomize(WorldPacket& recv_data) SendPacket( &data ); return; } - // prevent character rename to invalid name if (!normalizePlayerName(newname)) { @@ -1207,7 +1003,6 @@ void WorldSession::HandleCharCustomize(WorldPacket& recv_data) SendPacket( &data ); return; } - uint8 res = ObjectMgr::CheckPlayerName(newname,true); if (res != CHAR_NAME_SUCCESS) { @@ -1216,7 +1011,6 @@ void WorldSession::HandleCharCustomize(WorldPacket& recv_data) SendPacket( &data ); return; } - // check name limitations if (GetSecurity() == SEC_PLAYER && objmgr.IsReservedName(newname)) { @@ -1225,7 +1019,6 @@ void WorldSession::HandleCharCustomize(WorldPacket& recv_data) SendPacket( &data ); return; } - // character with this name already exist if (uint64 newguid = objmgr.GetPlayerGUIDByName(newname)) { @@ -1237,7 +1030,6 @@ void WorldSession::HandleCharCustomize(WorldPacket& recv_data) return; } } - CharacterDatabase.escape_string(newname); if(QueryResult *result = CharacterDatabase.PQuery("SELECT name FROM characters WHERE guid ='%u'", GUID_LOPART(guid))) { @@ -1248,7 +1040,6 @@ void WorldSession::HandleCharCustomize(WorldPacket& recv_data) Player::Customize(guid, gender, skin, face, hairStyle, hairColor, facialHair); CharacterDatabase.PExecute("UPDATE characters set name = '%s', at_login = at_login & ~ %u WHERE guid ='%u'", newname.c_str(), uint32(AT_LOGIN_CUSTOMIZE), GUID_LOPART(guid)); CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid ='%u'", GUID_LOPART(guid)); - WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1+8+(newname.size()+1)+6); data << uint8(RESPONSE_SUCCESS); data << uint64(guid); @@ -1261,90 +1052,66 @@ void WorldSession::HandleCharCustomize(WorldPacket& recv_data) data << uint8(facialHair); SendPacket(&data); } - void WorldSession::HandleEquipmentSetSave(WorldPacket &recv_data) { sLog.outDebug("CMSG_EQUIPMENT_SET_SAVE"); - uint64 setGuid; if(!recv_data.readPackGUID(setGuid)) return; - uint32 index; recv_data >> index; if(index >= MAX_EQUIPMENT_SET_INDEX) // client set slots amount return; - std::string name; recv_data >> name; - std::string iconName; recv_data >> iconName; - EquipmentSet eqSet; - eqSet.Guid = setGuid; eqSet.Name = name; eqSet.IconName = iconName; eqSet.state = EQUIPMENT_SET_NEW; - for(uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i) { uint64 itemGuid; if(!recv_data.readPackGUID(itemGuid)) return; - Item *item = _player->GetItemByPos(INVENTORY_SLOT_BAG_0, i); - if(!item && itemGuid) // cheating check 1 return; - if(item && item->GetGUID() != itemGuid) // cheating check 2 return; - eqSet.Items[i] = GUID_LOPART(itemGuid); } - _player->SetEquipmentSet(index, eqSet); } - void WorldSession::HandleEquipmentSetDelete(WorldPacket &recv_data) { sLog.outDebug("CMSG_EQUIPMENT_SET_DELETE"); - uint64 setGuid; if(!recv_data.readPackGUID(setGuid)) return; - _player->DeleteEquipmentSet(setGuid); } - void WorldSession::HandleEquipmentSetUse(WorldPacket &recv_data) { sLog.outDebug("CMSG_EQUIPMENT_SET_USE"); recv_data.hexlike(); - for(uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i) { uint64 itemGuid; if(!recv_data.readPackGUID(itemGuid)) return; - uint8 srcbag, srcslot; recv_data >> srcbag >> srcslot; - sLog.outDebug("Item " UI64FMTD ": srcbag %u, srcslot %u", itemGuid, srcbag, srcslot); - Item *item = _player->GetItemByGuid(itemGuid); - uint16 dstpos = i | (INVENTORY_SLOT_BAG_0 << 8); - if(!item) { Item *uItem = _player->GetItemByPos(INVENTORY_SLOT_BAG_0, i); if(!uItem) continue; - ItemPosCountVec sDest; uint8 msg = _player->CanStoreItem( NULL_BAG, NULL_SLOT, sDest, uItem, false ); if(msg == EQUIP_ERR_OK) @@ -1354,61 +1121,48 @@ void WorldSession::HandleEquipmentSetUse(WorldPacket &recv_data) } else _player->SendEquipError(msg, uItem, NULL); - continue; } - if(item->GetPos() == dstpos) continue; - _player->SwapItem(item->GetPos(), dstpos); } - WorldPacket data(SMSG_EQUIPMENT_SET_USE_RESULT, 1); data << uint8(0); // 4 - equipment swap failed - inventory is full SendPacket(&data); } - void WorldSession::HandleOnPVPKill(Player *killed) { Script->OnPVPKill(GetPlayer(), killed); } - bool WorldSession::HandleOnPlayerChat(const char *text) { return Script->OnPlayerChat(GetPlayer(), text); } - uint32 WorldSession::HandleOnGetXP(uint32 amount) { return Script->OnGetXP(GetPlayer(), amount); } - int32 WorldSession::HandleOnGetMoney(int32 amount) { return Script->OnGetMoney(GetPlayer(), amount); } - void WorldSession::HandleOnAreaChange(AreaTableEntry const *pArea) { Script->OnAreaChange(GetPlayer(), pArea); } - bool WorldSession::HandleOnItemClick(Item *pItem) { return Script->OnItemClick(GetPlayer(), pItem); } - bool WorldSession::HandleOnItemOpen(Item *pItem) { return Script->OnItemOpen(GetPlayer(), pItem); } - bool WorldSession::HandleOnGoClick(GameObject *pGameObject) { return Script->OnGoClick(GetPlayer(), pGameObject); } - void WorldSession::HandleOnCreatureKill(Creature *pCreature) { Script->OnCreatureKill(GetPlayer(), pCreature); diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index 32233aae5a9..bb8d71e4a3c 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -17,14 +17,12 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "Common.h" #include "ObjectMgr.h" #include "World.h" #include "WorldPacket.h" #include "WorldSession.h" #include "Database/DatabaseEnv.h" - #include "AccountMgr.h" #include "CellImpl.h" #include "Chat.h" @@ -36,7 +34,6 @@ #include "UpdateMask.h" #include "SpellMgr.h" #include "ScriptCalls.h" - // Supported shift-links (client generated and server side) // |color|Hachievement:achievement_id:player_guid:0:0:0:0:0:0:0:0|h[name]|h|r // - client, item icon shift click, not used in server currently @@ -59,9 +56,7 @@ // |color|Htaxinode:id|h[name]|h|r // |color|Htele:id|h[name]|h|r // |color|Htrade:spell_id,cur_value,max_value,unk3int,unk3str|h[name]|h|r - client, spellbook profession icon shift-click - bool ChatHandler::load_command_table = true; - ChatCommand * ChatHandler::getCommandTable() { static ChatCommand accountSetCommandTable[] = @@ -71,7 +66,6 @@ ChatCommand * ChatHandler::getCommandTable() { "password", SEC_CONSOLE, true, &ChatHandler::HandleAccountSetPasswordCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand accountCommandTable[] = { { "addon", SEC_PLAYER, false, &ChatHandler::HandleAccountAddonCommand, "", NULL }, @@ -84,7 +78,6 @@ ChatCommand * ChatHandler::getCommandTable() { "", SEC_PLAYER, false, &ChatHandler::HandleAccountCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand banCommandTable[] = { { "account", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanAccountCommand, "", NULL }, @@ -92,7 +85,6 @@ ChatCommand * ChatHandler::getCommandTable() { "ip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanIPCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand baninfoCommandTable[] = { { "account", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanInfoAccountCommand, "", NULL }, @@ -100,7 +92,6 @@ ChatCommand * ChatHandler::getCommandTable() { "ip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanInfoIPCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand banlistCommandTable[] = { { "account", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanListAccountCommand, "", NULL }, @@ -108,7 +99,6 @@ ChatCommand * ChatHandler::getCommandTable() { "ip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleBanListIPCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand castCommandTable[] = { { "back", SEC_ADMINISTRATOR, false, &ChatHandler::HandleCastBackCommand, "", NULL }, @@ -118,7 +108,6 @@ ChatCommand * ChatHandler::getCommandTable() { "", SEC_ADMINISTRATOR, false, &ChatHandler::HandleCastCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand characterCommandTable[] = { { "customize", SEC_GAMEMASTER, true, &ChatHandler::HandleCharacterCustomizeCommand, "", NULL }, @@ -128,7 +117,6 @@ ChatCommand * ChatHandler::getCommandTable() { "reputation", SEC_GAMEMASTER, true, &ChatHandler::HandleCharacterReputationCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand debugPlayCommandTable[] = { { "cinematic", SEC_MODERATOR, false, &ChatHandler::HandleDebugPlayCinematicCommand, "", NULL }, @@ -136,7 +124,6 @@ ChatCommand * ChatHandler::getCommandTable() { "sound", SEC_MODERATOR, false, &ChatHandler::HandleDebugPlaySoundCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand debugSendCommandTable[] = { { "buyerror", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendBuyErrorCommand, "", NULL }, @@ -153,7 +140,6 @@ ChatCommand * ChatHandler::getCommandTable() { "spellfail", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSendSpellFailCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand debugCommandTable[] = { { "setbit", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSet32Bit, "", NULL }, @@ -179,7 +165,6 @@ ChatCommand * ChatHandler::getCommandTable() { "itemexpire", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugItemExpireCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand eventCommandTable[] = { { "activelist", SEC_GAMEMASTER, true, &ChatHandler::HandleEventActiveListCommand, "", NULL }, @@ -188,7 +173,6 @@ ChatCommand * ChatHandler::getCommandTable() { "", SEC_GAMEMASTER, true, &ChatHandler::HandleEventInfoCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand gmCommandTable[] = { { "chat", SEC_MODERATOR, false, &ChatHandler::HandleGMChatCommand, "", NULL }, @@ -199,7 +183,6 @@ ChatCommand * ChatHandler::getCommandTable() { "", SEC_MODERATOR, false, &ChatHandler::HandleGMCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand goCommandTable[] = { { "creature", SEC_MODERATOR, false, &ChatHandler::HandleGoCreatureCommand, "", NULL }, @@ -212,12 +195,9 @@ ChatCommand * ChatHandler::getCommandTable() { "xy", SEC_MODERATOR, false, &ChatHandler::HandleGoXYCommand, "", NULL }, { "xyz", SEC_MODERATOR, false, &ChatHandler::HandleGoXYZCommand, "", NULL }, { "", SEC_MODERATOR, false, &ChatHandler::HandleGoXYZCommand, "", NULL }, - { "ticket", SEC_MODERATOR, false, &ChatHandler::HandleGoTicketCommand, "", NULL }, - { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand gobjectCommandTable[] = { { "activate", SEC_GAMEMASTER, false, &ChatHandler::HandleActivateObjectCommand, "", NULL }, @@ -232,7 +212,6 @@ ChatCommand * ChatHandler::getCommandTable() { "turn", SEC_GAMEMASTER, false, &ChatHandler::HandleGameObjectTurnCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand groupCommandTable[] = { { "leader", SEC_ADMINISTRATOR, false, &ChatHandler::HandleGroupLeaderCommand, "", NULL }, @@ -240,7 +219,6 @@ ChatCommand * ChatHandler::getCommandTable() { "remove", SEC_ADMINISTRATOR, false, &ChatHandler::HandleGroupRemoveCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand guildCommandTable[] = { { "create", SEC_GAMEMASTER, true, &ChatHandler::HandleGuildCreateCommand, "", NULL }, @@ -250,7 +228,6 @@ ChatCommand * ChatHandler::getCommandTable() { "rank", SEC_GAMEMASTER, true, &ChatHandler::HandleGuildRankCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand honorCommandTable[] = { { "add", SEC_GAMEMASTER, false, &ChatHandler::HandleHonorAddCommand, "", NULL }, @@ -258,7 +235,6 @@ ChatCommand * ChatHandler::getCommandTable() { "update", SEC_GAMEMASTER, false, &ChatHandler::HandleHonorUpdateCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand instanceCommandTable[] = { { "listbinds", SEC_ADMINISTRATOR, false, &ChatHandler::HandleInstanceListBindsCommand, "", NULL }, @@ -267,7 +243,6 @@ ChatCommand * ChatHandler::getCommandTable() { "savedata", SEC_ADMINISTRATOR, false, &ChatHandler::HandleInstanceSaveDataCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand learnCommandTable[] = { { "all", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLearnAllCommand, "", NULL }, @@ -283,7 +258,6 @@ ChatCommand * ChatHandler::getCommandTable() { "", SEC_ADMINISTRATOR, false, &ChatHandler::HandleLearnCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand listCommandTable[] = { { "creature", SEC_ADMINISTRATOR, true, &ChatHandler::HandleListCreatureCommand, "", NULL }, @@ -292,7 +266,6 @@ ChatCommand * ChatHandler::getCommandTable() { "auras", SEC_ADMINISTRATOR, false, &ChatHandler::HandleListAurasCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand lookupPlayerCommandTable[] = { { "ip", SEC_GAMEMASTER, true, &ChatHandler::HandleLookupPlayerIpCommand, "", NULL }, @@ -300,7 +273,6 @@ ChatCommand * ChatHandler::getCommandTable() { "email", SEC_GAMEMASTER, true, &ChatHandler::HandleLookupPlayerEmailCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand lookupCommandTable[] = { { "area", SEC_MODERATOR, true, &ChatHandler::HandleLookupAreaCommand, "", NULL }, @@ -319,7 +291,6 @@ ChatCommand * ChatHandler::getCommandTable() { "map", SEC_ADMINISTRATOR, true, &ChatHandler::HandleLookupMapCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand modifyCommandTable[] = { { "hp", SEC_MODERATOR, false, &ChatHandler::HandleModifyHPCommand, "", NULL }, @@ -350,7 +321,6 @@ ChatCommand * ChatHandler::getCommandTable() { "gender", SEC_GAMEMASTER, false, &ChatHandler::HandleModifyGenderCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand npcCommandTable[] = { { "add", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcAddCommand, "", NULL }, @@ -382,16 +352,13 @@ ChatCommand * ChatHandler::getCommandTable() { "setdeathstate", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSetDeathStateCommand, "", NULL }, { "addformation", SEC_MODERATOR, false, &ChatHandler::HandleNpcAddFormationCommand, "", NULL }, { "setlink", SEC_MODERATOR, false, &ChatHandler::HandleNpcSetLinkCommand, "", NULL }, - //{ TODO: fix or remove this commands { "addweapon", SEC_ADMINISTRATOR, false, &ChatHandler::HandleNpcAddWeaponCommand, "", NULL }, { "name", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcNameCommand, "", NULL }, { "subname", SEC_GAMEMASTER, false, &ChatHandler::HandleNpcSubNameCommand, "", NULL }, //} - { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand petCommandTable[] = { { "create", SEC_GAMEMASTER, false, &ChatHandler::HandleCreatePetCommand, "", NULL }, @@ -400,14 +367,12 @@ ChatCommand * ChatHandler::getCommandTable() { "tp", SEC_GAMEMASTER, false, &ChatHandler::HandlePetTpCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand pdumpCommandTable[] = { { "load", SEC_ADMINISTRATOR, true, &ChatHandler::HandlePDumpLoadCommand, "", NULL }, { "write", SEC_ADMINISTRATOR, true, &ChatHandler::HandlePDumpWriteCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand questCommandTable[] = { { "add", SEC_ADMINISTRATOR, false, &ChatHandler::HandleQuestAdd, "", NULL }, @@ -415,7 +380,6 @@ ChatCommand * ChatHandler::getCommandTable() { "remove", SEC_ADMINISTRATOR, false, &ChatHandler::HandleQuestRemove, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand reloadCommandTable[] = { { "all", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllCommand, "", NULL }, @@ -429,9 +393,7 @@ ChatCommand * ChatHandler::getCommandTable() { "all_quest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllQuestCommand, "", NULL }, { "all_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllScriptsCommand, "", NULL }, { "all_spell", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllSpellCommand, "", NULL }, - { "config", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadConfigCommand, "", NULL }, - { "access_requirement", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAccessRequirementCommand, "", NULL }, { "achievement_criteria_data", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAchievementCriteriaDataCommand, "", NULL }, { "achievement_reward", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAchievementRewardCommand, "", NULL }, @@ -507,10 +469,8 @@ ChatCommand * ChatHandler::getCommandTable() { "auctions", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAuctionsCommand, "", NULL }, { "waypoint_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadWpScriptsCommand, "", NULL }, { "gm_tickets", SEC_ADMINISTRATOR, true, &ChatHandler::HandleGMTicketReloadCommand, "", NULL }, - { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand resetCommandTable[] = { { "achievements", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetAchievementsCommand, "", NULL }, @@ -522,7 +482,6 @@ ChatCommand * ChatHandler::getCommandTable() { "all", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetAllCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand sendCommandTable[] = { { "items", SEC_ADMINISTRATOR, true, &ChatHandler::HandleSendItemsCommand, "", NULL }, @@ -531,35 +490,30 @@ ChatCommand * ChatHandler::getCommandTable() { "money", SEC_ADMINISTRATOR, true, &ChatHandler::HandleSendMoneyCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand serverIdleRestartCommandTable[] = { { "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL }, { "" , SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerIdleRestartCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand serverIdleShutdownCommandTable[] = { { "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL }, { "" , SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerIdleShutDownCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand serverRestartCommandTable[] = { { "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL }, { "" , SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerRestartCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand serverShutdownCommandTable[] = { { "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL }, { "" , SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand serverSetCommandTable[] = { { "difftime", SEC_CONSOLE, true, &ChatHandler::HandleServerSetDiffTimeCommand, "", NULL }, @@ -569,7 +523,6 @@ ChatCommand * ChatHandler::getCommandTable() { "closed", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerSetClosedCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand serverCommandTable[] = { { "corpses", SEC_GAMEMASTER, true, &ChatHandler::HandleServerCorpsesCommand, "", NULL }, @@ -584,7 +537,6 @@ ChatCommand * ChatHandler::getCommandTable() { "set", SEC_ADMINISTRATOR, true, NULL, "", serverSetCommandTable }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand teleCommandTable[] = { { "add", SEC_ADMINISTRATOR, false, &ChatHandler::HandleTeleAddCommand, "", NULL }, @@ -594,7 +546,6 @@ ChatCommand * ChatHandler::getCommandTable() { "", SEC_MODERATOR, false, &ChatHandler::HandleTeleCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand unbanCommandTable[] = { { "account", SEC_ADMINISTRATOR, true, &ChatHandler::HandleUnBanAccountCommand, "", NULL }, @@ -602,7 +553,6 @@ ChatCommand * ChatHandler::getCommandTable() { "ip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleUnBanIPCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand wpCommandTable[] = { { "show", SEC_GAMEMASTER, false, &ChatHandler::HandleWpShowCommand, "", NULL }, @@ -613,7 +563,6 @@ ChatCommand * ChatHandler::getCommandTable() { "unload", SEC_GAMEMASTER, false, &ChatHandler::HandleWpUnLoadPathCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand ticketCommandTable[] = { { "list", SEC_MODERATOR, false, &ChatHandler::HandleGMTicketListCommand, "", NULL }, @@ -628,7 +577,6 @@ ChatCommand * ChatHandler::getCommandTable() { "comment", SEC_MODERATOR, false, &ChatHandler::HandleGMTicketCommentCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; - static ChatCommand commandTable[] = { { "account", SEC_PLAYER, true, NULL, "", accountCommandTable }, @@ -654,12 +602,10 @@ ChatCommand * ChatHandler::getCommandTable() { "reset", SEC_ADMINISTRATOR, true, NULL, "", resetCommandTable }, { "instance", SEC_ADMINISTRATOR, true, NULL, "", instanceCommandTable }, { "server", SEC_ADMINISTRATOR, true, NULL, "", serverCommandTable }, - { "pet", SEC_GAMEMASTER, false, NULL, "", petCommandTable }, { "loadpath", SEC_ADMINISTRATOR, false, &ChatHandler::HandleReloadAllPaths, "", NULL }, { "ahbotoptions", SEC_GAMEMASTER, true, &ChatHandler::HandleAHBotOptionsCommand, "", NULL }, { "ticket", SEC_MODERATOR, false, NULL, "", ticketCommandTable }, - { "aura", SEC_ADMINISTRATOR, false, &ChatHandler::HandleAuraCommand, "", NULL }, { "unaura", SEC_ADMINISTRATOR, false, &ChatHandler::HandleUnAuraCommand, "", NULL }, { "nameannounce", SEC_MODERATOR, false, &ChatHandler::HandleNameAnnounceCommand, "", NULL }, @@ -720,24 +666,19 @@ ChatCommand * ChatHandler::getCommandTable() { "flusharenapoints",SEC_ADMINISTRATOR, false, &ChatHandler::HandleFlushArenaPointsCommand, "", NULL }, { "repairitems", SEC_GAMEMASTER, true, &ChatHandler::HandleRepairitemsCommand, "", NULL }, { "waterwalk", SEC_GAMEMASTER, false, &ChatHandler::HandleWaterwalkCommand, "", NULL }, - { "freeze", SEC_ADMINISTRATOR, false, &ChatHandler::HandleFreezeCommand, "", NULL }, { "unfreeze", SEC_ADMINISTRATOR, false, &ChatHandler::HandleUnFreezeCommand, "", NULL }, { "listfreeze", SEC_ADMINISTRATOR, false, &ChatHandler::HandleListFreezeCommand, "", NULL }, - { "possess", SEC_ADMINISTRATOR, false, &ChatHandler::HandlePossessCommand, "", NULL }, { "unpossess", SEC_ADMINISTRATOR, false, &ChatHandler::HandleUnPossessCommand, "", NULL }, { "bindsight", SEC_ADMINISTRATOR, false, &ChatHandler::HandleBindSightCommand, "", NULL }, { "unbindsight", SEC_ADMINISTRATOR, false, &ChatHandler::HandleUnbindSightCommand, "", NULL }, { "playall", SEC_ADMINISTRATOR, false, &ChatHandler::HandlePlayAllCommand, "", NULL }, - { NULL, 0, false, NULL, "", NULL } }; - if (load_command_table) { load_command_table = false; - QueryResult *result = WorldDatabase.Query("SELECT name,security,help FROM command"); if (result) { @@ -745,77 +686,61 @@ ChatCommand * ChatHandler::getCommandTable() { Field *fields = result->Fetch(); std::string name = fields[0].GetCppString(); - SetDataForCommandInTable(commandTable, name.c_str(), fields[1].GetUInt16(), fields[2].GetCppString(), name); - } while(result->NextRow()); delete result; } } - return commandTable; } - const char *ChatHandler::GetTrinityString(int32 entry) const { return m_session->GetTrinityString(entry); } - bool ChatHandler::isAvailable(ChatCommand const& cmd) const { // check security level only for simple command (without child commands) return m_session->GetSecurity() >= cmd.SecurityLevel; } - bool ChatHandler::HasLowerSecurity(Player* target, uint64 guid, bool strong) { WorldSession* target_session = NULL; uint32 target_account = 0; - if (target) target_session = target->GetSession(); else if (guid) target_account = objmgr.GetPlayerAccountIdByGUID(guid); - if (!target_session && !target_account) { SendSysMessage(LANG_PLAYER_NOT_FOUND); SetSentErrorMessage(true); return true; } - return HasLowerSecurityAccount(target_session,target_account,strong); } - bool ChatHandler::HasLowerSecurityAccount(WorldSession* target, uint32 target_account, bool strong) { uint32 target_sec; - // allow everything from console and RA console if (!m_session) return false; - // ignore only for non-players for non strong checks (when allow apply command at least to same sec level) if (m_session->GetSecurity() > SEC_PLAYER && !strong && !sWorld.getConfig(CONFIG_GM_LOWER_SECURITY)) return false; - if (target) target_sec = target->GetSecurity(); else if (target_account) target_sec = accmgr.GetSecurity(target_account); else return true; // caller must report error for (target==NULL && target_account==0) - if (m_session->GetSecurity() < target_sec || (strong && m_session->GetSecurity() <= target_sec)) { SendSysMessage(LANG_YOURS_SECURITY_IS_LOW); SetSentErrorMessage(true); return true; } - return false; } - bool ChatHandler::hasStringAbbr(const char* name, const char* part) { // non "" command @@ -824,7 +749,6 @@ bool ChatHandler::hasStringAbbr(const char* name, const char* part) // "" part from non-"" command if (!*part) return false; - for (;;) { if (!*part) @@ -837,54 +761,42 @@ bool ChatHandler::hasStringAbbr(const char* name, const char* part) } } // allow with any for "" - return true; } - void ChatHandler::SendSysMessage(const char *str) { WorldPacket data; - // need copy to prevent corruption by strtok call in LineFromMessage original string char* buf = strdup(str); char* pos = buf; - while(char* line = LineFromMessage(pos)) { FillSystemMessageData(&data, line); m_session->SendPacket(&data); } - free(buf); } - void ChatHandler::SendGlobalSysMessage(const char *str) { // Chat output WorldPacket data; - // need copy to prevent corruption by strtok call in LineFromMessage original string char* buf = strdup(str); char* pos = buf; - while(char* line = LineFromMessage(pos)) { FillSystemMessageData(&data, line); sWorld.SendGlobalMessage(&data); } - free(buf); } - void ChatHandler::SendGlobalGMSysMessage(const char *str) { // Chat output WorldPacket data; - // need copy to prevent corruption by strtok call in LineFromMessage original string char* buf = strdup(str); char* pos = buf; - while(char* line = LineFromMessage(pos)) { FillSystemMessageData(&data, line); @@ -892,12 +804,10 @@ void ChatHandler::SendGlobalGMSysMessage(const char *str) } free(buf); } - void ChatHandler::SendSysMessage(int32 entry) { SendSysMessage(GetTrinityString(entry)); } - void ChatHandler::PSendSysMessage(int32 entry, ...) { const char *format = GetTrinityString(entry); @@ -908,7 +818,6 @@ void ChatHandler::PSendSysMessage(int32 entry, ...) va_end(ap); SendSysMessage(str); } - void ChatHandler::PSendSysMessage(const char *format, ...) { va_list ap; @@ -918,25 +827,20 @@ void ChatHandler::PSendSysMessage(const char *format, ...) va_end(ap); SendSysMessage(str); } - bool ChatHandler::ExecuteCommandInTable(ChatCommand *table, const char* text, const std::string& fullcmd) { char const* oldtext = text; std::string cmd = ""; - while (*text != ' ' && *text != '\0') { cmd += *text; ++text; } - while (*text == ' ') ++text; - for (uint32 i = 0; table[i].Name != NULL; ++i) { if (!hasStringAbbr(table[i].Name, cmd.c_str())) continue; - // select subcommand from child commands list if (table[i].ChildCommands != NULL) { @@ -946,17 +850,13 @@ bool ChatHandler::ExecuteCommandInTable(ChatCommand *table, const char* text, co SendSysMessage(LANG_NO_SUBCMD); else SendSysMessage(LANG_CMD_SYNTAX); - ShowHelpForCommand(table[i].ChildCommands,text); } - return true; } - // must be available and have handler if (!table[i].Handler || !isAvailable(table[i])) continue; - SetSentErrorMessage(false); // table[i].Name == "" is special case: send original command to handler if ((this->*(table[i].Handler))(strlen(table[i].Name)!=0 ? text : oldtext)) @@ -982,31 +882,24 @@ bool ChatHandler::ExecuteCommandInTable(ChatCommand *table, const char* text, co else SendSysMessage(LANG_CMD_SYNTAX); } - return true; } - return false; } - bool ChatHandler::SetDataForCommandInTable(ChatCommand *table, const char* text, uint32 security, std::string const& help, std::string const& fullcommand) { std::string cmd = ""; - while (*text != ' ' && *text != '\0') { cmd += *text; ++text; } - while (*text == ' ') ++text; - for (uint32 i = 0; table[i].Name != NULL; i++) { // for data fill use full explicit command names if (table[i].Name != cmd) continue; - // select subcommand from child commands list (including "") if (table[i].ChildCommands != NULL) { @@ -1014,7 +907,6 @@ bool ChatHandler::SetDataForCommandInTable(ChatCommand *table, const char* text, return true; else if (*text) return false; - // fail with "" subcommands, then use normal level up command instead } // expected subcommand by full name DB content @@ -1023,15 +915,12 @@ bool ChatHandler::SetDataForCommandInTable(ChatCommand *table, const char* text, sLog.outErrorDb("Table `command` have unexpected subcommand '%s' in command '%s', skip.",text,fullcommand.c_str()); return false; } - if (table[i].SecurityLevel != security) sLog.outDetail("Table `command` overwrite for command '%s' default security (%u) by %u",fullcommand.c_str(),table[i].SecurityLevel,security); - table[i].SecurityLevel = security; table[i].Help = help; return true; } - // in case "" command let process by caller if (!cmd.empty()) { @@ -1040,40 +929,31 @@ bool ChatHandler::SetDataForCommandInTable(ChatCommand *table, const char* text, else sLog.outErrorDb("Table `command` have not existed subcommand '%s' in command '%s', skip.",cmd.c_str(),fullcommand.c_str()); } - return false; } - int ChatHandler::ParseCommands(const char* text) { ASSERT(text); ASSERT(*text); - std::string fullcmd = text; - if (m_session && !m_session->HandleOnPlayerChat(text)) return 0; - /// chat case (.command or !command format) if (m_session) { if (text[0] != '!' && text[0] != '.') return 0; } - /// ignore single . and ! in line if (strlen(text) < 2) return 0; // original `text` can't be used. It content destroyed in command code processing. - /// ignore messages staring from many dots. if ((text[0] == '.' && text[1] == '.') || (text[0] == '!' && text[1] == '!')) return 0; - /// skip first . or ! (in console allowed use command with . and ! and without its) if (text[0] == '!' || text[0] == '.') ++text; - if (!ExecuteCommandInTable(getCommandTable(), text, fullcmd)) { if (m_session && m_session->GetSecurity() == SEC_PLAYER) @@ -1082,11 +962,9 @@ int ChatHandler::ParseCommands(const char* text) } return 1; } - bool ChatHandler::isValidChatMessage(const char* message) { /* - valid examples: |cffa335ee|Hitem:812:0:0:0:0:0:0:0:70|h[Glowing Brightwood Staff]|h|r |cff808080|Hquest:2278:47|h[The Platinum Discs]|h|r @@ -1096,34 +974,26 @@ valid examples: |cffffd000|Henchant:3919|h[Engineering: Rough Dynamite]|h|r |cffffff00|Hachievement:546:0000000000000001:0:0:0:-1:0:0:0:0|h[Safe Deposit]|h|r |cff66bbff|Hglyph:21:762|h[Glyph of Bladestorm]|h|r - | will be escaped to || */ - if (strlen(message) > 255) return false; - const char validSequence[6] = "cHhhr"; const char* validSequenceIterator = validSequence; - // more simple checks if (sWorld.getConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY) < 3) { const std::string validCommands = "cHhr|"; - while(*message) { // find next pipe command message = strchr(message, '|'); - if (!message) return true; - ++message; char commandChar = *message; if (validCommands.find(commandChar) == std::string::npos) return false; - ++message; // validate sequence if (sWorld.getConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY) == 2) @@ -1141,17 +1011,13 @@ valid examples: } return true; } - std::istringstream reader(message); char buffer[256]; - uint32 color; - ItemPrototype const* linkedItem; Quest const* linkedQuest; SpellEntry const *linkedSpell; AchievementEntry const* linkedAchievement; - while(!reader.eof()) { if (validSequence == validSequenceIterator) @@ -1160,7 +1026,6 @@ valid examples: linkedQuest = NULL; linkedSpell = NULL; linkedAchievement = NULL; - reader.ignore(255, '|'); } else if (reader.get() != '|') @@ -1170,7 +1035,6 @@ valid examples: #endif return false; } - // pipe has always to be followed by at least one char if (reader.peek() == '\0') { @@ -1179,14 +1043,11 @@ valid examples: #endif return false; } - // no further pipe commands if (reader.eof()) break; - char commandChar; reader >> commandChar; - // | in normal messages is escaped by || if (commandChar != '|') { @@ -1213,7 +1074,6 @@ valid examples: #endif return false; } - switch (commandChar) { case 'c': @@ -1230,7 +1090,6 @@ valid examples: #endif return false; } - color <<= 4; // check for hex char if (c >= '0' && c <='9') @@ -1252,12 +1111,10 @@ valid examples: case 'H': // read chars up to colon = link type reader.getline(buffer, 256, ':'); - if (strcmp(buffer, "item") == 0) { // read item entry reader.getline(buffer, 256, ':'); - linkedItem= objmgr.GetItemPrototype(atoi(buffer)); if (!linkedItem) { @@ -1266,7 +1123,6 @@ valid examples: #endif return false; } - if (color != ItemQualityColors[linkedItem->Quality]) { #ifdef MANGOS_DEBUG @@ -1275,9 +1131,7 @@ valid examples: #endif return false; } - char c = reader.peek(); - // ignore enchants etc. while((c >='0' && c <='9') || c==':') { @@ -1298,9 +1152,7 @@ valid examples: questid += c-'0'; c = reader.peek(); } - linkedQuest = objmgr.GetQuestTemplate(questid); - if (!linkedQuest) { #ifdef MANOGS_DEBUG @@ -1320,13 +1172,11 @@ valid examples: { if (color != CHAT_LINK_COLOR_TRADE) return false; - // read spell entry reader.getline(buffer, 256, ':'); linkedSpell = sSpellStore.LookupEntry(atoi(buffer)); if (!linkedSpell) return false; - char c = reader.peek(); // base64 encoded stuff while(c !='|' && c!='\0') @@ -1340,17 +1190,14 @@ valid examples: // talent links are always supposed to be blue if (color != CHAT_LINK_COLOR_TALENT) return false; - // read talent entry reader.getline(buffer, 256, ':'); TalentEntry const *talentInfo = sTalentStore.LookupEntry(atoi(buffer)); if (!talentInfo) return false; - linkedSpell = sSpellStore.LookupEntry(talentInfo->RankID[0]); if (!linkedSpell) return false; - char c = reader.peek(); // skillpoints? whatever, drop it while(c !='|' && c!='\0') @@ -1363,7 +1210,6 @@ valid examples: { if (color != CHAT_LINK_COLOR_SPELL) return false; - uint32 spellid = 0; // read spell entry char c = reader.peek(); @@ -1382,7 +1228,6 @@ valid examples: { if (color != CHAT_LINK_COLOR_ENCHANT) return false; - uint32 spellid = 0; // read spell entry char c = reader.peek(); @@ -1404,10 +1249,8 @@ valid examples: reader.getline(buffer, 256, ':'); uint32 achievementId = atoi(buffer); linkedAchievement = sAchievementStore.LookupEntry(achievementId); - if (!linkedAchievement) return false; - char c = reader.peek(); // skip progress while(c !='|' && c!='\0') @@ -1420,7 +1263,6 @@ valid examples: { if (color != CHAT_LINK_COLOR_GLYPH) return false; - // first id is slot, drop it reader.getline(buffer, 256, ':'); uint32 glyphId = 0; @@ -1435,9 +1277,7 @@ valid examples: GlyphPropertiesEntry const* glyph = sGlyphPropertiesStore.LookupEntry(glyphId); if (!glyph) return false; - linkedSpell = sSpellStore.LookupEntry(glyph->SpellId); - if (!linkedSpell) return false; } @@ -1462,7 +1302,6 @@ valid examples: return false; } reader.getline(buffer, 256, ']'); - // verify the link name if (linkedSpell) { @@ -1475,20 +1314,16 @@ valid examples: { return false; } - SkillLineAbilityEntry const *skillInfo = bounds.first->second; - if (!skillInfo) { return false; } - SkillLineEntry const *skillLine = sSkillLineStore.LookupEntry(skillInfo->skillId); if (!skillLine) { return false; } - for (uint8 i=0; iname[i]); @@ -1518,7 +1353,6 @@ valid examples: if (linkedQuest->GetTitle() != buffer) { QuestLocale const *ql = objmgr.GetQuestLocale(linkedQuest->GetQuestId()); - if (!ql) { #ifdef MANOGS_DEBUG @@ -1526,7 +1360,6 @@ valid examples: #endif return false; } - bool foundName = false; for (uint8 i=0; iTitle.size(); i++) { @@ -1550,7 +1383,6 @@ valid examples: if (strcmp(linkedItem->Name1, buffer) != 0) { ItemLocale const *il = objmgr.GetItemLocale(linkedItem->ItemId); - if (!il) { #ifdef MANGOS_DEBUG @@ -1558,7 +1390,6 @@ valid examples: #endif return false; } - bool foundName = false; for (uint8 i=0; iName.size(); ++i) { @@ -1608,7 +1439,6 @@ valid examples: return false; } } - // check if every opened sequence was also closed properly #ifdef MANGOS_DEBUG if (validSequence != validSequenceIterator) @@ -1616,7 +1446,6 @@ valid examples: #endif return validSequence == validSequenceIterator; } - bool ChatHandler::ShowHelpForSubCommands(ChatCommand *table, char const* cmd, char const* subcmd) { std::string list; @@ -1625,25 +1454,19 @@ bool ChatHandler::ShowHelpForSubCommands(ChatCommand *table, char const* cmd, ch // must be available (ignore handler existence for show command with possibe avalable subcomands if (!isAvailable(table[i])) continue; - /// for empty subcmd show all available if (*subcmd && !hasStringAbbr(table[i].Name, subcmd)) continue; - if (m_session) list += "\n "; else list += "\n\r "; - list += table[i].Name; - if (table[i].ChildCommands) list += " ..."; } - if (list.empty()) return false; - if (table==getCommandTable()) { SendSysMessage(LANG_AVIABLE_CMD); @@ -1651,10 +1474,8 @@ bool ChatHandler::ShowHelpForSubCommands(ChatCommand *table, char const* cmd, ch } else PSendSysMessage(LANG_SUBCMDS_LIST,cmd,list.c_str()); - return true; } - bool ChatHandler::ShowHelpForCommand(ChatCommand *table, const char* cmd) { if (*cmd) @@ -1664,26 +1485,20 @@ bool ChatHandler::ShowHelpForCommand(ChatCommand *table, const char* cmd) // must be available (ignore handler existence for show command with possibe avalable subcomands if (!isAvailable(table[i])) continue; - if (!hasStringAbbr(table[i].Name, cmd)) continue; - // have subcommand char const* subcmd = (*cmd) ? strtok(NULL, " ") : ""; - if (table[i].ChildCommands && subcmd && *subcmd) { if (ShowHelpForCommand(table[i].ChildCommands, subcmd)) return true; } - if (!table[i].Help.empty()) SendSysMessage(table[i].Help.c_str()); - if (table[i].ChildCommands) if (ShowHelpForSubCommands(table[i].ChildCommands,table[i].Name,subcmd ? subcmd : "")) return true; - return !table[i].Help.empty(); } } @@ -1694,36 +1509,28 @@ bool ChatHandler::ShowHelpForCommand(ChatCommand *table, const char* cmd) // must be available (ignore handler existence for show command with possibe avalable subcomands if (!isAvailable(table[i])) continue; - if (strlen(table[i].Name)) continue; - if (!table[i].Help.empty()) SendSysMessage(table[i].Help.c_str()); - if (table[i].ChildCommands) if (ShowHelpForSubCommands(table[i].ChildCommands,"","")) return true; - return !table[i].Help.empty(); } } - return ShowHelpForSubCommands(table,"",cmd); } - //Note: target_guid used only in CHAT_MSG_WHISPER_INFORM mode (in this case channelName ignored) void ChatHandler::FillMessageData(WorldPacket *data, WorldSession* session, uint8 type, uint32 language, const char *channelName, uint64 target_guid, const char *message, Unit *speaker) { uint32 messageLength = (message ? strlen(message) : 0) + 1; - data->Initialize(SMSG_MESSAGECHAT, 100); // guess size *data << uint8(type); if ((type != CHAT_MSG_CHANNEL && type != CHAT_MSG_WHISPER) || language == LANG_ADDON) *data << uint32(language); else *data << uint32(LANG_UNIVERSAL); - switch(type) { case CHAT_MSG_SAY: @@ -1773,16 +1580,13 @@ void ChatHandler::FillMessageData(WorldPacket *data, WorldSession* session, uint target_guid = 0; // only for CHAT_MSG_WHISPER_INFORM used original value target_guid break; } - *data << uint64(target_guid); // there 0 for BG messages *data << uint32(0); // can be chat msg group or something - if (type == CHAT_MSG_CHANNEL) { ASSERT(channelName); *data << channelName; } - *data << uint64(target_guid); *data << uint32(messageLength); *data << message; @@ -1791,153 +1595,116 @@ void ChatHandler::FillMessageData(WorldPacket *data, WorldSession* session, uint else *data << uint8(0); } - Player * ChatHandler::getSelectedPlayer() { if (!m_session) return NULL; - uint64 guid = m_session->GetPlayer()->GetSelection(); - if (guid == 0) return m_session->GetPlayer(); - return objmgr.GetPlayer(guid); } - Unit* ChatHandler::getSelectedUnit() { if (!m_session) return NULL; - uint64 guid = m_session->GetPlayer()->GetSelection(); - if (guid == 0) return m_session->GetPlayer(); - return ObjectAccessor::GetUnit(*m_session->GetPlayer(),guid); } - WorldObject *ChatHandler::getSelectedObject() { if (!m_session) return NULL; - uint64 guid = m_session->GetPlayer()->GetSelection(); - if (guid == 0) return GetNearbyGameObject(); - return ObjectAccessor::GetUnit(*m_session->GetPlayer(),guid); } - Creature* ChatHandler::getSelectedCreature() { if (!m_session) return NULL; - return ObjectAccessor::GetCreatureOrPetOrVehicle(*m_session->GetPlayer(),m_session->GetPlayer()->GetSelection()); } - char* ChatHandler::extractKeyFromLink(char* text, char const* linkType, char** something1) { // skip empty if (!text) return NULL; - // skip spaces while(*text==' '||*text=='\t'||*text=='\b') ++text; - if (!*text) return NULL; - // return non link case if (text[0]!='|') return strtok(text, " "); - // [name] Shift-click form |color|linkType:key|h[name]|h|r // or // [name] Shift-click form |color|linkType:key:something1:...:somethingN|h[name]|h|r - char* check = strtok(text, "|"); // skip color if (!check) return NULL; // end of data - char* cLinkType = strtok(NULL, ":"); // linktype if (!cLinkType) return NULL; // end of data - if (strcmp(cLinkType,linkType) != 0) { strtok(NULL, " "); // skip link tail (to allow continue strtok(NULL,s) use after retturn from function SendSysMessage(LANG_WRONG_LINK_TYPE); return NULL; } - char* cKeys = strtok(NULL, "|"); // extract keys and values char* cKeysTail = strtok(NULL, ""); - char* cKey = strtok(cKeys, ":|"); // extract key if (something1) *something1 = strtok(NULL, ":|"); // extract something - strtok(cKeysTail, "]"); // restart scan tail and skip name with possible spaces strtok(NULL, " "); // skip link tail (to allow continue strtok(NULL,s) use after return from function return cKey; } - char* ChatHandler::extractKeyFromLink(char* text, char const* const* linkTypes, int* found_idx, char** something1) { // skip empty if (!text) return NULL; - // skip spaces while(*text==' '||*text=='\t'||*text=='\b') ++text; - if (!*text) return NULL; - // return non link case if (text[0]!='|') return strtok(text, " "); - // [name] Shift-click form |color|linkType:key|h[name]|h|r // or // [name] Shift-click form |color|linkType:key:something1:...:somethingN|h[name]|h|r // or // [name] Shift-click form |linkType:key|h[name]|h|r - char* tail; - if (text[1]=='c') { char* check = strtok(text, "|"); // skip color if (!check) return NULL; // end of data - tail = strtok(NULL, ""); // tail } else tail = text+1; // skip first | - char* cLinkType = strtok(tail, ":"); // linktype if (!cLinkType) return NULL; // end of data - for (int i = 0; linkTypes[i]; ++i) { if (strcmp(cLinkType,linkTypes[i]) == 0) { char* cKeys = strtok(NULL, "|"); // extract keys and values char* cKeysTail = strtok(NULL, ""); - char* cKey = strtok(cKeys, ":|"); // extract key if (something1) *something1 = strtok(NULL, ":|"); // extract something - strtok(cKeysTail, "]"); // restart scan tail and skip name with possible spaces strtok(NULL, " "); // skip link tail (to allow continue strtok(NULL,s) use after return from function if (found_idx) @@ -1945,12 +1712,10 @@ char* ChatHandler::extractKeyFromLink(char* text, char const* const* linkTypes, return cKey; } } - strtok(NULL, " "); // skip link tail (to allow continue strtok(NULL,s) use after return from function SendSysMessage(LANG_WRONG_LINK_TYPE); return NULL; } - char const *fmtstring(char const *format, ...) { va_list argptr; @@ -1960,34 +1725,25 @@ char const *fmtstring(char const *format, ...) 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::GetNearbyGameObject() { if (!m_session) return NULL; - Player* pl = m_session->GetPlayer(); GameObject* obj = NULL; Trinity::NearestGameObjectCheck check(*pl); @@ -1995,34 +1751,26 @@ GameObject* ChatHandler::GetNearbyGameObject() pl->VisitNearbyGridObject(999, searcher); return obj; } - GameObject* ChatHandler::GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid,uint32 entry) { if (!m_session) return NULL; - Player* pl = m_session->GetPlayer(); - GameObject* obj = pl->GetMap()->GetGameObject(MAKE_NEW_GUID(lowguid, entry, HIGHGUID_GAMEOBJECT)); - if (!obj && objmgr.GetGOData(lowguid)) // guid is DB guid of object { // search near player then CellPair p(Trinity::ComputeCellPair(pl->GetPositionX(), pl->GetPositionY())); Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; - MaNGOS::GameObjectWithDbGUIDCheck go_check(*pl,lowguid); MaNGOS::GameObjectSearcher checker(pl,obj,go_check); - TypeContainerVisitor, GridTypeMapContainer > object_checker(checker); CellLock cell_lock(cell, p); cell_lock->Visit(cell_lock, object_checker, *pl->GetMap()); } - return obj; } - enum SpellLinkType { SPELL_LINK_SPELL = 0, @@ -2031,7 +1779,6 @@ enum SpellLinkType SPELL_LINK_TRADE = 3, SPELL_LINK_GLYPH = 4 }; - static char const* const spellKeys[] = { "Hspell", // normal spell @@ -2041,7 +1788,6 @@ static char const* const spellKeys[] = "Hglyph", // glyph 0 }; - uint32 ChatHandler::extractSpellIdFromLink(char* text) { // number or [name] Shift-click form |color|Henchant:recipe_spell_id|h[prof_name: recipe_name]|h|r @@ -2054,9 +1800,7 @@ uint32 ChatHandler::extractSpellIdFromLink(char* text) char* idS = extractKeyFromLink(text,spellKeys,&type,¶m1_str); if (!idS) return 0; - uint32 id = (uint32)atol(idS); - switch(type) { case SPELL_LINK_SPELL: @@ -2067,14 +1811,11 @@ uint32 ChatHandler::extractSpellIdFromLink(char* text) TalentEntry const* talentEntry = sTalentStore.LookupEntry(id); if (!talentEntry) return 0; - int32 rank = param1_str ? (uint32)atol(param1_str) : 0; if (rank >= MAX_TALENT_RANK) return 0; - if (rank < 0) rank = 0; - return talentEntry->RankID[rank]; } case SPELL_LINK_ENCHANT: @@ -2083,41 +1824,33 @@ uint32 ChatHandler::extractSpellIdFromLink(char* text) case SPELL_LINK_GLYPH: { uint32 glyph_prop_id = param1_str ? (uint32)atol(param1_str) : 0; - GlyphPropertiesEntry const* glyphPropEntry = sGlyphPropertiesStore.LookupEntry(glyph_prop_id); if (!glyphPropEntry) return 0; - return glyphPropEntry->SpellId; } } - // unknown type? return 0; } - GameTele const* ChatHandler::extractGameTeleFromLink(char* text) { // id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r char* cId = extractKeyFromLink(text,"Htele"); if (!cId) return false; - // id case (explicit or from shift link) if (cId[0] >= '0' || cId[0] >= '9') if (uint32 id = atoi(cId)) return objmgr.GetGameTele(id); - return objmgr.GetGameTele(cId); } - enum GuidLinkType { SPELL_LINK_PLAYER = 0, // must be first for selection in not link case SPELL_LINK_CREATURE = 1, SPELL_LINK_GAMEOBJECT = 2 }; - static char const* const guidKeys[] = { "Hplayer", @@ -2125,18 +1858,15 @@ static char const* const guidKeys[] = "Hgameobject", 0 }; - uint64 ChatHandler::extractGuidFromLink(char* text) { int type = 0; - // |color|Hcreature:creature_guid|h[name]|h|r // |color|Hgameobject:go_guid|h[name]|h|r // |color|Hplayer:name|h[name]|h|r char* idS = extractKeyFromLink(text,guidKeys,&type); if (!idS) return 0; - switch(type) { case SPELL_LINK_PLAYER: @@ -2144,19 +1874,15 @@ uint64 ChatHandler::extractGuidFromLink(char* text) std::string name = idS; if (!normalizePlayerName(name)) return 0; - if (Player* player = objmgr.GetPlayer(name.c_str())) return player->GetGUID(); - if (uint64 guid = objmgr.GetPlayerGUIDByName(name)) return guid; - return 0; } case SPELL_LINK_CREATURE: { uint32 lowguid = (uint32)atol(idS); - if (CreatureData const* data = objmgr.GetCreatureData(lowguid)) return MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_UNIT); else @@ -2165,32 +1891,26 @@ uint64 ChatHandler::extractGuidFromLink(char* text) case SPELL_LINK_GAMEOBJECT: { uint32 lowguid = (uint32)atol(idS); - if (GameObjectData const* data = objmgr.GetGOData(lowguid)) return MAKE_NEW_GUID(lowguid,data->id,HIGHGUID_GAMEOBJECT); else return 0; } } - // unknown type? return 0; } - std::string ChatHandler::extractPlayerNameFromLink(char* text) { // |color|Hplayer:name|h[name]|h|r char* name_str = extractKeyFromLink(text,"Hplayer"); if (!name_str) return ""; - std::string name = name_str; if (!normalizePlayerName(name)) return ""; - return name; } - bool ChatHandler::extractPlayerTarget(char* args, Player** player, uint64* player_guid /*=NULL*/,std::string* player_name /*= NULL*/) { if (args && *args) @@ -2202,20 +1922,15 @@ bool ChatHandler::extractPlayerTarget(char* args, Player** player, uint64* playe SetSentErrorMessage(true); return false; } - Player* pl = objmgr.GetPlayer(name.c_str()); - // if allowed player pointer if (player) *player = pl; - // if need guid value from DB (in name case for check player existence) uint64 guid = !pl && (player_guid || player_name) ? objmgr.GetPlayerGUIDByName(name) : 0; - // if allowed player guid (if no then only online players allowed) if (player_guid) *player_guid = pl ? pl->GetGUID() : guid; - if (player_name) *player_name = pl || guid ? name : ""; } @@ -2228,11 +1943,9 @@ bool ChatHandler::extractPlayerTarget(char* args, Player** player, uint64* playe // if allowed player guid (if no then only online players allowed) if (player_guid) *player_guid = pl ? pl->GetGUID() : 0; - if (player_name) *player_name = pl ? pl->GetName() : ""; } - // some from req. data must be provided (note: name is empty if player not exist) if ((!player || !*player) && (!player_guid || !*player_guid) && (!player_name || player_name->empty())) { @@ -2240,33 +1953,26 @@ bool ChatHandler::extractPlayerTarget(char* args, Player** player, uint64* playe SetSentErrorMessage(true); return false; } - return true; } - void ChatHandler::extractOptFirstArg(char* args, char** arg1, char** arg2) { char* p1 = strtok(args, " "); char* p2 = strtok(NULL, " "); - if (!p2) { p2 = p1; p1 = NULL; } - if (arg1) *arg1 = p1; - if (arg2) *arg2 = p2; } - char* ChatHandler::extractQuotedArg(char* args) { if (!*args) return NULL; - if (*args=='"') return strtok(args+1, "\""); else @@ -2277,55 +1983,45 @@ char* ChatHandler::extractQuotedArg(char* args) return strtok(NULL, "\""); } } - bool ChatHandler::needReportToTarget(Player* chr) const { Player* pl = m_session->GetPlayer(); return pl != chr && pl->IsVisibleGloballyFor(chr); } - LocaleConstant ChatHandler::GetSessionDbcLocale() const { return m_session->GetSessionDbcLocale(); } - int ChatHandler::GetSessionDbLocaleIndex() const { return m_session->GetSessionDbLocaleIndex(); } - const char *CliHandler::GetMangosString(int32 entry) const { return objmgr.GetTrinityStringForDBCLocale(entry); } - bool CliHandler::isAvailable(ChatCommand const& cmd) const { // skip non-console commands in console case return cmd.AllowConsole; } - void CliHandler::SendSysMessage(const char *str) { m_print(str); m_print("\r\n"); } - std::string CliHandler::GetNameLink() const { return GetTrinityString(LANG_CONSOLE_COMMAND); } - bool CliHandler::needReportToTarget(Player* /*chr*/) const { return true; } - bool ChatHandler::GetPlayerGroupAndGUIDByName(const char* cname, Player* &plr, Group* &group, uint64 &guid, bool offline) { plr = NULL; guid = 0; - if (cname) { std::string name = cname; @@ -2337,13 +2033,11 @@ bool ChatHandler::GetPlayerGroupAndGUIDByName(const char* cname, Player* &plr, G SetSentErrorMessage(true); return false; } - plr = objmgr.GetPlayer(name.c_str()); if (offline) guid = objmgr.GetPlayerGUIDByName(name.c_str()); } } - if (plr) { group = plr->GetGroup(); @@ -2356,21 +2050,17 @@ bool ChatHandler::GetPlayerGroupAndGUIDByName(const char* cname, Player* &plr, G plr = getSelectedPlayer(); else plr = m_session->GetPlayer(); - if (!guid || !offline) guid = plr->GetGUID(); group = plr->GetGroup(); } - return true; } - LocaleConstant CliHandler::GetSessionDbcLocale() const { return sWorld.GetDefaultDbcLocale(); } - int CliHandler::GetSessionDbLocaleIndex() const { return objmgr.GetDBCLocaleIndex(); -} \ No newline at end of file +} diff --git a/src/game/Chat.h b/src/game/Chat.h index 1518cb6d45e..35e39ad8b08 100644 --- a/src/game/Chat.h +++ b/src/game/Chat.h @@ -17,19 +17,15 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef TRINITYCORE_CHAT_H #define TRINITYCORE_CHAT_H - #include "SharedDefines.h" - class ChatHandler; class WorldSession; class Creature; class Player; class Unit; struct GameTele; - class ChatCommand { public: @@ -40,66 +36,50 @@ class ChatCommand std::string Help; ChatCommand * ChildCommands; }; - class TRINITY_DLL_SPEC ChatHandler { public: explicit ChatHandler(WorldSession* session) : m_session(session) {} explicit ChatHandler(Player* player) : m_session(player->GetSession()) {} ~ChatHandler() {} - static void FillMessageData( WorldPacket *data, WorldSession* session, uint8 type, uint32 language, const char *channelName, uint64 target_guid, const char *message, Unit *speaker); - void FillMessageData( WorldPacket *data, uint8 type, uint32 language, uint64 target_guid, const char* message) { FillMessageData( data, m_session, type, language, NULL, target_guid, message, NULL); } - void FillSystemMessageData( WorldPacket *data, const char* message ) { FillMessageData( data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, 0, message ); } - static char* LineFromMessage(char*& pos) { char* start = strtok(pos,"\n"); pos = NULL; return start; } - // function with different implementation for chat/console virtual const char *GetMangosString(int32 entry) const; virtual void SendSysMessage( const char *str); - void SendSysMessage( int32 entry); void PSendSysMessage( const char *format, ...) ATTR_PRINTF(2,3); void PSendSysMessage( int32 entry, ... ); std::string PGetParseString(int32 entry, ...); - int ParseCommands(const char* text); - static ChatCommand* getCommandTable(); - bool isValidChatMessage(const char* msg); void SendGlobalSysMessage(const char *str); protected: explicit ChatHandler() : m_session(NULL) {} // for CLI subclass - bool hasStringAbbr(const char* name, const char* part); - // function with different implementation for chat/console virtual bool isAvailable(ChatCommand const& cmd) const; virtual std::string GetNameLink() const { return GetNameLink(m_session->GetPlayer()); } virtual bool needReportToTarget(Player* chr) const; virtual LocaleConstant GetSessionDbcLocale() const; virtual int GetSessionDbLocaleIndex() const; - bool HasLowerSecurity(Player* target, uint64 guid, bool strong = false); bool HasLowerSecurityAccount(WorldSession* target, uint32 account, bool strong = false); - void SendGlobalGMSysMessage(const char *str); - static bool SetDataForCommandInTable(ChatCommand *table, const char* text, uint32 security, std::string const& help, std::string const& fullcommand ); bool ExecuteCommandInTable(ChatCommand *table, const char* text, const std::string& fullcommand); bool ShowHelpForCommand(ChatCommand *table, const char* cmd); bool ShowHelpForSubCommands(ChatCommand *table, char const* cmd, char const* subcmd); - bool HandleAccountCommand(const char* args); bool HandleAccountAddonCommand(const char* args); bool HandleAccountCreateCommand(const char* args); @@ -110,13 +90,11 @@ class TRINITY_DLL_SPEC ChatHandler bool HandleAccountSetAddonCommand(const char* args); bool HandleAccountSetGmLevelCommand(const char* args); bool HandleAccountSetPasswordCommand(const char* args); - bool HandleAHBotOptionsCommand(const char * args); bool HandleNameAnnounceCommand(const char* args); bool HandleGMNameAnnounceCommand(const char* args); bool HandleGMAnnounceCommand(const char* args); bool HandleGMNotifyCommand(const char* args); - bool HandleBanAccountCommand(const char* args); bool HandleBanCharacterCommand(const char* args); bool HandleBanIPCommand(const char* args); @@ -126,19 +104,16 @@ class TRINITY_DLL_SPEC ChatHandler bool HandleBanListAccountCommand(const char* args); bool HandleBanListCharacterCommand(const char* args); bool HandleBanListIPCommand(const char* args); - bool HandleCastCommand(const char *args); bool HandleCastBackCommand(const char *args); bool HandleCastDistCommand(const char *args); bool HandleCastSelfCommand(const char *args); bool HandleCastTargetCommand(const char *args); - bool HandleCharacterCustomizeCommand(const char * args); bool HandleCharacterDeleteCommand(const char* args); bool HandleCharacterLevelCommand(const char* args); bool HandleCharacterRenameCommand(const char * args); bool HandleCharacterReputationCommand(const char* args); - bool HandleDebugAnimCommand(const char* args); bool HandleDebugArenaCommand(const char * args); bool HandleDebugBattlegroundCommand(const char * args); @@ -156,7 +131,6 @@ class TRINITY_DLL_SPEC ChatHandler bool HandleDebugSpellCheckCommand(const char* args); bool HandleDebugUpdateCommand(const char* args); bool HandleDebugUpdateWorldStateCommand(const char* args); - bool HandleDebugSet32Bit(const char* args); bool HandleDebugThreatList(const char * args); bool HandleDebugHostilRefList(const char * args); @@ -164,11 +138,9 @@ class TRINITY_DLL_SPEC ChatHandler bool HandleUnPossessCommand(const char* args); bool HandleBindSightCommand(const char* args); bool HandleUnbindSightCommand(const char* args); - bool HandleDebugPlayCinematicCommand(const char* args); bool HandleDebugPlayMovieCommand(const char* args); bool HandleDebugPlaySoundCommand(const char* args); - bool HandleDebugSendBuyErrorCommand(const char* args); bool HandleDebugSendChannelNotifyCommand(const char* args); bool HandleDebugSendChatMsgCommand(const char* args); @@ -181,12 +153,10 @@ class TRINITY_DLL_SPEC ChatHandler bool HandleDebugSendSellErrorCommand(const char* args); bool HandleDebugSendSetPhaseShiftCommand(const char * args); bool HandleDebugSendSpellFailCommand(const char* args); - bool HandleEventActiveListCommand(const char* args); bool HandleEventStartCommand(const char* args); bool HandleEventStopCommand(const char* args); bool HandleEventInfoCommand(const char* args); - bool HandleGameObjectAddCommand(const char* args); bool HandleGameObjectDeleteCommand(const char* args); bool HandleGameObjectMoveCommand(const char* args); @@ -195,14 +165,12 @@ class TRINITY_DLL_SPEC ChatHandler bool HandleGameObjectStateCommand(const char* args); bool HandleGameObjectTargetCommand(const char* args); bool HandleGameObjectTurnCommand(const char* args); - bool HandleGMCommand(const char* args); bool HandleGMChatCommand(const char* args); bool HandleGMFlyCommand(const char* args); bool HandleGMListFullCommand(const char* args); bool HandleGMListIngameCommand(const char* args); bool HandleGMVisibleCommand(const char* args); - bool HandleGoCommand(const char* args); bool HandleGoCreatureCommand(const char* args); bool HandleGoGraveyardCommand(const char* args); @@ -213,24 +181,19 @@ class TRINITY_DLL_SPEC ChatHandler bool HandleGoXYCommand(const char* args); bool HandleGoXYZCommand(const char* args); bool HandleGoZoneXYCommand(const char* args); - bool HandleGoTicketCommand(const char* args); - bool HandleGuildCreateCommand(const char* args); bool HandleGuildInviteCommand(const char* args); bool HandleGuildUninviteCommand(const char* args); bool HandleGuildRankCommand(const char* args); bool HandleGuildDeleteCommand(const char* args); - bool HandleHonorAddCommand(const char* args); bool HandleHonorAddKillCommand(const char* args); bool HandleHonorUpdateCommand(const char* args); - bool HandleInstanceListBindsCommand(const char* args); bool HandleInstanceUnbindCommand(const char* args); bool HandleInstanceStatsCommand(const char* args); bool HandleInstanceSaveDataCommand(const char * args); - bool HandleLearnCommand(const char* args); bool HandleLearnAllCommand(const char* args); bool HandleLearnAllGMCommand(const char* args); @@ -242,12 +205,10 @@ class TRINITY_DLL_SPEC ChatHandler bool HandleLearnAllMyPetTalentsCommand(const char* args); bool HandleLearnAllMySpellsCommand(const char* args); bool HandleLearnAllMyTalentsCommand(const char* args); - bool HandleListAurasCommand(const char * args); bool HandleListCreatureCommand(const char* args); bool HandleListItemCommand(const char* args); bool HandleListObjectCommand(const char* args); - bool HandleLookupAreaCommand(const char* args); bool HandleLookupCreatureCommand(const char* args); bool HandleLookupEventCommand(const char* args); @@ -264,7 +225,6 @@ class TRINITY_DLL_SPEC ChatHandler bool HandleLookupTaxiNodeCommand(const char * args); bool HandleLookupTeleCommand(const char * args); bool HandleLookupMapCommand(const char* args); - bool HandleModifyKnownTitlesCommand(const char* args); bool HandleModifyHPCommand(const char* args); bool HandleModifyManaCommand(const char* args); @@ -288,7 +248,6 @@ class TRINITY_DLL_SPEC ChatHandler bool HandleModifyArenaCommand(const char* args); bool HandleModifyPhaseCommand(const char* args); bool HandleModifyGenderCommand(const char* args); - //-----------------------Npc Commands----------------------- bool HandleNpcAddCommand(const char* args); bool HandleNpcAddMoveCommand(const char* args); @@ -318,20 +277,16 @@ class TRINITY_DLL_SPEC ChatHandler bool HandleNpcYellCommand(const char* args); bool HandleNpcAddFormationCommand(const char* args); bool HandleNpcSetLinkCommand(const char* args); - //TODO: NpcCommands that needs to be fixed : bool HandleNpcAddWeaponCommand(const char* args); bool HandleNpcNameCommand(const char* args); bool HandleNpcSubNameCommand(const char* args); //---------------------------------------------------------- - bool HandlePDumpLoadCommand(const char *args); bool HandlePDumpWriteCommand(const char *args); - bool HandleQuestAdd(const char * args); bool HandleQuestRemove(const char * args); bool HandleQuestComplete(const char * args); - bool HandleReloadAllCommand(const char* args); bool HandleReloadAllAchievementCommand(const char* args); bool HandleReloadAllAreaCommand(const char* args); @@ -343,9 +298,7 @@ class TRINITY_DLL_SPEC ChatHandler bool HandleReloadAllEventAICommand(const char* args); bool HandleReloadAllSpellCommand(const char* args); bool HandleReloadAllLocalesCommand(const char* args); - bool HandleReloadConfigCommand(const char* args); - bool HandleReloadAccessRequirementCommand(const char* args); bool HandleReloadAchievementCriteriaDataCommand(const char* args); bool HandleReloadAchievementRewardCommand(const char* args); @@ -420,7 +373,6 @@ class TRINITY_DLL_SPEC ChatHandler bool HandleReloadSpellDisabledCommand(const char* args); bool HandleReloadAuctionsCommand(const char* args); bool HandleReloadWpScriptsCommand(const char* args); - bool HandleResetAchievementsCommand(const char * args); bool HandleResetAllCommand(const char * args); bool HandleResetHonorCommand(const char * args); @@ -428,12 +380,10 @@ class TRINITY_DLL_SPEC ChatHandler bool HandleResetSpellsCommand(const char * args); bool HandleResetStatsCommand(const char * args); bool HandleResetTalentsCommand(const char * args); - bool HandleSendItemsCommand(const char* args); bool HandleSendMailCommand(const char* args); bool HandleSendMessageCommand(const char * args); bool HandleSendMoneyCommand(const char* args); - bool HandleServerCorpsesCommand(const char* args); bool HandleServerExitCommand(const char* args); bool HandleServerIdleRestartCommand(const char* args); @@ -447,20 +397,16 @@ class TRINITY_DLL_SPEC ChatHandler bool HandleServerShutDownCommand(const char* args); bool HandleServerShutDownCancelCommand(const char* args); bool HandleServerSetClosedCommand(const char* args); - bool HandleServerSetLogFileLevelCommand(const char* args); bool HandleServerSetDiffTimeCommand(const char* args); - bool HandleTeleCommand(const char * args); bool HandleTeleAddCommand(const char * args); bool HandleTeleDelCommand(const char * args); bool HandleTeleGroupCommand(const char* args); bool HandleTeleNameCommand(const char* args); - bool HandleUnBanAccountCommand(const char* args); bool HandleUnBanCharacterCommand(const char* args); bool HandleUnBanIPCommand(const char* args); - bool HandleWpAddCommand(const char* args); bool HandleWpLoadPathCommand(const char* args); bool HandleWpUnLoadPathCommand(const char* args); @@ -468,13 +414,11 @@ class TRINITY_DLL_SPEC ChatHandler bool HandleWpEventCommand(const char* args); bool HandleWpShowCommand(const char* args); bool HandleReloadAllPaths(const char *args); - bool HandleHelpCommand(const char* args); bool HandleCommandsCommand(const char* args); bool HandleStartCommand(const char* args); bool HandleDismountCommand(const char* args); bool HandleSaveCommand(const char* args); - bool HandleNamegoCommand(const char* args); bool HandleGonameCommand(const char* args); bool HandleGroupgoCommand(const char* args); @@ -485,9 +429,7 @@ class TRINITY_DLL_SPEC ChatHandler bool HandleTaxiCheatCommand(const char* args); bool HandleWhispersCommand(const char* args); bool HandleModifyDrunkCommand(const char* args); - bool HandleLoadScriptsCommand(const char* args); - bool HandleGUIDCommand(const char* args); bool HandleItemMoveCommand(const char* args); bool HandleDeMorphCommand(const char* args); @@ -498,7 +440,6 @@ class TRINITY_DLL_SPEC ChatHandler bool HandleFreezeCommand(const char *args); bool HandleUnFreezeCommand(const char *args); bool HandleListFreezeCommand(const char* args); - bool HandleCooldownCommand(const char* args); bool HandleUnLearnCommand(const char* args); bool HandleGetDistanceCommand(const char* args); @@ -525,15 +466,12 @@ class TRINITY_DLL_SPEC ChatHandler bool HandlePetUnlearnCommand(const char* args); bool HandlePetLearnCommand(const char* args); bool HandleCreatePetCommand(const char* args); - bool HandleGroupLeaderCommand(const char* args); bool HandleGroupDisbandCommand(const char* args); bool HandleGroupRemoveCommand(const char* args); - bool HandleBankCommand(const char* args); bool HandleChangeWeather(const char* args); bool HandleKickPlayerCommand(const char * args); - // GM ticket command handlers bool HandleGMTicketListCommand(const char* args); bool HandleGMTicketListOnlineCommand(const char* args); @@ -546,44 +484,33 @@ class TRINITY_DLL_SPEC ChatHandler bool HandleGMTicketCommentCommand(const char* args); bool HandleGMTicketDeleteByIdCommand(const char* args); bool HandleGMTicketReloadCommand(const char*); - bool HandleMaxSkillCommand(const char* args); bool HandleSetSkillCommand(const char* args); bool HandleRespawnCommand(const char* args); bool HandleComeToMeCommand(const char *args); bool HandleCombatStopCommand(const char *args); - /*bool HandleCharDeleteCommand(const char *args); bool HandleSendMessageCommand(const char * args);*/ - bool HandleFlushArenaPointsCommand(const char *args); bool HandlePlayAllCommand(const char* args); bool HandleRepairitemsCommand(const char* args); - bool HandleTempGameObjectCommand(const char* args); bool HandleTempAddSpwCommand(const char* args); - //! Development Commands - /*bool HandleQuestAdd(const char * args); bool HandleQuestRemove(const char * args); bool HandleQuestComplete(const char * args);*/ - //bool HandleSet32Bit(const char* args); bool HandleSaveAllCommand(const char* args); - Player* getSelectedPlayer(); Creature* getSelectedCreature(); Unit* getSelectedUnit(); WorldObject* getSelectedObject(); - char* extractKeyFromLink(char* text, char const* linkType, char** something1 = NULL); char* extractKeyFromLink(char* text, char const* const* linkTypes, int* found_idx, char** something1 = NULL); - // if args have single value then it return in arg2 and arg1 == NULL void extractOptFirstArg(char* args, char** arg1, char** arg2); char* extractQuotedArg(char* args); - uint32 extractSpellIdFromLink(char* text); uint64 extractGuidFromLink(char* text); GameTele const* extractGameTeleFromLink(char* text); @@ -591,13 +518,10 @@ class TRINITY_DLL_SPEC ChatHandler std::string extractPlayerNameFromLink(char* text); // select by arg (name/link) or in-game selection online/offline player bool extractPlayerTarget(char* args, Player** player, uint64* player_guid = NULL, std::string* player_name = NULL); - std::string playerLink(std::string const& name) const { return m_session ? "|cffffffff|Hplayer:"+name+"|h["+name+"]|h|r" : name; } std::string GetNameLink(Player* chr) const { return playerLink(chr->GetName()); } - GameObject* GetNearbyGameObject(); GameObject* GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid,uint32 entry); - // Utility methods for commands bool LookupPlayerSearchCommand(QueryResult* result, int32 limit); bool HandleBanListHelper(QueryResult* result); @@ -606,22 +530,18 @@ class TRINITY_DLL_SPEC ChatHandler bool HandleUnBanHelper(BanMode mode,char const* args); void HandleCharacterLevel(Player* player, uint64 player_guid, uint32 oldlevel, uint32 newlevel); void HandleLearnSkillRecipesHelper(Player* player,uint32 skill_id); - void SetSentErrorMessage(bool val){ sentErrorMessage = val;}; private: WorldSession * m_session; // != NULL for chat command call and NULL for CLI command - // common global flag static bool load_command_table; bool sentErrorMessage; }; - class CliHandler : public ChatHandler { public: typedef void Print(char const*); explicit CliHandler(Print* zprint) : m_print(zprint) {} - // overwrite functions const char *GetTrinityString(int32 entry) const; bool isAvailable(ChatCommand const& cmd) const; @@ -630,12 +550,9 @@ class CliHandler : public ChatHandler bool needReportToTarget(Player* chr) const; LocaleConstant GetSessionDbcLocale() const; int GetSessionDbLocaleIndex() const; - private: Print* m_print; }; - char const *fmtstring( char const *format, ... ); - #endif diff --git a/src/game/ChatHandler.cpp b/src/game/ChatHandler.cpp index e5aaab05c9d..11b57618d21 100644 --- a/src/game/ChatHandler.cpp +++ b/src/game/ChatHandler.cpp @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "Common.h" #include "ObjectAccessor.h" #include "ObjectMgr.h" @@ -25,7 +24,6 @@ #include "WorldPacket.h" #include "WorldSession.h" #include "Database/DatabaseEnv.h" - #include "CellImpl.h" #include "Chat.h" #include "ChannelMgr.h" @@ -39,7 +37,6 @@ #include "ScriptCalls.h" #include "SpellAuras.h" #include "Util.h" - bool WorldSession::processChatmessageFurtherAfterSecurityChecks(std::string& msg, uint32 lang) { if (lang != LANG_ADDON) @@ -47,7 +44,6 @@ bool WorldSession::processChatmessageFurtherAfterSecurityChecks(std::string& msg // strip invisible characters for non-addon messages if(sWorld.getConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING)) stripLineInvisibleChars(msg); - if (sWorld.getConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY) && GetSecurity() < SEC_MODERATOR && !ChatHandler(this).isValidChatMessage(msg.c_str())) { @@ -58,26 +54,20 @@ bool WorldSession::processChatmessageFurtherAfterSecurityChecks(std::string& msg return false; } } - return true; } - void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data ) { uint32 type; uint32 lang; - recv_data >> type; recv_data >> lang; - if(type >= MAX_CHAT_MSG_TYPE) { sLog.outError("CHAT: Wrong message type received: %u", type); return; } - //sLog.outDebug("CHAT: packet received. type %u, lang %u", type, lang ); - // prevent talking at unknown language (cheating) LanguageDesc const* langDesc = GetLanguageDescByID(lang); if(!langDesc) @@ -104,24 +94,20 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data ) return; } } - if(lang == LANG_ADDON) { if(sWorld.getConfig(CONFIG_CHATLOG_ADDON)) { std::string msg = ""; recv_data >> msg; - if(msg.empty()) { sLog.outDebug("Player %s send empty addon msg", GetPlayer()->GetName()); return; } - sLog.outChat("[ADDON] Player %s sends: %s", GetPlayer()->GetName(), msg.c_str()); } - // Disabled addon channel? if(!sWorld.getConfig(CONFIG_ADDON_CHANNEL)) return; @@ -157,33 +143,27 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data ) break; } } - // but overwrite it by SPELL_AURA_MOD_LANGUAGE auras (only single case used) Unit::AuraEffectList const& ModLangAuras = _player->GetAurasByType(SPELL_AURA_MOD_LANGUAGE); if(!ModLangAuras.empty()) lang = ModLangAuras.front()->GetMiscValue(); } - if (!_player->CanSpeak()) { std::string timeStr = secsToTimeString(m_muteTime - time(NULL)); SendNotification(GetTrinityString(LANG_WAIT_BEFORE_SPEAKING),timeStr.c_str()); return; } - if (type != CHAT_MSG_AFK && type != CHAT_MSG_DND) GetPlayer()->UpdateSpeakTime(); } - if (GetPlayer()->HasAura(1852) && type != CHAT_MSG_WHISPER) { std::string msg=""; recv_data >> msg; - SendNotification(GetTrinityString(LANG_GM_SILENCE), GetPlayer()->GetName()); return; } - switch(type) { case CHAT_MSG_SAY: @@ -192,19 +172,14 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data ) { std::string msg = ""; recv_data >> msg; - if(msg.empty()) break; - if (ChatHandler(this).ParseCommands(msg.c_str()) > 0) break; - if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; - if(msg.empty()) break; - if(type == CHAT_MSG_SAY) GetPlayer()->Say(msg, lang); else if(type == CHAT_MSG_EMOTE) @@ -212,19 +187,15 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data ) else if(type == CHAT_MSG_YELL) GetPlayer()->Yell(msg, lang); } break; - case CHAT_MSG_WHISPER: { std::string to, msg; recv_data >> to; recv_data >> msg; - if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; - if(msg.empty()) break; - if(!normalizePlayerName(to)) { WorldPacket data(SMSG_CHAT_PLAYER_NOT_FOUND, (to.size()+1)); @@ -232,7 +203,6 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data ) SendPacket(&data); break; } - Player *player = objmgr.GetPlayer(to.c_str()); uint32 tSecurity = GetSecurity(); uint32 pSecurity = player ? player->GetSession()->GetSecurity() : SEC_PLAYER; @@ -243,7 +213,6 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data ) SendPacket(&data); return; } - if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT) && tSecurity == SEC_PLAYER && pSecurity == SEC_PLAYER ) { uint32 sidea = GetPlayer()->GetTeam(); @@ -256,43 +225,33 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data ) return; } } - if (GetPlayer()->HasAura(1852) && !player->isGameMaster()) { SendNotification(GetTrinityString(LANG_GM_SILENCE), GetPlayer()->GetName()); return; } - GetPlayer()->Whisper(msg, lang,player->GetGUID()); } break; - case CHAT_MSG_PARTY: { std::string msg = ""; recv_data >> msg; - if(msg.empty()) break; - if (ChatHandler(this).ParseCommands(msg.c_str()) > 0) break; - if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; - if(msg.empty()) break; - // if player is in battleground, he cannot say to battleground members by /p Group *group = GetPlayer()->GetOriginalGroup(); // so if player hasn't OriginalGroup and his player->GetGroup() is BG raid, then return if( !group && (!(group = GetPlayer()->GetGroup()) || group->isBGGroup()) ) return; - WorldPacket data; ChatHandler::FillMessageData(&data, this, CHAT_MSG_PARTY, lang, NULL, 0, msg.c_str(),NULL); group->BroadcastPacket(&data, false, group->GetMemberGroup(GetPlayer()->GetGUID())); - if(sWorld.getConfig(CONFIG_CHATLOG_PARTY)) sLog.outChat("[PARTY] Player %s tells group with leader %s: %s", GetPlayer()->GetName(), group->GetLeaderName(), msg.c_str()); @@ -302,25 +261,19 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data ) { std::string msg = ""; recv_data >> msg; - if(msg.empty()) break; - if (ChatHandler(this).ParseCommands(msg.c_str()) > 0) break; - if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; - if(msg.empty()) break; - if (GetPlayer()->GetGuildId()) { Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); if (guild) guild->BroadcastToGuild(this, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL); - if(lang != LANG_ADDON && sWorld.getConfig(CONFIG_CHATLOG_GUILD)) { sLog.outChat("[GUILD] Player %s tells guild %s: %s", @@ -332,32 +285,25 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data ) GetPlayer()->GetName(), guild->GetName().c_str(), msg.c_str()); } } - break; } case CHAT_MSG_OFFICER: { std::string msg = ""; recv_data >> msg; - if(msg.empty()) break; - if (ChatHandler(this).ParseCommands(msg.c_str()) > 0) break; - if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; - if(msg.empty()) break; - if (GetPlayer()->GetGuildId()) { Guild *guild = objmgr.GetGuildById(GetPlayer()->GetGuildId()); if (guild) guild->BroadcastToOfficers(this, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL); - if(sWorld.getConfig(CONFIG_CHATLOG_GUILD)) sLog.outChat("[OFFICER] Player %s tells guild %s officers: %s", GetPlayer()->GetName(), guild->GetName().c_str(), msg.c_str()); @@ -368,29 +314,22 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data ) { std::string msg=""; recv_data >> msg; - if(msg.empty()) break; - if (ChatHandler(this).ParseCommands(msg.c_str()) > 0) break; - if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; - if(msg.empty()) break; - // if player is in battleground, he cannot say to battleground members by /ra Group *group = GetPlayer()->GetOriginalGroup(); // so if player hasn't OriginalGroup and his player->GetGroup() is BG raid or his group isn't raid, then return if ((!group && !(group = GetPlayer()->GetGroup())) || group->isBGGroup() || !group->isRaidGroup()) return; - WorldPacket data; ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID, lang, "", 0, msg.c_str(),NULL); group->BroadcastPacket(&data, false); - if(sWorld.getConfig(CONFIG_CHATLOG_RAID)) sLog.outChat("[RAID] Player %s tells raid with leader %s: %s", GetPlayer()->GetName(), group->GetLeaderName(), msg.c_str()); @@ -399,28 +338,21 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data ) { std::string msg=""; recv_data >> msg; - if(msg.empty()) break; - if (ChatHandler(this).ParseCommands(msg.c_str()) > 0) break; - if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; - if(msg.empty()) break; - // if player is in battleground, he cannot say to battleground members by /ra Group *group = GetPlayer()->GetOriginalGroup(); if( !group && !(group = GetPlayer()->GetGroup()) || group->isBGGroup() || !group->isRaidGroup() || !group->IsLeader(GetPlayer()->GetGUID())) return; - WorldPacket data; ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID_LEADER, lang, "", 0, msg.c_str(),NULL); group->BroadcastPacket(&data, false); - if(sWorld.getConfig(CONFIG_CHATLOG_RAID)) sLog.outChat("[RAID] Leader player %s tells raid: %s", GetPlayer()->GetName(), msg.c_str()); @@ -429,97 +361,74 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data ) { std::string msg=""; recv_data >> msg; - if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; - if(msg.empty()) break; - Group *group = GetPlayer()->GetGroup(); if(!group || !group->isRaidGroup() || !(group->IsLeader(GetPlayer()->GetGUID()) || group->IsAssistant(GetPlayer()->GetGUID())) || group->isBGGroup()) return; - WorldPacket data; //in battleground, raid warning is sent only to players in battleground - code is ok ChatHandler::FillMessageData(&data, this, CHAT_MSG_RAID_WARNING, lang, "", 0, msg.c_str(),NULL); group->BroadcastPacket(&data, false); - if(sWorld.getConfig(CONFIG_CHATLOG_RAID)) sLog.outChat("[RAID] Leader player %s warns raid with: %s", GetPlayer()->GetName(), msg.c_str()); } break; - case CHAT_MSG_BATTLEGROUND: { std::string msg=""; recv_data >> msg; - if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; - if(msg.empty()) break; - //battleground raid is always in Player->GetGroup(), never in GetOriginalGroup() Group *group = GetPlayer()->GetGroup(); if(!group || !group->isBGGroup()) return; - WorldPacket data; ChatHandler::FillMessageData(&data, this, CHAT_MSG_BATTLEGROUND, lang, "", 0, msg.c_str(),NULL); group->BroadcastPacket(&data, false); - if(sWorld.getConfig(CONFIG_CHATLOG_BGROUND)) sLog.outChat("[BATTLEGROUND] Player %s tells battleground with leader %s: %s", GetPlayer()->GetName(), group->GetLeaderName(), msg.c_str()); } break; - case CHAT_MSG_BATTLEGROUND_LEADER: { std::string msg=""; recv_data >> msg; - if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; - if(msg.empty()) break; - //battleground raid is always in Player->GetGroup(), never in GetOriginalGroup() Group *group = GetPlayer()->GetGroup(); if(!group || !group->isBGGroup() || !group->IsLeader(GetPlayer()->GetGUID())) return; - WorldPacket data; ChatHandler::FillMessageData(&data, this, CHAT_MSG_BATTLEGROUND_LEADER, lang, "", 0, msg.c_str(),NULL); group->BroadcastPacket(&data, false); - if(sWorld.getConfig(CONFIG_CHATLOG_BGROUND)) sLog.outChat("[RAID] Leader player %s tells battleground: %s", GetPlayer()->GetName(), msg.c_str()); } break; - case CHAT_MSG_CHANNEL: { std::string channel = "", msg = ""; recv_data >> channel; - recv_data >> msg; - if (!processChatmessageFurtherAfterSecurityChecks(msg, lang)) return; - if(msg.empty()) break; - if(ChannelMgr* cMgr = channelMgr(_player->GetTeam())) { Channel *chn = cMgr->GetChannel(channel,_player); if(chn) { chn->Say(_player->GetGUID(),msg.c_str(),lang); - if((chn->HasFlag(CHANNEL_FLAG_TRADE) || chn->HasFlag(CHANNEL_FLAG_GENERAL) || chn->HasFlag(CHANNEL_FLAG_CITY) || @@ -533,12 +442,10 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data ) } } } break; - case CHAT_MSG_AFK: { std::string msg; recv_data >> msg; - if((msg.empty() || !_player->isAFK()) && !_player->isInCombat() ) { if(!_player->isAFK()) @@ -552,12 +459,10 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data ) _player->ToggleDND(); } } break; - case CHAT_MSG_DND: { std::string msg; recv_data >> msg; - if(msg.empty() || !_player->isDND()) { if(!_player->isDND()) @@ -571,23 +476,19 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data ) _player->ToggleAFK(); } } break; - default: sLog.outError("CHAT: unknown message type %u, lang: %u", type, lang); break; } } - void WorldSession::HandleEmoteOpcode( WorldPacket & recv_data ) { if(!GetPlayer()->isAlive()) return; - uint32 emote; recv_data >> emote; GetPlayer()->HandleEmoteCommand(emote); } - namespace MaNGOS { class EmoteChatBuilder @@ -595,12 +496,10 @@ namespace MaNGOS public: EmoteChatBuilder(Player const& pl, uint32 text_emote, uint32 emote_num, Unit const* target) : i_player(pl), i_text_emote(text_emote), i_emote_num(emote_num), i_target(target) {} - void operator()(WorldPacket& data, int32 loc_idx) { char const* nam = i_target ? i_target->GetNameForLocaleIdx(loc_idx) : NULL; uint32 namlen = (nam ? strlen(nam) : 0) + 1; - data.Initialize(SMSG_TEXT_EMOTE, (20+namlen)); data << i_player.GetGUID(); data << (uint32)i_text_emote; @@ -611,7 +510,6 @@ namespace MaNGOS else data << (uint8)0x00; } - private: Player const& i_player; uint32 i_text_emote; @@ -619,32 +517,25 @@ namespace MaNGOS Unit const* i_target; }; } // namespace MaNGOS - void WorldSession::HandleTextEmoteOpcode( WorldPacket & recv_data ) { if(!GetPlayer()->isAlive()) return; - if (!GetPlayer()->CanSpeak()) { std::string timeStr = secsToTimeString(m_muteTime - time(NULL)); SendNotification(GetTrinityString(LANG_WAIT_BEFORE_SPEAKING),timeStr.c_str()); return; } - uint32 text_emote, emoteNum; uint64 guid; - recv_data >> text_emote; recv_data >> emoteNum; recv_data >> guid; - EmotesTextEntry const *em = sEmotesTextStore.LookupEntry(text_emote); if (!em) return; - uint32 emote_anim = em->textid; - switch(emote_anim) { case EMOTE_STATE_SLEEP: @@ -656,47 +547,36 @@ void WorldSession::HandleTextEmoteOpcode( WorldPacket & recv_data ) GetPlayer()->HandleEmoteCommand(emote_anim); break; } - Unit* unit = ObjectAccessor::GetUnit(*_player, guid); - CellPair p = MaNGOS::ComputeCellPair(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY()); - Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); - MaNGOS::EmoteChatBuilder emote_builder(*GetPlayer(), text_emote, emoteNum, unit); MaNGOS::LocalizedPacketDo emote_do(emote_builder); MaNGOS::PlayerDistWorker > emote_worker(GetPlayer(),sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE),emote_do); TypeContainerVisitor >, WorldTypeMapContainer > message(emote_worker); CellLock cell_lock(cell, p); cell_lock->Visit(cell_lock, message, *GetPlayer()->GetMap(), *GetPlayer(), sWorld.getConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE)); - GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, unit); - //Send scripted event call if (unit && unit->GetTypeId()==TYPEID_UNIT && ((Creature*)unit)->AI()) ((Creature*)unit)->AI()->ReceiveEmote(GetPlayer(),text_emote); } - void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recv_data ) { uint64 iguid; uint8 unk; //sLog.outDebug("WORLD: Received CMSG_CHAT_IGNORED"); - recv_data >> iguid; recv_data >> unk; // probably related to spam reporting - Player *player = objmgr.GetPlayer(iguid); if(!player || !player->GetSession()) return; - WorldPacket data; ChatHandler::FillMessageData(&data, this, CHAT_MSG_IGNORED, LANG_UNIVERSAL, NULL, GetPlayer()->GetGUID(), GetPlayer()->GetName(),NULL); player->GetSession()->SendPacket(&data); } - void WorldSession::HandleChannelDeclineInvite(WorldPacket &recvPacket) { sLog.outDebug("Opcode %u", recvPacket.GetOpcode()); diff --git a/src/game/CombatAI.cpp b/src/game/CombatAI.cpp index b18e6dd7532..00d06b9ec33 100644 --- a/src/game/CombatAI.cpp +++ b/src/game/CombatAI.cpp @@ -17,64 +17,51 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "CombatAI.h" #include "SpellMgr.h" - int AggressorAI::Permissible(const Creature *creature) { // have some hostile factions, it will be selected by IsHostileTo check at MoveInLineOfSight if( !creature->isCivilian() && !creature->IsNeutralToAll() ) return PERMIT_BASE_PROACTIVE; - return PERMIT_BASE_NO; } - void AggressorAI::UpdateAI(const uint32 /*diff*/) { if(!UpdateVictim()) return; - DoMeleeAttackIfReady(); } - // some day we will delete these useless things int CombatAI::Permissible(const Creature *creature) { return PERMIT_BASE_NO; } - int ArchorAI::Permissible(const Creature *creature) { return PERMIT_BASE_NO; } - int TurretAI::Permissible(const Creature *creature) { return PERMIT_BASE_NO; } - void CombatAI::InitializeAI() { for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i) if(me->m_spells[i] && GetSpellStore()->LookupEntry(me->m_spells[i])) spells.push_back(me->m_spells[i]); - CreatureAI::InitializeAI(); } - void CombatAI::Reset() { events.Reset(); } - void CombatAI::JustDied(Unit *killer) { for(SpellVct::iterator i = spells.begin(); i != spells.end(); ++i) if(AISpellInfo[*i].condition == AICOND_DIE) me->CastSpell(killer, *i, true); } - void CombatAI::EnterCombat(Unit *who) { for(SpellVct::iterator i = spells.begin(); i != spells.end(); ++i) @@ -85,17 +72,13 @@ void CombatAI::EnterCombat(Unit *who) events.ScheduleEvent(*i, AISpellInfo[*i].cooldown + rand()%AISpellInfo[*i].cooldown); } } - void CombatAI::UpdateAI(const uint32 diff) { if(!UpdateVictim()) return; - events.Update(diff); - if(me->hasUnitState(UNIT_STAT_CASTING)) return; - if(uint32 spellId = events.ExecuteEvent()) { DoCast(spellId); @@ -105,15 +88,12 @@ void CombatAI::UpdateAI(const uint32 diff) DoMeleeAttackIfReady(); } - ///////////////// //CasterAI ///////////////// - void CasterAI::InitializeAI() { CombatAI::InitializeAI(); - float m_attackDist = 30.0f; for(SpellVct::iterator itr = spells.begin(); itr != spells.end(); ++itr) if (AISpellInfo[*itr].condition == AICOND_COMBAT && m_attackDist > GetAISpellInfo(*itr)->maxRange) @@ -121,12 +101,10 @@ void CasterAI::InitializeAI() if (m_attackDist == 30.0f) m_attackDist = MELEE_RANGE; } - void CasterAI::EnterCombat(Unit *who) { if (spells.empty()) return; - uint32 spell = rand()%spells.size(); uint32 count = 0; for(SpellVct::iterator itr = spells.begin(); itr != spells.end(); ++itr, ++count) @@ -145,17 +123,13 @@ void CasterAI::EnterCombat(Unit *who) } } } - void CasterAI::UpdateAI(const uint32 diff) { if(!UpdateVictim()) return; - events.Update(diff); - if(me->hasUnitState(UNIT_STAT_CASTING)) return; - if(uint32 spellId = events.ExecuteEvent()) { DoCast(spellId); @@ -164,11 +138,9 @@ void CasterAI::UpdateAI(const uint32 diff) } } - ////////////// //ArchorAI ////////////// - ArchorAI::ArchorAI(Creature *c) : CreatureAI(c) { ASSERT(me->m_spells[0]); @@ -178,12 +150,10 @@ ArchorAI::ArchorAI(Creature *c) : CreatureAI(c) me->m_CombatDistance = GetSpellMaxRange(me->m_spells[0], false); me->m_SightDistance = me->m_CombatDistance; } - void ArchorAI::AttackStart(Unit *who) { if(!who) return; - if(me->IsWithinCombatRange(who, m_minRange)) { if(me->Attack(who, true) && !who->IsFlying()) @@ -194,27 +164,22 @@ void ArchorAI::AttackStart(Unit *who) if(me->Attack(who, false) && !who->IsFlying()) me->GetMotionMaster()->MoveChase(who, me->m_CombatDistance); } - if(who->IsFlying()) me->GetMotionMaster()->MoveIdle(); } - void ArchorAI::UpdateAI(const uint32 diff) { if(!UpdateVictim()) return; - if(!me->IsWithinCombatRange(me->getVictim(), m_minRange)) DoSpellAttackIfReady(me->m_spells[0]); else DoMeleeAttackIfReady(); } - ////////////// //TurretAI ////////////// - TurretAI::TurretAI(Creature *c) : CreatureAI(c) { ASSERT(me->m_spells[0]); @@ -222,7 +187,6 @@ TurretAI::TurretAI(Creature *c) : CreatureAI(c) me->m_CombatDistance = GetSpellMaxRange(me->m_spells[0], false); me->m_SightDistance = me->m_CombatDistance; } - bool TurretAI::CanAIAttack(const Unit *who) const { // TODO: use one function to replace it @@ -231,20 +195,16 @@ bool TurretAI::CanAIAttack(const Unit *who) const return false; return true; } - void TurretAI::AttackStart(Unit *who) { if(who) me->Attack(who, false); } - void TurretAI::UpdateAI(const uint32 diff) { if(!UpdateVictim()) return; - DoSpellAttackIfReady(me->m_spells[0]); - //if(!DoSpellAttackIfReady(me->m_spells[0])) //if(HostilReference *ref = me->getThreatManager().getCurrentVictim()) //ref->removeReference(); diff --git a/src/game/CombatAI.h b/src/game/CombatAI.h index 5ded95601ae..d63ee424bf5 100644 --- a/src/game/CombatAI.h +++ b/src/game/CombatAI.h @@ -17,31 +17,23 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef TRINITY_COMBATAI_H #define TRINITY_COMBATAI_H - #include "CreatureAI.h" #include "CreatureAIImpl.h" - class Creature; - class TRINITY_DLL_DECL AggressorAI : public CreatureAI { public: explicit AggressorAI(Creature *c) : CreatureAI(c) {} - void UpdateAI(const uint32); static int Permissible(const Creature *); }; - typedef std::vector SpellVct; - class TRINITY_DLL_SPEC CombatAI : public CreatureAI { public: explicit CombatAI(Creature *c) : CreatureAI(c) {} - void InitializeAI(); void Reset(); void EnterCombat(Unit* who); @@ -52,7 +44,6 @@ class TRINITY_DLL_SPEC CombatAI : public CreatureAI EventMap events; SpellVct spells; }; - class TRINITY_DLL_SPEC CasterAI : public CombatAI { public: @@ -64,19 +55,16 @@ class TRINITY_DLL_SPEC CasterAI : public CombatAI private: float m_attackDist; }; - struct TRINITY_DLL_SPEC ArchorAI : public CreatureAI { public: explicit ArchorAI(Creature *c); void AttackStart(Unit *who); void UpdateAI(const uint32 diff); - static int Permissible(const Creature *); protected: float m_minRange; }; - struct TRINITY_DLL_SPEC TurretAI : public CreatureAI { public: @@ -84,10 +72,8 @@ struct TRINITY_DLL_SPEC TurretAI : public CreatureAI bool CanAIAttack(const Unit *who) const; void AttackStart(Unit *who); void UpdateAI(const uint32 diff); - static int Permissible(const Creature *); protected: float m_minRange; }; - #endif diff --git a/src/game/CombatHandler.cpp b/src/game/CombatHandler.cpp index 095986303f8..80ca6ba3532 100644 --- a/src/game/CombatHandler.cpp +++ b/src/game/CombatHandler.cpp @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "Common.h" #include "Log.h" #include "WorldPacket.h" @@ -25,61 +24,47 @@ #include "ObjectAccessor.h" #include "CreatureAI.h" #include "ObjectDefines.h" - void WorldSession::HandleAttackSwingOpcode( WorldPacket & recv_data ) { uint64 guid; recv_data >> guid; - DEBUG_LOG( "WORLD: Recvd CMSG_ATTACKSWING Message guidlow:%u guidhigh:%u", GUID_LOPART(guid), GUID_HIPART(guid) ); - Unit *pEnemy = ObjectAccessor::GetUnit(*_player, guid); - if(!pEnemy) { if(!IS_UNIT_GUID(guid)) sLog.outError("WORLD: Object %u (TypeID: %u) isn't player, pet or creature",GUID_LOPART(guid),GuidHigh2TypeId(GUID_HIPART(guid))); else sLog.outError( "WORLD: Enemy %s %u not found",GetLogNameForGuid(guid),GUID_LOPART(guid)); - // stop attack state at client SendAttackStop(NULL); return; } - if(!_player->canAttack(pEnemy)) { sLog.outError( "WORLD: Enemy %s %u is friendly",(IS_PLAYER_GUID(guid) ? "player" : "creature"),GUID_LOPART(guid)); - // stop attack state at client SendAttackStop(pEnemy); return; } - _player->Attack(pEnemy,true); } - void WorldSession::HandleAttackStopOpcode( WorldPacket & /*recv_data*/ ) { GetPlayer()->AttackStop(); } - void WorldSession::HandleSetSheathedOpcode( WorldPacket & recv_data ) { uint32 sheathed; recv_data >> sheathed; - //sLog.outDebug( "WORLD: Recvd CMSG_SETSHEATHED Message guidlow:%u value1:%u", GetPlayer()->GetGUIDLow(), sheathed ); - if(sheathed >= MAX_SHEATH_STATE) { sLog.outError("Unknown sheath state %u ??",sheathed); return; } - GetPlayer()->SetSheath(SheathState(sheathed)); } - void WorldSession::SendAttackStop(Unit const* enemy) { WorldPacket data( SMSG_ATTACKSTOP, (4+20) ); // we guess size diff --git a/src/game/ConfusedMovementGenerator.cpp b/src/game/ConfusedMovementGenerator.cpp index 23477c6e62f..76531d35f01 100644 --- a/src/game/ConfusedMovementGenerator.cpp +++ b/src/game/ConfusedMovementGenerator.cpp @@ -17,19 +17,16 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "Creature.h" #include "MapManager.h" #include "Opcodes.h" #include "ConfusedMovementGenerator.h" #include "DestinationHolderImp.h" #include "VMapFactory.h" - #ifdef MAP_BASED_RAND_GEN #define rand_norm() unit.rand_norm() #define urand(a,b) unit.urand(a,b) #endif - template void ConfusedMovementGenerator::Initialize(T &unit) @@ -39,35 +36,26 @@ ConfusedMovementGenerator::Initialize(T &unit) x = unit.GetPositionX(); y = unit.GetPositionY(); z = unit.GetPositionZ(); - Map const* map = unit.GetBaseMap(); - i_nextMove = 1; - bool is_water_ok, is_land_ok; _InitSpecific(unit, is_water_ok, is_land_ok); - VMAP::IVMapManager *vMaps = VMAP::VMapFactory::createOrGetVMapManager(); - for(unsigned int idx=0; idx < MAX_CONF_WAYPOINTS+1; ++idx) { const float wanderX=wander_distance*rand_norm() - wander_distance/2; const float wanderY=wander_distance*rand_norm() - wander_distance/2; - - const bool isInLoS = vMaps->isInLineOfSight(unit.GetMapId(), x, y, z + 2.0f, i_waypoints[idx][0], i_waypoints[idx][1], z + 2.0f); + const bool isInLoS = vMaps->isInLineOfSight(unit.GetMapId(), x, y, z + 2.0f, i_waypoints[idx][0], i_waypoints[idx][1], z + 2.0f); if (!isInLoS) { - i_waypoints[idx][0] = x; + i_waypoints[idx][0] = x; i_waypoints[idx][1] = y; } - i_waypoints[idx][0] = x + wanderX; i_waypoints[idx][1] = y + wanderY; - // prevent invalid coordinates generation Trinity::NormalizeMapCoord(i_waypoints[idx][0]); Trinity::NormalizeMapCoord(i_waypoints[idx][1]); - bool is_water = map->IsInWater(i_waypoints[idx][0],i_waypoints[idx][1],z); // if generated wrong path just ignore if ((is_water && !is_water_ok) || (!is_water && !is_land_ok)) @@ -75,11 +63,9 @@ ConfusedMovementGenerator::Initialize(T &unit) i_waypoints[idx][0] = idx > 0 ? i_waypoints[idx-1][0] : x; i_waypoints[idx][1] = idx > 0 ? i_waypoints[idx-1][1] : y; } - unit.UpdateGroundPositionZ(i_waypoints[idx][0],i_waypoints[idx][1],z); i_waypoints[idx][2] = z; } - unit.SetUInt64Value(UNIT_FIELD_TARGET, 0); unit.SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED); unit.CastStop(); @@ -87,7 +73,6 @@ ConfusedMovementGenerator::Initialize(T &unit) unit.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); unit.addUnitState(UNIT_STAT_CONFUSED); } - template<> void ConfusedMovementGenerator::_InitSpecific(Creature &creature, bool &is_water_ok, bool &is_land_ok) @@ -95,7 +80,6 @@ ConfusedMovementGenerator::_InitSpecific(Creature &creature, bool &is_ is_water_ok = creature.canSwim(); is_land_ok = creature.canWalk(); } - template<> void ConfusedMovementGenerator::_InitSpecific(Player &, bool &is_water_ok, bool &is_land_ok) @@ -103,7 +87,6 @@ ConfusedMovementGenerator::_InitSpecific(Player &, bool &is_water_ok, bo is_water_ok = true; is_land_ok = true; } - template void ConfusedMovementGenerator::Reset(T &unit) @@ -113,17 +96,14 @@ ConfusedMovementGenerator::Reset(T &unit) i_destinationHolder.ResetUpdate(); unit.StopMoving(); } - template bool ConfusedMovementGenerator::Update(T &unit, const uint32 &diff) { if(!&unit) return true; - if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED)) return true; - if( i_nextMoveTime.Passed() ) { // currently moving, update location @@ -134,7 +114,6 @@ ConfusedMovementGenerator::Update(T &unit, const uint32 &diff) { // arrived, stop and wait a bit unit.clearUnitState(UNIT_STAT_MOVE); - i_nextMove = urand(1,MAX_CONF_WAYPOINTS); i_nextMoveTime.Reset(urand(0, 1500-1)); // TODO: check the minimum reset time, should be probably higher } @@ -157,7 +136,6 @@ ConfusedMovementGenerator::Update(T &unit, const uint32 &diff) } return true; } - template void ConfusedMovementGenerator::Finalize(T &unit) @@ -167,7 +145,6 @@ ConfusedMovementGenerator::Finalize(T &unit) if(unit.GetTypeId() == TYPEID_UNIT && unit.getVictim()) unit.SetUInt64Value(UNIT_FIELD_TARGET, unit.getVictim()->GetGUID()); } - template void ConfusedMovementGenerator::Initialize(Player &player); template void ConfusedMovementGenerator::Initialize(Creature &creature); template void ConfusedMovementGenerator::Finalize(Player &player); diff --git a/src/game/ConfusedMovementGenerator.h b/src/game/ConfusedMovementGenerator.h index ad47b13cb39..0675ea49e4c 100644 --- a/src/game/ConfusedMovementGenerator.h +++ b/src/game/ConfusedMovementGenerator.h @@ -17,35 +17,28 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef TRINITY_CONFUSEDGENERATOR_H #define TRINITY_CONFUSEDGENERATOR_H - #include "MovementGenerator.h" #include "DestinationHolder.h" #include "Traveller.h" - #define MAX_CONF_WAYPOINTS 24 - template class TRINITY_DLL_SPEC ConfusedMovementGenerator : public MovementGeneratorMedium< T, ConfusedMovementGenerator > { public: explicit ConfusedMovementGenerator() : i_nextMoveTime(0) {} - void Initialize(T &); void Finalize(T &); void Reset(T &); bool Update(T &, const uint32 &); - bool GetDestination(float &x, float &y, float &z) const { if(i_destinationHolder.HasArrived()) return false; i_destinationHolder.GetDestination(x,y,z); return true; } - MovementGeneratorType GetMovementGeneratorType() { return CONFUSED_MOTION_TYPE; } private: void _InitSpecific(T &, bool &, bool &); diff --git a/src/game/Corpse.cpp b/src/game/Corpse.cpp index 16e52ef46aa..350e314152d 100644 --- a/src/game/Corpse.cpp +++ b/src/game/Corpse.cpp @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "Common.h" #include "Corpse.h" #include "Player.h" @@ -27,87 +26,65 @@ #include "Opcodes.h" #include "GossipDef.h" #include "World.h" - Corpse::Corpse(CorpseType type) : WorldObject() , m_type(type) { m_objectType |= TYPEMASK_CORPSE; m_objectTypeId = TYPEID_CORPSE; - m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_POSITION); - m_valuesCount = CORPSE_END; - m_time = time(NULL); - lootForBody = false; - if(type != CORPSE_BONES) m_isWorldObject = true; } - Corpse::~Corpse() { } - void Corpse::AddToWorld() { ///- Register the corpse for guid lookup if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this); - Object::AddToWorld(); } - void Corpse::RemoveFromWorld() { ///- Remove the corpse from the accessor if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this); - Object::RemoveFromWorld(); } - bool Corpse::Create( uint32 guidlow, Map *map ) { SetMap(map); Object::_Create(guidlow, 0, HIGHGUID_CORPSE); return true; } - bool Corpse::Create( uint32 guidlow, Player *owner) { ASSERT(owner); - Relocate(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ(), owner->GetOrientation()); - if(!IsPositionValid()) { sLog.outError("Corpse (guidlow %d, owner %s) not created. Suggested coordinates isn't valid (X: %f Y: %f)", guidlow, owner->GetName(), owner->GetPositionX(), owner->GetPositionY()); return false; } - //we need to assign owner's map for corpse //in other way we will get a crash in Corpse::SaveToDB() SetMap(owner->GetMap()); - WorldObject::_Create(guidlow, HIGHGUID_CORPSE, owner->GetPhaseMask()); - SetFloatValue( OBJECT_FIELD_SCALE_X, 1 ); SetUInt64Value( CORPSE_FIELD_OWNER, owner->GetGUID() ); - m_grid = Trinity::ComputeGridPair(GetPositionX(), GetPositionY()); - return true; } - void Corpse::SaveToDB() { // prevent DB data inconsistence problems and duplicates CharacterDatabase.BeginTransaction(); DeleteFromDB(); - std::ostringstream ss; ss << "INSERT INTO corpse (guid,player,position_x,position_y,position_z,orientation,zone,map,data,time,corpse_type,instance,phaseMask) VALUES (" << GetGUIDLow() << ", " @@ -128,21 +105,17 @@ void Corpse::SaveToDB() CharacterDatabase.Execute( ss.str().c_str() ); CharacterDatabase.CommitTransaction(); } - void Corpse::DeleteBonesFromWorld() { assert(GetType() == CORPSE_BONES); Corpse* corpse = ObjectAccessor::GetCorpse(*this, GetGUID()); - if (!corpse) { sLog.outError("Bones %u not found in world.", GetGUIDLow()); return; } - AddObjectToRemoveList(); } - void Corpse::DeleteFromDB() { if(GetType() == CORPSE_BONES) @@ -152,7 +125,6 @@ void Corpse::DeleteFromDB() // all corpses (not bones) CharacterDatabase.PExecute("DELETE FROM corpse WHERE player = '%d' AND corpse_type <> '0'", GUID_LOPART(GetOwnerGUID())); } - /* bool Corpse::LoadFromDB(uint32 guid, QueryResult *result, uint32 InstanceId) { @@ -160,29 +132,22 @@ bool Corpse::LoadFromDB(uint32 guid, QueryResult *result, uint32 InstanceId) if (!external) // 0 1 2 3 4 5 6 7 8 9 result = CharacterDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map,data,time,corpse_type,instance,phaseMask FROM corpse WHERE guid = '%u'",guid); - if( !result ) { sLog.outError("Corpse (GUID: %u) not found in table `corpse`, can't load. ",guid); return false; } - Field *fields = result->Fetch(); - if(!LoadFromDB(guid, fields)) { if (!external) delete result; - return false; } - if (!external) delete result; - return true; }*/ - bool Corpse::LoadFromDB(uint32 guid, Field *fields) { // 0 1 2 3 4 5 6 7 8 9 @@ -192,52 +157,39 @@ bool Corpse::LoadFromDB(uint32 guid, Field *fields) float positionZ = fields[2].GetFloat(); float ort = fields[3].GetFloat(); uint32 mapid = fields[4].GetUInt32(); - Object::_Create(guid, 0, HIGHGUID_CORPSE); - if(!LoadValues( fields[5].GetString() )) { sLog.outError("Corpse #%d have broken data in `data` field. Can't be loaded.",guid); return false; } - m_time = time_t(fields[6].GetUInt64()); m_type = CorpseType(fields[7].GetUInt32()); - if(m_type >= MAX_CORPSE_TYPE) { sLog.outError("Corpse (guidlow %d, owner %d) have wrong corpse type, not load.",GetGUIDLow(),GUID_LOPART(GetOwnerGUID())); return false; } - if(m_type != CORPSE_BONES) m_isWorldObject = true; - uint32 instanceid = fields[8].GetUInt32(); - uint32 phaseMask = fields[9].GetUInt32(); - // overwrite possible wrong/corrupted guid SetUInt64Value(OBJECT_FIELD_GUID, MAKE_NEW_GUID(guid, 0, HIGHGUID_CORPSE)); - // place SetLocationInstanceId(instanceid); SetLocationMapId(mapid); SetPhaseMask(phaseMask, false); Relocate(positionX, positionY, positionZ, ort); - if(!IsPositionValid()) { sLog.outError("Corpse (guidlow %d, owner %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)", GetGUIDLow(), GUID_LOPART(GetOwnerGUID()), GetPositionX(), GetPositionY()); return false; } - m_grid = Trinity::ComputeGridPair(GetPositionX(), GetPositionY()); - return true; } - bool Corpse::isVisibleForInState(Player const* u, bool inVisibleList) const { return IsInWorld() && u->IsInWorld() && IsWithinDistInMap(u->m_seer, World::GetMaxVisibleDistanceForObject() + (inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), false); diff --git a/src/game/Corpse.h b/src/game/Corpse.h index e0374a03470..ca9a16d8ced 100644 --- a/src/game/Corpse.h +++ b/src/game/Corpse.h @@ -17,15 +17,12 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef TRINITYCORE_CORPSE_H #define TRINITYCORE_CORPSE_H - #include "Object.h" #include "Database/DatabaseEnv.h" #include "GridDefines.h" #include "LootMgr.h" - enum CorpseType { CORPSE_BONES = 0, @@ -33,10 +30,8 @@ enum CorpseType CORPSE_RESURRECTABLE_PVP = 2 }; #define MAX_CORPSE_TYPE 3 - // Value equal client resurrection dialog show radius. #define CORPSE_RECLAIM_RADIUS 39 - enum CorpseFlags { CORPSE_FLAG_NONE = 0x00, @@ -47,51 +42,38 @@ enum CorpseFlags CORPSE_FLAG_HIDE_CLOAK = 0x10, CORPSE_FLAG_LOOTABLE = 0x20 }; - class Corpse : public WorldObject { public: explicit Corpse( CorpseType type = CORPSE_BONES ); ~Corpse( ); - void AddToWorld(); void RemoveFromWorld(); - bool Create( uint32 guidlow, Map *map ); bool Create( uint32 guidlow, Player *owner ); - void SaveToDB(); //bool LoadFromDB(uint32 guid, QueryResult *result, uint32 InstanceId); bool LoadFromDB(uint32 guid, Field *fields); - void DeleteBonesFromWorld(); void DeleteFromDB(); - uint64 const& GetOwnerGUID() const { return GetUInt64Value(CORPSE_FIELD_OWNER); } - time_t const& GetGhostTime() const { return m_time; } void ResetGhostTime() { m_time = time(NULL); } CorpseType GetType() const { return m_type; } - GridPair const& GetGrid() const { return m_grid; } void SetGrid(GridPair const& grid) { m_grid = grid; } - bool isVisibleForInState(Player const* u, bool inVisibleList) const; - Loot loot; // remove insignia ONLY at BG Player* lootRecipient; bool lootForBody; - void Say(int32 textId, uint32 language, uint64 TargetGuid) { MonsterSay(textId,language,TargetGuid); } void Yell(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYell(textId,language,TargetGuid); } void TextEmote(int32 textId, uint64 TargetGuid) { MonsterTextEmote(textId,TargetGuid); } void Whisper(int32 textId,uint64 receiver) { MonsterWhisper(textId,receiver); } void YellToZone(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYellToZone(textId,language,TargetGuid); } - GridReference &GetGridRef() { return m_gridRef; } private: GridReference m_gridRef; - CorpseType m_type; time_t m_time; GridPair m_grid; // gride for corpse position for fast search diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index a3a2e5c1690..63c9d34d157 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "Common.h" #include "Database/DatabaseEnv.h" #include "WorldPacket.h" @@ -49,16 +48,13 @@ #include "Vehicle.h" // apply implementation of the singletons #include "Policies/SingletonImp.h" - TrainerSpell const* TrainerSpellData::Find(uint32 spell_id) const { TrainerSpellMap::const_iterator itr = spellList.find(spell_id); if (itr != spellList.end()) return &itr->second; - return NULL; } - bool VendorItemData::RemoveItem( uint32 item_id ) { for(VendorItemList::iterator i = m_items.begin(); i != m_items.end(); ++i ) @@ -71,7 +67,6 @@ bool VendorItemData::RemoveItem( uint32 item_id ) } return false; } - size_t VendorItemData::FindItemSlot(uint32 item_id) const { for(size_t i = 0; i < m_items.size(); ++i ) @@ -79,7 +74,6 @@ size_t VendorItemData::FindItemSlot(uint32 item_id) const return i; return m_items.size(); } - VendorItem const* VendorItemData::FindItem(uint32 item_id) const { for(VendorItemList::const_iterator i = m_items.begin(); i != m_items.end(); ++i ) @@ -87,20 +81,16 @@ VendorItem const* VendorItemData::FindItem(uint32 item_id) const return *i; return NULL; } - uint32 CreatureInfo::GetRandomValidModelId() const { uint8 c = 0; uint32 modelIDs[4]; - if (Modelid1) modelIDs[c++] = Modelid1; if (Modelid2) modelIDs[c++] = Modelid2; if (Modelid3) modelIDs[c++] = Modelid3; if (Modelid4) modelIDs[c++] = Modelid4; - return ((c>0) ? modelIDs[urand(0,c-1)] : 0); } - uint32 CreatureInfo::GetFirstValidModelId() const { if(Modelid1) return Modelid1; @@ -109,7 +99,6 @@ uint32 CreatureInfo::GetFirstValidModelId() const if(Modelid4) return Modelid4; return 0; } - bool AssistDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) { if(Unit* victim = Unit::GetUnit(m_owner, m_victim)) @@ -118,7 +107,6 @@ bool AssistDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) { Creature* assistant = Unit::GetCreature(m_owner, *m_assistants.begin()); m_assistants.pop_front(); - if (assistant && assistant->CanAssistTo(&m_owner, victim)) { assistant->SetNoCallAssistance(true); @@ -130,7 +118,6 @@ bool AssistDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) } return true; } - Creature::Creature() : Unit(), lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLeaderGUID(0), @@ -145,34 +132,27 @@ m_creatureInfo(NULL), m_reactState(REACT_AGGRESSIVE), m_formation(NULL) { m_regenTimer = 200; m_valuesCount = UNIT_END; - for(uint8 i =0; iInstall(); } } - void Creature::RemoveFromWorld() { if(IsInWorld()) @@ -201,7 +180,6 @@ void Creature::RemoveFromWorld() ObjectAccessor::Instance().RemoveObject(this); } } - void Creature::DisappearAndDie() { DestroyForNearbyPlayers(); @@ -211,26 +189,21 @@ void Creature::DisappearAndDie() setDeathState(JUST_DIED); RemoveCorpse(); } - void Creature::SearchFormation() { if(isSummon()) return; - uint32 lowguid = GetDBTableGUIDLow(); if(!lowguid) return; - CreatureGroupInfoType::iterator frmdata = CreatureGroupMap.find(lowguid); if(frmdata != CreatureGroupMap.end()) formation_mgr.AddCreatureToGroup(frmdata->second->leaderGUID, this); } - void Creature::RemoveCorpse() { if ((getDeathState()!=CORPSE && !m_isDeadByDefault) || (getDeathState()!=ALIVE && m_isDeadByDefault)) return; - m_deathTimer = 0; setDeathState(DEAD); ObjectAccessor::UpdateObjectVisibility(this); @@ -238,15 +211,12 @@ void Creature::RemoveCorpse() uint32 respawnDelay = m_respawnDelay; if (AI()) AI()->CorpseRemoved(respawnDelay); - m_respawnTime = time(NULL) + m_respawnDelay; - float x,y,z,o; GetRespawnCoord(x, y, z, &o); SetHomePosition(x,y,z,o); GetMap()->CreatureRelocation(this,x,y,z,o); } - /** * change the entry of creature until respawn */ @@ -258,7 +228,6 @@ bool Creature::InitEntry(uint32 Entry, uint32 team, const CreatureData *data ) sLog.outErrorDb("Creature::UpdateEntry creature entry %u does not exist.", Entry); return false; } - // get heroic mode entry uint32 actualEntry = Entry; CreatureInfo const *cinfo = normalInfo; @@ -275,23 +244,18 @@ bool Creature::InitEntry(uint32 Entry, uint32 team, const CreatureData *data ) } } } - SetEntry(Entry); // normal entry always m_creatureInfo = cinfo; // map mode related always - // equal to player Race field, but creature does not have race SetByteValue(UNIT_FIELD_BYTES_0, 0, 0); - // known valid are: CLASS_WARRIOR,CLASS_PALADIN,CLASS_ROGUE,CLASS_MAGE SetByteValue(UNIT_FIELD_BYTES_0, 1, uint8(cinfo->unit_class)); - // Cancel load if no model defined if (!(cinfo->GetFirstValidModelId())) { sLog.outErrorDb("Creature (Entry: %u) has no model defined in table `creature_template`, can't load. ",Entry); return false; } - uint32 display_id = objmgr.ChooseDisplayId(0, GetCreatureInfo(), data); CreatureModelInfo const *minfo = objmgr.GetCreatureModelRandomGender(display_id); if (!minfo) // Cancel load if no model defined @@ -299,13 +263,10 @@ bool Creature::InitEntry(uint32 Entry, uint32 team, const CreatureData *data ) sLog.outErrorDb("Creature (Entry: %u) has no model defined in table `creature_template`, can't load. ",Entry); return false; } - display_id = minfo->modelid; // it can be different (for another gender) - SetDisplayId(display_id); SetNativeDisplayId(display_id); SetByteValue(UNIT_FIELD_BYTES_0, 2, minfo->gender); - // Load creature equipment if(!data || data->equipmentId == 0) { // use default from the template @@ -315,61 +276,44 @@ bool Creature::InitEntry(uint32 Entry, uint32 team, const CreatureData *data ) { // override, -1 means no equipment LoadEquipment(data->equipmentId); } - SetName(normalInfo->Name); // at normal entry always - SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS,minfo->bounding_radius); SetFloatValue(UNIT_FIELD_COMBATREACH,minfo->combat_reach ); - SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f); - SetSpeed(MOVE_WALK, cinfo->speed ); SetSpeed(MOVE_RUN, cinfo->speed ); SetSpeed(MOVE_SWIM, cinfo->speed ); - SetFloatValue(OBJECT_FIELD_SCALE_X, cinfo->scale); - // checked at loading m_defaultMovementType = MovementGeneratorType(cinfo->MovementType); if(!m_respawnradius && m_defaultMovementType==RANDOM_MOTION_TYPE) m_defaultMovementType = IDLE_MOTION_TYPE; - for(uint8 i=0; i < CREATURE_MAX_SPELLS; ++i) m_spells[i] = GetCreatureInfo()->spells[i]; - return true; } - bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData *data ) { if(!InitEntry(Entry,team,data)) return false; - m_regenHealth = GetCreatureInfo()->RegenHealth; - // creatures always have melee weapon ready if any SetSheath(SHEATH_STATE_MELEE); - SelectLevel(GetCreatureInfo()); if (team == HORDE) setFaction(GetCreatureInfo()->faction_H); else setFaction(GetCreatureInfo()->faction_A); - if(GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_WORLDEVENT) SetUInt32Value(UNIT_NPC_FLAGS,GetCreatureInfo()->npcflag | gameeventmgr.GetNPCFlag(this)); else SetUInt32Value(UNIT_NPC_FLAGS,GetCreatureInfo()->npcflag); - SetAttackTime(BASE_ATTACK, GetCreatureInfo()->baseattacktime); SetAttackTime(OFF_ATTACK, GetCreatureInfo()->baseattacktime); SetAttackTime(RANGED_ATTACK,GetCreatureInfo()->rangeattacktime); - SetUInt32Value(UNIT_FIELD_FLAGS,GetCreatureInfo()->unit_flags); SetUInt32Value(UNIT_DYNAMIC_FLAGS,GetCreatureInfo()->dynamicflags); - RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT); - SetMeleeDamageSchool(SpellSchools(GetCreatureInfo()->dmgschool)); SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, float(GetCreatureInfo()->armor)); SetModifierValue(UNIT_MOD_RESISTANCE_HOLY, BASE_VALUE, float(GetCreatureInfo()->resistance1)); @@ -378,10 +322,8 @@ bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData *data ) SetModifierValue(UNIT_MOD_RESISTANCE_FROST, BASE_VALUE, float(GetCreatureInfo()->resistance4)); SetModifierValue(UNIT_MOD_RESISTANCE_SHADOW, BASE_VALUE, float(GetCreatureInfo()->resistance5)); SetModifierValue(UNIT_MOD_RESISTANCE_ARCANE, BASE_VALUE, float(GetCreatureInfo()->resistance6)); - SetCanModifyStats(true); UpdateAllStats(); - FactionTemplateEntry const* factionTemplate = sFactionTemplateStore.LookupEntry(GetCreatureInfo()->faction_A); if (factionTemplate) // check and error show at loading templates { @@ -391,11 +333,9 @@ bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData *data ) (factionEntry->team == ALLIANCE || factionEntry->team == HORDE) ) SetPvP(true); } - // HACK: trigger creature is always not selectable if(isTrigger()) SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - if(isTotem() || isTrigger() || GetCreatureType() == CREATURE_TYPE_CRITTER) SetReactState(REACT_PASSIVE); @@ -403,26 +343,21 @@ bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData *data ) SetReactState(REACT_DEFENSIVE);*/ else SetReactState(REACT_AGGRESSIVE); - if(GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_TAUNT) { ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true); ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true); } - if(GetCreatureInfo()->InhabitType & INHABIT_AIR) AddUnitMovementFlag(MOVEMENTFLAG_FLY_MODE + MOVEMENTFLAG_FLYING); - return true; } - void Creature::Update(uint32 diff) { if(m_GlobalCooldown <= diff) m_GlobalCooldown = 0; else m_GlobalCooldown -= diff; - switch( m_deathState ) { case JUST_ALIVED: @@ -459,7 +394,6 @@ void Creature::Update(uint32 diff) { if (m_isDeadByDefault) break; - if( m_deathTimer <= diff ) { RemoveCorpse(); @@ -469,7 +403,6 @@ void Creature::Update(uint32 diff) { // for delayed spells m_Events.Update( diff ); - m_deathTimer -= diff; if (m_groupLootTimer && lootingGroupLeaderGUID) { @@ -487,7 +420,6 @@ void Creature::Update(uint32 diff) } } } - break; } case ALIVE: @@ -504,14 +436,11 @@ void Creature::Update(uint32 diff) m_deathTimer -= diff; } } - Unit::Update( diff ); - // creature can be dead after Unit::Update call // CORPSE/DEAD state will processed at next tick (in other case death timer will be updated unexpectedly) if(!isAlive()) break; - // if creature is charmed, switch to charmed AI if(NeedChangeAI) { @@ -519,7 +448,6 @@ void Creature::Update(uint32 diff) NeedChangeAI = false; IsAIEnabled = true; } - if(!IsInEvadeMode() && IsAIEnabled) { // do not allow the AI to be changed during update @@ -527,12 +455,10 @@ void Creature::Update(uint32 diff) i_AI->UpdateAI(diff); m_AI_locked = false; } - // creature can be dead after UpdateAI call // CORPSE/DEAD state will processed at next tick (in other case death timer will be updated unexpectedly) if(!isAlive()) break; - if(m_regenTimer > 0) { if(diff >= m_regenTimer) @@ -540,20 +466,16 @@ void Creature::Update(uint32 diff) else m_regenTimer -= diff; } - if (m_regenTimer != 0) break; - bool bIsPolymorphed = IsPolymorphed(); bool bInCombat = isInCombat() && (!getVictim() || // if isInCombat() is true and this has no victim !getVictim()->GetCharmerOrOwnerPlayerOrPlayerItself() || // or the victim/owner/charmer is not a player !getVictim()->GetCharmerOrOwnerPlayerOrPlayerItself()->isGameMaster()); // or the victim/owner/charmer is not a GameMaster - - /*if(m_regenTimer <= diff) + /*if(m_regenTimer <= diff) {*/ if(!bInCombat || bIsPolymorphed) // regenerate health if not in combat or if polymorphed RegenerateHealth(); - if(getPowerType() == POWER_ENERGY) { if(!IsVehicle() || GetVehicleKit()->GetVehicleInfo()->m_powerType != POWER_PYRITE) @@ -561,10 +483,9 @@ void Creature::Update(uint32 diff) } else RegenerateMana(); - /*if(!bIsPolymorphed) // only increase the timer if not polymorphed m_regenTimer += 2000 - diff; - } + } else if(!bIsPolymorphed) // if polymorphed, skip the timer m_regenTimer -= diff;*/ @@ -577,17 +498,13 @@ void Creature::Update(uint32 diff) break; } } - void Creature::RegenerateMana() { uint32 curValue = GetPower(POWER_MANA); uint32 maxValue = GetMaxPower(POWER_MANA); - if (curValue >= maxValue) return; - uint32 addvalue = 0; - // Combat and any controlled creature if (isInCombat() || GetCharmerOrOwnerGUID()) { @@ -595,35 +512,27 @@ void Creature::RegenerateMana() { float ManaIncreaseRate = sWorld.getRate(RATE_POWER_MANA); float Spirit = GetStat(STAT_SPIRIT); - addvalue = uint32((Spirit/5.0f + 17.0f) * ManaIncreaseRate); } } else addvalue = maxValue/3; - ModifyPower(POWER_MANA, addvalue); } - void Creature::RegenerateHealth() { if (!isRegeneratingHealth()) return; - uint32 curValue = GetHealth(); uint32 maxValue = GetMaxHealth(); - if (curValue >= maxValue) return; - uint32 addvalue = 0; - // Not only pet, but any controlled creature if(GetCharmerOrOwnerGUID()) { float HealthIncreaseRate = sWorld.getRate(RATE_HEALTH); float Spirit = GetStat(STAT_SPIRIT); - if( GetPower(POWER_MANA) > 0 ) addvalue = uint32(Spirit * 0.25 * HealthIncreaseRate); else @@ -631,35 +540,27 @@ void Creature::RegenerateHealth() } else addvalue = maxValue/3; - ModifyHealth(addvalue); } - void Creature::DoFleeToGetAssistance() { if (!getVictim()) return; - if(HasAuraType(SPELL_AURA_PREVENTS_FLEEING)) return; - float radius = sWorld.getConfig(CONFIG_CREATURE_FAMILY_FLEE_ASSISTANCE_RADIUS); if (radius >0) { Creature* pCreature = NULL; - CellPair p(MaNGOS::ComputeCellPair(GetPositionX(), GetPositionY())); Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); MaNGOS::NearestAssistCreatureInCreatureRangeCheck u_check(this, getVictim(), radius); MaNGOS::CreatureLastSearcher searcher(this, pCreature, u_check); - TypeContainerVisitor, GridTypeMapContainer > grid_creature_searcher(searcher); - CellLock cell_lock(cell, p); cell_lock->Visit(cell_lock, grid_creature_searcher, *GetMap(), *this, radius); - SetNoSearchAssistance(true); if(!pCreature) //SetFeared(true, getVictim()->GetGUID(), 0 ,sWorld.getConfig(CONFIG_CREATURE_FAMILY_FLEE_DELAY)); @@ -669,7 +570,6 @@ void Creature::DoFleeToGetAssistance() GetMotionMaster()->MoveSeekAssistance(pCreature->GetPositionX(), pCreature->GetPositionY(), pCreature->GetPositionZ()); } } - bool Creature::AIM_Initialize(CreatureAI* ai) { // make sure nothing can change the AI during AI update @@ -678,24 +578,20 @@ bool Creature::AIM_Initialize(CreatureAI* ai) sLog.outDebug("AIM_Initialize: failed to init, locked."); return false; } - UnitAI *oldAI = i_AI; - Motion_Initialize(); - i_AI = ai ? ai : FactorySelector::selectAI(this); if(oldAI) delete oldAI; IsAIEnabled = true; i_AI->InitializeAI(); return true; } - void Creature::Motion_Initialize() { if(!m_formation) i_motionMaster.Initialize(); else if(m_formation->getLeader() == this) - { + { m_formation->FormationReset(false); i_motionMaster.Initialize(); } @@ -704,24 +600,19 @@ void Creature::Motion_Initialize() else i_motionMaster.Initialize(); } - bool Creature::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 vehId, uint32 team, float x, float y, float z, float ang, const CreatureData *data) { ASSERT(map); SetMap(map); SetPhaseMask(phaseMask,false); - Relocate(x, y, z, ang); - if(!IsPositionValid()) { sLog.outError("Creature (guidlow %d, entry %d) not loaded. Suggested coordinates isn't valid (X: %f Y: %f)",guidlow,Entry,x,y); return false; } - //oX = x; oY = y; dX = x; dY = y; m_moveTime = 0; m_startMove = 0; const bool bResult = CreateFromProto(guidlow, Entry, vehId, team, data); - if (bResult) { switch (GetCreatureInfo()->rank) @@ -747,7 +638,6 @@ bool Creature::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, if (minfo && !isTotem()) // Cancel load if no model defined or if totem { uint32 display_id = minfo->modelid; // it can be different (for another gender) - SetDisplayId(display_id); SetNativeDisplayId(display_id); SetByteValue(UNIT_FIELD_BYTES_0, 2, minfo->gender); @@ -755,21 +645,17 @@ bool Creature::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, } return bResult; } - bool Creature::isCanTrainingOf(Player* pPlayer, bool msg) const { if(!isTrainer()) return false; - TrainerSpellData const* trainer_spells = GetTrainerSpells(); - if(!trainer_spells || trainer_spells->spellList.empty()) { sLog.outErrorDb("Creature %u (Entry: %u) have UNIT_NPC_FLAG_TRAINER but have empty trainer spell list.", GetGUIDLow(),GetEntry()); return false; } - switch(GetCreatureInfo()->trainer_type) { case TRAINER_TYPE_CLASS: @@ -841,16 +727,13 @@ bool Creature::isCanTrainingOf(Player* pPlayer, bool msg) const } return true; } - bool Creature::isCanInteractWithBattleMaster(Player* pPlayer, bool msg) const { if(!isBattleMaster()) return false; - BattleGroundTypeId bgTypeId = sBattleGroundMgr.GetBattleMasterBG(GetEntry()); if(!msg) return pPlayer->GetBGAccessByLevel(bgTypeId); - if(!pPlayer->GetBGAccessByLevel(bgTypeId)) { pPlayer->PlayerTalkClass->ClearMenus(); @@ -873,27 +756,22 @@ bool Creature::isCanInteractWithBattleMaster(Player* pPlayer, bool msg) const } return true; } - bool Creature::isCanTrainingAndResetTalentsOf(Player* pPlayer) const { return pPlayer->getLevel() >= 10 && GetCreatureInfo()->trainer_type == TRAINER_TYPE_CLASS && pPlayer->getClass() == GetCreatureInfo()->trainer_class; } - void Creature::prepareGossipMenu( Player *pPlayer,uint32 gossipid ) { //Prevent gossip from NPCs that are possessed. Unit* Charmed = Unit::GetCharmer(); if (Charmed) return; - PlayerMenu* pm=pPlayer->PlayerTalkClass; pm->ClearMenus(); - // lazy loading single time at use LoadGossipOptions(); - for( GossipOptionList::iterator i = m_goptions.begin( ); i != m_goptions.end( ); ++i ) { GossipOption* gso=&*i; @@ -976,7 +854,6 @@ void Creature::prepareGossipMenu( Player *pPlayer,uint32 gossipid ) break; } } - //note for future dev: should have database fields for BoxMessage & BoxMoney if(!gso->OptionText.empty() && cantalking) { @@ -998,7 +875,6 @@ void Creature::prepareGossipMenu( Player *pPlayer,uint32 gossipid ) } } } - ///some gossips aren't handled in normal way ... so we need to do it this way .. TODO: handle it in normal way ;-) if(pm->Empty()) { @@ -1012,38 +888,30 @@ void Creature::prepareGossipMenu( Player *pPlayer,uint32 gossipid ) } } } - void Creature::sendPreparedGossip(Player* player) { if(!player) return; - if(GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_WORLDEVENT) // if world event npc then gameeventmgr.HandleWorldEventGossip(player, this); // update world state with progress - // in case no gossip flag and quest menu not empty, open quest menu (client expect gossip menu with this flag) if (!HasFlag(UNIT_NPC_FLAGS,UNIT_NPC_FLAG_GOSSIP) && !player->PlayerTalkClass->GetQuestMenu().Empty()) { player->SendPreparedQuest(GetGUID()); return; } - // in case non empty gossip menu (that not included quests list size) show it // (quest entries from quest menu will be included in list) player->PlayerTalkClass->SendGossipMenu(GetNpcTextId(), GetGUID()); } - void Creature::OnGossipSelect(Player* player, uint32 option) { GossipMenu& gossipmenu = player->PlayerTalkClass->GetGossipMenu(); - if(option >= gossipmenu.MenuItemCount()) return; - uint32 action=gossipmenu.GetItem(option).m_gAction; uint32 zoneid=GetZoneId(); uint64 guid=GetGUID(); - GossipOption const *gossip=GetGossipOption( action ); if(!gossip) { @@ -1052,7 +920,6 @@ void Creature::OnGossipSelect(Player* player, uint32 option) if(!gossip) return; } - switch (gossip->Action) { case GOSSIP_OPTION_GOSSIP: @@ -1060,7 +927,6 @@ void Creature::OnGossipSelect(Player* player, uint32 option) uint32 textid = GetGossipTextId(action, zoneid); if (textid == 0) textid=GetNpcTextId(); - player->PlayerTalkClass->CloseGossip(); player->PlayerTalkClass->SendTalking(textid); break; @@ -1102,12 +968,10 @@ void Creature::OnGossipSelect(Player* player, uint32 option) else { player->ModifyMoney(-10000000); - // Cast spells that teach dual spec // Both are also ImplicitTarget self and must be cast by player player->CastSpell(player,63680,true,NULL,NULL,player->GetGUID()); player->CastSpell(player,63624,true,NULL,NULL,player->GetGUID()); - // Should show another Gossip text with "Congratulations..." player->PlayerTalkClass->CloseGossip(); } @@ -1154,9 +1018,7 @@ void Creature::OnGossipSelect(Player* player, uint32 option) OnPoiSelect( player, gossip ); break; } - } - void Creature::OnPoiSelect(Player* player, GossipOption const *gossip) { if(gossip->GossipId==GOSSIP_GUARD_SPELLTRAINER || gossip->GossipId==GOSSIP_GUARD_SKILLTRAINER) @@ -1184,38 +1046,28 @@ void Creature::OnPoiSelect(Player* player, GossipOption const *gossip) // how this could worked player->PlayerTalkClass->SendPointOfInterest( x, y, icon, 2, 15, areaname.c_str() ); } } - uint32 Creature::GetGossipTextId(uint32 action, uint32 zoneid) { QueryResult *result= WorldDatabase.PQuery("SELECT textid FROM npc_gossip_textid WHERE action = '%u' AND zoneid ='%u'", action, zoneid ); - if(!result) return 0; - Field *fields = result->Fetch(); uint32 id = fields[0].GetUInt32(); - delete result; - return id; } - uint32 Creature::GetNpcTextId() { // don't cache / use cache in case it's a world event announcer if(GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_WORLDEVENT) if(uint32 textid = gameeventmgr.GetNpcTextId(m_DBTableGuid)) return textid; - if (!m_DBTableGuid) return DEFAULT_GOSSIP_MESSAGE; - if(uint32 pos = objmgr.GetNpcGossip(m_DBTableGuid)) return pos; - return DEFAULT_GOSSIP_MESSAGE; } - GossipOption const* Creature::GetGossipOption( uint32 id ) const { for( GossipOptionList::const_iterator i = m_goptions.begin( ); i != m_goptions.end( ); ++i ) @@ -1225,28 +1077,22 @@ GossipOption const* Creature::GetGossipOption( uint32 id ) const } return NULL; } - void Creature::ResetGossipOptions() { m_gossipOptionLoaded = false; m_goptions.clear(); } - void Creature::LoadGossipOptions() { if(m_gossipOptionLoaded) return; - uint32 npcflags=GetUInt32Value(UNIT_NPC_FLAGS); - CacheNpcOptionList const& noList = objmgr.GetNpcOptions (); for (CacheNpcOptionList::const_iterator i = noList.begin (); i != noList.end (); ++i) if(i->NpcFlag & npcflags) addGossipOption(*i); - m_gossipOptionLoaded = true; } - void Creature::AI_SendMoveToPacket(float x, float y, float z, uint32 time, uint32 MovementFlags, uint8 type) { /* uint32 timeElap = getMSTime(); @@ -1260,28 +1106,23 @@ void Creature::AI_SendMoveToPacket(float x, float y, float z, uint32 time, uint3 oX = dX; oY = dY; } - dX = x; dY = y; m_orientation = atan2((oY - dY), (oX - dX)); - m_startMove = getMSTime(); m_moveTime = time;*/ SendMonsterMove(x, y, z, time); } - Player *Creature::GetLootRecipient() const { if (!m_lootRecipient) return NULL; else return ObjectAccessor::FindPlayer(m_lootRecipient); } - void Creature::SetLootRecipient(Unit *unit) { // set the player whose group should receive the right // to loot the creature after it dies // should be set to NULL after the loot disappears - if (!unit) { m_lootRecipient = 0; @@ -1289,15 +1130,12 @@ void Creature::SetLootRecipient(Unit *unit) RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_OTHER_TAGGER); return; } - Player* player = unit->GetCharmerOrOwnerPlayerOrPlayerItself(); if(!player) // normal creature, no player involved return; - m_lootRecipient = player->GetGUID(); SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_OTHER_TAGGER); } - void Creature::SaveToDB() { // this should only be used when the creature has already been loaded @@ -1308,19 +1146,15 @@ void Creature::SaveToDB() sLog.outError("Creature::SaveToDB failed, cannot get creature data!"); return; } - SaveToDB(GetMapId(), data->spawnMask,GetPhaseMask()); } - void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask) { // update in loaded data if (!m_DBTableGuid) m_DBTableGuid = GetGUIDLow(); CreatureData& data = objmgr.NewOrExistCreatureData(m_DBTableGuid); - uint32 displayId = GetNativeDisplayId(); - // check if it's a custom model and if not, use 0 for displayId CreatureInfo const *cinfo = GetCreatureInfo(); if (cinfo) @@ -1329,7 +1163,6 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask) displayId == cinfo->Modelid3 || displayId == cinfo->Modelid4) displayId = 0; } - // data->guid = guid don't must be update at save data.id = GetEntry(); data.mapid = mapid; @@ -1351,12 +1184,9 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask) data.movementType = !m_respawnradius && GetDefaultMovementType()==RANDOM_MOTION_TYPE ? IDLE_MOTION_TYPE : GetDefaultMovementType(); data.spawnMask = spawnMask; - // updated in DB WorldDatabase.BeginTransaction(); - WorldDatabase.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", m_DBTableGuid); - std::ostringstream ss; ss << "INSERT INTO creature VALUES (" << m_DBTableGuid << "," @@ -1377,64 +1207,46 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask) << GetPower(POWER_MANA) << "," //curmana << (m_isDeadByDefault ? 1 : 0) << "," //is_dead << GetDefaultMovementType() << ")"; //default movement generator type - WorldDatabase.PExecuteLog( ss.str( ).c_str( ) ); - WorldDatabase.CommitTransaction(); } - void Creature::SelectLevel(const CreatureInfo *cinfo) { uint32 rank = isPet()? 0 : cinfo->rank; - // level uint32 minlevel = std::min(cinfo->maxlevel, cinfo->minlevel); uint32 maxlevel = std::max(cinfo->maxlevel, cinfo->minlevel); uint32 level = minlevel == maxlevel ? minlevel : urand(minlevel, maxlevel); SetLevel(level); - float rellevel = maxlevel == minlevel ? 0 : (float(level - minlevel))/(maxlevel - minlevel); - // health float healthmod = _GetHealthMod(rank); - uint32 minhealth = std::min(cinfo->maxhealth, cinfo->minhealth); uint32 maxhealth = std::max(cinfo->maxhealth, cinfo->minhealth); uint32 health = uint32(healthmod * (minhealth + uint32(rellevel*(maxhealth - minhealth)))); - SetCreateHealth(health); SetMaxHealth(health); SetHealth(health); ResetPlayerDamageReq(); - // mana uint32 minmana = std::min(cinfo->maxmana, cinfo->minmana); uint32 maxmana = std::max(cinfo->maxmana, cinfo->minmana); uint32 mana = minmana + uint32(rellevel*(maxmana - minmana)); - SetCreateMana(mana); SetMaxPower(POWER_MANA, mana); //MAX Mana SetPower(POWER_MANA, mana); - // TODO: set UNIT_FIELD_POWER*, for some creature class case (energy, etc) - SetModifierValue(UNIT_MOD_HEALTH, BASE_VALUE, health); SetModifierValue(UNIT_MOD_MANA, BASE_VALUE, mana); - //damage float damagemod = 1.0f;//_GetDamageMod(rank); - SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, cinfo->mindmg * damagemod); SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, cinfo->maxdmg * damagemod); - SetFloatValue(UNIT_FIELD_MINRANGEDDAMAGE,cinfo->minrangedmg * damagemod); SetFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE,cinfo->maxrangedmg * damagemod); - SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, cinfo->attackpower * damagemod); - } - float Creature::_GetHealthMod(int32 Rank) { switch (Rank) // define rates for each elite rank @@ -1453,7 +1265,6 @@ float Creature::_GetHealthMod(int32 Rank) return sWorld.getRate(RATE_CREATURE_ELITE_ELITE_HP); } } - float Creature::_GetDamageMod(int32 Rank) { switch (Rank) // define rates for each elite rank @@ -1472,7 +1283,6 @@ float Creature::_GetDamageMod(int32 Rank) return sWorld.getRate(RATE_CREATURE_ELITE_ELITE_DAMAGE); } } - float Creature::GetSpellDamageMod(int32 Rank) { switch (Rank) // define rates for each elite rank @@ -1491,7 +1301,6 @@ float Creature::GetSpellDamageMod(int32 Rank) return sWorld.getRate(RATE_CREATURE_ELITE_ELITE_SPELLDAMAGE); } } - bool Creature::CreateFromProto(uint32 guidlow, uint32 Entry, uint32 vehId, uint32 team, const CreatureData *data) { SetZoneScript(); @@ -1501,56 +1310,41 @@ bool Creature::CreateFromProto(uint32 guidlow, uint32 Entry, uint32 vehId, uint3 if(!Entry) return false; } - CreatureInfo const *cinfo = objmgr.GetCreatureTemplate(Entry); if(!cinfo) { sLog.outErrorDb("Creature entry %u does not exist.", Entry); return false; } - SetOriginalEntry(Entry); - if(!vehId) vehId = cinfo->VehicleId; - if(vehId && !CreateVehicleKit(vehId)) vehId = 0; - Object::_Create(guidlow, Entry, vehId ? HIGHGUID_VEHICLE : HIGHGUID_UNIT); - if(!UpdateEntry(Entry, team, data)) return false; - return true; } - bool Creature::LoadFromDB(uint32 guid, Map *map) { CreatureData const* data = objmgr.GetCreatureData(guid); - if(!data) { sLog.outErrorDb("Creature (GUID: %u) not found in table `creature`, can't load. ",guid); return false; } - m_DBTableGuid = guid; if (map->GetInstanceId() != 0) guid = objmgr.GenerateLowGuid(HIGHGUID_UNIT); - uint16 team = 0; if(!Create(guid,map,data->phaseMask,data->id,0,team,data->posX,data->posY,data->posZ,data->orientation,data)) return false; - //We should set first home position, because then AI calls home movement SetHomePosition(data->posX,data->posY,data->posZ,data->orientation); - m_respawnradius = data->spawndist; - m_respawnDelay = data->spawntimesecs; m_isDeadByDefault = data->is_dead; m_deathState = m_isDeadByDefault ? DEAD : ALIVE; - m_respawnTime = objmgr.GetCreatureRespawnTime(m_DBTableGuid,GetInstanceId()); if(m_respawnTime) // respawn on Update { @@ -1562,7 +1356,6 @@ bool Creature::LoadFromDB(uint32 guid, Map *map) Relocate(data->posX,data->posY,tz); } } - uint32 curhealth = data->curhealth; if(curhealth) { @@ -1570,18 +1363,13 @@ bool Creature::LoadFromDB(uint32 guid, Map *map) if(curhealth < 1) curhealth = 1; } - SetHealth(m_deathState == ALIVE ? curhealth : 0); SetPower(POWER_MANA,data->curmana); - // checked at creature_template loading m_defaultMovementType = MovementGeneratorType(data->movementType); - m_creatureData = data; - return true; } - void Creature::LoadEquipment(uint32 equip_entry, bool force) { if(equip_entry == 0) @@ -1594,16 +1382,13 @@ void Creature::LoadEquipment(uint32 equip_entry, bool force) } return; } - EquipmentInfo const *einfo = objmgr.GetEquipmentInfo(equip_entry); if (!einfo) return; - m_equipmentId = equip_entry; for (uint8 i = 0; i < 3; ++i) SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + i, einfo->equipentry[i]); } - bool Creature::hasQuest(uint32 quest_id) const { QuestRelations const& qr = objmgr.mCreatureQuestRelations; @@ -1614,7 +1399,6 @@ bool Creature::hasQuest(uint32 quest_id) const } return false; } - bool Creature::hasInvolvedQuest(uint32 quest_id) const { QuestRelations const& qr = objmgr.mCreatureQuestInvolvedRelations; @@ -1625,7 +1409,6 @@ bool Creature::hasInvolvedQuest(uint32 quest_id) const } return false; } - void Creature::DeleteFromDB() { if (!m_DBTableGuid) @@ -1633,10 +1416,8 @@ void Creature::DeleteFromDB() sLog.outDebug("Trying to delete not saved creature!"); return; } - objmgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),0); objmgr.DeleteCreatureData(m_DBTableGuid); - WorldDatabase.BeginTransaction(); WorldDatabase.PExecuteLog("DELETE FROM creature WHERE guid = '%u'", m_DBTableGuid); WorldDatabase.PExecuteLog("DELETE FROM creature_addon WHERE guid = '%u'", m_DBTableGuid); @@ -1644,40 +1425,31 @@ void Creature::DeleteFromDB() WorldDatabase.PExecuteLog("DELETE FROM game_event_model_equip WHERE guid = '%u'", m_DBTableGuid); WorldDatabase.CommitTransaction(); } - bool Creature::canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList, bool is3dDistance) const { // not in world if(!IsInWorld() || !u->IsInWorld()) return false; - // all dead creatures/players not visible for any creatures if(!u->isAlive() || !isAlive()) return false; - // Always can see self if (u == this) return true; - // phased visibility (both must phased in same way) if(!InSamePhase(u)) return false; - // always seen by owner if(GetGUID() == u->GetCharmerOrOwnerGUID()) return true; - if(u->GetVisibility() == VISIBILITY_OFF) //GM return false; - // invisible aura if((m_invisibilityMask || u->m_invisibilityMask) && !canDetectInvisibilityOf(u)) return false; - // unit got in stealth in this moment and must ignore old detected state //if (m_Visibility == VISIBILITY_GROUP_NO_DETECT) // return false; - // GM invisibility checks early, invisibility if any detectable, so if not stealth then visible if(u->GetVisibility() == VISIBILITY_GROUP_STEALTH) { @@ -1685,113 +1457,86 @@ bool Creature::canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList, bo if(!detect || !canDetectStealthOf(u, GetDistance(u))) return false; } - // Now check is target visible with LoS //return u->IsWithinLOS(GetPositionX(),GetPositionY(),GetPositionZ()); return true; } - bool Creature::canStartAttack(Unit const* who, bool force) const { if(isCivilian()) return false; - if(!canFly() && (GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE + m_CombatDistance)) //|| who->IsControlledByPlayer() && who->IsFlying())) // we cannot check flying for other creatures, too much map/vmap calculation // TODO: should switch to range attack return false; - if(!force) { if(!_IsTargetAcceptable(who)) return false; - if(who->isInCombat()) if(Unit *victim = who->getAttackerForHelper()) if(IsWithinDistInMap(victim, sWorld.getConfig(CONFIG_CREATURE_FAMILY_ASSISTANCE_RADIUS))) force = true; - if(!force && (IsNeutralToAll() || !IsWithinDistInMap(who, GetAttackDistance(who) + m_CombatDistance))) return false; } - if(!canCreatureAttack(who, force)) return false; - return IsWithinLOSInMap(who); } - float Creature::GetAttackDistance(Unit const* pl) const { float aggroRate = sWorld.getRate(RATE_CREATURE_AGGRO); if(aggroRate==0) return 0.0f; - uint32 playerlevel = pl->getLevelForTarget(this); uint32 creaturelevel = getLevelForTarget(pl); - int32 leveldif = int32(playerlevel) - int32(creaturelevel); - // "The maximum Aggro Radius has a cap of 25 levels under. Example: A level 30 char has the same Aggro Radius of a level 5 char on a level 60 mob." if ( leveldif < - 25) leveldif = -25; - // "The aggro radius of a mob having the same level as the player is roughly 20 yards" float RetDistance = 20; - // "Aggro Radius varies with level difference at a rate of roughly 1 yard/level" // radius grow if playlevel < creaturelevel RetDistance -= (float)leveldif; - if(creaturelevel+5 <= sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)) { // detect range auras RetDistance += GetTotalAuraModifier(SPELL_AURA_MOD_DETECT_RANGE); - // detected range auras RetDistance += pl->GetTotalAuraModifier(SPELL_AURA_MOD_DETECTED_RANGE); } - // "Minimum Aggro Radius for a mob seems to be combat range (5 yards)" if(RetDistance < 5) RetDistance = 5; - return (RetDistance*aggroRate); } - void Creature::setDeathState(DeathState s) { if((s == JUST_DIED && !m_isDeadByDefault)||(s == JUST_ALIVED && m_isDeadByDefault)) { m_deathTimer = m_corpseDelay*IN_MILISECONDS; - // always save boss respawn time at death to prevent crash cheating if(sWorld.getConfig(CONFIG_SAVE_RESPAWN_TIME_IMMEDIATELY) || isWorldBoss()) SaveRespawnTime(); } Unit::setDeathState(s); - if(s == JUST_DIED) { SetUInt64Value(UNIT_FIELD_TARGET,0); // remove target selection in any cases (can be set at aura remove in Unit::setDeathState) SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE); - setActive(false); - if(!isPet() && GetCreatureInfo()->SkinLootId) if ( LootTemplates_Skinning.HaveLootFor(GetCreatureInfo()->SkinLootId) ) SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); - SetNoSearchAssistance(false); - //Dismiss group if is leader if(m_formation && m_formation->getLeader() == this) m_formation->FormationReset(true); - if ((canFly() || IsFlying()) && FallGround()) return; - Unit::setDeathState(CORPSE); } else if(s == JUST_ALIVED) @@ -1816,28 +1561,23 @@ void Creature::setDeathState(DeathState s) Unit::setDeathState(ALIVE); } } - bool Creature::FallGround() { // Let's abort after we called this function one time if (getDeathState() == DEAD_FALLING) return false; - float x, y, z; GetPosition(x, y, z); float ground_Z = GetMap()->GetVmapHeight(x, y, z, true); if (fabs(ground_Z - z) < 0.1f) return false; - GetMotionMaster()->MoveFall(ground_Z, EVENT_FALL_GROUND); Unit::setDeathState(DEAD_FALLING); return true; } - void Creature::Respawn(bool force) { DestroyForNearbyPlayers(); - if(force) { if(isAlive()) @@ -1845,25 +1585,19 @@ void Creature::Respawn(bool force) else if(getDeathState() != CORPSE) setDeathState(CORPSE); } - RemoveCorpse(); - if(getDeathState()==DEAD) { if (m_DBTableGuid) objmgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),0); - DEBUG_LOG("Respawning..."); m_respawnTime = 0; lootForPickPocketed = false; lootForBody = false; - if(m_originalEntry != GetEntry()) UpdateEntry(m_originalEntry); - CreatureInfo const *cinfo = GetCreatureInfo(); SelectLevel(cinfo); - if (m_isDeadByDefault) { setDeathState(JUST_DIED); @@ -1874,59 +1608,46 @@ void Creature::Respawn(bool force) } else setDeathState( JUST_ALIVED ); - CreatureModelInfo const *minfo = objmgr.GetCreatureModelRandomGender(GetNativeDisplayId()); if (minfo) // Cancel load if no model defined { uint32 display_id = minfo->modelid; // it can be different (for another gender) - SetDisplayId(display_id); SetNativeDisplayId(display_id); SetByteValue(UNIT_FIELD_BYTES_0, 2, minfo->gender); } - //Call AI respawn virtual function AI()->JustRespawned(); - uint16 poolid = poolhandler.IsPartOfAPool(GetGUIDLow(), GetTypeId()); if (poolid) poolhandler.UpdatePool(poolid, GetGUIDLow(), GetTypeId()); } - SetToNotify(); } - void Creature::ForcedDespawn() { setDeathState(JUST_DIED); RemoveCorpse(); SetHealth(0); // just for nice GM-mode view } - bool Creature::IsImmunedToSpell(SpellEntry const* spellInfo) { if (!spellInfo) return false; - if (GetCreatureInfo()->MechanicImmuneMask & (1 << (spellInfo->Mechanic - 1))) return true; - return Unit::IsImmunedToSpell(spellInfo); } - bool Creature::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const { if (GetCreatureInfo()->MechanicImmuneMask & (1 << (spellInfo->EffectMechanic[index] - 1))) return true; - return Unit::IsImmunedToSpellEffect(spellInfo, index); } - SpellEntry const *Creature::reachWithSpellAttack(Unit *pVictim) { if(!pVictim) return NULL; - for(uint32 i=0; i < CREATURE_MAX_SPELLS; ++i) { if(!m_spells[i]) @@ -1937,7 +1658,6 @@ SpellEntry const *Creature::reachWithSpellAttack(Unit *pVictim) sLog.outError("WORLD: unknown spell id %i", m_spells[i]); continue; } - bool bcontinue = true; for(uint32 j=0;j<3;j++) { @@ -1952,7 +1672,6 @@ SpellEntry const *Creature::reachWithSpellAttack(Unit *pVictim) } } if(bcontinue) continue; - if(spellInfo->manaCost > GetPower(POWER_MANA)) continue; SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(spellInfo->rangeIndex); @@ -1971,12 +1690,10 @@ SpellEntry const *Creature::reachWithSpellAttack(Unit *pVictim) } return NULL; } - SpellEntry const *Creature::reachWithSpellCure(Unit *pVictim) { if(!pVictim) return NULL; - for(uint32 i=0; i < CREATURE_MAX_SPELLS; ++i) { if(!m_spells[i]) @@ -1987,7 +1704,6 @@ SpellEntry const *Creature::reachWithSpellCure(Unit *pVictim) sLog.outError("WORLD: unknown spell id %i", m_spells[i]); continue; } - bool bcontinue = true; for(uint32 j=0;j<3;j++) { @@ -1998,7 +1714,6 @@ SpellEntry const *Creature::reachWithSpellCure(Unit *pVictim) } } if(bcontinue) continue; - if(spellInfo->manaCost > GetPower(POWER_MANA)) continue; SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(spellInfo->rangeIndex); @@ -2017,17 +1732,14 @@ SpellEntry const *Creature::reachWithSpellCure(Unit *pVictim) } return NULL; } - bool Creature::IsVisibleInGridForPlayer(Player const* pl) const { // gamemaster in GM mode see all, including ghosts if(pl->isGameMaster()) return true; - // Trigger shouldn't be visible for players if(isTrigger()) return false; - // Live player (or with not release body see live creatures or death creatures with corpse disappearing time > 0 if(pl->isAlive() || pl->GetDeathTimer() > 0) { @@ -2035,7 +1747,6 @@ bool Creature::IsVisibleInGridForPlayer(Player const* pl) const return false; return (isAlive() || m_deathTimer > 0 || (m_isDeadByDefault && m_deathState==CORPSE)); } - // Dead player see live creatures near own corpse if(isAlive()) { @@ -2047,66 +1758,50 @@ bool Creature::IsVisibleInGridForPlayer(Player const* pl) const return true; } } - // Dead player see Spirit Healer or Spirit Guide if(isSpiritService()) return true; - // and not see any other return false; } - Unit* Creature::SelectNearestTarget(float dist) const { CellPair p(Trinity::ComputeCellPair(GetPositionX(), GetPositionY())); Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); - Unit *target = NULL; - { Trinity::NearestHostileUnitInAttackDistanceCheck u_check(this, dist); Trinity::UnitLastSearcher searcher(this, target, u_check); - TypeContainerVisitor, WorldTypeMapContainer > world_unit_searcher(searcher); TypeContainerVisitor, GridTypeMapContainer > grid_unit_searcher(searcher); - CellLock cell_lock(cell, p); cell_lock->Visit(cell_lock, world_unit_searcher, *GetMap(), *this, ATTACK_DISTANCE); cell_lock->Visit(cell_lock, grid_unit_searcher, *GetMap(), *this, ATTACK_DISTANCE); } - return target; } - void Creature::CallAssistance() { if( !m_AlreadyCallAssistance && getVictim() && !isPet() && !isCharmed()) { SetNoCallAssistance(true); - float radius = sWorld.getConfig(CONFIG_CREATURE_FAMILY_ASSISTANCE_RADIUS); - if(radius > 0) { std::list assistList; - { CellPair p(Trinity::ComputeCellPair(GetPositionX(), GetPositionY())); Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); - MaNGOS::AnyAssistCreatureInRangeCheck u_check(this, getVictim(), radius); MaNGOS::CreatureListSearcher searcher(this, assistList, u_check); - TypeContainerVisitor, GridTypeMapContainer > grid_creature_searcher(searcher); - CellLock cell_lock(cell, p); cell_lock->Visit(cell_lock, grid_creature_searcher, *GetMap(), *this, radius); } - if (!assistList.empty()) { AssistDelayEvent *e = new AssistDelayEvent(getVictim()->GetGUID(), *this); @@ -2121,48 +1816,37 @@ void Creature::CallAssistance() } } } - void Creature::CallForHelp(float fRadius) { if (fRadius <= 0.0f || !getVictim() || isPet() || isCharmed()) return; - CellPair p(MaNGOS::ComputeCellPair(GetPositionX(), GetPositionY())); Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); - MaNGOS::CallOfHelpCreatureInRangeDo u_do(this, getVictim(), fRadius); MaNGOS::CreatureWorker worker(this, u_do); - TypeContainerVisitor, GridTypeMapContainer > grid_creature_searcher(worker); - CellLock cell_lock(cell, p); cell_lock->Visit(cell_lock, grid_creature_searcher, *GetMap(), *this, fRadius); } - bool Creature::CanAssistTo(const Unit* u, const Unit* enemy, bool checkfaction /*= true*/) const { // is it true? if(!HasReactState(REACT_AGGRESSIVE)) return false; - // we don't need help from zombies :) if (!isAlive()) return false; - // we don't need help from non-combatant ;) if (isCivilian()) return false; - // skip fighting creature if (isInCombat()) return false; - // only free creature if (GetCharmerOrOwnerGUID()) return false; - // only from same creature faction if (checkfaction) { @@ -2174,80 +1858,61 @@ bool Creature::CanAssistTo(const Unit* u, const Unit* enemy, bool checkfaction / if (!IsFriendlyTo(u)) return false; } - // skip non hostile to caster enemy creatures if (!IsHostileTo(enemy)) return false; - return true; } - // use this function to avoid having hostile creatures attack // friendlies and other mobs they shouldn't attack bool Creature::_IsTargetAcceptable(const Unit *target) const { const Unit *myVictim = getAttackerForHelper(); - // if I'm already fighting target, the target is acceptable if (myVictim == target || target->getVictim() == this) return true; - // if I'm hostile towards the target, the target is acceptable if (IsHostileTo(target)) return true; - const Unit *targetVictim = target->getAttackerForHelper(); - // if the target does not have a victim, the target is not acceptable if (!targetVictim) return false; - // if the target's victim is friendly, and the target is neutral, the target is acceptable if (IsFriendlyTo(targetVictim) && !IsFriendlyTo(target)) return true; - // if the target's victim is not friendly, or the target is friendly, the target is not acceptable return false; } - void Creature::SaveRespawnTime() { if(isSummon() || !m_DBTableGuid || m_creatureData && !m_creatureData->dbData) return; - if(m_respawnTime > time(NULL)) // dead (no corpse) objmgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),m_respawnTime); else if(m_deathTimer > 0) // dead (corpse) objmgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),time(NULL)+m_respawnDelay+m_deathTimer/IN_MILISECONDS); } - -// this should not be called by petAI or +// this should not be called by petAI or bool Creature::canCreatureAttack(Unit const *pVictim, bool force) const { if(!pVictim->IsInMap(this)) return false; - if(!canAttack(pVictim, force)) return false; - if(!pVictim->isInAccessiblePlaceFor(this)) return false; - if(IsAIEnabled && !AI()->CanAIAttack(pVictim)) return false; - if(sMapStore.LookupEntry(GetMapId())->IsDungeon()) return true; - //Use AttackDistance in distance check if threat radius is lower. This prevents creature bounce in and out of combat every update tick. float dist = std::max(GetAttackDistance(pVictim), (float)sWorld.getConfig(CONFIG_THREAT_RADIUS)) + m_CombatDistance; - if(Unit *unit = GetCharmerOrOwner()) return pVictim->IsWithinDist(unit, dist); else return pVictim->IsInDist(&m_homePosition, dist); } - CreatureDataAddon const* Creature::GetCreatureAddon() const { if (m_DBTableGuid) @@ -2255,42 +1920,35 @@ CreatureDataAddon const* Creature::GetCreatureAddon() const if(CreatureDataAddon const* addon = ObjectMgr::GetCreatureAddon(m_DBTableGuid)) return addon; } - // dependent from heroic mode entry return ObjectMgr::GetCreatureTemplateAddon(GetCreatureInfo()->Entry); } - //creature_addon table bool Creature::LoadCreaturesAddon(bool reload) { CreatureDataAddon const *cainfo = GetCreatureAddon(); if(!cainfo) return false; - if (cainfo->mount != 0) Mount(cainfo->mount); - if (cainfo->bytes1 != 0) { // 0 StandState // 1 FreeTalentPoints Pet only, so always 0 for default creature // 2 StandFlags // 3 StandMiscFlags - SetByteValue(UNIT_FIELD_BYTES_1, 0, uint8(cainfo->bytes1 & 0xFF)); //SetByteValue(UNIT_FIELD_BYTES_1, 1, uint8((cainfo->bytes1 >> 8) & 0xFF)); SetByteValue(UNIT_FIELD_BYTES_1, 1, 0); SetByteValue(UNIT_FIELD_BYTES_1, 2, uint8((cainfo->bytes1 >> 16) & 0xFF)); SetByteValue(UNIT_FIELD_BYTES_1, 3, uint8((cainfo->bytes1 >> 24) & 0xFF)); } - if (cainfo->bytes2 != 0) { // 0 SheathState // 1 Bytes2Flags // 2 UnitRename Pet only, so always 0 for default creature // 3 ShapeshiftForm Must be determined/set by shapeshift spell/aura - SetByteValue(UNIT_FIELD_BYTES_2, 0, uint8(cainfo->bytes2 & 0xFF)); SetByteValue(UNIT_FIELD_BYTES_2, 1, uint8((cainfo->bytes2 >> 8) & 0xFF)); //SetByteValue(UNIT_FIELD_BYTES_2, 2, uint8((cainfo->bytes2 >> 16) & 0xFF)); @@ -2298,20 +1956,15 @@ bool Creature::LoadCreaturesAddon(bool reload) //SetByteValue(UNIT_FIELD_BYTES_2, 3, uint8((cainfo->bytes2 >> 24) & 0xFF)); SetByteValue(UNIT_FIELD_BYTES_2, 3, 0); } - if (cainfo->emote != 0) SetUInt32Value(UNIT_NPC_EMOTESTATE, cainfo->emote); - if (cainfo->move_flags != 0) SetUnitMovementFlags(cainfo->move_flags); - if (cainfo->move_flags & (MOVEMENTFLAG_FLY_MODE | MOVEMENTFLAG_FLYING)) sLog.outErrorDb("Creature (GUID: %u Entry: %u) has improper `moveflags` value in `creature_template_addon`. Use `InhabitType` = 4 (Flying) in `creature_template`, not MOVEMENTFLAG_FLY_MODE or MOVEMENTFLAG_FLYING in `creature_template_addon`.",GetGUIDLow(),GetEntry()); - //Load Path if (cainfo->path_id != 0) m_path_id = cainfo->path_id; - if(cainfo->auras) { for (CreatureDataAddonAura const* cAura = cainfo->auras; cAura->spell_id; ++cAura) @@ -2322,33 +1975,27 @@ bool Creature::LoadCreaturesAddon(bool reload) sLog.outErrorDb("Creature (GUID: %u Entry: %u) has wrong spell %u defined in `auras` field.",GetGUIDLow(),GetEntry(),cAura->spell_id); continue; } - // skip already applied aura if(HasAuraEffect(cAura->spell_id,cAura->effect_idx)) { if(!reload) sLog.outErrorDb("Creature (GUID: %u Entry: %u) has duplicate aura (spell %u effect %u) in `auras` field.",GetGUIDLow(),GetEntry(),cAura->spell_id,cAura->effect_idx); - continue; } - AddAuraEffect(AdditionalSpellInfo, cAura->effect_idx, this, this); sLog.outDebug("Spell: %u with Aura %u added to creature (GUID: %u Entry: %u)", cAura->spell_id, AdditionalSpellInfo->EffectApplyAuraName[cAura->effect_idx],GetGUIDLow(),GetEntry()); } } return true; } - /// Send a message to LocalDefense channel for players opposition team in the zone void Creature::SendZoneUnderAttackMessage(Player* attacker) { uint32 enemy_team = attacker->GetTeam(); - WorldPacket data(SMSG_ZONE_UNDER_ATTACK,4); data << (uint32)GetAreaId(); sWorld.SendGlobalMessage(&data,NULL,(enemy_team==ALLIANCE ? HORDE : ALLIANCE)); } - void Creature::SetInCombatWithZone() { if (!CanHaveThreatList()) @@ -2356,27 +2003,21 @@ void Creature::SetInCombatWithZone() sLog.outError("Creature entry %u call SetInCombatWithZone but creature cannot have threat list.", GetEntry()); return; } - Map* pMap = GetMap(); - if (!pMap->IsDungeon()) { sLog.outError("Creature entry %u call SetInCombatWithZone for map (id: %u) that isn't an instance.", GetEntry(), pMap->GetId()); return; } - Map::PlayerList const &PlList = pMap->GetPlayers(); - if (PlList.isEmpty()) return; - for(Map::PlayerList::const_iterator i = PlList.begin(); i != PlList.end(); ++i) { if (Player* pPlayer = i->getSource()) { if (pPlayer->isGameMaster()) continue; - if (pPlayer->isAlive()) { pPlayer->SetInCombatWith(this); @@ -2385,56 +2026,44 @@ void Creature::SetInCombatWithZone() } } } - void Creature::_AddCreatureSpellCooldown(uint32 spell_id, time_t end_time) { m_CreatureSpellCooldowns[spell_id] = end_time; } - void Creature::_AddCreatureCategoryCooldown(uint32 category, time_t apply_time) { m_CreatureCategoryCooldowns[category] = apply_time; } - void Creature::AddCreatureSpellCooldown(uint32 spellid) { SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellid); if(!spellInfo) return; - uint32 cooldown = GetSpellRecoveryTime(spellInfo); if(Player *modOwner = GetSpellModOwner()) modOwner->ApplySpellMod(spellid, SPELLMOD_COOLDOWN, cooldown); - if(cooldown) _AddCreatureSpellCooldown(spellid, time(NULL) + cooldown/IN_MILISECONDS); - if(spellInfo->Category) _AddCreatureCategoryCooldown(spellInfo->Category, time(NULL)); - m_GlobalCooldown = spellInfo->StartRecoveryTime; } - bool Creature::HasCategoryCooldown(uint32 spell_id) const { SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id); if(!spellInfo) return false; - // check global cooldown if spell affected by it if (spellInfo->StartRecoveryCategory > 0 && m_GlobalCooldown > 0) return true; - CreatureSpellCooldowns::const_iterator itr = m_CreatureCategoryCooldowns.find(spellInfo->Category); return(itr != m_CreatureCategoryCooldowns.end() && time_t(itr->second + (spellInfo->CategoryRecoveryTime / IN_MILISECONDS)) > time(NULL)); } - bool Creature::HasSpellCooldown(uint32 spell_id) const { CreatureSpellCooldowns::const_iterator itr = m_CreatureSpellCooldowns.find(spell_id); return (itr != m_CreatureSpellCooldowns.end() && itr->second > time(NULL)) || HasCategoryCooldown(spell_id); } - bool Creature::HasSpell(uint32 spellID) const { uint8 i; @@ -2443,7 +2072,6 @@ bool Creature::HasSpell(uint32 spellID) const break; return i < CREATURE_MAX_SPELLS; //broke before end of iteration of known spells } - time_t Creature::GetRespawnTimeEx() const { time_t now = time(NULL); @@ -2454,7 +2082,6 @@ time_t Creature::GetRespawnTimeEx() const else return now; } - void Creature::GetRespawnCoord( float &x, float &y, float &z, float* ori, float* dist ) const { if (m_DBTableGuid) @@ -2468,11 +2095,9 @@ void Creature::GetRespawnCoord( float &x, float &y, float &z, float* ori, float* *ori = data->orientation; if(dist) *dist = data->spawndist; - return; } } - x = GetPositionX(); y = GetPositionY(); z = GetPositionZ(); @@ -2481,33 +2106,27 @@ void Creature::GetRespawnCoord( float &x, float &y, float &z, float* ori, float* if(dist) *dist = 0; } - void Creature::AllLootRemovedFromCorpse() { if (!HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE)) { uint32 nDeathTimer; - CreatureInfo const *cinfo = GetCreatureInfo(); - // corpse was not skinnable -> apply corpse looted timer if (!cinfo || !cinfo->SkinLootId) nDeathTimer = (uint32)((m_corpseDelay * IN_MILISECONDS) * sWorld.getRate(RATE_CORPSE_DECAY_LOOTED)); // corpse skinnable, but without skinning flag, and then skinned, corpse will despawn next update else nDeathTimer = 0; - // update death timer only if looted timer is shorter if (m_deathTimer > nDeathTimer) m_deathTimer = nDeathTimer; } } - uint32 Creature::getLevelForTarget( Unit const* target ) const { if(!isWorldBoss()) return Unit::getLevelForTarget(target); - uint32 level = target->getLevel()+sWorld.getConfig(CONFIG_WORLD_BOSS_LEVEL_DIFF); if(level < 1) return 1; @@ -2515,104 +2134,81 @@ uint32 Creature::getLevelForTarget( Unit const* target ) const return 255; return level; } - std::string Creature::GetAIName() const { return ObjectMgr::GetCreatureTemplate(GetEntry())->AIName; } - std::string Creature::GetScriptName() const { return objmgr.GetScriptName(GetScriptId()); } - uint32 Creature::GetScriptId() const { return ObjectMgr::GetCreatureTemplate(GetEntry())->ScriptID; } - VendorItemData const* Creature::GetVendorItems() const { return objmgr.GetNpcVendorItemList(GetEntry()); } - uint32 Creature::GetVendorItemCurrentCount(VendorItem const* vItem) { if(!vItem->maxcount) return vItem->maxcount; - VendorItemCounts::iterator itr = m_vendorItemCounts.begin(); for(; itr != m_vendorItemCounts.end(); ++itr) if(itr->itemId==vItem->item) break; - if(itr == m_vendorItemCounts.end()) return vItem->maxcount; - VendorItemCount* vCount = &*itr; - time_t ptime = time(NULL); - if( vCount->lastIncrementTime + vItem->incrtime <= ptime ) { ItemPrototype const* pProto = objmgr.GetItemPrototype(vItem->item); - uint32 diff = uint32((ptime - vCount->lastIncrementTime)/vItem->incrtime); if((vCount->count + diff * pProto->BuyCount) >= vItem->maxcount ) { m_vendorItemCounts.erase(itr); return vItem->maxcount; } - vCount->count += diff * pProto->BuyCount; vCount->lastIncrementTime = ptime; } - return vCount->count; } - uint32 Creature::UpdateVendorItemCurrentCount(VendorItem const* vItem, uint32 used_count) { if(!vItem->maxcount) return 0; - VendorItemCounts::iterator itr = m_vendorItemCounts.begin(); for(; itr != m_vendorItemCounts.end(); ++itr) if(itr->itemId==vItem->item) break; - if(itr == m_vendorItemCounts.end()) { uint32 new_count = vItem->maxcount > used_count ? vItem->maxcount-used_count : 0; m_vendorItemCounts.push_back(VendorItemCount(vItem->item,new_count)); return new_count; } - VendorItemCount* vCount = &*itr; - time_t ptime = time(NULL); - if( vCount->lastIncrementTime + vItem->incrtime <= ptime ) { ItemPrototype const* pProto = objmgr.GetItemPrototype(vItem->item); - uint32 diff = uint32((ptime - vCount->lastIncrementTime)/vItem->incrtime); if((vCount->count + diff * pProto->BuyCount) < vItem->maxcount ) vCount->count += diff * pProto->BuyCount; else vCount->count = vItem->maxcount; } - vCount->count = vCount->count > used_count ? vCount->count-used_count : 0; vCount->lastIncrementTime = ptime; return vCount->count; } - TrainerSpellData const* Creature::GetTrainerSpells() const { return objmgr.GetNpcTrainerSpells(GetEntry()); } - // overwrite WorldObject function for proper name localization const char* Creature::GetNameForLocaleIdx(int32 loc_idx) const { @@ -2625,27 +2221,21 @@ const char* Creature::GetNameForLocaleIdx(int32 loc_idx) const return cl->Name[loc_idx].c_str(); } } - return GetName(); } - const CreatureData* Creature::GetLinkedRespawnCreatureData() const { if(!m_DBTableGuid) // only hard-spawned creatures from DB can have a linked master return NULL; - if(uint32 targetGuid = objmgr.GetLinkedRespawnGuid(m_DBTableGuid)) return objmgr.GetCreatureData(targetGuid); - return NULL; } - // returns master's remaining respawn time if any time_t Creature::GetLinkedCreatureRespawnTime() const { if(!m_DBTableGuid) // only hard-spawned creatures from DB can have a linked master return 0; - if(uint32 targetGuid = objmgr.GetLinkedRespawnGuid(m_DBTableGuid)) { Map* targetMap = NULL; @@ -2659,7 +2249,6 @@ time_t Creature::GetLinkedCreatureRespawnTime() const if(targetMap) return objmgr.GetCreatureRespawnTime(targetGuid,targetMap->GetInstanceId()); } - return 0; } diff --git a/src/game/Creature.h b/src/game/Creature.h index 5fbe4a07a28..f66d485d183 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -17,10 +17,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef TRINITYCORE_CREATURE_H #define TRINITYCORE_CREATURE_H - #include "Common.h" #include "Unit.h" #include "UpdateMask.h" @@ -28,17 +26,13 @@ #include "LootMgr.h" #include "Database/DatabaseEnv.h" #include "Cell.h" - #include - struct SpellEntry; - class CreatureAI; class Quest; class Player; class WorldSession; class CreatureGroup; - enum Gossip_Option { GOSSIP_OPTION_NONE = 0, //UNIT_NPC_FLAG_NONE = 0, @@ -62,7 +56,6 @@ enum Gossip_Option GOSSIP_OPTION_LEARNDUALSPEC = 18, //UNIT_NPC_FLAG_TRAINER (bonus option for GOSSIP_OPTION_TRAINER) GOSSIP_OPTION_OUTDOORPVP = 19 //added by code (option for outdoor pvp creatures) }; - enum Gossip_Guard { GOSSIP_GUARD_BANK = 32, @@ -77,7 +70,6 @@ enum Gossip_Guard GOSSIP_GUARD_SPELLTRAINER = 41, GOSSIP_GUARD_SKILLTRAINER = 42 }; - enum Gossip_Guard_Spell { GOSSIP_GUARD_SPELL_WARRIOR = 64, @@ -92,7 +84,6 @@ enum Gossip_Guard_Spell GOSSIP_GUARD_SPELL_UNKNOWN2 = 73, GOSSIP_GUARD_SPELL_DRUID = 74 }; - enum Gossip_Guard_Skill { GOSSIP_GUARD_SKILL_ALCHEMY = 80, @@ -108,7 +99,6 @@ enum Gossip_Guard_Skill GOSSIP_GUARD_SKILL_TAILORING = 90, GOSSIP_GUARD_SKILL_ENGINERING = 91 }; - enum GossipOptionIcon { GOSSIP_ICON_CHAT = 0, //white chat bubble @@ -123,7 +113,6 @@ enum GossipOptionIcon GOSSIP_ICON_BATTLE = 9, //two swords GOSSIP_ICON_DOT = 10 //yellow dot }; - struct GossipOption { uint32 Id; @@ -136,7 +125,6 @@ struct GossipOption std::string OptionText; std::string BoxText; }; - enum CreatureFlagsExtra { CREATURE_FLAG_EXTRA_INSTANCE_BIND = 0x00000001, // creature kill bind instance with killer and killer's group @@ -153,16 +141,13 @@ enum CreatureFlagsExtra CREATURE_FLAG_EXTRA_NO_CRIT = 0x00020000, // creature can't do critical strikes CREATURE_FLAG_EXTRA_NO_SKILLGAIN = 0x00040000, // creature won't increase weapon skills }; - // GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform #if defined( __GNUC__ ) #pragma pack(1) #else #pragma pack(push,1) #endif - #define MAX_KILL_CREDIT 2 - // from `creature_template` table struct CreatureInfo { @@ -238,7 +223,6 @@ struct CreatureInfo uint32 ScriptID; uint32 GetRandomValidModelId() const; uint32 GetFirstValidModelId() const; - // helpers SkillType GetRequiredLootSkill() const { @@ -251,40 +235,33 @@ struct CreatureInfo else return SKILL_SKINNING; // normal case } - bool isTameable(bool exotic) const { if(type != CREATURE_TYPE_BEAST || family == 0 || (type_flags & CREATURE_TYPEFLAGS_TAMEABLE)==0) return false; - // if can tame exotic then can tame any temable return exotic || (type_flags & CREATURE_TYPEFLAGS_EXOTIC)==0; } }; - struct CreatureLocale { std::vector Name; std::vector SubName; }; - struct NpcOptionLocale { std::vector OptionText; std::vector BoxText; }; - struct PointOfInterestLocale { std::vector IconName; }; - struct EquipmentInfo { uint32 entry; uint32 equipentry[3]; }; - // from `creature` table struct CreatureData { @@ -308,13 +285,11 @@ struct CreatureData uint8 spawnMask; bool dbData; }; - struct CreatureDataAddonAura { uint32 spell_id; uint8 effect_idx; }; - // from `creature_addon` table struct CreatureDataAddon { @@ -327,7 +302,6 @@ struct CreatureDataAddon uint32 move_flags; CreatureDataAddonAura const* auras; // loaded as char* "spell1 eff1 spell2 eff2 ... " }; - struct CreatureModelInfo { uint32 modelid; @@ -336,7 +310,6 @@ struct CreatureModelInfo uint8 gender; uint32 modelid_other_gender; }; - enum InhabitTypeValues { INHABIT_GROUND = 1, @@ -344,7 +317,6 @@ enum InhabitTypeValues INHABIT_AIR = 4, INHABIT_ANYWHERE = INHABIT_GROUND | INHABIT_WATER | INHABIT_AIR }; - // Enums used by StringTextData::Type (CreatureEventAI) enum ChatType { @@ -356,7 +328,6 @@ enum ChatType CHAT_TYPE_BOSS_WHISPER = 5, CHAT_TYPE_ZONE_YELL = 6 }; - //Selection method used by SelectTarget (CreatureEventAI) enum AttackingTarget { @@ -369,31 +340,26 @@ enum AttackingTarget ATTACKING_TARGET_BOTTOMAGGRO_PLAYER, //Selects targets from bottom aggro to top (player only) */ }; - // GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform #if defined( __GNUC__ ) #pragma pack() #else #pragma pack(pop) #endif - // Vendors struct VendorItem { VendorItem(uint32 _item, uint32 _maxcount, uint32 _incrtime, uint32 _ExtendedCost) : item(_item), maxcount(_maxcount), incrtime(_incrtime), ExtendedCost(_ExtendedCost) {} - uint32 item; uint32 maxcount; // 0 for infinity item amount uint32 incrtime; // time for restore items amount if maxcount != 0 uint32 ExtendedCost; }; typedef std::vector VendorItemList; - struct VendorItemData { VendorItemList m_items; - VendorItem* GetItem(uint32 slot) const { if(slot>=m_items.size()) return NULL; @@ -408,7 +374,6 @@ struct VendorItemData bool RemoveItem( uint32 item_id ); VendorItem const* FindItem(uint32 item_id) const; size_t FindItemSlot(uint32 item_id) const; - void Clear() { for (VendorItemList::const_iterator itr = m_items.begin(); itr != m_items.end(); ++itr) @@ -416,84 +381,62 @@ struct VendorItemData m_items.clear(); } }; - struct VendorItemCount { explicit VendorItemCount(uint32 _item, uint32 _count) : itemId(_item), count(_count), lastIncrementTime(time(NULL)) {} - uint32 itemId; uint32 count; time_t lastIncrementTime; }; - typedef std::list VendorItemCounts; - struct TrainerSpell { TrainerSpell() : spell(0), spellCost(0), reqSkill(0), reqSkillValue(0), reqLevel(0), learnedSpell(0) {} - TrainerSpell(uint32 _spell, uint32 _spellCost, uint32 _reqSkill, uint32 _reqSkillValue, uint32 _reqLevel, uint32 _learnedspell) : spell(_spell), spellCost(_spellCost), reqSkill(_reqSkill), reqSkillValue(_reqSkillValue), reqLevel(_reqLevel), learnedSpell(_learnedspell) {} - uint32 spell; uint32 spellCost; uint32 reqSkill; uint32 reqSkillValue; uint32 reqLevel; uint32 learnedSpell; - // helpers bool IsCastable() const { return learnedSpell != spell; } }; - typedef UNORDERED_MAP TrainerSpellMap; - struct TrainerSpellData { TrainerSpellData() : trainerType(0) {} - TrainerSpellMap spellList; uint32 trainerType; // trainer type based at trainer spells, can be different from creature_template value. // req. for correct show non-prof. trainers like weaponmaster, allowed values 0 and 2. TrainerSpell const* Find(uint32 spell_id) const; void Clear() { spellList.clear(); } }; - typedef std::list GossipOptionList; - typedef std::map CreatureSpellCooldowns; - // max different by z coordinate for creature aggro reaction #define CREATURE_Z_ATTACK_RANGE 3 - #define MAX_VENDOR_ITEMS 150 // Limitation in 3.x.x item count in SMSG_LIST_INVENTORY - class TRINITY_DLL_SPEC Creature : public Unit { public: - explicit Creature(); virtual ~Creature(); - void AddToWorld(); void RemoveFromWorld(); - void DisappearAndDie(); - bool Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 vehId, uint32 team, float x, float y, float z, float ang, const CreatureData *data = NULL); bool LoadCreaturesAddon(bool reload = false); void SelectLevel(const CreatureInfo *cinfo); void LoadEquipment(uint32 equip_entry, bool force=false); - uint32 GetDBTableGUIDLow() const { return m_DBTableGuid; } char const* GetSubName() const { return GetCreatureInfo()->SubName; } - void Update( uint32 time ); // overwrited Unit::Update void GetRespawnCoord(float &x, float &y, float &z, float* ori = NULL, float* dist =NULL) const; uint32 GetEquipmentId() const { return GetCreatureInfo()->equipmentId; } - void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; } bool isRacialLeader() const { return GetCreatureInfo()->RacialLeader; } bool isCivilian() const { return GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_CIVILIAN; } @@ -517,45 +460,33 @@ class TRINITY_DLL_SPEC Creature : public Unit { if(isPet()) return false; - uint32 rank = GetCreatureInfo()->rank; return rank != CREATURE_ELITE_NORMAL && rank != CREATURE_ELITE_RARE; } - bool isWorldBoss() const { if(isPet()) return false; - return GetCreatureInfo()->rank == CREATURE_ELITE_WORLDBOSS; } - uint32 getLevelForTarget(Unit const* target) const; // overwrite Unit::getLevelForTarget for boss level support - bool IsInEvadeMode() const { return hasUnitState(UNIT_STAT_EVADE); } - bool AIM_Initialize(CreatureAI* ai = NULL); void Motion_Initialize(); - void AI_SendMoveToPacket(float x, float y, float z, uint32 time, uint32 MovementFlags, uint8 type); CreatureAI * AI() const { return (CreatureAI*)i_AI; } - uint32 GetShieldBlockValue() const //dunno mob block value { return (getLevel()/2 + uint32(GetStat(STAT_STRENGTH)/20)); } - SpellSchoolMask GetMeleeDamageSchoolMask() const { return m_meleeDamageSchoolMask; } void SetMeleeDamageSchool(SpellSchools school) { m_meleeDamageSchoolMask = SpellSchoolMask(1 << school); } - void _AddCreatureSpellCooldown(uint32 spell_id, time_t end_time); void _AddCreatureCategoryCooldown(uint32 category, time_t apply_time); void AddCreatureSpellCooldown(uint32 spellid); bool HasSpellCooldown(uint32 spell_id) const; bool HasCategoryCooldown(uint32 spell_id) const; - bool HasSpell(uint32 spellID) const; - bool UpdateEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData* data=NULL); bool UpdateStats(Stats stat); bool UpdateAllStats(); @@ -567,72 +498,56 @@ class TRINITY_DLL_SPEC Creature : public Unit void UpdateDamagePhysical(WeaponAttackType attType); uint32 GetCurrentEquipmentId() { return m_equipmentId; } float GetSpellDamageMod(int32 Rank); - VendorItemData const* GetVendorItems() const; uint32 GetVendorItemCurrentCount(VendorItem const* vItem); uint32 UpdateVendorItemCurrentCount(VendorItem const* vItem, uint32 used_count); - TrainerSpellData const* GetTrainerSpells() const; - CreatureInfo const *GetCreatureInfo() const { return m_creatureInfo; } CreatureData const *GetCreatureData() const { return m_creatureData; } CreatureDataAddon const* GetCreatureAddon() const; - std::string GetAIName() const; std::string GetScriptName() const; uint32 GetScriptId() const; - void prepareGossipMenu( Player *pPlayer, uint32 gossipid = 0 ); void sendPreparedGossip( Player* player ); void OnGossipSelect(Player* player, uint32 option); void OnPoiSelect(Player* player, GossipOption const *gossip); - uint32 GetGossipTextId(uint32 action, uint32 zoneid); uint32 GetNpcTextId(); void LoadGossipOptions(); void ResetGossipOptions(); GossipOption const* GetGossipOption( uint32 id ) const; void addGossipOption(GossipOption const& gso) { m_goptions.push_back(gso); } - void Say(int32 textId, uint32 language, uint64 TargetGuid) { MonsterSay(textId,language,TargetGuid); } void Yell(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYell(textId,language,TargetGuid); } void TextEmote(int32 textId, uint64 TargetGuid, bool IsBossEmote = false) { MonsterTextEmote(textId,TargetGuid,IsBossEmote); } void Whisper(int32 textId, uint64 receiver, bool IsBossWhisper = false) { MonsterWhisper(textId,receiver,IsBossWhisper); } void YellToZone(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYellToZone(textId,language,TargetGuid); } - // overwrite WorldObject function for proper name localization const char* GetNameForLocaleIdx(int32 locale_idx) const; - void setDeathState(DeathState s); // overwrite virtual Unit::setDeathState bool FallGround(); - bool LoadFromDB(uint32 guid, Map *map); void SaveToDB(); // overwrited in Pet virtual void SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask); virtual void DeleteFromDB(); // overwrited in Pet - Loot loot; bool lootForPickPocketed; bool lootForBody; Player *GetLootRecipient() const; bool hasLootRecipient() const { return m_lootRecipient!=0; } - void SetLootRecipient (Unit* unit); void AllLootRemovedFromCorpse(); - SpellEntry const *reachWithSpellAttack(Unit *pVictim); SpellEntry const *reachWithSpellCure(Unit *pVictim); - uint32 m_spells[CREATURE_MAX_SPELLS]; CreatureSpellCooldowns m_CreatureSpellCooldowns; CreatureSpellCooldowns m_CreatureCategoryCooldowns; uint32 m_GlobalCooldown; - bool canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList = false, bool is3dDistance = true) const; bool canStartAttack(Unit const* u, bool force) const; float GetAttackDistance(Unit const* pl) const; - Unit* SelectNearestTarget(float dist = 0) const; void DoFleeToGetAssistance(); void CallForHelp(float fRadius); @@ -642,47 +557,33 @@ class TRINITY_DLL_SPEC Creature : public Unit bool HasSearchedAssistance() { return m_AlreadySearchedAssistance; } bool CanAssistTo(const Unit* u, const Unit* enemy, bool checkfaction = true) const; bool _IsTargetAcceptable(const Unit* target) const; - MovementGeneratorType GetDefaultMovementType() const { return m_defaultMovementType; } void SetDefaultMovementType(MovementGeneratorType mgt) { m_defaultMovementType = mgt; } - // for use only in LoadHelper, Map::Add Map::CreatureCellRelocation Cell const& GetCurrentCell() const { return m_currentCell; } void SetCurrentCell(Cell const& cell) { m_currentCell = cell; } - bool IsVisibleInGridForPlayer(Player const* pl) const; - void RemoveCorpse(); bool isDeadByDefault() const { return m_isDeadByDefault; }; - void ForcedDespawn(); - time_t const& GetRespawnTime() const { return m_respawnTime; } time_t GetRespawnTimeEx() const; void SetRespawnTime(uint32 respawn) { m_respawnTime = respawn ? time(NULL) + respawn : 0; } void Respawn(bool force = false); void SaveRespawnTime(); - uint32 GetRespawnDelay() const { return m_respawnDelay; } void SetRespawnDelay(uint32 delay) { m_respawnDelay = delay; } - float GetRespawnRadius() const { return m_respawnradius; } void SetRespawnRadius(float dist) { m_respawnradius = dist; } - // Linked Creature Respawning System time_t GetLinkedCreatureRespawnTime() const; const CreatureData* GetLinkedRespawnCreatureData() const; - uint32 m_groupLootTimer; // (msecs)timer used for group loot uint64 lootingGroupLeaderGUID; // used to find group which is looting corpse - void SendZoneUnderAttackMessage(Player* attacker); - void SetInCombatWithZone(); - bool hasQuest(uint32 quest_id) const; bool hasInvolvedQuest(uint32 quest_id) const; - GridReference &GetGridRef() { return m_gridRef; } bool isRegeneratingHealth() { return m_regenHealth; } virtual uint8 GetPetAutoSpellSize() const { return CREATURE_MAX_SPELLS; } @@ -693,26 +594,19 @@ class TRINITY_DLL_SPEC Creature : public Unit else return m_charmInfo->GetCharmSpell(pos)->GetAction(); } - void SetHomePosition(float x, float y, float z, float o) { m_homePosition.Relocate(x, y, z, o); } void SetHomePosition(const Position &pos) { m_homePosition.Relocate(pos);} void GetHomePosition(float &x, float &y, float &z, float &ori) { m_homePosition.GetPosition(x, y, z, ori); } - uint32 GetGlobalCooldown() const { return m_GlobalCooldown; } - uint32 GetWaypointPath(){return m_path_id;} void LoadPath(uint32 pathid) { m_path_id = pathid; } - uint32 GetCurrentWaypointID(){return m_waypointID;} void UpdateWaypointID(uint32 wpID){m_waypointID = wpID;} - void SearchFormation(); CreatureGroup *GetFormation() {return m_formation;} void SetFormation(CreatureGroup *formation) {m_formation = formation;} - Unit *SelectVictim(); void SetDeadByDefault (bool death_state) {m_isDeadByDefault = death_state;} - void SetDisableReputationGain(bool disable) { DisableReputationGain = disable; } bool IsReputationGainDisabled() { return DisableReputationGain; } bool IsDamageEnoughForLootingAndReward() { return m_PlayerDamageReq == 0; } @@ -723,36 +617,26 @@ class TRINITY_DLL_SPEC Creature : public Unit } void ResetPlayerDamageReq() { m_PlayerDamageReq = GetHealth() / 2; } uint32 m_PlayerDamageReq; - void SetOriginalEntry(uint32 entry) { m_originalEntry = entry; } - static float _GetDamageMod(int32 Rank); - float m_SightDistance, m_CombatDistance; protected: bool CreateFromProto(uint32 guidlow, uint32 Entry, uint32 vehId, uint32 team, const CreatureData *data = NULL); bool InitEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData* data=NULL); - // vendor items VendorItemCounts m_vendorItemCounts; - void _RealtimeSetCreatureInfo(); - static float _GetHealthMod(int32 Rank); - uint32 m_lootMoney; uint64 m_lootRecipient; - /// Timers uint32 m_deathTimer; // (msecs)timer for death or corpse disappearance time_t m_respawnTime; // (secs) time of next respawn uint32 m_respawnDelay; // (secs) delay between corpse disappearance and respawning uint32 m_corpseDelay; // (secs) delay between death and corpse disappearance float m_respawnradius; - bool m_gossipOptionLoaded; GossipOptionList m_goptions; - ReactStates m_reactState; // for AI, not charmInfo void RegenerateMana(); void RegenerateHealth(); @@ -761,48 +645,36 @@ class TRINITY_DLL_SPEC Creature : public Unit Cell m_currentCell; // store current cell where creature listed uint32 m_DBTableGuid; ///< For new or temporary creatures is 0 for saved it is lowguid uint32 m_equipmentId; - bool m_AlreadyCallAssistance; bool m_AlreadySearchedAssistance; bool m_regenHealth; bool m_AI_locked; bool m_isDeadByDefault; - SpellSchoolMask m_meleeDamageSchoolMask; uint32 m_originalEntry; - Position m_homePosition; - bool DisableReputationGain; - CreatureInfo const* m_creatureInfo; // in heroic mode can different from ObjMgr::GetCreatureTemplate(GetEntry()) CreatureData const* m_creatureData; - private: //WaypointMovementGenerator vars uint32 m_waypointID; uint32 m_path_id; - //Formation var CreatureGroup *m_formation; - GridReference m_gridRef; }; - class AssistDelayEvent : public BasicEvent { public: AssistDelayEvent(const uint64& victim, Unit& owner) : BasicEvent(), m_victim(victim), m_owner(owner) { } - bool Execute(uint64 e_time, uint32 p_time); void AddAssistant(const uint64& guid) { m_assistants.push_back(guid); } private: AssistDelayEvent(); - uint64 m_victim; std::list m_assistants; Unit& m_owner; }; - #endif diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp index 27fe428efd1..6727575e920 100644 --- a/src/game/CreatureAI.cpp +++ b/src/game/CreatureAI.cpp @@ -17,14 +17,12 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "CreatureAI.h" #include "CreatureAIImpl.h" #include "Creature.h" #include "World.h" #include "SpellMgr.h" #include "Vehicle.h" - //Disable CreatureAI when charmed void CreatureAI::OnCharmed(bool apply) { @@ -32,25 +30,20 @@ void CreatureAI::OnCharmed(bool apply) me->NeedChangeAI = true; me->IsAIEnabled = false; } - AISpellInfoType * UnitAI::AISpellInfo; TRINITY_DLL_SPEC AISpellInfoType * GetAISpellInfo(uint32 i) { return &CreatureAI::AISpellInfo[i]; } - void CreatureAI::DoZoneInCombat(Creature* creature) { if (!creature) creature = me; - if(!creature->CanHaveThreatList()) return; - Map *map = creature->GetMap(); if (!map->IsDungeon()) //use IsDungeon instead of Instanceable, in case battlegrounds will be instantiated { sLog.outError("DoZoneInCombat call for map that isn't an instance (creature entry = %d)", creature->GetTypeId() == TYPEID_UNIT ? ((Creature*)creature)->GetEntry() : 0); return; } - if(!creature->HasReactState(REACT_PASSIVE) && !creature->getVictim()) { if(Unit *target = creature->SelectNearestTarget(50)) @@ -67,32 +60,26 @@ void CreatureAI::DoZoneInCombat(Creature* creature) } } } - if(!creature->HasReactState(REACT_PASSIVE) && !creature->getVictim()) { sLog.outError("DoZoneInCombat called for creature that has empty threat list (creature entry = %u)", creature->GetEntry()); return; } - Map::PlayerList const &PlList = map->GetPlayers(); - if(PlList.isEmpty()) return; - for(Map::PlayerList::const_iterator i = PlList.begin(); i != PlList.end(); ++i) { if(Player* pPlayer = i->getSource()) { if(pPlayer->isGameMaster()) continue; - if(pPlayer->isAlive()) { creature->SetInCombatWith(pPlayer); pPlayer->SetInCombatWith(creature); creature->AddThreat(pPlayer, 0.0f); } - /* Causes certain things to never leave the threat list (Priest Lightwell, etc): for(Unit::ControlList::const_iterator itr = pPlayer->m_Controlled.begin(); itr != pPlayer->m_Controlled.end(); ++itr) { @@ -103,15 +90,12 @@ void CreatureAI::DoZoneInCombat(Creature* creature) } } } - void CreatureAI::MoveInLineOfSight(Unit *who) { if(me->getVictim()) return; - if (me->GetTypeId() == CREATURE_TYPE_NON_COMBAT_PET) // non-combat pets should just stand there and look good;) return; - if(me->canStartAttack(who, false)) AttackStart(who); //else if(who->getVictim() && me->IsFriendlyTo(who) @@ -119,7 +103,6 @@ void CreatureAI::MoveInLineOfSight(Unit *who) // && me->canStartAttack(who->getVictim(), true)) // TODO: if we use true, it will not attack it when it arrives // me->GetMotionMaster()->MoveChase(who->getVictim()); } - void CreatureAI::SelectNearestTarget(Unit *who) { if(me->getVictim() && me->GetDistanceOrder(who, me->getVictim()) && me->canAttack(who)) @@ -128,14 +111,11 @@ void CreatureAI::SelectNearestTarget(Unit *who) me->AddThreat(who, 1000000.0f); } } - void CreatureAI::EnterEvadeMode() { if(!_EnterEvadeMode()) return; - sLog.outDebug("Creature %u enters evade mode.", me->GetEntry()); - if(!me->GetVehicle()) // otherwise me will be in evade mode forever { if(Unit *owner = me->GetCharmerOrOwner()) @@ -146,13 +126,10 @@ void CreatureAI::EnterEvadeMode() else me->GetMotionMaster()->MoveTargetedHome(); } - Reset(); - if(me->IsVehicle()) // use the same sequence of addtoworld, aireset may remove all summons! me->GetVehicleKit()->Reset(); } - /*void CreatureAI::AttackedBy( Unit* attacker ) { if(!m_creature->getVictim()) diff --git a/src/game/CreatureAI.h b/src/game/CreatureAI.h index 556e9be14e0..98a145b79e0 100644 --- a/src/game/CreatureAI.h +++ b/src/game/CreatureAI.h @@ -17,38 +17,29 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef TRINITY_CREATUREAI_H #define TRINITY_CREATUREAI_H - #include "UnitAI.h" #include "Common.h" - class WorldObject; class Unit; class Creature; class Player; struct SpellEntry; - #define TIME_INTERVAL_LOOK 5000 #define VISIBILITY_RANGE 10000 - //Spell targets used by SelectSpell enum SelectTargetType { SELECT_TARGET_DONTCARE = 0, //All target types allowed - SELECT_TARGET_SELF, //Only Self casting - SELECT_TARGET_SINGLE_ENEMY, //Only Single Enemy SELECT_TARGET_AOE_ENEMY, //Only AoE Enemy SELECT_TARGET_ANY_ENEMY, //AoE or Single Enemy - SELECT_TARGET_SINGLE_FRIEND, //Only Single Friend SELECT_TARGET_AOE_FRIEND, //Only AoE Friend SELECT_TARGET_ANY_FRIEND, //AoE or Single Friend }; - //Spell Effects used by SelectSpell enum SelectEffect { @@ -57,123 +48,84 @@ enum SelectEffect SELECT_EFFECT_HEALING, //Spell does healing SELECT_EFFECT_AURA, //Spell applies an aura }; - enum SCEquip { EQUIP_NO_CHANGE = -1, EQUIP_UNEQUIP = 0 }; - class TRINITY_DLL_SPEC CreatureAI : public UnitAI { protected: Creature * const me; Creature * const m_creature; - bool UpdateVictim(); bool UpdateVictimWithGaze(); bool UpdateCombatState(); - void SelectNearestTarget(Unit *who); - void SetGazeOn(Unit *target); - Creature *DoSummon(uint32 uiEntry, const Position &pos, uint32 uiDespawntime = 30000, TempSummonType uiType = TEMPSUMMON_CORPSE_TIMED_DESPAWN); Creature *DoSummon(uint32 uiEntry, WorldObject *obj, float fRadius = 5.0f, uint32 uiDespawntime = 30000, TempSummonType uiType = TEMPSUMMON_CORPSE_TIMED_DESPAWN); Creature *DoSummonFlyer(uint32 uiEntry, WorldObject *obj, float fZ, float fRadius = 5.0f, uint32 uiDespawntime = 30000, TempSummonType uiType = TEMPSUMMON_CORPSE_TIMED_DESPAWN); - public: explicit CreatureAI(Creature *c) : UnitAI((Unit*)c), me(c), m_creature(c) {} - virtual ~CreatureAI() {} - ///== Reactions At ================================= - // Called if IsVisible(Unit *who) is true at each *who move, reaction at visibility zone enter virtual void MoveInLineOfSight(Unit *); - // Called for reaction at stopping attack at no attackers or targets virtual void EnterEvadeMode(); - // Called for reaction at enter to combat if not in combat yet (enemy can be NULL) virtual void EnterCombat(Unit* /*enemy*/) {} - // Called at any Damage from any attacker (before damage apply) // Note: it for recalculation damage or special reaction at damage // for attack reaction use AttackedBy called for not DOT damage in Unit::DealDamage also virtual void DamageTaken(Unit *done_by, uint32 & /*damage*/) {} - // Called when the creature is killed virtual void JustDied(Unit *) {} - // Called when the creature kills a unit virtual void KilledUnit(Unit *) {} - // Called when the creature summon successfully other creature virtual void JustSummoned(Creature* ) {} virtual void IsSummonedBy(Unit *summoner) {} - virtual void SummonedCreatureDespawn(Creature* /*unit*/) {} - // Called when hit by a spell virtual void SpellHit(Unit*, const SpellEntry*) {} - // Called when spell hits a target virtual void SpellHitTarget(Unit* target, const SpellEntry*) {} - // Called when the creature is target of hostile action: swing, hostile spell landed, fear/etc) //virtual void AttackedBy(Unit* attacker); virtual bool IsEscorted() {return false;} - // Called when creature is spawned or respawned (for reseting variables) virtual void JustRespawned() { Reset(); } - // Called at waypoint reached or point movement finished virtual void MovementInform(uint32 /*MovementType*/, uint32 /*Data*/) {} - void OnCharmed(bool apply); - //virtual void SpellClick(Player *player) {} - // Called at reaching home after evade virtual void JustReachedHome() {} - void DoZoneInCombat(Creature* pUnit = NULL); - - // Called at text emote receive from player + // Called at text emote receive from player virtual void ReceiveEmote(Player* pPlayer, uint32 text_emote) {} - ///== Triggered Actions Requested ================== - // Called when creature attack expected (if creature can and no have current victim) // Note: for reaction at hostile action must be called AttackedBy function. //virtual void AttackStart(Unit *) {} - // Called at World update tick //virtual void UpdateAI(const uint32 diff ) {} - ///== State checks ================================= - // Is unit visible for MoveInLineOfSight //virtual bool IsVisible(Unit *) const { return false; } - // called when the corpse of this creature gets removed virtual void CorpseRemoved(uint32 & /*respawnDelay*/) {} - // Called when victim entered water and creature can not enter water //virtual bool canReachByRangeAttack(Unit*) { return false; } - ///== Fields ======================================= - // Pointer to controlled by AI creature //Creature* const m_creature; - virtual void PassengerBoarded(Unit *who, int8 seatId, bool apply) {} - protected: bool _EnterEvadeMode(); }; - enum Permitions { PERMIT_BASE_NO = -1, @@ -183,5 +135,4 @@ enum Permitions PERMIT_BASE_FACTION_SPECIFIC = 400, PERMIT_BASE_SPECIAL = 800 }; - #endif diff --git a/src/game/CreatureAIFactory.h b/src/game/CreatureAIFactory.h index d546c2b1720..a2396fc5117 100644 --- a/src/game/CreatureAIFactory.h +++ b/src/game/CreatureAIFactory.h @@ -19,26 +19,20 @@ */ #ifndef TRINITY_CREATUREAIFACTORY_H #define TRINITY_CREATUREAIFACTORY_H - //#include "Policies/Singleton.h" #include "Dynamic/ObjectRegistry.h" #include "Dynamic/FactoryHolder.h" - struct SelectableAI : public FactoryHolder, public Permissible { SelectableAI(const char *id) : FactoryHolder(id) {} }; - template struct CreatureAIFactory : public SelectableAI { CreatureAIFactory(const char *name) : SelectableAI(name) {} - CreatureAI* Create(void *) const; - int Permit(const Creature *c) const { return REAL_AI::Permissible(c); } }; - template inline CreatureAI* CreatureAIFactory::Create(void *data) const @@ -46,7 +40,6 @@ CreatureAIFactory::Create(void *data) const Creature* creature = reinterpret_cast(data); return (new REAL_AI(creature)); } - typedef FactoryHolder CreatureAICreator; typedef FactoryHolder::FactoryHolderRegistry CreatureAIRegistry; typedef FactoryHolder::FactoryHolderRepository CreatureAIRepository; diff --git a/src/game/CreatureAIImpl.h b/src/game/CreatureAIImpl.h index 89d5bbc2a9e..4fddcc6392d 100644 --- a/src/game/CreatureAIImpl.h +++ b/src/game/CreatureAIImpl.h @@ -17,21 +17,17 @@ */ #ifndef CREATUREAIIMPL_H #define CREATUREAIIMPL_H - #include "Common.h" #include "Platform/Define.h" #include "TemporarySummon.h" #include "CreatureAI.h" - #define HEROIC(n,h) (HeroicMode ? h : n) - template inline const T& RAND(const T& v1, const T& v2) { return (rand()%2) ? v1 : v2; } - template inline const T& RAND(const T& v1, const T& v2, const T& v3) @@ -44,7 +40,6 @@ const T& RAND(const T& v1, const T& v2, const T& v3) case 2: return v3; } } - template inline const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4) @@ -58,7 +53,6 @@ const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4) case 3: return v4; } } - template inline const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5) @@ -73,7 +67,6 @@ const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5) case 4: return v5; } } - template inline const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6) @@ -89,7 +82,6 @@ const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, c case 5: return v6; } } - template inline const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7) @@ -106,7 +98,6 @@ const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, c case 6: return v7; } } - template inline const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8) @@ -124,7 +115,6 @@ const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, c case 7: return v8; } } - template inline const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8, @@ -144,7 +134,6 @@ const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, c case 8: return v9; } } - template inline const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8, @@ -165,7 +154,6 @@ const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, c case 9: return v10; } } - template inline const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8, @@ -187,7 +175,6 @@ const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, c case 10: return v11; } } - template inline const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8, @@ -210,7 +197,6 @@ const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, c case 11: return v12; } } - template inline const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8, @@ -234,7 +220,6 @@ const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, c case 12: return v13; } } - template inline const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8, @@ -259,7 +244,6 @@ const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, c case 13: return v14; } } - template inline const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8, @@ -285,7 +269,6 @@ const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, c case 14: return v15; } } - template inline const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8, @@ -312,26 +295,20 @@ const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, c case 15: return v16; } } - class EventMap : private std::map { private: uint32 m_time, m_phase; public: explicit EventMap() : m_phase(0), m_time(0) {} - uint32 GetTimer() const { return m_time; } - void Reset() { clear(); m_time = 0; m_phase = 0; } - void Update(uint32 time) { m_time += time; } - void SetPhase(uint32 phase) { if(phase && phase < 9) m_phase = (1 << (phase + 24)); } - void ScheduleEvent(uint32 eventId, uint32 time, uint32 gcd = 0, uint32 phase = 0) { time += m_time; @@ -347,13 +324,11 @@ class EventMap : private std::map } insert(std::make_pair(time, eventId)); } - void RescheduleEvent(uint32 eventId, uint32 time, uint32 gcd = 0, uint32 phase = 0) { CancelEvent(eventId); ScheduleEvent(eventId, time, gcd, phase); } - void RepeatEvent(uint32 time) { if(empty()) @@ -369,12 +344,10 @@ class EventMap : private std::map } insert(std::make_pair(time, eventId)); } - void PopEvent() { erase(begin()); } - uint32 ExecuteEvent() { while(!empty()) @@ -392,7 +365,6 @@ class EventMap : private std::map } return 0; } - uint32 GetEvent() { while(!empty()) @@ -408,7 +380,6 @@ class EventMap : private std::map } return 0; } - void DelayEvents(uint32 time, uint32 gcd) { time += m_time; @@ -426,7 +397,6 @@ class EventMap : private std::map ++itr; } } - void CancelEvent(uint32 eventId) { for(iterator itr = begin(); itr != end();) @@ -437,7 +407,6 @@ class EventMap : private std::map ++itr; } } - void CancelEventsByGCD(uint32 gcd) { for(iterator itr = begin(); itr != end();) @@ -449,7 +418,6 @@ class EventMap : private std::map } } }; - enum AITarget { AITARGET_SELF, @@ -459,16 +427,13 @@ enum AITarget AITARGET_BUFF, AITARGET_DEBUFF, }; - enum AICondition { AICOND_AGGRO, AICOND_COMBAT, AICOND_DIE, }; - #define AI_DEFAULT_COOLDOWN 5000 - struct AISpellInfoType { AISpellInfoType() : target(AITARGET_SELF), condition(AICOND_COMBAT) @@ -479,10 +444,8 @@ struct AISpellInfoType uint32 realCooldown; float maxRange; }; - TRINITY_DLL_SPEC AISpellInfoType * GetAISpellInfo(uint32 i); - inline void CreatureAI::SetGazeOn(Unit *target) { if(me->canAttack(target)) @@ -491,12 +454,10 @@ inline void CreatureAI::SetGazeOn(Unit *target) me->SetReactState(REACT_PASSIVE); } } - inline bool CreatureAI::UpdateVictimWithGaze() { if(!me->isInCombat()) return false; - if(me->HasReactState(REACT_PASSIVE)) { if(me->getVictim()) @@ -504,17 +465,14 @@ inline bool CreatureAI::UpdateVictimWithGaze() else me->SetReactState(REACT_AGGRESSIVE); } - if(Unit *victim = me->SelectVictim()) AttackStart(victim); return me->getVictim(); } - inline bool CreatureAI::UpdateCombatState() { if(!me->isInCombat()) return false; - if(!me->HasReactState(REACT_PASSIVE)) { if(Unit *victim = me->SelectVictim()) @@ -526,15 +484,12 @@ inline bool CreatureAI::UpdateCombatState() EnterEvadeMode(); return false; } - return true; } - inline bool CreatureAI::UpdateVictim() { if(!me->isInCombat()) return false; - if(!me->HasReactState(REACT_PASSIVE)) { if(Unit *victim = me->SelectVictim()) @@ -546,10 +501,8 @@ inline bool CreatureAI::UpdateVictim() EnterEvadeMode(); return false; } - return true; } - /* inline bool CreatureAI::UpdateVictim() { @@ -560,12 +513,10 @@ inline bool CreatureAI::UpdateVictim() return me->getVictim(); } */ - inline bool CreatureAI::_EnterEvadeMode() { if(!me->isAlive()) return false; - // sometimes bosses stuck in combat? me->RemoveAllAuras(); me->DeleteThreatList(); @@ -573,46 +524,36 @@ inline bool CreatureAI::_EnterEvadeMode() me->LoadCreaturesAddon(); me->SetLootRecipient(NULL); me->ResetPlayerDamageReq(); - if(me->IsInEvadeMode()) return false; - return true; } - inline void UnitAI::DoCast(Unit* victim, uint32 spellId, bool triggered) { if(!victim || me->hasUnitState(UNIT_STAT_CASTING) && !triggered) return; - me->CastSpell(victim, spellId, triggered); } - inline void UnitAI::DoCastVictim(uint32 spellId, bool triggered) { me->CastSpell(me->getVictim(), spellId, triggered); } - inline void UnitAI::DoCastAOE(uint32 spellId, bool triggered) { if(!triggered && me->hasUnitState(UNIT_STAT_CASTING)) return; - me->CastSpell((Unit*)NULL, spellId, triggered); } - inline Creature *CreatureAI::DoSummon(uint32 uiEntry, const Position &pos, uint32 uiDespawntime, TempSummonType uiType) { return me->SummonCreature(uiEntry, pos, uiType, uiDespawntime); } - inline Creature *CreatureAI::DoSummon(uint32 uiEntry, WorldObject* obj, float fRadius, uint32 uiDespawntime, TempSummonType uiType) { Position pos; obj->GetRandomNearPosition(pos, fRadius); return me->SummonCreature(uiEntry, pos, uiType, uiDespawntime); } - inline Creature *CreatureAI::DoSummonFlyer(uint32 uiEntry, WorldObject *obj, float _fZ, float fRadius, uint32 uiDespawntime, TempSummonType uiType) { Position pos; @@ -620,6 +561,5 @@ inline Creature *CreatureAI::DoSummonFlyer(uint32 uiEntry, WorldObject *obj, flo pos.m_positionZ += _fZ; return me->SummonCreature(uiEntry, pos, uiType, uiDespawntime); } - #endif diff --git a/src/game/CreatureAIRegistry.cpp b/src/game/CreatureAIRegistry.cpp index 67c1f857a56..900f89da3b4 100644 --- a/src/game/CreatureAIRegistry.cpp +++ b/src/game/CreatureAIRegistry.cpp @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "PassiveAI.h" #include "ReactorAI.h" #include "CombatAI.h" @@ -30,7 +29,6 @@ #include "CreatureAIRegistry.h" #include "WaypointMovementGenerator.h" #include "CreatureAIFactory.h" - //#include "CreatureAIImpl.h" namespace AIRegistry { @@ -49,7 +47,6 @@ namespace AIRegistry (new CreatureAIFactory("ArchorAI"))->RegisterSelf(); (new CreatureAIFactory("TurretAI"))->RegisterSelf(); (new CreatureAIFactory("EventAI"))->RegisterSelf(); - (new MovementGeneratorFactory >(RANDOM_MOTION_TYPE))->RegisterSelf(); (new MovementGeneratorFactory >(WAYPOINT_MOTION_TYPE))->RegisterSelf(); } diff --git a/src/game/CreatureAIRegistry.h b/src/game/CreatureAIRegistry.h index 2b92a096731..c75167d74af 100644 --- a/src/game/CreatureAIRegistry.h +++ b/src/game/CreatureAIRegistry.h @@ -17,10 +17,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef TRINITY_CREATUREAIREGISTRY_H #define TRINITY_CREATUREAIREGISTRY_H - namespace AIRegistry { void Initialize(void); diff --git a/src/game/CreatureAISelector.cpp b/src/game/CreatureAISelector.cpp index 9f2828bf776..2f7bd0ff211 100644 --- a/src/game/CreatureAISelector.cpp +++ b/src/game/CreatureAISelector.cpp @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "Creature.h" #include "CreatureAISelector.h" #include "PassiveAI.h" @@ -27,30 +26,24 @@ #include "Pet.h" #include "TemporarySummon.h" #include "CreatureAIFactory.h" - INSTANTIATE_SINGLETON_1(CreatureAIRegistry); INSTANTIATE_SINGLETON_1(MovementGeneratorRegistry); - namespace FactorySelector { CreatureAI* selectAI(Creature *creature) { const CreatureAICreator *ai_factory = NULL; CreatureAIRegistry &ai_registry(CreatureAIRepository::Instance()); - if(creature->isPet()) ai_factory = ai_registry.GetRegistryItem("PetAI"); - //scriptname in db if(!ai_factory) if(CreatureAI* scriptedAI = Script->GetAI(creature)) return scriptedAI; - // AIname in db std::string ainame=creature->GetAIName(); if(!ai_factory && !ainame.empty()) ai_factory = ai_registry.GetRegistryItem( ainame.c_str() ); - // select by NPC flags if(!ai_factory) { @@ -74,7 +67,6 @@ namespace FactorySelector else if(creature->GetCreatureType() == CREATURE_TYPE_CRITTER && !creature->HasUnitTypeMask(UNIT_MASK_GUARDIAN)) ai_factory = ai_registry.GetRegistryItem("CritterAI"); } - if(!ai_factory) { for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i) @@ -86,7 +78,6 @@ namespace FactorySelector } } } - // select by permit check if(!ai_factory) { @@ -106,20 +97,16 @@ namespace FactorySelector } } } - // select NullCreatureAI if not another cases ainame = (ai_factory == NULL) ? "NullCreatureAI" : ai_factory->key(); - DEBUG_LOG("Creature %u used AI is %s.", creature->GetGUIDLow(), ainame.c_str() ); return ( ai_factory == NULL ? new NullCreatureAI(creature) : ai_factory->Create(creature) ); } - MovementGenerator* selectMovementGenerator(Creature *creature) { MovementGeneratorRegistry &mv_registry(MovementGeneratorRepository::Instance()); assert( creature->GetCreatureInfo() != NULL ); const MovementGeneratorCreator *mv_factory = mv_registry.GetRegistryItem( creature->GetDefaultMovementType()); - /* if( mv_factory == NULL ) { int best_val = -1; @@ -138,9 +125,7 @@ namespace FactorySelector } } }*/ - return ( mv_factory == NULL ? NULL : mv_factory->Create(creature) ); - } } diff --git a/src/game/CreatureAISelector.h b/src/game/CreatureAISelector.h index 436233b5b21..e7e980518dd 100644 --- a/src/game/CreatureAISelector.h +++ b/src/game/CreatureAISelector.h @@ -17,14 +17,11 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef TRINITY_CREATUREAISELECTOR_H #define TRINITY_CREATUREAISELECTOR_H - class CreatureAI; class Creature; class MovementGenerator; - namespace FactorySelector { CreatureAI* selectAI(Creature *); diff --git a/src/game/CreatureEventAI.cpp b/src/game/CreatureEventAI.cpp index b2f5dc354d2..9a6e907f33b 100644 --- a/src/game/CreatureEventAI.cpp +++ b/src/game/CreatureEventAI.cpp @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "Common.h" #include "CreatureEventAI.h" #include "CreatureEventAIMgr.h" @@ -32,7 +31,6 @@ #include "InstanceData.h" #include "SpellMgr.h" #include "CreatureAIImpl.h" - bool CreatureEventAIHolder::UpdateRepeatTimer( Creature* creature, uint32 repeatMin, uint32 repeatMax ) { if (repeatMin == repeatMax) @@ -45,17 +43,14 @@ bool CreatureEventAIHolder::UpdateRepeatTimer( Creature* creature, uint32 repeat Enabled = false; return false; } - return true; } - int CreatureEventAI::Permissible(const Creature *creature) { if( creature->GetAIName() == "EventAI" ) return PERMIT_BASE_SPECIAL; return PERMIT_BASE_NO; } - CreatureEventAI::CreatureEventAI(Creature *c ) : CreatureAI(c) { // Need make copy for filter unneeded steps and safe in case table reload @@ -65,7 +60,6 @@ CreatureEventAI::CreatureEventAI(Creature *c ) : CreatureAI(c) std::vector::const_iterator i; for (i = (*CreatureEvents).second.begin(); i != (*CreatureEvents).second.end(); ++i) { - //Debug check #ifndef TRINITY_DEBUG if ((*i).event_flags & EFLAG_DEBUG_ONLY) @@ -89,16 +83,13 @@ CreatureEventAI::CreatureEventAI(Creature *c ) : CreatureAI(c) } else sLog.outError("CreatureEventAI: EventMap for Creature %u is empty but creature is using CreatureEventAI.", m_creature->GetEntry()); - bEmptyList = CreatureEventAIList.empty(); Phase = 0; CombatMovementEnabled = true; MeleeEnabled = true; AttackDistance = 0.0f; AttackAngle = 0.0f; - InvinceabilityHpLevel = 0; - //Handle Spawned Events if (!bEmptyList) { @@ -107,32 +98,26 @@ CreatureEventAI::CreatureEventAI(Creature *c ) : CreatureAI(c) ProcessEvent(*i); } } - bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pActionInvoker) { if (!pHolder.Enabled || pHolder.Time) return false; - //Check the inverse phase mask (event doesn't trigger if current phase bit is set in mask) if (pHolder.Event.event_inverse_phase_mask & (1 << Phase)) return false; - CreatureEventAI_Event const& event = pHolder.Event; - //Check event conditions based on the event type, also reset events switch (event.event_type) { case EVENT_T_TIMER: if (!m_creature->isInCombat()) return false; - //Repeat Timers pHolder.UpdateRepeatTimer(m_creature,event.timer.repeatMin,event.timer.repeatMax); break; case EVENT_T_TIMER_OOC: if (m_creature->isInCombat()) return false; - //Repeat Timers pHolder.UpdateRepeatTimer(m_creature,event.timer.repeatMin,event.timer.repeatMax); break; @@ -140,12 +125,9 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction { if (!m_creature->isInCombat() || !m_creature->GetMaxHealth()) return false; - uint32 perc = (m_creature->GetHealth()*100) / m_creature->GetMaxHealth(); - if (perc > event.percent_range.percentMax || perc < event.percent_range.percentMin) return false; - //Repeat Timers pHolder.UpdateRepeatTimer(m_creature,event.percent_range.repeatMin,event.percent_range.repeatMax); break; @@ -154,12 +136,9 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction { if (!m_creature->isInCombat() || !m_creature->GetMaxPower(POWER_MANA)) return false; - uint32 perc = (m_creature->GetPower(POWER_MANA)*100) / m_creature->GetMaxPower(POWER_MANA); - if (perc > event.percent_range.percentMax || perc < event.percent_range.percentMin) return false; - //Repeat Timers pHolder.UpdateRepeatTimer(m_creature,event.percent_range.repeatMin,event.percent_range.repeatMax); break; @@ -175,7 +154,6 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction break; case EVENT_T_SPELLHIT: //Spell hit is special case, param1 and param2 handled within CreatureEventAI::SpellHit - //Repeat Timers pHolder.UpdateRepeatTimer(m_creature,event.spell_hit.repeatMin,event.spell_hit.repeatMax); break; @@ -193,12 +171,9 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction { if (!m_creature->isInCombat() || !m_creature->getVictim() || !m_creature->getVictim()->GetMaxHealth()) return false; - uint32 perc = (m_creature->getVictim()->GetHealth()*100) / m_creature->getVictim()->GetMaxHealth(); - if (perc > event.percent_range.percentMax || perc < event.percent_range.percentMin) return false; - //Repeat Timers pHolder.UpdateRepeatTimer(m_creature,event.percent_range.repeatMin,event.percent_range.repeatMax); break; @@ -206,7 +181,6 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction case EVENT_T_TARGET_CASTING: if (!m_creature->isInCombat() || !m_creature->getVictim() || !m_creature->getVictim()->IsNonMeleeSpellCasted(false, false, true)) return false; - //Repeat Timers pHolder.UpdateRepeatTimer(m_creature,event.target_casting.repeatMin,event.target_casting.repeatMax); break; @@ -214,13 +188,10 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction { if (!m_creature->isInCombat()) return false; - Unit* pUnit = DoSelectLowestHpFriendly(event.friendly_hp.radius, event.friendly_hp.hpDeficit); if (!pUnit) return false; - pActionInvoker = pUnit; - //Repeat Timers pHolder.UpdateRepeatTimer(m_creature,event.friendly_hp.repeatMin,event.friendly_hp.repeatMax); break; @@ -229,17 +200,13 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction { if (!m_creature->isInCombat()) return false; - std::list pList; DoFindFriendlyCC(pList, event.friendly_is_cc.radius); - //List is empty if (pList.empty()) return false; - //We don't really care about the whole list, just return first available pActionInvoker = *(pList.begin()); - //Repeat Timers pHolder.UpdateRepeatTimer(m_creature,event.friendly_is_cc.repeatMin,event.friendly_is_cc.repeatMax); break; @@ -248,14 +215,11 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction { std::list pList; DoFindFriendlyMissingBuff(pList, event.friendly_buff.radius, event.friendly_buff.spellId); - //List is empty if (pList.empty()) return false; - //We don't really care about the whole list, just return first available pActionInvoker = *(pList.begin()); - //Repeat Timers pHolder.UpdateRepeatTimer(m_creature,event.friendly_buff.repeatMin,event.friendly_buff.repeatMax); break; @@ -265,11 +229,9 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction //Prevent event from occuring on no unit or non creatures if (!pActionInvoker || pActionInvoker->GetTypeId()!=TYPEID_UNIT) return false; - //Creature id doesn't match up if (((Creature*)pActionInvoker)->GetEntry() != event.summon_unit.creatureId) return false; - //Repeat Timers pHolder.UpdateRepeatTimer(m_creature,event.summon_unit.repeatMin,event.summon_unit.repeatMax); break; @@ -278,12 +240,9 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction { if (!m_creature->isInCombat() || !m_creature->getVictim() || !m_creature->getVictim()->GetMaxPower(POWER_MANA)) return false; - uint32 perc = (m_creature->getVictim()->GetPower(POWER_MANA)*100) / m_creature->getVictim()->GetMaxPower(POWER_MANA); - if (perc > event.percent_range.percentMax || perc < event.percent_range.percentMin) return false; - //Repeat Timers pHolder.UpdateRepeatTimer(m_creature,event.percent_range.repeatMin,event.percent_range.repeatMax); break; @@ -298,7 +257,6 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction Aura* aura = m_creature->GetAura(event.buffed.spellId,0); if(!aura || aura->GetStackAmount() < event.buffed.amount) return false; - //Repeat Timers pHolder.UpdateRepeatTimer(m_creature,event.buffed.repeatMin,event.buffed.repeatMax); break; @@ -308,13 +266,11 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction //Prevent event from occuring on no unit if (!pActionInvoker) return false; - //Note: checked only aura for effect 0, if need check aura for effect 1/2 then // possible way: pack in event.buffed.amount 2 uint16 (ammount+effectIdx) Aura* aura = pActionInvoker->GetAura(event.buffed.spellId,0); if(!aura || aura->GetStackAmount() < event.buffed.amount) return false; - //Repeat Timers pHolder.UpdateRepeatTimer(m_creature,event.buffed.repeatMin,event.buffed.repeatMax); break; @@ -323,25 +279,19 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction sLog.outErrorDb("CreatureEventAI: Creature %u using Event %u has invalid Event Type(%u), missing from ProcessEvent() Switch.", m_creature->GetEntry(), pHolder.Event.event_id, pHolder.Event.event_type); break; } - //Disable non-repeatable events if (!(pHolder.Event.event_flags & EFLAG_REPEATABLE)) pHolder.Enabled = false; - //Store random here so that all random actions match up uint32 rnd = rand(); - //Return if chance for event is not met if (pHolder.Event.event_chance <= rnd % 100) return false; - //Process actions for (uint32 j = 0; j < MAX_ACTIONS; j++) ProcessAction(pHolder.Event.action[j], rnd, pHolder.Event.event_id, pActionInvoker); - return true; } - void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32 rnd, uint32 EventId, Unit* pActionInvoker) { switch (action.type) @@ -350,20 +300,16 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32 { if (!action.text.TextId1) return; - int32 temp = 0; - if (action.text.TextId2 && action.text.TextId3) temp = RAND(action.text.TextId1,action.text.TextId2,action.text.TextId3); else if (action.text.TextId2 && urand(0,1)) temp = action.text.TextId2; else temp = action.text.TextId1; - if (temp) { Unit* target = NULL; - if (pActionInvoker) { if (pActionInvoker->GetTypeId() == TYPEID_PLAYER) @@ -381,7 +327,6 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32 if (owner->GetTypeId() == TYPEID_PLAYER) target = owner; } - DoScriptText(temp, m_creature, target); } break; @@ -446,27 +391,21 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32 { Unit* target = GetTargetByType(action.cast.target, pActionInvoker); Unit* caster = m_creature; - if (!target) return; - if (action.cast.castFlags & CAST_FORCE_TARGET_SELF) caster = target; - //Allowed to cast only if not casting (unless we interrupt ourself) or if spell is triggered bool canCast = !caster->IsNonMeleeSpellCasted(false) || (action.cast.castFlags & (CAST_TRIGGERED | CAST_INTURRUPT_PREVIOUS)); - // If cast flag CAST_AURA_NOT_PRESENT is active, check if target already has aura on them if(action.cast.castFlags & CAST_AURA_NOT_PRESENT) { if(target->HasAura(action.cast.spellId)) return; } - if (canCast) { const SpellEntry* tSpell = GetSpellStore()->LookupEntry(action.cast.spellId); - //Verify that spell exists if (tSpell) { @@ -481,21 +420,17 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32 { AttackDistance = 0.0f; AttackAngle = 0.0f; - m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim(), AttackDistance, AttackAngle); } } - } else { //Interrupt any previous spell if (caster->IsNonMeleeSpellCasted(false) && action.cast.castFlags & CAST_INTURRUPT_PREVIOUS) caster->InterruptNonMeleeSpells(false); - caster->CastSpell(target, action.cast.spellId, (action.cast.castFlags & CAST_TRIGGERED)); } - } else sLog.outErrorDb("CreatureEventAI: event %d creature %d attempt to cast spell that doesn't exist %d", EventId, m_creature->GetEntry(), action.cast.spellId); @@ -505,14 +440,11 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32 case ACTION_T_SUMMON: { Unit* target = GetTargetByType(action.summon.target, pActionInvoker); - Creature* pCreature = NULL; - if (action.summon.duration) pCreature = m_creature->SummonCreature(action.summon.creatureId, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, action.summon.duration); else pCreature = m_creature->SummonCreature(action.summon.creatureId, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0); - if (!pCreature) sLog.outErrorDb( "CreatureEventAI: failed to spawn creature %u. Spawn event %d is on creature %d", action.summon.creatureId, EventId, m_creature->GetEntry()); else if (action.summon.target != TARGET_T_SELF && target) @@ -544,14 +476,11 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32 case ACTION_T_SET_UNIT_FIELD: { Unit* target = GetTargetByType(action.set_unit_field.target, pActionInvoker); - // not allow modify important for integrity object fields if (action.set_unit_field.field < OBJECT_END || action.set_unit_field.field >= UNIT_END) return; - if (target) target->SetUInt32Value(action.set_unit_field.field, action.set_unit_field.value); - break; } case ACTION_T_SET_UNIT_FLAG: @@ -569,16 +498,13 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32 // ignore no affect case if(CombatMovementEnabled==(action.combat_movement.state!=0)) return; - CombatMovementEnabled = action.combat_movement.state != 0; - //Allow movement (create new targeted movement gen only if idle) if (CombatMovementEnabled) { if(action.combat_movement.melee && m_creature->isInCombat()) if(Unit* victim = m_creature->getVictim()) m_creature->SendMeleeAttackStart(victim); - m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim(), AttackDistance, AttackAngle); } else @@ -586,7 +512,6 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32 if(action.combat_movement.melee && m_creature->isInCombat()) if(Unit* victim = m_creature->getVictim()) m_creature->SendMeleeAttackStop(victim); - m_creature->GetMotionMaster()->MoveIdle(); } break; @@ -608,7 +533,6 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32 } else Phase = new_phase; - break; } case ACTION_T_EVADE: @@ -641,7 +565,6 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32 case ACTION_T_RANGED_MOVEMENT: AttackDistance = (float)action.ranged_movement.distance; AttackAngle = action.ranged_movement.angle/180.0f*M_PI; - if (CombatMovementEnabled) { m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim(), AttackDistance, AttackAngle); @@ -659,25 +582,21 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32 case ACTION_T_SUMMON_ID: { Unit* target = GetTargetByType(action.summon_id.target, pActionInvoker); - CreatureEventAI_Summon_Map::const_iterator i = CreatureEAI_Mgr.GetCreatureEventAISummonMap().find(action.summon_id.spawnId); if (i == CreatureEAI_Mgr.GetCreatureEventAISummonMap().end()) { sLog.outErrorDb( "CreatureEventAI: failed to spawn creature %u. Summon map index %u does not exist. EventID %d. CreatureID %d", action.summon_id.creatureId, action.summon_id.spawnId, EventId, m_creature->GetEntry()); return; } - Creature* pCreature = NULL; if ((*i).second.SpawnTimeSecs) pCreature = m_creature->SummonCreature(action.summon_id.creatureId, (*i).second.position_x, (*i).second.position_y, (*i).second.position_z, (*i).second.orientation, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, (*i).second.SpawnTimeSecs); else pCreature = m_creature->SummonCreature(action.summon_id.creatureId, (*i).second.position_x, (*i).second.position_y, (*i).second.position_z, (*i).second.orientation, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0); - if (!pCreature) sLog.outErrorDb( "CreatureEventAI: failed to spawn creature %u. EventId %d.Creature %d", action.summon_id.creatureId, EventId, m_creature->GetEntry()); else if (action.summon_id.target != TARGET_T_SELF && target) pCreature->AI()->AttackStart(target); - break; } case ACTION_T_KILLED_MONSTER: @@ -700,7 +619,6 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32 sLog.outErrorDb("CreatureEventAI: Event %d attempt to set instance data without instance script. Creature %d", EventId, m_creature->GetEntry()); return; } - pInst->SetData(action.set_inst_data.field, action.set_inst_data.value); break; } @@ -712,31 +630,26 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32 sLog.outErrorDb("CreatureEventAI: Event %d attempt to set instance data64 but Target == NULL. Creature %d", EventId, m_creature->GetEntry()); return; } - InstanceData* pInst = (InstanceData*)m_creature->GetInstanceData(); if (!pInst) { sLog.outErrorDb("CreatureEventAI: Event %d attempt to set instance data64 without instance script. Creature %d", EventId, m_creature->GetEntry()); return; } - pInst->SetData64(action.set_inst_data64.field, target->GetGUID()); break; } case ACTION_T_UPDATE_TEMPLATE: if (m_creature->GetEntry() == action.update_template.creatureId) { - sLog.outErrorDb("CreatureEventAI: Event %d ACTION_T_UPDATE_TEMPLATE call with param1 == current entry. Creature %d", EventId, m_creature->GetEntry()); return; } - m_creature->UpdateEntry(action.update_template.creatureId, action.update_template.team ? HORDE : ALLIANCE); break; case ACTION_T_DIE: if (m_creature->isDead()) { - sLog.outErrorDb("CreatureEventAI: Event %d ACTION_T_DIE on dead creature. Creature %d", EventId, m_creature->GetEntry()); return; } @@ -753,7 +666,6 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32 break; } break; - // TRINITY ONLY case ACTION_T_SET_ACTIVE: me->setActive(action.raw.param1 ? true : false); @@ -767,7 +679,6 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32 case ACTION_T_SUMMON_GO: { GameObject* pObject = NULL; - float x,y,z; m_creature->GetPosition(x,y,z); pObject = m_creature->SummonGameObject(action.raw.param1, x, y, z, 0, 0, 0, 0, 0, action.raw.param2); @@ -777,7 +688,6 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32 } break; } - case ACTION_T_SET_SHEATH: { m_creature->SetSheath(SheathState(action.set_sheath.sheath)); @@ -798,28 +708,22 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32 } } } - void CreatureEventAI::JustRespawned() { Reset(); - if (bEmptyList) return; - //Handle Spawned Events for (std::list::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i) if (SpawnedEventConditionsCheck((*i).Event)) ProcessEvent(*i); } - void CreatureEventAI::Reset() { EventUpdateTime = EVENT_UPDATE_TIME; EventDiff = 0; - if (bEmptyList) return; - //Reset all events to enabled for (std::list::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i) { @@ -841,11 +745,9 @@ void CreatureEventAI::Reset() } } } - void CreatureEventAI::JustReachedHome() { m_creature->LoadCreaturesAddon(); - if (!bEmptyList) { for (std::list::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i) @@ -854,17 +756,13 @@ void CreatureEventAI::JustReachedHome() ProcessEvent(*i); } } - Reset(); } - void CreatureEventAI::EnterEvadeMode() { CreatureAI::EnterEvadeMode(); - if (bEmptyList) return; - //Handle Evade events for (std::list::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i) { @@ -872,49 +770,40 @@ void CreatureEventAI::EnterEvadeMode() ProcessEvent(*i); } } - void CreatureEventAI::JustDied(Unit* killer) { Reset(); - if (bEmptyList) return; - //Handle Evade events for (std::list::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i) { if ((*i).Event.event_type == EVENT_T_DEATH) ProcessEvent(*i, killer); } - // reset phase after any death state events Phase = 0; } - void CreatureEventAI::KilledUnit(Unit* victim) { if (bEmptyList || victim->GetTypeId() != TYPEID_PLAYER) return; - for (std::list::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i) { if ((*i).Event.event_type == EVENT_T_KILL) ProcessEvent(*i, victim); } } - void CreatureEventAI::JustSummoned(Creature* pUnit) { if (bEmptyList || !pUnit) return; - for (std::list::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i) { if ((*i).Event.event_type == EVENT_T_SUMMONED_UNIT) ProcessEvent(*i, pUnit); } } - void CreatureEventAI::EnterCombat(Unit *enemy) { //Check for on combat start events @@ -942,16 +831,13 @@ void CreatureEventAI::EnterCombat(Unit *enemy) } } } - EventUpdateTime = EVENT_UPDATE_TIME; EventDiff = 0; } - void CreatureEventAI::AttackStart(Unit *who) { if (!who) return; - if (m_creature->Attack(who, MeleeEnabled)) { if (CombatMovementEnabled) @@ -964,12 +850,10 @@ void CreatureEventAI::AttackStart(Unit *who) } } } - void CreatureEventAI::MoveInLineOfSight(Unit *who) { if(me->getVictim()) return; - //Check for OOC LOS Event if (!bEmptyList) { @@ -979,7 +863,6 @@ void CreatureEventAI::MoveInLineOfSight(Unit *who) { //can trigger if closer than fMaxAllowedRange float fMaxAllowedRange = (*itr).Event.ooc_los.maxRange; - //if range is ok and we are actually in LOS if (m_creature->IsWithinDistInMap(who, fMaxAllowedRange) && m_creature->IsWithinLOSInMap(who)) { @@ -991,16 +874,12 @@ void CreatureEventAI::MoveInLineOfSight(Unit *who) } } } - CreatureAI::MoveInLineOfSight(who); } - void CreatureEventAI::SpellHit(Unit* pUnit, const SpellEntry* pSpell) { - if (bEmptyList) return; - for (std::list::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i) if ((*i).Event.event_type == EVENT_T_SPELLHIT) //If spell id matches (or no spell id) & if spell school matches (or no spell school) @@ -1008,19 +887,16 @@ void CreatureEventAI::SpellHit(Unit* pUnit, const SpellEntry* pSpell) if (pSpell->SchoolMask & (*i).Event.spell_hit.schoolMask) ProcessEvent(*i, pUnit); } - void CreatureEventAI::UpdateAI(const uint32 diff) { //Check if we are in combat (also updates calls threat update code) bool Combat = UpdateVictim(); - if (!bEmptyList) { //Events are only updated once every EVENT_UPDATE_TIME ms to prevent lag with large amount of events if (EventUpdateTime < diff) { EventDiff += diff; - //Check for time based events for (std::list::iterator i = CreatureEventAIList.begin(); i != CreatureEventAIList.end(); ++i) { @@ -1032,13 +908,11 @@ void CreatureEventAI::UpdateAI(const uint32 diff) //Do not decrement timers if event cannot trigger in this phase if (!((*i).Event.event_inverse_phase_mask & (1 << Phase))) (*i).Time -= EventDiff; - //Skip processing of events that have time remaining continue; } else (*i).Time = 0; } - //Events that are updated every EVENT_UPDATE_TIME switch ((*i).Event.event_type) { @@ -1062,7 +936,6 @@ void CreatureEventAI::UpdateAI(const uint32 diff) break; } } - EventDiff = 0; EventUpdateTime = EVENT_UPDATE_TIME; } @@ -1072,22 +945,18 @@ void CreatureEventAI::UpdateAI(const uint32 diff) EventUpdateTime -= diff; } } - //Melee Auto-Attack if (Combat && MeleeEnabled) DoMeleeAttackIfReady(); } - inline Unit* CreatureEventAI::SelectUnit(AttackingTarget target, uint32 position) { //ThreatList m_threatlist; std::list& m_threatlist = m_creature->getThreatManager().getThreatList(); std::list::iterator i = m_threatlist.begin(); std::list::reverse_iterator r = m_threatlist.rbegin(); - if (position >= m_threatlist.size() || !m_threatlist.size()) return NULL; - switch (target) { case ATTACKING_TARGET_RANDOM: @@ -1108,7 +977,6 @@ inline Unit* CreatureEventAI::SelectUnit(AttackingTarget target, uint32 position } return NULL; } - inline uint32 CreatureEventAI::GetRandActionParam(uint32 rnd, uint32 param1, uint32 param2, uint32 param3) { switch (rnd % 3) @@ -1119,7 +987,6 @@ inline uint32 CreatureEventAI::GetRandActionParam(uint32 rnd, uint32 param1, uin } return 0; } - inline int32 CreatureEventAI::GetRandActionParam(uint32 rnd, int32 param1, int32 param2, int32 param3) { switch (rnd % 3) @@ -1130,7 +997,6 @@ inline int32 CreatureEventAI::GetRandActionParam(uint32 rnd, int32 param1, int32 } return 0; } - inline Unit* CreatureEventAI::GetTargetByType(uint32 Target, Unit* pActionInvoker) { switch (Target) @@ -1153,65 +1019,50 @@ inline Unit* CreatureEventAI::GetTargetByType(uint32 Target, Unit* pActionInvoke return NULL; }; } - Unit* CreatureEventAI::DoSelectLowestHpFriendly(float range, uint32 MinHPDiff) { CellPair p(MaNGOS::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY())); Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); - Unit* pUnit = NULL; - MaNGOS::MostHPMissingInRange u_check(m_creature, range, MinHPDiff); MaNGOS::UnitLastSearcher searcher(m_creature, pUnit, u_check); - /* typedef TYPELIST_4(GameObject, Creature*except pets*, DynamicObject, Corpse*Bones*) AllGridObjectTypes; This means that if we only search grid then we cannot possibly return pets or players so this is safe */ TypeContainerVisitor, GridTypeMapContainer > grid_unit_searcher(searcher); - CellLock cell_lock(cell, p); cell_lock->Visit(cell_lock, grid_unit_searcher, *m_creature->GetMap(), *m_creature, range); return pUnit; } - void CreatureEventAI::DoFindFriendlyCC(std::list& _list, float range) { CellPair p(MaNGOS::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY())); Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); - MaNGOS::FriendlyCCedInRange u_check(m_creature, range); MaNGOS::CreatureListSearcher searcher(m_creature, _list, u_check); - TypeContainerVisitor, GridTypeMapContainer > grid_creature_searcher(searcher); - CellLock cell_lock(cell, p); cell_lock->Visit(cell_lock, grid_creature_searcher, *m_creature->GetMap()); } - void CreatureEventAI::DoFindFriendlyMissingBuff(std::list& _list, float range, uint32 spellid) { CellPair p(MaNGOS::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY())); Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); - MaNGOS::FriendlyMissingBuffInRange u_check(m_creature, range, spellid); MaNGOS::CreatureListSearcher searcher(m_creature, _list, u_check); - TypeContainerVisitor, GridTypeMapContainer > grid_creature_searcher(searcher); - CellLock cell_lock(cell, p); cell_lock->Visit(cell_lock, grid_creature_searcher, *m_creature->GetMap()); } - //********************************* //*** Functions used globally *** - void CreatureEventAI::DoScriptText(int32 textEntry, WorldObject* pSource, Unit* target) { if (!pSource) @@ -1219,23 +1070,18 @@ void CreatureEventAI::DoScriptText(int32 textEntry, WorldObject* pSource, Unit* sLog.outErrorDb("CreatureEventAI: DoScriptText entry %i, invalid Source pointer.",textEntry); return; } - if (textEntry >= 0) { sLog.outErrorDb("CreatureEventAI: DoScriptText with source entry %u (TypeId=%u, guid=%u) attempts to process text entry %i, but text entry must be negative.",pSource->GetEntry(),pSource->GetTypeId(),pSource->GetGUIDLow(),textEntry); return; } - CreatureEventAI_TextMap::const_iterator i = CreatureEAI_Mgr.GetCreatureEventAITextMap().find(textEntry); - if (i == CreatureEAI_Mgr.GetCreatureEventAITextMap().end()) { sLog.outErrorDb("CreatureEventAI: DoScriptText with source entry %u (TypeId=%u, guid=%u) could not find text entry %i.",pSource->GetEntry(),pSource->GetTypeId(),pSource->GetGUIDLow(),textEntry); return; } - sLog.outDebug("CreatureEventAI: DoScriptText: text entry=%i, Sound=%u, Type=%u, Language=%u, Emote=%u",textEntry,(*i).second.SoundId,(*i).second.Type,(*i).second.Language,(*i).second.Emote); - if((*i).second.SoundId) { if (GetSoundEntriesStore()->LookupEntry((*i).second.SoundId)) @@ -1243,7 +1089,6 @@ void CreatureEventAI::DoScriptText(int32 textEntry, WorldObject* pSource, Unit* else sLog.outErrorDb("CreatureEventAI: DoScriptText entry %i tried to process invalid sound id %u.",textEntry,(*i).second.SoundId); } - if((*i).second.Emote) { if (pSource->GetTypeId() == TYPEID_UNIT || pSource->GetTypeId() == TYPEID_PLAYER) @@ -1253,7 +1098,6 @@ void CreatureEventAI::DoScriptText(int32 textEntry, WorldObject* pSource, Unit* else sLog.outErrorDb("CreatureEventAI: DoScriptText entry %i tried to process emote for invalid TypeId (%u).",textEntry,pSource->GetTypeId()); } - switch((*i).second.Type) { case CHAT_TYPE_SAY: @@ -1285,48 +1129,37 @@ void CreatureEventAI::DoScriptText(int32 textEntry, WorldObject* pSource, Unit* break; } } - bool CreatureEventAI::CanCast(Unit* Target, SpellEntry const *Spell, bool Triggered) { //No target so we can't cast if (!Target || !Spell) return false; - //Silenced so we can't cast if (!Triggered && me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED)) return false; - //Check for power if (!Triggered && me->GetPower((Powers)Spell->powerType) < CalculatePowerCost(Spell, me, GetSpellSchoolMask(Spell))) return false; - SpellRangeEntry const *TempRange = NULL; - TempRange = GetSpellRangeStore()->LookupEntry(Spell->rangeIndex); - //Spell has invalid range store so we can't use it if (!TempRange) return false; - //Unit is out of range of this spell if (!m_creature->IsInRange(Target,TempRange->minRangeHostile,TempRange->maxRangeHostile)) return false; - return true; } - void CreatureEventAI::ReceiveEmote(Player* pPlayer, uint32 text_emote) { if (bEmptyList) return; - for (std::list::iterator itr = CreatureEventAIList.begin(); itr != CreatureEventAIList.end(); ++itr) { if ((*itr).Event.event_type == EVENT_T_RECEIVE_EMOTE) { if ((*itr).Event.receive_emote.emoteId != text_emote) return; - PlayerCondition pcon((*itr).Event.receive_emote.condition,(*itr).Event.receive_emote.conditionValue1,(*itr).Event.receive_emote.conditionValue2); if (pcon.Meets(pPlayer)) { @@ -1336,7 +1169,6 @@ void CreatureEventAI::ReceiveEmote(Player* pPlayer, uint32 text_emote) } } } - void CreatureEventAI::DamageTaken( Unit* done_by, uint32& damage ) { if(InvinceabilityHpLevel > 0 && m_creature->GetHealth() < InvinceabilityHpLevel+damage) @@ -1347,12 +1179,10 @@ void CreatureEventAI::DamageTaken( Unit* done_by, uint32& damage ) damage = m_creature->GetHealth() - InvinceabilityHpLevel; } } - bool CreatureEventAI::SpawnedEventConditionsCheck(CreatureEventAI_Event const& event) { if(event.event_type != EVENT_T_SPAWNED) return false; - switch (event.spawned.condition) { case SPAWNED_EVENT_ALWAY: @@ -1371,6 +1201,5 @@ bool CreatureEventAI::SpawnedEventConditionsCheck(CreatureEventAI_Event const& e default: break; } - return false; } diff --git a/src/game/CreatureEventAI.h b/src/game/CreatureEventAI.h index 7882e7542ec..b26dfe2e055 100644 --- a/src/game/CreatureEventAI.h +++ b/src/game/CreatureEventAI.h @@ -15,22 +15,17 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef MANGOS_CREATURE_EAI_H #define MANGOS_CREATURE_EAI_H - #include "Common.h" #include "Creature.h" #include "CreatureAI.h" #include "Unit.h" - class Player; class WorldObject; - #define EVENT_UPDATE_TIME 500 #define MAX_ACTIONS 3 #define MAX_PHASE 32 - enum EventAI_Type { EVENT_T_TIMER = 0, // InitialMin, InitialMax, RepeatMin, RepeatMax @@ -58,10 +53,8 @@ enum EventAI_Type EVENT_T_RECEIVE_EMOTE = 22, // EmoteId, Condition, CondValue1, CondValue2 EVENT_T_BUFFED = 23, // Param1 = SpellID, Param2 = Number of Time STacked, Param3/4 Repeat Min/Max EVENT_T_TARGET_BUFFED = 24, // Param1 = SpellID, Param2 = Number of Time STacked, Param3/4 Repeat Min/Max - EVENT_T_END, }; - enum EventAI_ActionType { ACTION_T_NONE = 0, // No action @@ -105,44 +98,35 @@ enum EventAI_ActionType ACTION_T_ZONE_COMBAT_PULSE = 38, // No Params ACTION_T_CALL_FOR_HELP = 39, // Radius ACTION_T_SET_SHEATH = 40, // Sheath (0-passive,1-melee,2-ranged) - ACTION_T_SET_ACTIVE = 101, //Apply ACTION_T_SET_AGGRESSIVE = 102, //Apply ACTION_T_ATTACK_START_PULSE = 103, //Distance ACTION_T_SUMMON_GO = 104, //GameObjectID, DespawnTime in ms - ACTION_T_FORCE_DESPAWN = 41, // No Params ACTION_T_END = 105, ACTION_T_SET_INVINCIBILITY_HP_LEVEL = 42, // MinHpValue, format(0-flat,1-percent from max health) }; - enum Target { //Self (m_creature) TARGET_T_SELF = 0, //Self cast - //Hostile targets (if pet then returns pet owner) TARGET_T_HOSTILE, //Our current target (ie: highest aggro) TARGET_T_HOSTILE_SECOND_AGGRO, //Second highest aggro (generaly used for cleaves and some special attacks) TARGET_T_HOSTILE_LAST_AGGRO, //Dead last on aggro (no idea what this could be used for) TARGET_T_HOSTILE_RANDOM, //Just any random target on our threat list TARGET_T_HOSTILE_RANDOM_NOT_TOP, //Any random target except top threat - //Invoker targets (if pet then returns pet owner) TARGET_T_ACTION_INVOKER, //Unit who caused this Event to occur (only works for EVENT_T_AGGRO, EVENT_T_KILL, EVENT_T_DEATH, EVENT_T_SPELLHIT, EVENT_T_OOC_LOS, EVENT_T_FRIENDLY_HP, EVENT_T_FRIENDLY_IS_CC, EVENT_T_FRIENDLY_MISSING_BUFF) - //Hostile targets (including pets) TARGET_T_HOSTILE_WPET, //Current target (can be a pet) TARGET_T_HOSTILE_WPET_SECOND_AGGRO, //Second highest aggro (generaly used for cleaves and some special attacks) TARGET_T_HOSTILE_WPET_LAST_AGGRO, //Dead last on aggro (no idea what this could be used for) TARGET_T_HOSTILE_WPET_RANDOM, //Just any random target on our threat list TARGET_T_HOSTILE_WPET_RANDOM_NOT_TOP, //Any random target except top threat - TARGET_T_ACTION_INVOKER_WPET, - TARGET_T_END }; - enum CastFlags { CAST_INTURRUPT_PREVIOUS = 0x01, //Interrupt any spell casting @@ -152,7 +136,6 @@ enum CastFlags CAST_FORCE_TARGET_SELF = 0x10, //Forces the target to cast this spell on itself CAST_AURA_NOT_PRESENT = 0x20, //Only casts the spell if the target does not have an aura from the spell }; - enum EventFlags { EFLAG_REPEATABLE = 0x01, //Event repeats @@ -164,14 +147,12 @@ enum EventFlags EFLAG_RESERVED_6 = 0x40, EFLAG_DEBUG_ONLY = 0x80, //Event only occurs in debug build }; - enum SpawnedEventMode { SPAWNED_EVENT_ALWAY = 0, SPAWNED_EVENT_MAP = 1, SPAWNED_EVENT_ZONE = 2 }; - // String text additional data, used in (CreatureEventAI) struct StringTextData { @@ -182,7 +163,6 @@ struct StringTextData }; // Text Maps typedef UNORDERED_MAP CreatureEventAI_TextMap; - struct CreatureEventAI_Action { EventAI_ActionType type: 16; @@ -395,19 +375,14 @@ struct CreatureEventAI_Action } raw; }; }; - struct CreatureEventAI_Event { uint32 event_id; - uint32 creature_id; - uint32 event_inverse_phase_mask; - EventAI_Type event_type : 16; uint8 event_chance : 8; uint8 event_flags : 8; - union { // EVENT_T_TIMER = 0 @@ -526,7 +501,6 @@ struct CreatureEventAI_Event uint32 repeatMin; uint32 repeatMax; } buffed; - // RAW struct { @@ -536,41 +510,32 @@ struct CreatureEventAI_Event uint32 param4; } raw; }; - CreatureEventAI_Action action[MAX_ACTIONS]; }; //Event_Map typedef UNORDERED_MAP > CreatureEventAI_Event_Map; - struct CreatureEventAI_Summon { uint32 id; - float position_x; float position_y; float position_z; float orientation; uint32 SpawnTimeSecs; }; - //EventSummon_Map typedef UNORDERED_MAP CreatureEventAI_Summon_Map; - struct CreatureEventAIHolder { CreatureEventAIHolder(CreatureEventAI_Event p) : Event(p), Time(0), Enabled(true){} - CreatureEventAI_Event Event; uint32 Time; bool Enabled; - // helper bool UpdateRepeatTimer(Creature* creature, uint32 repeatMin, uint32 repeatMax); }; - class TRINITY_DLL_SPEC CreatureEventAI : public CreatureAI { - public: explicit CreatureEventAI(Creature *c); ~CreatureEventAI() @@ -592,29 +557,23 @@ class TRINITY_DLL_SPEC CreatureEventAI : public CreatureAI void UpdateAI(const uint32 diff); void ReceiveEmote(Player* pPlayer, uint32 text_emote); static int Permissible(const Creature *); - bool ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pActionInvoker = NULL); void ProcessAction(CreatureEventAI_Action const& action, uint32 rnd, uint32 EventId, Unit* pActionInvoker); inline uint32 GetRandActionParam(uint32 rnd, uint32 param1, uint32 param2, uint32 param3); inline int32 GetRandActionParam(uint32 rnd, int32 param1, int32 param2, int32 param3); inline Unit* GetTargetByType(uint32 Target, Unit* pActionInvoker); inline Unit* SelectUnit(AttackingTarget target, uint32 position); - void DoScriptText(int32 textEntry, WorldObject* pSource, Unit* target); bool CanCast(Unit* Target, SpellEntry const *Spell, bool Triggered); - bool SpawnedEventConditionsCheck(CreatureEventAI_Event const& event); - Unit* DoSelectLowestHpFriendly(float range, uint32 MinHPDiff); void DoFindFriendlyMissingBuff(std::list& _list, float range, uint32 spellid); void DoFindFriendlyCC(std::list& _list, float range); - //Holder for events (stores enabled, time, and eventid) std::list CreatureEventAIList; uint32 EventUpdateTime; //Time between event updates uint32 EventDiff; //Time between the last event call bool bEmptyList; - //Variables used by Events themselves uint8 Phase; // Current phase, max 32 phases bool CombatMovementEnabled; // If we allow targeted movment gen (movement twoards top threat) diff --git a/src/game/CreatureEventAIMgr.cpp b/src/game/CreatureEventAIMgr.cpp index 5325edff4a9..18c4ca97de4 100644 --- a/src/game/CreatureEventAIMgr.cpp +++ b/src/game/CreatureEventAIMgr.cpp @@ -15,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "Common.h" #include "Database/DatabaseEnv.h" #include "Database/SQLStorage.h" @@ -26,77 +25,61 @@ #include "Policies/SingletonImp.h" #include "ObjectDefines.h" #include "GridDefines.h" - INSTANTIATE_SINGLETON_1(CreatureEventAIMgr); - // ------------------- void CreatureEventAIMgr::LoadCreatureEventAI_Texts() { // Drop Existing Text Map, only done once and we are ready to add data from multiple sources. m_CreatureEventAI_TextMap.clear(); - // Load EventAI Text objmgr.LoadTrinityStrings(WorldDatabase,"creature_ai_texts",MIN_CREATURE_AI_TEXT_STRING_ID,MAX_CREATURE_AI_TEXT_STRING_ID); - // Gather Additional data from EventAI Texts QueryResult *result = WorldDatabase.Query("SELECT entry, sound, type, language, emote FROM creature_ai_texts"); - sLog.outString("Loading EventAI Texts additional data..."); if (result) { barGoLink bar(result->GetRowCount()); uint32 count = 0; - do { bar.step(); Field* fields = result->Fetch(); StringTextData temp; - int32 i = fields[0].GetInt32(); temp.SoundId = fields[1].GetInt32(); temp.Type = fields[2].GetInt32(); temp.Language = fields[3].GetInt32(); temp.Emote = fields[4].GetInt32(); - // range negative if (i > MIN_CREATURE_AI_TEXT_STRING_ID || i <= MAX_CREATURE_AI_TEXT_STRING_ID) { sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` is not in valid range(%d-%d)",i,MIN_CREATURE_AI_TEXT_STRING_ID,MAX_CREATURE_AI_TEXT_STRING_ID); continue; } - // range negative (don't must be happen, loaded from same table) if (!objmgr.GetTrinityStringLocale(i)) { sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` not found",i); continue; } - if (temp.SoundId) { if (!sSoundEntriesStore.LookupEntry(temp.SoundId)) sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` has Sound %u but sound does not exist.",i,temp.SoundId); } - if (!GetLanguageDescByID(temp.Language)) sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` using Language %u but Language does not exist.",i,temp.Language); - if (temp.Type > CHAT_TYPE_ZONE_YELL) sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` has Type %u but this Chat Type does not exist.",i,temp.Type); - if (temp.Emote) { if (!sEmotesStore.LookupEntry(temp.Emote)) sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` has Emote %u but emote does not exist.",i,temp.Emote); } - m_CreatureEventAI_TextMap[i] = temp; ++count; } while (result->NextRow()); - delete result; - sLog.outString(); sLog.outString(">> Loaded %u additional CreatureEventAI Texts data.", count); } @@ -107,50 +90,39 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Texts() sLog.outString(); sLog.outString(">> Loaded 0 additional CreatureEventAI Texts data. DB table `creature_ai_texts` is empty."); } - } - // ------------------- void CreatureEventAIMgr::LoadCreatureEventAI_Summons() { - //Drop Existing EventSummon Map m_CreatureEventAI_Summon_Map.clear(); - // Gather additional data for EventAI QueryResult *result = WorldDatabase.Query("SELECT id, position_x, position_y, position_z, orientation, spawntimesecs FROM creature_ai_summons"); if (result) { barGoLink bar(result->GetRowCount()); uint32 Count = 0; - do { bar.step(); Field *fields = result->Fetch(); - CreatureEventAI_Summon temp; - uint32 i = fields[0].GetUInt32(); temp.position_x = fields[1].GetFloat(); temp.position_y = fields[2].GetFloat(); temp.position_z = fields[3].GetFloat(); temp.orientation = fields[4].GetFloat(); temp.SpawnTimeSecs = fields[5].GetUInt32(); - if(!MaNGOS::IsValidMapCoord(temp.position_x,temp.position_y,temp.position_z,temp.orientation)) { sLog.outErrorDb("CreatureEventAI: Summon id %u have wrong coordinates (%f,%f,%f,%f), skipping.", i,temp.position_x,temp.position_y,temp.position_z,temp.orientation); continue; } - //Add to map m_CreatureEventAI_Summon_Map[i] = temp; ++Count; } while (result->NextRow()); - delete result; - sLog.outString(); sLog.outString(">> Loaded %u CreatureEventAI summon definitions", Count); } @@ -161,15 +133,12 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Summons() sLog.outString(); sLog.outString(">> Loaded 0 CreatureEventAI Summon definitions. DB table `creature_ai_summons` is empty."); } - } - // ------------------- void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() { //Drop Existing EventAI List m_CreatureEventAI_Event_Map.clear(); - // Gather event data QueryResult *result = WorldDatabase.Query("SELECT id, creature_id, event_type, event_inverse_phase_mask, event_chance, event_flags, " "event_param1, event_param2, event_param3, event_param4, " @@ -181,19 +150,15 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() { barGoLink bar(result->GetRowCount()); uint32 Count = 0; - do { bar.step(); Field *fields = result->Fetch(); - CreatureEventAI_Event temp; temp.event_id = EventAI_Type(fields[0].GetUInt32()); uint32 i = temp.event_id; - temp.creature_id = fields[1].GetUInt32(); uint32 creature_id = temp.creature_id; - uint32 e_type = fields[2].GetUInt32(); //Report any errors in event if (e_type >= EVENT_T_END) @@ -202,7 +167,6 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() continue; } temp.event_type = EventAI_Type(e_type); - temp.event_inverse_phase_mask = fields[3].GetUInt32(); temp.event_chance = fields[4].GetUInt8(); temp.event_flags = fields[5].GetUInt8(); @@ -210,14 +174,12 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() temp.raw.param2 = fields[7].GetUInt32(); temp.raw.param3 = fields[8].GetUInt32(); temp.raw.param4 = fields[9].GetUInt32(); - //Creature does not exist in database if (!sCreatureStorage.LookupEntry(temp.creature_id)) { sLog.outErrorDb("CreatureEventAI: Event %u has script for non-existing creature entry (%u), skipping.", i, temp.creature_id); continue; } - //No chance of this event occuring if (temp.event_chance == 0) sLog.outErrorDb("CreatureEventAI: Event %u has 0 percent chance. Event will never trigger!", i); @@ -227,7 +189,6 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() sLog.outErrorDb("CreatureEventAI: Creature %u are using event %u with more than 100 percent chance. Adjusting to 100 percent.", temp.creature_id, i); temp.event_chance = 100; } - //Individual event checks switch (temp.event_type) { @@ -244,10 +205,8 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() case EVENT_T_TARGET_MANA: if (temp.percent_range.percentMax > 100) sLog.outErrorDb("CreatureEventAI: Creature %u are using percentage event(%u) with param2 (MinPercent) > 100. Event will never trigger! ", temp.creature_id, i); - if (temp.percent_range.percentMax <= temp.percent_range.percentMin) sLog.outErrorDb("CreatureEventAI: Creature %u are using percentage event(%u) with param1 <= param2 (MaxPercent <= MinPercent). Event will never trigger! ", temp.creature_id, i); - if (temp.event_flags & EFLAG_REPEATABLE && !temp.percent_range.repeatMin && !temp.percent_range.repeatMax) { sLog.outErrorDb("CreatureEventAI: Creature %u has param3 and param4=0 (RepeatMin/RepeatMax) but cannot be repeatable without timers. Removing EFLAG_REPEATABLE for event %u.", temp.creature_id, i); @@ -263,14 +222,11 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() sLog.outErrorDb("CreatureEventAI: Creature %u has non-existant SpellID(%u) defined in event %u.", temp.creature_id, temp.spell_hit.spellId, i); continue; } - if ((temp.spell_hit.schoolMask & pSpell->SchoolMask) != pSpell->SchoolMask) sLog.outErrorDb("CreatureEventAI: Creature %u has param1(spellId %u) but param2 is not -1 and not equal to spell's school mask. Event %u can never trigger.", temp.creature_id, temp.spell_hit.schoolMask, i); } - if (!temp.spell_hit.schoolMask) sLog.outErrorDb("CreatureEventAI: Creature %u is using invalid SpellSchoolMask(%u) defined in event %u.", temp.creature_id, temp.spell_hit.schoolMask, i); - if (temp.spell_hit.repeatMax < temp.spell_hit.repeatMin) sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i); break; @@ -341,7 +297,6 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with not existed qyest id (%u) in param1, skipped.", temp.creature_id, i, temp.quest.questId); sLog.outErrorDb("CreatureEventAI: Creature %u using not implemented event (%u) in event %u.", temp.creature_id, temp.event_id, i); continue; - case EVENT_T_AGGRO: case EVENT_T_DEATH: case EVENT_T_EVADE: @@ -352,10 +307,8 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() sLog.outErrorDb("CreatureEventAI: Creature %u has EFLAG_REPEATABLE set. Event can never be repeatable. Removing flag for event %u.", temp.creature_id, i); temp.event_flags &= ~EFLAG_REPEATABLE; } - break; } - case EVENT_T_RECEIVE_EMOTE: { if (!sEmotesTextStore.LookupEntry(temp.receive_emote.emoteId)) @@ -363,22 +316,18 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() sLog.outErrorDb("CreatureEventAI: Creature %u using event %u: param1 (EmoteTextId: %u) are not valid.",temp.creature_id, i, temp.receive_emote.emoteId); continue; } - if (!PlayerCondition::IsValid(ConditionType(temp.receive_emote.condition), temp.receive_emote.conditionValue1, temp.receive_emote.conditionValue2)) { sLog.outErrorDb("CreatureEventAI: Creature %u using event %u: param2 (Condition: %u) are not valid.",temp.creature_id, i, temp.receive_emote.condition); continue; } - if (!(temp.event_flags & EFLAG_REPEATABLE)) { sLog.outErrorDb("CreatureEventAI: Creature %u using event %u: EFLAG_REPEATABLE not set. Event must always be repeatable. Flag applied.", temp.creature_id, i); temp.event_flags |= EFLAG_REPEATABLE; } - break; } - case EVENT_T_BUFFED: case EVENT_T_TARGET_BUFFED: { @@ -392,12 +341,10 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i); break; } - default: sLog.outErrorDb("CreatureEventAI: Creature %u using not checked at load event (%u) in event %u. Need check code update?", temp.creature_id, temp.event_id, i); break; } - for (uint32 j = 0; j < MAX_ACTIONS; j++) { uint16 action_type = fields[10+(j*4)].GetUInt16(); @@ -407,14 +354,11 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() temp.action[j].type = ACTION_T_NONE; continue; } - CreatureEventAI_Action& action = temp.action[j]; - action.type = EventAI_ActionType(action_type); action.raw.param1 = fields[11+(j*4)].GetUInt32(); action.raw.param2 = fields[12+(j*4)].GetUInt32(); action.raw.param3 = fields[13+(j*4)].GetUInt32(); - //Report any errors in actions switch (action.type) { @@ -431,7 +375,6 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() { if (m_CreatureEventAI_TextMap.find(action.text.TextId2) == m_CreatureEventAI_TextMap.end()) sLog.outErrorDb("CreatureEventAI: Event %u Action %u param2 refrences non-existing entry in texts table.", i, j+1); - if (!action.text.TextId1) sLog.outErrorDb("CreatureEventAI: Event %u Action %u has param2, but param1 is not set. Required for randomized text.", i, j+1); } @@ -439,7 +382,6 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() { if (m_CreatureEventAI_TextMap.find(action.text.TextId3) == m_CreatureEventAI_TextMap.end()) sLog.outErrorDb("CreatureEventAI: Event %u Action %u param3 refrences non-existing entry in texts table.", i, j+1); - if (!action.text.TextId1 || !action.text.TextId2) sLog.outErrorDb("CreatureEventAI: Event %u Action %u has param3, but param1 and/or param2 is not set. Required for randomized text.", i, j+1); } @@ -460,7 +402,6 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant Creature entry %u.", i, j+1, action.morph.creatureId); action.morph.creatureId = 0; } - if (action.morph.modelId) { if (action.morph.creatureId) @@ -516,11 +457,9 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() } } */ - //Cast is always triggered if target is forced to cast on self if (action.cast.castFlags & CAST_FORCE_TARGET_SELF) action.cast.castFlags |= CAST_TRIGGERED; - if (action.cast.target >= TARGET_T_END) sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1); break; @@ -528,7 +467,6 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() case ACTION_T_SUMMON: if (!sCreatureStorage.LookupEntry(action.summon.creatureId)) sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent creature entry %u.", i, j+1, action.summon.creatureId); - if (action.summon.target >= TARGET_T_END) sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1); break; @@ -550,10 +488,8 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() } else sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent Quest entry %u.", i, j+1, action.quest_event.questId); - if (action.quest_event.target >= TARGET_T_END) sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1); - break; case ACTION_T_CAST_EVENT: if (!sCreatureStorage.LookupEntry(action.cast_event.creatureId)) @@ -682,29 +618,24 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() case ACTION_T_RANGED_MOVEMENT: //Distance, Angle case ACTION_T_CALL_FOR_HELP: //Distance break; - case ACTION_T_RANDOM_SAY: case ACTION_T_RANDOM_YELL: case ACTION_T_RANDOM_TEXTEMOTE: sLog.outErrorDb("CreatureEventAI: Event %u Action %u currently unused ACTION type. Did you forget to update database?", i, j+1); break; - case ACTION_T_SET_ACTIVE: case ACTION_T_SET_AGGRESSIVE: case ACTION_T_ATTACK_START_PULSE: case ACTION_T_SUMMON_GO: break; - default: sLog.outErrorDb("CreatureEventAI: Event %u Action %u have currently not checked at load action type (%u). Need check code update?", i, j+1, temp.action[j].type); break; } } - //Add to list m_CreatureEventAI_Event_Map[creature_id].push_back(temp); ++Count; - if(CreatureInfo const* cInfo = sCreatureStorage.LookupEntry(temp.creature_id)) { if(!cInfo->AIName || !cInfo->AIName[0]) @@ -722,11 +653,9 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() { //sLog.outErrorDb("CreatureEventAI: Creature Entry %u has EventAI script but it also has C++ script. EventAI script will be overriden.", cInfo->Entry); } - } + } } while (result->NextRow()); - delete result; - sLog.outString(); sLog.outString(">> Loaded %u CreatureEventAI scripts", Count); } diff --git a/src/game/CreatureEventAIMgr.h b/src/game/CreatureEventAIMgr.h index b4672460cc6..821cdb35c6a 100644 --- a/src/game/CreatureEventAIMgr.h +++ b/src/game/CreatureEventAIMgr.h @@ -15,32 +15,25 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef MANGOS_CREATURE_EAI_MGR_H #define MANGOS_CREATURE_EAI_MGR_H - #include "Common.h" #include "CreatureEventAI.h" - class CreatureEventAIMgr { public: CreatureEventAIMgr(){}; ~CreatureEventAIMgr(){}; - void LoadCreatureEventAI_Texts(); void LoadCreatureEventAI_Summons(); void LoadCreatureEventAI_Scripts(); - CreatureEventAI_Event_Map const& GetCreatureEventAIMap() const { return m_CreatureEventAI_Event_Map; } CreatureEventAI_Summon_Map const& GetCreatureEventAISummonMap() const { return m_CreatureEventAI_Summon_Map; } CreatureEventAI_TextMap const& GetCreatureEventAITextMap() const { return m_CreatureEventAI_TextMap; } - private: CreatureEventAI_Event_Map m_CreatureEventAI_Event_Map; CreatureEventAI_Summon_Map m_CreatureEventAI_Summon_Map; CreatureEventAI_TextMap m_CreatureEventAI_TextMap; }; - #define CreatureEAI_Mgr MaNGOS::Singleton::Instance() #endif diff --git a/src/game/CreatureGroups.cpp b/src/game/CreatureGroups.cpp index 97610754e69..c0816f36804 100644 --- a/src/game/CreatureGroups.cpp +++ b/src/game/CreatureGroups.cpp @@ -17,28 +17,21 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "Creature.h" #include "CreatureGroups.h" #include "ObjectMgr.h" #include "ProgressBar.h" #include "Policies/SingletonImp.h" #include "CreatureAI.h" - #define MAX_DESYNC 5.0f - INSTANTIATE_SINGLETON_1(CreatureGroupManager); - CreatureGroupInfoType CreatureGroupMap; - void CreatureGroupManager::AddCreatureToGroup(uint32 groupId, Creature *member) { Map *map = member->FindMap(); if(!map) return; - CreatureGroupHolderType::iterator itr = map->CreatureGroupHolder.find(groupId); - //Add member to an existing group if(itr != map->CreatureGroupHolder.end()) { @@ -54,58 +47,47 @@ void CreatureGroupManager::AddCreatureToGroup(uint32 groupId, Creature *member) group->AddMember(member); } } - void CreatureGroupManager::RemoveCreatureFromGroup(CreatureGroup *group, Creature *member) { sLog.outDebug("Deleting member pointer to GUID: %u from group %u", group->GetId(), member->GetDBTableGUIDLow()); group->RemoveMember(member); - if(group->isEmpty()) { Map *map = member->FindMap(); if(!map) return; - sLog.outDebug("Deleting group with InstanceID %u", member->GetInstanceId()); map->CreatureGroupHolder.erase(group->GetId()); delete group; } } - void CreatureGroupManager::LoadCreatureFormations() { //Clear existing map CreatureGroupMap.clear(); - //Check Integrity of the table QueryResult *result = WorldDatabase.PQuery("SELECT MAX(leaderGUID) FROM creature_formations"); - if(!result) { sLog.outErrorDb(" ...an error occured while loading the table creature_formations ( maybe it doesn't exist ?)\n"); return; } delete result; - //Get group data result = WorldDatabase.PQuery("SELECT leaderGUID, memberGUID, dist, angle, groupAI FROM creature_formations ORDER BY leaderGUID"); - if(!result) { sLog.outErrorDb("The table creature_formations is empty or corrupted"); return; } - uint32 total_records = result->GetRowCount(); barGoLink bar( total_records); Field *fields; - FormationInfo *group_member; //Loading data... do { fields = result->Fetch(); - bar.step(); //Load group member data group_member = new FormationInfo; @@ -123,7 +105,6 @@ void CreatureGroupManager::LoadCreatureFormations() group_member->follow_dist = 0; group_member->follow_angle = 0; } - // check data correctness { QueryResult* result = WorldDatabase.PQuery("SELECT guid FROM creature WHERE guid = %u", group_member->leaderGUID); @@ -132,7 +113,6 @@ void CreatureGroupManager::LoadCreatureFormations() sLog.outErrorDb("creature_formations table leader guid %u incorrect (not exist)", group_member->leaderGUID); continue; } - result = WorldDatabase.PQuery("SELECT guid FROM creature WHERE guid = %u", memberGUID); if(!result) { @@ -140,71 +120,56 @@ void CreatureGroupManager::LoadCreatureFormations() continue; } } - CreatureGroupMap[memberGUID] = group_member; - } + } while(result->NextRow()) ; - sLog.outString(); sLog.outString( ">> Loaded %u creatures in formations", total_records ); sLog.outString(); //Free some heap delete result; } - void CreatureGroup::AddMember(Creature *member) { sLog.outDebug("CreatureGroup::AddMember: Adding unit GUID: %u.", member->GetGUIDLow()); - //Check if it is a leader if(member->GetDBTableGUIDLow() == m_groupID) { sLog.outDebug("Unit GUID: %u is formation leader. Adding group.", member->GetGUIDLow()); m_leader = member; } - m_members[member] = CreatureGroupMap.find(member->GetDBTableGUIDLow())->second; member->SetFormation(this); } - void CreatureGroup::RemoveMember(Creature *member) { if(m_leader == member) m_leader = NULL; - m_members.erase(member); member->SetFormation(NULL); } - void CreatureGroup::MemberAttackStart(Creature *member, Unit *target) { uint8 groupAI = CreatureGroupMap[member->GetDBTableGUIDLow()]->groupAI; if(!groupAI) return; - if(groupAI == 1 && member != m_leader) return; - for(CreatureGroupMemberType::iterator itr = m_members.begin(); itr != m_members.end(); ++itr) { sLog.outDebug("GROUP ATTACK: group instance id %u calls member instid %u", m_leader->GetInstanceId(), member->GetInstanceId()); //sLog.outDebug("AI:%u:Group member found: %u, attacked by %s.", groupAI, itr->second->GetGUIDLow(), member->getVictim()->GetName()); - //Skip one check if(itr->first == member) continue; - if(!itr->first->isAlive()) continue; - if(itr->first->getVictim()) continue; - if(itr->first->canAttack(target)) itr->first->AI()->AttackStart(target); } } - void CreatureGroup::FormationReset(bool dismiss) { for(CreatureGroupMemberType::iterator itr = m_members.begin(); itr != m_members.end(); ++itr) @@ -220,37 +185,28 @@ void CreatureGroup::FormationReset(bool dismiss) } m_Formed = !dismiss; } - void CreatureGroup::LeaderMoveTo(float x, float y, float z) { if(!m_leader) return; - float pathangle = atan2(m_leader->GetPositionY() - y, m_leader->GetPositionX() - x); - for(CreatureGroupMemberType::iterator itr = m_members.begin(); itr != m_members.end(); ++itr) { Creature *member = itr->first; if(member == m_leader || !member->isAlive() || member->getVictim()) continue; - float angle = itr->second->follow_angle; - float dist = itr->second->follow_dist; - + float dist = itr->second->follow_dist; float dx = x + cos(angle + pathangle) * dist; float dy = y + sin(angle + pathangle) * dist; float dz = z; - Trinity::NormalizeMapCoord(dx); Trinity::NormalizeMapCoord(dy); - member->UpdateGroundPositionZ(dx, dy, dz); - if(member->IsWithinDist(m_leader, dist + MAX_DESYNC)) member->SetUnitMovementFlags(m_leader->GetUnitMovementFlags()); else member->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); - member->GetMotionMaster()->MovePoint(0, dx, dy, dz); member->SetHomePosition(dx, dy, dz, pathangle); } diff --git a/src/game/CreatureGroups.h b/src/game/CreatureGroups.h index cc3eacfe185..1cdbc5c3695 100644 --- a/src/game/CreatureGroups.h +++ b/src/game/CreatureGroups.h @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2005-2009 MaNGOS * * Copyright (C) 2008-2009 Trinity @@ -17,22 +17,17 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef _FORMATIONS_H #define _FORMATIONS_H - #include "Common.h" - class CreatureGroup; - struct FormationInfo { uint32 leaderGUID; - float follow_dist; - float follow_angle; + float follow_dist; + float follow_angle; uint8 groupAI; }; - class CreatureGroupManager { public: @@ -40,39 +35,29 @@ class CreatureGroupManager void RemoveCreatureFromGroup(CreatureGroup *group, Creature *creature); void LoadCreatureFormations(); }; - typedef UNORDERED_MAP CreatureGroupInfoType; - extern CreatureGroupInfoType CreatureGroupMap; - class CreatureGroup { private: Creature *m_leader; //Important do not forget sometimes to work with pointers instead synonims :D:D typedef std::map CreatureGroupMemberType; CreatureGroupMemberType m_members; - uint32 m_groupID; bool m_Formed; - public: //Group cannot be created empty explicit CreatureGroup(uint32 id) : m_groupID(id), m_leader(NULL), m_Formed(false) {} ~CreatureGroup() { sLog.outDebug("Destroying group"); } - Creature* getLeader() const { return m_leader; } uint32 GetId() const { return m_groupID; } bool isEmpty() const { return m_members.empty(); } bool isFormed() const { return m_Formed; } - void AddMember(Creature *member); void RemoveMember(Creature *member); void FormationReset(bool dismiss); - void LeaderMoveTo(float x, float y, float z); void MemberAttackStart(Creature* member, Unit *target); }; - #define formation_mgr Trinity::Singleton::Instance() - #endif diff --git a/src/game/DBCEnums.h b/src/game/DBCEnums.h index a0e030bf7cb..21d23dca840 100644 --- a/src/game/DBCEnums.h +++ b/src/game/DBCEnums.h @@ -15,36 +15,29 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef DBCENUMS_H #define DBCENUMS_H - // Client expected level limitation, like as used in DBC item max levels for "until max player level" // use as default max player level, must be fit max level for used client // also see MAX_LEVEL and STRONG_MAX_LEVEL define #define DEFAULT_MAX_LEVEL 80 - // client supported max level for player/pets/etc. Avoid overflow or client stability affected. // also see GT_MAX_LEVEL define #define MAX_LEVEL 100 - // Server side limitation. Base at used code requirements. // also see MAX_LEVEL and GT_MAX_LEVEL define #define STRONG_MAX_LEVEL 255 - enum AreaTeams { AREATEAM_NONE = 0, AREATEAM_ALLY = 2, AREATEAM_HORDE = 4 }; - enum AchievementFactionFlags { ACHIEVEMENT_FACTION_FLAG_HORDE = 0x00000000, ACHIEVEMENT_FACTION_FLAG_ALLIANCE = 0x00000001, }; - enum AchievementFlags { ACHIEVEMENT_FLAG_COUNTER = 0x00000001, // Just count statistic (never stop and complete) @@ -58,7 +51,6 @@ enum AchievementFlags ACHIEVEMENT_FLAG_REALM_FIRST_REACH = 0x00000100, // ACHIEVEMENT_FLAG_REALM_FIRST_KILL = 0x00000200, // }; - enum AchievementCriteriaCondition { ACHIEVEMENT_CRITERIA_CONDITION_NONE = 0, @@ -69,7 +61,6 @@ enum AchievementCriteriaCondition ACHIEVEMENT_CRITERIA_CONDITION_UNK2 = 9, // unk ACHIEVEMENT_CRITERIA_CONDITION_UNK3 = 13, // unk }; - enum AchievementCriteriaCompletionFlags { ACHIEVEMENT_CRITERIA_FLAG_SHOW_PROGRESS_BAR = 0x00000001, // Show progress as bar @@ -79,13 +70,11 @@ enum AchievementCriteriaCompletionFlags ACHIEVEMENT_CRITERIA_FLAG_UNK5 = 0x00000010, // not used ACHIEVEMENT_CRITERIA_FLAG_MONEY_COUNTER = 0x00000020, // Displays counter as money }; - enum AchievementCriteriaGroupFlags { // you mustn't be in a group while fulfilling this achievement ACHIEVEMENT_CRITERIA_GROUP_NOT_IN_GROUP = 2, }; - enum AchievementCriteriaTypes { ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE = 0, @@ -199,7 +188,6 @@ enum AchievementCriteriaTypes // 0..114 => 115 criteria types total ACHIEVEMENT_CRITERIA_TYPE_TOTAL = 115, }; - enum AreaFlags { AREA_FLAG_SNOW = 0x00000001, // snow (only Dun Morogh, Naxxramas, Razorfen Downs and Winterspring) @@ -231,12 +219,10 @@ enum AreaFlags AREA_FLAG_UNK10 = 0x04000000, // unknown AREA_FLAG_OUTDOOR_PVP2 = 0x08000000 // Wintergrasp and it's subzones }; - enum FactionTemplateFlags { FACTION_TEMPLATE_FLAG_CONTESTED_GUARD = 0x00001000, // faction will attack players that were involved in PvP combats }; - enum FactionMasks { FACTION_MASK_PLAYER = 1, // any player @@ -245,7 +231,6 @@ enum FactionMasks FACTION_MASK_MONSTER = 8 // aggressive creature from monster team // if none flags set then non-aggressive creature }; - enum MapTypes { MAP_COMMON = 0, @@ -254,13 +239,11 @@ enum MapTypes MAP_BATTLEGROUND = 3, MAP_ARENA = 4 }; - enum AbilytyLearnType { ABILITY_LEARNED_ON_GET_PROFESSION_SKILL = 1, ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL = 2 }; - enum ItemEnchantmentType { ITEM_ENCHANTMENT_TYPE_NONE = 0, @@ -273,7 +256,6 @@ enum ItemEnchantmentType ITEM_ENCHANTMENT_TYPE_USE_SPELL = 7, ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET = 8 }; - enum TotemCategoryType { TOTEM_CATEGORY_TYPE_KNIFE = 1, @@ -284,7 +266,6 @@ enum TotemCategoryType TOTEM_CATEGORY_TYPE_HAMMER = 23, TOTEM_CATEGORY_TYPE_SPANNER = 24 }; - // SummonProperties.dbc, col 1 enum SummonPropGroup { @@ -294,7 +275,6 @@ enum SummonPropGroup SUMMON_PROP_GROUP_CONTROLLABLE = 3, // 13 spells in 3.0.3, mostly controllable SUMMON_PROP_GROUP_UNKNOWN3 = 4 // 86 spells in 3.0.3, taxi/mounts }; - // SummonProperties.dbc, col 3 enum SummonPropType { @@ -311,7 +291,6 @@ enum SummonPropType SUMMON_PROP_TYPE_DRAKE_VEH = 10, // summon drake (vehicle), 3 spells SUMMON_PROP_TYPE_LIGHTWELL = 11 // summon lightwell, 6 spells in 3.0.3 }; - // SummonProperties.dbc, col 5 enum SummonPropFlags { @@ -331,6 +310,5 @@ enum SummonPropFlags SUMMON_PROP_FLAG_UNK13 = 0x1000, // 8 spells in 3.0.3, siege vehicle SUMMON_PROP_FLAG_UNK14 = 0x2000, // 2 spells in 3.0.3, escort? }; - #endif diff --git a/src/game/DBCStores.cpp b/src/game/DBCStores.cpp index 5dae4cb6e17..fa117a169c0 100644 --- a/src/game/DBCStores.cpp +++ b/src/game/DBCStores.cpp @@ -17,27 +17,21 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "DBCStores.h" #include "Policies/SingletonImp.h" #include "Log.h" #include "ProgressBar.h" #include "SharedDefines.h" #include "SpellMgr.h" - #include "DBCfmt.h" - #include - typedef std::map AreaFlagByAreaID; typedef std::map AreaFlagByMapID; - DBCStorage sAreaStore(AreaTableEntryfmt); DBCStorage sAreaGroupStore(AreaGroupEntryfmt); DBCStorage sAreaPOIStore(AreaPOIEntryfmt); static AreaFlagByAreaID sAreaFlagByAreaID; static AreaFlagByMapID sAreaFlagByMapID; // for instances without generated *.map files - DBCStorage sAchievementStore(Achievementfmt); DBCStorage sAchievementCriteriaStore(AchievementCriteriafmt); DBCStorage sAreaTriggerStore(AreaTriggerEntryfmt); @@ -56,23 +50,18 @@ DBCStorage sCreatureFamilyStore(CreatureFamilyfmt); DBCStorage sCreatureSpellDataStore(CreatureSpellDatafmt); DBCStorage sCreatureTypeStore(CreatureTypefmt); DBCStorage sCurrencyTypesStore(CurrencyTypesfmt); - DBCStorage sDurabilityQualityStore(DurabilityQualityfmt); DBCStorage sDurabilityCostsStore(DurabilityCostsfmt); - DBCStorage sEmotesStore(EmotesEntryfmt); DBCStorage sEmotesTextStore(EmotesTextEntryfmt); - typedef std::map FactionTeamMap; static FactionTeamMap sFactionTeamMap; DBCStorage sFactionStore(FactionEntryfmt); DBCStorage sFactionTemplateStore(FactionTemplateEntryfmt); - DBCStorage sGameObjectDisplayInfoStore(GameObjectDisplayInfofmt); DBCStorage sGemPropertiesStore(GemPropertiesEntryfmt); DBCStorage sGlyphPropertiesStore(GlyphPropertiesfmt); DBCStorage sGlyphSlotStore(GlyphSlotfmt); - DBCStorage sGtBarberShopCostBaseStore(GtBarberShopCostBasefmt); DBCStorage sGtCombatRatingsStore(GtCombatRatingsfmt); DBCStorage sGtChanceToMeleeCritBaseStore(GtChanceToMeleeCritBasefmt); @@ -83,9 +72,7 @@ DBCStorage sGtOCTRegenHPStore(GtOCTRegenHPfmt); //DBCStorage sGtOCTRegenMPStore(GtOCTRegenMPfmt); -- not used currently DBCStorage sGtRegenHPPerSptStore(GtRegenHPPerSptfmt); DBCStorage sGtRegenMPPerSptStore(GtRegenMPPerSptfmt); - DBCStorage sHolidaysStore(Holidaysfmt); - DBCStorage sItemStore(Itemfmt); DBCStorage sItemBagFamilyStore(ItemBagFamilyfmt); //DBCStorage sItemCondExtCostsStore(ItemCondExtCostsEntryfmt); @@ -95,30 +82,22 @@ DBCStorage sItemLimitCategoryStore(ItemLimitCategoryEnt DBCStorage sItemRandomPropertiesStore(ItemRandomPropertiesfmt); DBCStorage sItemRandomSuffixStore(ItemRandomSuffixfmt); DBCStorage sItemSetStore(ItemSetEntryfmt); - DBCStorage sLockStore(LockEntryfmt); - DBCStorage sMailTemplateStore(MailTemplateEntryfmt); DBCStorage sMapStore(MapEntryfmt); DBCStorage sMovieStore(MovieEntryfmt); - DBCStorage sQuestSortStore(QuestSortEntryfmt); - DBCStorage sRandomPropertiesPointsStore(RandomPropertiesPointsfmt); DBCStorage sScalingStatDistributionStore(ScalingStatDistributionfmt); DBCStorage sScalingStatValuesStore(ScalingStatValuesfmt); - DBCStorage sSkillLineStore(SkillLinefmt); DBCStorage sSkillLineAbilityStore(SkillLineAbilityfmt); - DBCStorage sSoundEntriesStore(SoundEntriesfmt); - DBCStorage sSpellItemEnchantmentStore(SpellItemEnchantmentfmt); DBCStorage sSpellItemEnchantmentConditionStore(SpellItemEnchantmentConditionfmt); DBCStorage sSpellStore(SpellEntryfmt); SpellCategoryStore sSpellCategoryStore; PetFamilySpellsStore sPetFamilySpellsStore; - DBCStorage sSpellCastTimesStore(SpellCastTimefmt); DBCStorage sSpellDurationStore(SpellDurationfmt); DBCStorage sSpellFocusObjectStore(SpellFocusObjectfmt); @@ -131,21 +110,16 @@ DBCStorage sSummonPropertiesStore(SummonPropertiesfmt); DBCStorage sTalentStore(TalentEntryfmt); TalentSpellPosMap sTalentSpellPosMap; DBCStorage sTalentTabStore(TalentTabEntryfmt); - // store absolute bit position for first rank for talent inspect static uint32 sTalentTabPages[12/*MAX_CLASSES*/][3]; - DBCStorage sTaxiNodesStore(TaxiNodesEntryfmt); TaxiMask sTaxiNodesMask; TaxiMask sOldContinentsNodesMask; - // DBC used only for initialization sTaxiPathSetBySource at startup. TaxiPathSetBySource sTaxiPathSetBySource; DBCStorage sTaxiPathStore(TaxiPathEntryfmt); - // DBC used only for initialization sTaxiPathSetBySource at startup. TaxiPathNodesByPath sTaxiPathNodesByPath; - static DBCStorage sTaxiPathNodeStore(TaxiPathNodeEntryfmt); DBCStorage sTotemCategoryStore(TotemCategoryEntryfmt); DBCStorage sVehicleStore(VehicleEntryfmt); @@ -153,28 +127,22 @@ DBCStorage sVehicleSeatStore(VehicleSeatEntryfmt); DBCStorage sWorldMapAreaStore(WorldMapAreaEntryfmt); DBCStorage sWorldMapOverlayStore(WorldMapOverlayEntryfmt); DBCStorage sWorldSafeLocsStore(WorldSafeLocsEntryfmt); - typedef std::list StoreProblemList; - static bool LoadDBC_assert_print(uint32 fsize,uint32 rsize, const std::string& filename) { sLog.outError("ERROR: Size of '%s' setted by format string (%u) not equal size of C++ structure (%u).",filename.c_str(),fsize,rsize); - // assert must fail after function call return false; } - template inline void LoadDBC(uint32& availableDbcLocales,barGoLink& bar, StoreProblemList& errlist, DBCStorage& storage, const std::string& dbc_path, const std::string& filename, const std::string * custom_entries = NULL, const std::string * idname = NULL) { // compatibility format and C++ structure sizes assert(DBCFileLoader::GetFormatRecordSize(storage.GetFormat()) == sizeof(T) || LoadDBC_assert_print(DBCFileLoader::GetFormatRecordSize(storage.GetFormat()),sizeof(T),filename)); - std::string dbc_filename = dbc_path + filename; SqlDbc * sql = NULL; if (custom_entries) sql = new SqlDbc(&filename,custom_entries, idname,storage.GetFormat()); - if(storage.Load(dbc_filename.c_str(), sql)) { bar.step(); @@ -182,7 +150,6 @@ inline void LoadDBC(uint32& availableDbcLocales,barGoLink& bar, StoreProblemList { if(!(availableDbcLocales & (1 << i))) continue; - std::string dbc_filename_loc = dbc_path + localeNames[i] + "/" + filename; if(!storage.LoadStringsFrom(dbc_filename_loc.c_str())) availableDbcLocales &= ~(1<DBC records sAreaFlagByAreaID.insert(AreaFlagByAreaID::value_type(uint16(area->ID),area->exploreFlag)); - // fill MapId->DBC records ( skip sub zones and continents ) if(area->zone==0 && area->mapid != 0 && area->mapid != 1 && area->mapid != 530 && area->mapid != 571 ) sAreaFlagByMapID.insert(AreaFlagByMapID::value_type(area->mapid,area->exploreFlag)); } } - LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAchievementStore, dbcPath,"Achievement.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAchievementCriteriaStore, dbcPath,"Achievement_Criteria.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAreaTriggerStore, dbcPath,"AreaTrigger.dbc"); @@ -243,7 +202,6 @@ void LoadDBCStores(const std::string& dataPath) LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBattlemasterListStore, dbcPath,"BattlemasterList.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBarberShopStyleStore, dbcPath,"BarberShopStyle.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCharStartOutfitStore, dbcPath,"CharStartOutfit.dbc"); - LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCharTitlesStore, dbcPath,"CharTitles.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChatChannelsStore, dbcPath,"ChatChannels.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChrClassesStore, dbcPath,"ChrClasses.dbc"); @@ -268,7 +226,6 @@ void LoadDBCStores(const std::string& dataPath) flist.push_back(i); } } - LoadDBC(availableDbcLocales,bar,bad_dbc_files,sFactionTemplateStore, dbcPath,"FactionTemplate.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGameObjectDisplayInfoStore, dbcPath,"GameObjectDisplayInfo.dbc"); for(uint32 i = 0; i < sGameObjectDisplayInfoStore.GetNumRows(); ++i) @@ -283,20 +240,15 @@ void LoadDBCStores(const std::string& dataPath) std::swap(*(float*)(&info->maxZ), *(float*)(&info->minZ)); } } - LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGemPropertiesStore, dbcPath,"GemProperties.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGlyphPropertiesStore, dbcPath,"GlyphProperties.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGlyphSlotStore, dbcPath,"GlyphSlot.dbc"); - LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtBarberShopCostBaseStore,dbcPath,"gtBarberShopCostBase.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtCombatRatingsStore, dbcPath,"gtCombatRatings.dbc"); - LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToMeleeCritBaseStore, dbcPath,"gtChanceToMeleeCritBase.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToMeleeCritStore, dbcPath,"gtChanceToMeleeCrit.dbc"); - LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToSpellCritBaseStore, dbcPath,"gtChanceToSpellCritBase.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToSpellCritStore, dbcPath,"gtChanceToSpellCrit.dbc"); - LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtOCTRegenHPStore, dbcPath,"gtOCTRegenHP.dbc"); //LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtOCTRegenMPStore, dbcPath,"gtOCTRegenMP.dbc"); -- not used currently LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtRegenHPPerSptStore, dbcPath,"gtRegenHPPerSpt.dbc"); @@ -329,16 +281,12 @@ void LoadDBCStores(const std::string& dataPath) if(spell && spell->Category) sSpellCategoryStore[spell->Category].insert(i); } - for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j) { SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j); - if(!skillLine) continue; - SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId); - if(spellInfo && IsPassiveSpell(spellInfo->Id)) { for (uint32 i = 1; i < sCreatureFamilyStore.GetNumRows(); ++i) @@ -346,20 +294,16 @@ void LoadDBCStores(const std::string& dataPath) CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(i); if(!cFamily) continue; - if(skillLine->skillId != cFamily->skillLine[0] && skillLine->skillId != cFamily->skillLine[1]) continue; if(spellInfo->spellLevel) continue; - if(skillLine->learnOnGetSkill != ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL) continue; - sPetFamilySpellsStore[i].insert(spellInfo->Id); } } } - LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellCastTimesStore, dbcPath,"SpellCastTimes.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellDurationStore, dbcPath,"SpellDuration.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellFocusObjectStore, dbcPath,"SpellFocusObject.dbc"); @@ -372,7 +316,6 @@ void LoadDBCStores(const std::string& dataPath) LoadDBC(availableDbcLocales,bar,bad_dbc_files,sStableSlotPricesStore, dbcPath,"StableSlotPrices.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSummonPropertiesStore, dbcPath,"SummonProperties.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTalentStore, dbcPath,"Talent.dbc"); - // create talent spells set for (unsigned int i = 0; i < sTalentStore.GetNumRows(); ++i) { @@ -382,9 +325,7 @@ void LoadDBCStores(const std::string& dataPath) if(talentInfo->RankID[j]) sTalentSpellPosMap[talentInfo->RankID[j]] = TalentSpellPos(i,j); } - LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTalentTabStore, dbcPath,"TalentTab.dbc"); - // prepare fast data access to bit pos of talent ranks for use at inspecting { // now have all max ranks (and then bit amount used for store talent ranks in inspect) @@ -393,27 +334,21 @@ void LoadDBCStores(const std::string& dataPath) TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentTabId ); if(!talentTabInfo) continue; - // prevent memory corruption; otherwise cls will become 12 below if ((talentTabInfo->ClassMask & CLASSMASK_ALL_PLAYABLE)==0) continue; - // store class talent tab pages uint32 cls = 1; for(uint32 m=1;!(m & talentTabInfo->ClassMask) && cls < MAX_CLASSES;m <<=1, ++cls) {} - sTalentTabPages[cls][talentTabInfo->tabpage]=talentTabId; } } - LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiNodesStore, dbcPath,"TaxiNodes.dbc"); - LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiPathStore, dbcPath,"TaxiPath.dbc"); for(uint32 i = 1; i < sTaxiPathStore.GetNumRows(); ++i) if(TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(i)) sTaxiPathSetBySource[entry->from][entry->to] = TaxiPathBySourceAndDestination(entry->ID,entry->price); uint32 pathCount = sTaxiPathStore.GetNumRows(); - //## TaxiPathNode.dbc ## Loaded only for initialization different structures LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiPathNodeStore, dbcPath,"TaxiPathNode.dbc"); // Calculate path nodes count @@ -434,7 +369,6 @@ void LoadDBCStores(const std::string& dataPath) if(TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i)) sTaxiPathNodesByPath[entry->path][entry->index] = TaxiPathNode(entry->mapid,entry->x,entry->y,entry->z,entry->actionFlag,entry->delay); sTaxiPathNodeStore.Clear(); - // Initialize global taxinodes mask // include existed nodes that have at least single not spell base (scripted) path { @@ -444,7 +378,6 @@ void LoadDBCStores(const std::string& dataPath) for(int j=0; j < 3; ++j) if(sInfo->Effect[j]==123 /*SPELL_EFFECT_SEND_TAXI*/) spellPaths.insert(sInfo->EffectMiscValue[j]); - memset(sTaxiNodesMask,0,sizeof(sTaxiNodesMask)); memset(sOldContinentsNodesMask,0,sizeof(sTaxiNodesMask)); for(uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i) @@ -452,7 +385,6 @@ void LoadDBCStores(const std::string& dataPath) TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(i); if(!node) continue; - TaxiPathSetBySource::const_iterator src_i = sTaxiPathSetBySource.find(i); if(src_i!=sTaxiPathSetBySource.end() && !src_i->second.empty()) { @@ -466,29 +398,24 @@ void LoadDBCStores(const std::string& dataPath) break; } } - if(!ok) continue; } - // valid taxi network node uint8 field = (uint8)((i - 1) / 32); uint32 submask = 1<<((i-1)%32); sTaxiNodesMask[field] |= submask; - // old continent node (+ nodes virtually at old continents, check explicitly to avoid loading map files for zone info) if (node->map_id < 2 || i == 82 || i == 83 || i == 93 || i == 94) sOldContinentsNodesMask[field] |= submask; } } - LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTotemCategoryStore, dbcPath,"TotemCategory.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sVehicleStore, dbcPath,"Vehicle.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sVehicleSeatStore, dbcPath,"VehicleSeat.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldMapAreaStore, dbcPath,"WorldMapArea.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldMapOverlayStore, dbcPath,"WorldMapOverlay.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldSafeLocsStore, dbcPath,"WorldSafeLocs.dbc"); - // error checks if(bad_dbc_files.size() >= DBCFilesCount ) { @@ -500,11 +427,9 @@ void LoadDBCStores(const std::string& dataPath) std::string str; for(std::list::iterator i = bad_dbc_files.begin(); i != bad_dbc_files.end(); ++i) str += *i + "\n"; - sLog.outError("\nSome required *.dbc files (%u from %d) not found or not compatible:\n%s",(uint32)bad_dbc_files.size(),DBCFilesCount,str.c_str()); exit(1); } - // Check loaded DBC files proper version if( !sSpellStore.LookupEntry(66530) || // last added spell in 3.1.3 !sMapStore.LookupEntry(624) || // last map added in 3.1.3 @@ -517,11 +442,9 @@ void LoadDBCStores(const std::string& dataPath) sLog.outError("\nYou have _outdated_ DBC files. Please extract correct versions from current using client."); exit(1); } - sLog.outString(); sLog.outString( ">> Initialized %d data stores", DBCFilesCount ); } - SimpleFactionsList const* GetFactionTeamList(uint32 faction, bool &isTeamMember) { for(FactionTeamMap::const_iterator itr = sFactionTeamMap.begin(); itr != sFactionTeamMap.end(); ++itr) @@ -542,7 +465,6 @@ SimpleFactionsList const* GetFactionTeamList(uint32 faction, bool &isTeamMember) } return NULL; } - char* GetPetName(uint32 petfamily, uint32 dbclang) { if(!petfamily) @@ -552,53 +474,41 @@ char* GetPetName(uint32 petfamily, uint32 dbclang) return NULL; return pet_family->Name[dbclang]?pet_family->Name[dbclang]:NULL; } - TalentSpellPos const* GetTalentSpellPos(uint32 spellId) { TalentSpellPosMap::const_iterator itr = sTalentSpellPosMap.find(spellId); if(itr==sTalentSpellPosMap.end()) return NULL; - return &itr->second; } - uint32 GetTalentSpellCost(uint32 spellId) { if(TalentSpellPos const* pos = GetTalentSpellPos(spellId)) return pos->rank+1; - return 0; } - int32 GetAreaFlagByAreaID(uint32 area_id) { AreaFlagByAreaID::iterator i = sAreaFlagByAreaID.find(area_id); if(i == sAreaFlagByAreaID.end()) return -1; - return i->second; } - AreaTableEntry const* GetAreaEntryByAreaID(uint32 area_id) { int32 areaflag = GetAreaFlagByAreaID(area_id); if(areaflag < 0) return NULL; - return sAreaStore.LookupEntry(areaflag ); } - AreaTableEntry const* GetAreaEntryByAreaFlagAndMap(uint32 area_flag,uint32 map_id) { if(area_flag) return sAreaStore.LookupEntry(area_flag); - if(MapEntry const* mapEntry = sMapStore.LookupEntry(map_id)) return GetAreaEntryByAreaID(mapEntry->linked_zone); - return NULL; } - uint32 GetAreaFlagByMapId(uint32 mapid) { AreaFlagByMapID::iterator i = sAreaFlagByMapID.find(mapid); @@ -607,28 +517,22 @@ uint32 GetAreaFlagByMapId(uint32 mapid) else return i->second; } - uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId) { if(mapid != 530 && mapid != 571) // speed for most cases return mapid; - if(WorldMapAreaEntry const* wma = sWorldMapAreaStore.LookupEntry(zoneId)) return wma->virtual_map_id >= 0 ? wma->virtual_map_id : wma->map_id; - return mapid; } - ContentLevels GetContentLevelsForMapAndZone(uint32 mapid, uint32 zoneId) { mapid = GetVirtualMapForMapAndZone(mapid,zoneId); if(mapid < 2) return CONTENT_1_60; - MapEntry const* mapEntry = sMapStore.LookupEntry(mapid); if(!mapEntry) return CONTENT_1_60; - switch(mapEntry->Expansion()) { default: return CONTENT_1_60; @@ -636,7 +540,6 @@ ContentLevels GetContentLevelsForMapAndZone(uint32 mapid, uint32 zoneId) case 2: return CONTENT_71_80; } } - ChatChannelsEntry const* GetChannelEntryFor(uint32 channel_id) { // not sorted, numbering index from 0 @@ -648,58 +551,46 @@ ChatChannelsEntry const* GetChannelEntryFor(uint32 channel_id) } return NULL; } - bool IsTotemCategoryCompatiableWith(uint32 itemTotemCategoryId, uint32 requiredTotemCategoryId) { if(requiredTotemCategoryId==0) return true; if(itemTotemCategoryId==0) return false; - TotemCategoryEntry const* itemEntry = sTotemCategoryStore.LookupEntry(itemTotemCategoryId); if(!itemEntry) return false; TotemCategoryEntry const* reqEntry = sTotemCategoryStore.LookupEntry(requiredTotemCategoryId); if(!reqEntry) return false; - if(itemEntry->categoryType!=reqEntry->categoryType) return false; - return (itemEntry->categoryMask & reqEntry->categoryMask)==reqEntry->categoryMask; } - void Zone2MapCoordinates(float& x,float& y,uint32 zone) { WorldMapAreaEntry const* maEntry = sWorldMapAreaStore.LookupEntry(zone); - // if not listed then map coordinates (instance) if(!maEntry) return; - std::swap(x,y); // at client map coords swapped x = x*((maEntry->x2-maEntry->x1)/100)+maEntry->x1; y = y*((maEntry->y2-maEntry->y1)/100)+maEntry->y1; // client y coord from top to down } - void Map2ZoneCoordinates(float& x,float& y,uint32 zone) { WorldMapAreaEntry const* maEntry = sWorldMapAreaStore.LookupEntry(zone); - // if not listed then map coordinates (instance) if(!maEntry) return; - x = (x-maEntry->x1)/((maEntry->x2-maEntry->x1)/100); y = (y-maEntry->y1)/((maEntry->y2-maEntry->y1)/100); // client y coord from top to down std::swap(x,y); // client have map coords swapped } - uint32 const* GetTalentTabPages(uint32 cls) { return sTalentTabPages[cls]; } - // script support functions TRINITY_DLL_SPEC DBCStorage const* GetSoundEntriesStore() { return &sSoundEntriesStore; } TRINITY_DLL_SPEC DBCStorage const* GetSpellStore() { return &sSpellStore; } diff --git a/src/game/DBCStores.h b/src/game/DBCStores.h index 4fd5b6bcb59..90ac6dd97c8 100644 --- a/src/game/DBCStores.h +++ b/src/game/DBCStores.h @@ -15,30 +15,22 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef MANGOS_DBCSTORES_H #define MANGOS_DBCSTORES_H - #include "Common.h" #include "Database/DBCStore.h" #include "DBCStructure.h" - #include - typedef std::list SimpleFactionsList; - SimpleFactionsList const* GetFactionTeamList(uint32 faction, bool &isTeamMember); char* GetPetName(uint32 petfamily, uint32 dbclang); uint32 GetTalentSpellCost(uint32 spellId); TalentSpellPos const* GetTalentSpellPos(uint32 spellId); - int32 GetAreaFlagByAreaID(uint32 area_id); // -1 if not found AreaTableEntry const* GetAreaEntryByAreaID(uint32 area_id); AreaTableEntry const* GetAreaEntryByAreaFlagAndMap(uint32 area_flag,uint32 map_id); uint32 GetAreaFlagByMapId(uint32 mapid); - uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId); - enum ContentLevels { CONTENT_1_60 = 0, @@ -46,16 +38,11 @@ enum ContentLevels CONTENT_71_80 }; ContentLevels GetContentLevelsForMapAndZone(uint32 mapid, uint32 zoneId); - ChatChannelsEntry const* GetChannelEntryFor(uint32 channel_id); - bool IsTotemCategoryCompatiableWith(uint32 itemTotemCategoryId, uint32 requiredTotemCategoryId); - void Zone2MapCoordinates(float& x,float& y,uint32 zone); void Map2ZoneCoordinates(float& x,float& y,uint32 zone); - uint32 const* /*[3]*/ GetTalentTabPages(uint32 cls); - extern DBCStorage sAchievementStore; extern DBCStorage sAchievementCriteriaStore; extern DBCStorage sAreaStore;// recommend access using functions @@ -87,7 +74,6 @@ extern DBCStorage sGameObjectDisplayInfoStore; extern DBCStorage sGemPropertiesStore; extern DBCStorage sGlyphPropertiesStore; extern DBCStorage sGlyphSlotStore; - extern DBCStorage sGtBarberShopCostBaseStore; extern DBCStorage sGtCombatRatingsStore; extern DBCStorage sGtChanceToMeleeCritBaseStore; @@ -146,9 +132,7 @@ extern DBCStorage sVehicleSeatStore; //extern DBCStorage sWorldMapAreaStore; -- use Zone2MapCoordinates and Map2ZoneCoordinates extern DBCStorage sWorldMapOverlayStore; extern DBCStorage sWorldSafeLocsStore; - void LoadDBCStores(const std::string& dataPath); - // script support functions TRINITY_DLL_SPEC DBCStorage const* GetSoundEntriesStore(); TRINITY_DLL_SPEC DBCStorage const* GetSpellStore(); diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h index 7e459c61e8b..98f4dfd3744 100644 --- a/src/game/DBCStructure.h +++ b/src/game/DBCStructure.h @@ -17,27 +17,21 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #ifndef MANGOS_DBCSTRUCTURE_H #define MANGOS_DBCSTRUCTURE_H - #include "DBCEnums.h" #include "Platform/Define.h" #include "Util.h" - #include #include #include - // Structures using to access raw DBC data and required packing to portability - // GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform #if defined( __GNUC__ ) #pragma pack(1) #else #pragma pack(push,1) #endif - struct AchievementEntry { uint32 ID; // 0 @@ -58,7 +52,6 @@ struct AchievementEntry uint32 count; // 60 - need this count of completed criterias (own or referenced achievement criterias) uint32 refAchievement; // 61 - referenced achievement (counting of all completed criterias) }; - struct AchievementCategoryEntry { uint32 ID; // 0 @@ -67,7 +60,6 @@ struct AchievementCategoryEntry //uint32 name_flags; // 18 //uint32 sortOrder; // 19 }; - struct AchievementCriteriaEntry { uint32 ID; // 0 @@ -82,7 +74,6 @@ struct AchievementCriteriaEntry uint32 creatureID; // 3 uint32 creatureCount; // 4 } kill_creature; - // ACHIEVEMENT_CRITERIA_TYPE_WIN_BG = 1 struct { @@ -93,105 +84,89 @@ struct AchievementCriteriaEntry uint32 additionalRequirement2_type; // 7 additional requirement 2 type uint32 additionalRequirement2_value; // 8 additional requirement 1 value } win_bg; - // ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL = 5 struct { uint32 unused; // 3 uint32 level; // 4 } reach_level; - // ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL = 7 struct { uint32 skillID; // 3 uint32 skillLevel; // 4 } reach_skill_level; - // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT = 8 struct { uint32 linkedAchievement; // 3 } complete_achievement; - // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT = 9 struct { uint32 unused; // 3 uint32 totalQuestCount; // 4 } complete_quest_count; - // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY = 10 struct { uint32 unused; // 3 uint32 numberOfDays; // 4 } complete_daily_quest_daily; - // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE = 11 struct { uint32 zoneID; // 3 uint32 questCount; // 4 } complete_quests_in_zone; - // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST = 14 struct { uint32 unused; // 3 uint32 questCount; // 4 } complete_daily_quest; - // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND = 15 struct { uint32 mapID; // 3 } complete_battleground; - // ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP = 16 struct { uint32 mapID; // 3 } death_at_map; - // ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON = 18 struct { uint32 manLimit; // 3 } death_in_dungeon; - // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID = 19 struct { uint32 groupSize; // 3 can be 5, 10 or 25 } complete_raid; - // ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE = 20 struct { uint32 creatureEntry; // 3 } killed_by_creature; - // ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING = 24 struct { uint32 unused; // 3 uint32 fallHeight; // 4 } fall_without_dying; - // ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM = 26 struct { uint32 type; // 3, see enum EnviromentalDamage } death_from; - // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST = 27 struct { uint32 questID; // 3 uint32 questCount; // 4 } complete_quest; - // ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET = 28 // ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2 = 69 struct @@ -199,7 +174,6 @@ struct AchievementCriteriaEntry uint32 spellID; // 3 uint32 spellCount; // 4 } be_spell_target; - // ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL = 29 // ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2 = 110 struct @@ -207,39 +181,33 @@ struct AchievementCriteriaEntry uint32 spellID; // 3 uint32 castCount; // 4 } cast_spell; - // ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA = 31 struct { uint32 areaID; // 3 Reference to AreaTable.dbc uint32 killCount; // 4 } honorable_kill_at_area; - // ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA = 32 struct { uint32 mapID; // 3 Reference to Map.dbc } win_arena; - // ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA = 33 struct { uint32 mapID; // 3 Reference to Map.dbc } play_arena; - // ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL = 34 struct { uint32 spellID; // 3 Reference to Map.dbc } learn_spell; - // ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM = 36 struct { uint32 itemID; // 3 uint32 itemCount; // 4 } own_item; - // ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA = 37 struct { @@ -247,90 +215,77 @@ struct AchievementCriteriaEntry uint32 count; // 4 uint32 flag; // 5 4=in a row } win_rated_arena; - // ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING = 38 struct { uint32 teamtype; // 3 {2,3,5} } highest_team_rating; - // ACHIEVEMENT_CRITERIA_TYPE_REACH_TEAM_RATING = 39 struct { uint32 teamtype; // 3 {2,3,5} uint32 teamrating; // 4 } reach_team_rating; - // ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL = 40 struct { uint32 skillID; // 3 uint32 skillLevel; // 4 apprentice=1, journeyman=2, expert=3, artisan=4, master=5, grand master=6 } learn_skill_level; - // ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM = 41 struct { uint32 itemID; // 3 uint32 itemCount; // 4 } use_item; - // ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM = 42 struct { uint32 itemID; // 3 uint32 itemCount; // 4 } loot_item; - // ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA = 43 struct { // TODO: This rank is _NOT_ the index from AreaTable.dbc uint32 areaReference; // 3 } explore_area; - // ACHIEVEMENT_CRITERIA_TYPE_OWN_RANK = 44 struct { // TODO: This rank is _NOT_ the index from CharTitles.dbc uint32 rank; // 3 } own_rank; - // ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT = 45 struct { uint32 unused; // 3 uint32 numberOfSlots; // 4 } buy_bank_slot; - // ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION = 46 struct { uint32 factionID; // 3 uint32 reputationAmount; // 4 Total reputation amount, so 42000 = exalted } gain_reputation; - // ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION= 47 struct { uint32 unused; // 3 uint32 numberOfExaltedFactions; // 4 } gain_exalted_reputation; - // ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP = 48 struct { uint32 unused; // 3 uint32 numberOfVisits; // 4 } visit_barber; - // ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM = 49 // TODO: where is the required itemlevel stored? struct { uint32 itemSlot; // 3 } equip_epic_item; - // ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT = 50 struct { @@ -343,21 +298,18 @@ struct AchievementCriteriaEntry uint32 rollValue; // 3 uint32 count; // 4 } roll_greed_on_loot; - // ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS = 52 struct { uint32 classID; // 3 uint32 count; // 4 } hk_class; - // ACHIEVEMENT_CRITERIA_TYPE_HK_RACE = 53 struct { uint32 raceID; // 3 uint32 count; // 4 } hk_race; - // ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE = 54 // TODO: where is the information about the target stored? struct @@ -375,14 +327,12 @@ struct AchievementCriteriaEntry uint32 flag; // 5 =3 for battleground healing uint32 mapid; // 6 } healing_done; - // ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM = 57 struct { uint32 itemID; // 3 uint32 count; // 4 } equip_item; - // ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD= 62 struct { @@ -390,21 +340,18 @@ struct AchievementCriteriaEntry uint32 goldInCopper; // 4 } quest_reward_money; - // ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY = 67 struct { uint32 unused; // 3 uint32 goldInCopper; // 4 } loot_money; - // ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT = 68 struct { uint32 goEntry; // 3 uint32 useCount; // 4 } use_gameobject; - // ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL = 70 // TODO: are those special criteria stored in the dbc or do we have to add another sql table? struct @@ -412,73 +359,62 @@ struct AchievementCriteriaEntry uint32 unused; // 3 uint32 killCount; // 4 } special_pvp_kill; - // ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT = 72 struct { uint32 goEntry; // 3 uint32 lootCount; // 4 } fish_in_gameobject; - // ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS = 75 struct { uint32 skillLine; // 3 uint32 spellCount; // 4 } learn_skillline_spell; - // ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL = 76 struct { uint32 unused; // 3 uint32 duelCount; // 4 } win_duel; - // ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_POWER = 96 struct { uint32 powerType; // 3 mana=0, 1=rage, 3=energy, 6=runic power } highest_power; - // ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_STAT = 97 struct { uint32 statType; // 3 4=spirit, 3=int, 2=stamina, 1=agi, 0=strength } highest_stat; - // ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_SPELLPOWER = 98 struct { uint32 spellSchool; // 3 } highest_spellpower; - // ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_RATING = 100 struct { uint32 ratingType; // 3 } highest_rating; - // ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE = 109 struct { uint32 lootType; // 3 3=fishing, 2=pickpocket, 4=disentchant uint32 lootTypeCount; // 4 } loot_type; - // ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE = 112 struct { uint32 skillLine; // 3 uint32 spellCount; // 4 } learn_skill_line; - // ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL = 113 struct { uint32 unused; // 3 uint32 killCount; // 4 } honorable_kill; - struct { uint32 field3; // 3 main requirement @@ -499,7 +435,6 @@ struct AchievementCriteriaEntry uint32 timeLimit; // 29 time limit in seconds //uint32 showOrder; // 30 show order }; - struct AreaTableEntry { uint32 ID; // 0 @@ -512,7 +447,6 @@ struct AreaTableEntry char* area_name[16]; // 11-26 // 27, string flags, unused uint32 team; // 28 - // helpers bool IsSanctuary() const { @@ -521,14 +455,12 @@ struct AreaTableEntry return (flags & AREA_FLAG_SANCTUARY); } }; - struct AreaGroupEntry { uint32 AreaGroupId; // 0 uint32 AreaId[6]; // 1-6 uint32 nextGroup; // 7 index of next group }; - struct AreaPOIEntry { uint32 id; //0 @@ -546,7 +478,6 @@ struct AreaPOIEntry uint32 worldState; //52 //uint32 val2; //53 }; - struct AreaTriggerEntry { uint32 id; // 0 m_ID @@ -560,7 +491,6 @@ struct AreaTriggerEntry float box_z; // 8 m_box_heigh float box_orientation; // 9 m_box_yaw }; - struct AuctionHouseEntry { uint32 houseId; // 0 index @@ -570,13 +500,11 @@ struct AuctionHouseEntry //char* name[16]; // 4-19 // 20 string flag, unused }; - struct BankBagSlotPricesEntry { uint32 ID; uint32 price; }; - struct BarberShopStyleEntry { uint32 Id; // 0 @@ -590,7 +518,6 @@ struct BarberShopStyleEntry uint32 gender; // 38 0 -> male, 1 -> female uint32 hair_id; // 39 real ID to hair/facial hair }; - struct BattlemasterListEntry { uint32 id; // 0 @@ -607,9 +534,7 @@ struct BattlemasterListEntry // 33 unused //uint32 unk; // 34 new 3.1 }; - #define MAX_OUTFIT_ITEMS 24 - struct CharStartOutfitEntry { //uint32 Id; // 0 @@ -621,7 +546,6 @@ struct CharStartOutfitEntry //uint32 Unknown2; // 39 //uint32 Unknown3; // 40 }; - struct CharTitlesEntry { uint32 ID; // 0, title ids, for example in Quest::GetCharTitleId() @@ -632,7 +556,6 @@ struct CharTitlesEntry // 35 string flag, unused uint32 bit_index; // 36 used in PLAYER_CHOSEN_TITLE and 1<