Merge pull request #15139 from horn/6.x
Core/BattlePets: Basics for Battle Pets
This commit is contained in:
@@ -167,6 +167,56 @@ LOCK TABLES `autobroadcast` WRITE;
|
||||
/*!40000 ALTER TABLE `autobroadcast` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Table structure for table `battle_pets`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `battle_pets`;
|
||||
CREATE TABLE `battle_pets` (
|
||||
`guid` bigint(20) NOT NULL,
|
||||
`battlenetAccountId` int(10) NOT NULL,
|
||||
`species` int(10) NOT NULL,
|
||||
`breed` smallint(5) NOT NULL,
|
||||
`level` smallint(5) NOT NULL DEFAULT '1',
|
||||
`exp` smallint(5) NOT NULL DEFAULT '0',
|
||||
`health` int(10) NOT NULL DEFAULT '1',
|
||||
`quality` tinyint(3) NOT NULL DEFAULT '0',
|
||||
`flags` smallint(5) NOT NULL DEFAULT '0',
|
||||
`name` varchar(12) NOT NULL,
|
||||
PRIMARY KEY (`guid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- Dumping data for table `battle_pets`
|
||||
--
|
||||
|
||||
LOCK TABLES `battle_pets` WRITE;
|
||||
/*!40000 ALTER TABLE `battle_pets` DISABLE KEYS */;
|
||||
/*!40000 ALTER TABLE `battle_pets` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Table structure for table `battle_pet_slots`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `battle_pet_slots`;
|
||||
CREATE TABLE `battle_pet_slots` (
|
||||
`id` tinyint(3) NOT NULL,
|
||||
`battlenetAccountId` int(10) NOT NULL,
|
||||
`battlePetGuid` bigint(20) NOT NULL,
|
||||
`locked` tinyint(3) NOT NULL DEFAULT '1',
|
||||
PRIMARY KEY (`id`,`battlenetAccountId`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- Dumping data for table `battle_pet_slots`
|
||||
--
|
||||
|
||||
LOCK TABLES `battle_pet_slots` WRITE;
|
||||
/*!40000 ALTER TABLE `battle_pet_slots` DISABLE KEYS */;
|
||||
/*!40000 ALTER TABLE `battle_pet_slots` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Table structure for table `battlenet_account_bans`
|
||||
--
|
||||
|
||||
@@ -2523,6 +2523,10 @@ CREATE TABLE `item_instance` (
|
||||
`transmogrification` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`upgradeId` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`enchantIllusion` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`battlePetSpeciesId` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`battlePetBreedData` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`battlePetLevel` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||
`battlePetDisplayId` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`bonusListIDs` text,
|
||||
PRIMARY KEY (`guid`),
|
||||
KEY `idx_owner_guid` (`owner_guid`)
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
--
|
||||
-- Table structure for table `battle_pets`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `battle_pets`;
|
||||
CREATE TABLE `battle_pets` (
|
||||
`guid` bigint(20) NOT NULL,
|
||||
`battlenetAccountId` int(10) NOT NULL,
|
||||
`species` int(10) NOT NULL,
|
||||
`breed` smallint(5) NOT NULL,
|
||||
`level` smallint(5) NOT NULL DEFAULT '1',
|
||||
`exp` smallint(5) NOT NULL DEFAULT '0',
|
||||
`health` int(10) NOT NULL DEFAULT '1',
|
||||
`quality` tinyint(3) NOT NULL DEFAULT '0',
|
||||
`flags` smallint(5) NOT NULL DEFAULT '0',
|
||||
`name` varchar(12) NOT NULL,
|
||||
PRIMARY KEY (`guid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- Table structure for table `battle_pet_slots`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `battle_pet_slots`;
|
||||
CREATE TABLE `battle_pet_slots` (
|
||||
`id` tinyint(3) NOT NULL,
|
||||
`battlenetAccountId` int(10) NOT NULL,
|
||||
`battlePetGuid` bigint(20) NOT NULL,
|
||||
`locked` tinyint(3) NOT NULL DEFAULT '1',
|
||||
PRIMARY KEY (`id`,`battlenetAccountId`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
@@ -0,0 +1,5 @@
|
||||
ALTER TABLE `item_instance`
|
||||
ADD `battlePetSpeciesId` int(10) unsigned NOT NULL DEFAULT '0' AFTER `enchantIllusion`,
|
||||
ADD `battlePetBreedData` int(10) unsigned NOT NULL DEFAULT '0' AFTER `battlePetSpeciesId`,
|
||||
ADD `battlePetLevel` smallint(5) unsigned NOT NULL DEFAULT '0' AFTER `battlePetBreedData`,
|
||||
ADD `battlePetDisplayId` int(10) unsigned NOT NULL DEFAULT '0' AFTER `battlePetLevel`;
|
||||
@@ -0,0 +1,66 @@
|
||||
DELETE FROM `battle_pet_species` WHERE `ID` IN (1449,1636); -- already in BattlePetSpecies.db2
|
||||
|
||||
--
|
||||
-- Table structure for table `battle_pet_breed_quality`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `battle_pet_breed_quality`;
|
||||
CREATE TABLE `battle_pet_breed_quality` (
|
||||
`ID` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`Quality` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`Modifier` int(11) NOT NULL DEFAULT '0',
|
||||
`VerifiedBuild` smallint(6) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`ID`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- Table structure for table `battle_pet_breed_state`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `battle_pet_breed_state`;
|
||||
CREATE TABLE `battle_pet_breed_state` (
|
||||
`ID` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`BreedID` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`State` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`Value` int(11) NOT NULL DEFAULT '0',
|
||||
`VerifiedBuild` smallint(6) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`ID`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- Table structure for table `battle_pet_species_locale`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `battle_pet_species_locale`;
|
||||
CREATE TABLE `battle_pet_species_locale` (
|
||||
`ID` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`locale` varchar(4) NOT NULL,
|
||||
`SourceText` text,
|
||||
`Description` text,
|
||||
`VerifiedBuild` smallint(6) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`ID`,`locale`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- Table structure for table `battle_pet_species_state`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `battle_pet_species_state`;
|
||||
CREATE TABLE `battle_pet_species_state` (
|
||||
`ID` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`SpeciesID` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`State` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`Value` int(11) NOT NULL DEFAULT '0',
|
||||
`VerifiedBuild` smallint(6) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`ID`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- Table structure for table `item_to_battle_pet_species`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `item_to_battle_pet_species`;
|
||||
CREATE TABLE `item_to_battle_pet_species` (
|
||||
`ID` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`BattlePetSpeciesID` int(10) unsigned NOT NULL DEFAULT '0'
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -22,7 +22,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
||||
if (!m_reconnecting)
|
||||
m_stmts.resize(MAX_CHARACTERDATABASE_STATEMENTS);
|
||||
|
||||
#define SelectItemInstanceContent "ii.guid, ii.itemEntry, ii.creatorGuid, ii.giftCreatorGuid, ii.count, ii.duration, ii.charges, ii.flags, ii.enchantments, ii.randomPropertyId, ii.durability, ii.playedTime, ii.text, ii.transmogrification, ii.upgradeId, ii.enchantIllusion, ii.bonusListIDs"
|
||||
#define SelectItemInstanceContent "ii.guid, ii.itemEntry, ii.creatorGuid, ii.giftCreatorGuid, ii.count, ii.duration, ii.charges, ii.flags, ii.enchantments, ii.randomPropertyId, ii.durability, ii.playedTime, ii.text, ii.transmogrification, ii.upgradeId, ii.enchantIllusion, ii.battlePetSpeciesId, ii.battlePetBreedData, ii.battlePetLevel, ii.battlePetDisplayId, ii.bonusListIDs"
|
||||
|
||||
PrepareStatement(CHAR_DEL_QUEST_POOL_SAVE, "DELETE FROM pool_quest_save WHERE pool_id = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_QUEST_POOL_SAVE, "INSERT INTO pool_quest_save (pool_id, quest_id) VALUES (?, ?)", CONNECTION_ASYNC);
|
||||
@@ -159,8 +159,8 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
||||
PrepareStatement(CHAR_DEL_ITEM_BOP_TRADE, "DELETE FROM item_soulbound_trade_data WHERE itemGuid = ? LIMIT 1", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_ITEM_BOP_TRADE, "INSERT INTO item_soulbound_trade_data VALUES (?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_REP_INVENTORY_ITEM, "REPLACE INTO character_inventory (guid, bag, slot, item) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_REP_ITEM_INSTANCE, "REPLACE INTO item_instance (itemEntry, owner_guid, creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text, transmogrification, upgradeId, enchantIllusion, bonusListIDs, guid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_ITEM_INSTANCE, "UPDATE item_instance SET itemEntry = ?, owner_guid = ?, creatorGuid = ?, giftCreatorGuid = ?, count = ?, duration = ?, charges = ?, flags = ?, enchantments = ?, randomPropertyId = ?, durability = ?, playedTime = ?, text = ?, transmogrification = ?, upgradeId = ?, enchantIllusion = ?, bonusListIDs = ? WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_REP_ITEM_INSTANCE, "REPLACE INTO item_instance (itemEntry, owner_guid, creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text, transmogrification, upgradeId, enchantIllusion, battlePetSpeciesId, battlePetBreedData, battlePetLevel, battlePetDisplayId, bonusListIDs, guid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_ITEM_INSTANCE, "UPDATE item_instance SET itemEntry = ?, owner_guid = ?, creatorGuid = ?, giftCreatorGuid = ?, count = ?, duration = ?, charges = ?, flags = ?, enchantments = ?, randomPropertyId = ?, durability = ?, playedTime = ?, text = ?, transmogrification = ?, upgradeId = ?, enchantIllusion = ?, battlePetSpeciesId = ?, battlePetBreedData = ?, battlePetLevel = ?, battlePetDisplayId = ?, bonusListIDs = ? WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_ITEM_INSTANCE_ON_LOAD, "UPDATE item_instance SET duration = ?, flags = ?, durability = ? WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_ITEM_INSTANCE, "DELETE FROM item_instance WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_ITEM_INSTANCE_BY_OWNER, "DELETE FROM item_instance WHERE owner_guid = ?", CONNECTION_ASYNC);
|
||||
|
||||
@@ -47,6 +47,20 @@ void HotfixDatabaseConnection::DoPrepareStatements()
|
||||
" ORDER BY ID DESC", CONNECTION_SYNCH);
|
||||
PREPARE_LOCALE_STMT(HOTFIX_SEL_BARBER_SHOP_STYLE, "SELECT ID, DisplayName_lang, Description_lang FROM barber_shop_style_locale WHERE locale = ?", CONNECTION_SYNCH);
|
||||
|
||||
// BattlePetBreedQuality.db2
|
||||
PrepareStatement(HOTFIX_SEL_BATTLE_PET_BREED_QUALITY, "SELECT ID, Quality, Modifier FROM battle_pet_breed_quality ORDER BY ID DESC", CONNECTION_SYNCH);
|
||||
|
||||
// BattlePetBreedState.db2
|
||||
PrepareStatement(HOTFIX_SEL_BATTLE_PET_BREED_STATE, "SELECT ID, BreedID, State, Value FROM battle_pet_breed_state ORDER BY ID DESC", CONNECTION_SYNCH);
|
||||
|
||||
// BattlePetSpecies.db2
|
||||
PrepareStatement(HOTFIX_SEL_BATTLE_PET_SPECIES, "SELECT ID, CreatureID, IconFileID, SummonSpellID, PetType, Source, Flags, "
|
||||
"SourceText, Description FROM battle_pet_species ORDER BY ID DESC", CONNECTION_SYNCH);
|
||||
PREPARE_LOCALE_STMT(HOTFIX_SEL_BATTLE_PET_SPECIES, "SELECT ID, SourceText, Description FROM battle_pet_species_locale WHERE locale = ?", CONNECTION_SYNCH);
|
||||
|
||||
// BattlePetSpeciesState.db2
|
||||
PrepareStatement(HOTFIX_SEL_BATTLE_PET_SPECIES_STATE, "SELECT ID, SpeciesID, State, Value FROM battle_pet_species_state ORDER BY ID DESC", CONNECTION_SYNCH);
|
||||
|
||||
// BroadcastText.db2
|
||||
PrepareStatement(HOTFIX_SEL_BROADCAST_TEXT, "SELECT ID, Language, MaleText, FemaleText, EmoteID1, EmoteID2, EmoteID3, EmoteDelay1, EmoteDelay2, "
|
||||
"EmoteDelay3, SoundID, UnkEmoteID, Type FROM broadcast_text ORDER BY ID DESC", CONNECTION_SYNCH);
|
||||
@@ -277,6 +291,9 @@ void HotfixDatabaseConnection::DoPrepareStatements()
|
||||
// ItemSpecOverride.db2
|
||||
PrepareStatement(HOTFIX_SEL_ITEM_SPEC_OVERRIDE, "SELECT ID, ItemID, SpecID FROM item_spec_override ORDER BY ID DESC", CONNECTION_SYNCH);
|
||||
|
||||
// ItemToBattlePetSpecies.db2
|
||||
PrepareStatement(HOTFIX_SEL_ITEM_TO_BATTLE_PET_SPECIES, "SELECT ID, BattlePetSpeciesID FROM item_to_battle_pet_species ORDER BY ID DESC", CONNECTION_SYNCH);
|
||||
|
||||
// ItemXBonusTree.db2
|
||||
PrepareStatement(HOTFIX_SEL_ITEM_X_BONUS_TREE, "SELECT ID, ItemID, BonusTreeID FROM item_x_bonus_tree ORDER BY ID DESC", CONNECTION_SYNCH);
|
||||
|
||||
|
||||
@@ -42,6 +42,15 @@ enum HotfixDatabaseStatements
|
||||
HOTFIX_SEL_BARBER_SHOP_STYLE,
|
||||
HOTFIX_SEL_BARBER_SHOP_STYLE_LOCALE,
|
||||
|
||||
HOTFIX_SEL_BATTLE_PET_BREED_QUALITY,
|
||||
|
||||
HOTFIX_SEL_BATTLE_PET_BREED_STATE,
|
||||
|
||||
HOTFIX_SEL_BATTLE_PET_SPECIES,
|
||||
HOTFIX_SEL_BATTLE_PET_SPECIES_LOCALE,
|
||||
|
||||
HOTFIX_SEL_BATTLE_PET_SPECIES_STATE,
|
||||
|
||||
HOTFIX_SEL_BROADCAST_TEXT,
|
||||
HOTFIX_SEL_BROADCAST_TEXT_LOCALE,
|
||||
|
||||
@@ -159,6 +168,8 @@ enum HotfixDatabaseStatements
|
||||
|
||||
HOTFIX_SEL_ITEM_SPEC_OVERRIDE,
|
||||
|
||||
HOTFIX_SEL_ITEM_TO_BATTLE_PET_SPECIES,
|
||||
|
||||
HOTFIX_SEL_ITEM_X_BONUS_TREE,
|
||||
|
||||
HOTFIX_SEL_KEY_CHAIN,
|
||||
|
||||
@@ -144,4 +144,13 @@ void LoginDatabaseConnection::DoPrepareStatements()
|
||||
// Account wide toys
|
||||
PrepareStatement(LOGIN_SEL_ACCOUNT_TOYS, "SELECT itemId, isFavourite FROM battlenet_account_toys WHERE accountId = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(LOGIN_REP_ACCOUNT_TOYS, "REPLACE INTO battlenet_account_toys (accountId, itemId, isFavourite) VALUES (?, ?, ?)", CONNECTION_ASYNC);
|
||||
|
||||
// Battle Pets
|
||||
PrepareStatement(LOGIN_SEL_BATTLE_PETS, "SELECT guid, species, breed, level, exp, health, quality, flags, name FROM battle_pets WHERE battlenetAccountId = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(LOGIN_INS_BATTLE_PETS, "INSERT INTO battle_pets (guid, battlenetAccountId, species, breed, level, exp, health, quality, flags, name) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(LOGIN_DEL_BATTLE_PETS, "DELETE FROM battle_pets WHERE battlenetAccountId = ? AND guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(LOGIN_UPD_BATTLE_PETS, "UPDATE battle_pets SET level = ?, exp = ?, health = ?, quality = ?, flags = ?, name = ? WHERE battlenetAccountId = ? AND guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(LOGIN_SEL_BATTLE_PET_SLOTS, "SELECT id, battlePetGuid, locked FROM battle_pet_slots WHERE battlenetAccountId = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(LOGIN_INS_BATTLE_PET_SLOTS, "INSERT INTO battle_pet_slots (id, battlenetAccountId, battlePetGuid, locked) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(LOGIN_DEL_BATTLE_PET_SLOTS, "DELETE FROM battle_pet_slots WHERE battlenetAccountId = ?", CONNECTION_ASYNC);
|
||||
}
|
||||
|
||||
@@ -133,6 +133,14 @@ enum LoginDatabaseStatements
|
||||
LOGIN_SEL_ACCOUNT_TOYS,
|
||||
LOGIN_REP_ACCOUNT_TOYS,
|
||||
|
||||
LOGIN_SEL_BATTLE_PETS,
|
||||
LOGIN_INS_BATTLE_PETS,
|
||||
LOGIN_DEL_BATTLE_PETS,
|
||||
LOGIN_UPD_BATTLE_PETS,
|
||||
LOGIN_SEL_BATTLE_PET_SLOTS,
|
||||
LOGIN_INS_BATTLE_PET_SLOTS,
|
||||
LOGIN_DEL_BATTLE_PET_SLOTS,
|
||||
|
||||
MAX_LOGINDATABASE_STATEMENTS
|
||||
};
|
||||
|
||||
|
||||
@@ -1057,6 +1057,7 @@ void AchievementMgr<T>::UpdateAchievementCriteria(AchievementCriteriaTypes type,
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA: // This also behaves like ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_ON_LOGIN:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_PLACE_GARRISON_BUILDING:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_OWN_BATTLE_PET_COUNT:
|
||||
SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE);
|
||||
break;
|
||||
// std case: increment at miscValue1
|
||||
@@ -1164,6 +1165,7 @@ void AchievementMgr<T>::UpdateAchievementCriteria(AchievementCriteriaTypes type,
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_RECRUIT_GARRISON_FOLLOWER:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_OWN_BATTLE_PET:
|
||||
SetCriteriaProgress(achievementCriteria, 1, referencePlayer);
|
||||
break;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT:
|
||||
@@ -1280,8 +1282,6 @@ void AchievementMgr<T>::UpdateAchievementCriteria(AchievementCriteriaTypes type,
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_COUNT_OF_LFR_QUEUE_BOOSTS_BY_TANK:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_SCENARIO_COUNT:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_SCENARIO:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_OWN_BATTLE_PET:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_OWN_BATTLE_PET_COUNT:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_CAPTURE_BATTLE_PET:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_WIN_PET_BATTLE:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_LEVEL_BATTLE_PET:
|
||||
@@ -1444,12 +1444,14 @@ bool AchievementMgr<T>::IsCompletedCriteria(AchievementCriteria const* achieveme
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_CURRENCY:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_PLACE_GARRISON_BUILDING:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_OWN_BATTLE_PET_COUNT:
|
||||
return progress->counter >= requiredAmount;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_RECRUIT_GARRISON_FOLLOWER:
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_OWN_BATTLE_PET:
|
||||
return progress->counter >= 1;
|
||||
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL:
|
||||
return progress->counter >= (requiredAmount * 75);
|
||||
@@ -2533,6 +2535,10 @@ bool AchievementMgr<T>::AdditionalRequirementsSatisfied(ModifierTreeNode const*
|
||||
if (!unit || unit->GetHealthPct() >= reqValue)
|
||||
return false;
|
||||
break;
|
||||
case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_BATTLE_PET_SPECIES: // 91
|
||||
if (miscValue1 != reqValue)
|
||||
return false;
|
||||
break;
|
||||
case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_QUALITY: // 145
|
||||
{
|
||||
if (!referencePlayer)
|
||||
|
||||
@@ -0,0 +1,467 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "BattlePetMgr.h"
|
||||
#include "Containers.h"
|
||||
#include "Player.h"
|
||||
#include "WorldSession.h"
|
||||
|
||||
void BattlePetMgr::BattlePet::CalculateStats()
|
||||
{
|
||||
float health = 0.0f;
|
||||
float power = 0.0f;
|
||||
float speed = 0.0f;
|
||||
|
||||
// get base breed stats
|
||||
auto breedState = _battlePetBreedStates.find(PacketInfo.Breed);
|
||||
if (breedState == _battlePetBreedStates.end()) // non existing breed id
|
||||
return;
|
||||
|
||||
health = breedState->second[STATE_STAT_STAMINA];
|
||||
power = breedState->second[STATE_STAT_POWER];
|
||||
speed = breedState->second[STATE_STAT_SPEED];
|
||||
|
||||
// modify stats depending on species - not all pets have this
|
||||
auto speciesState = _battlePetSpeciesStates.find(PacketInfo.Species);
|
||||
if (speciesState != _battlePetSpeciesStates.end())
|
||||
{
|
||||
health += speciesState->second[STATE_STAT_STAMINA];
|
||||
power += speciesState->second[STATE_STAT_POWER];
|
||||
speed += speciesState->second[STATE_STAT_SPEED];
|
||||
}
|
||||
|
||||
// modify stats by quality
|
||||
for (auto itr : sBattlePetBreedQualityStore)
|
||||
{
|
||||
if (itr->Quality == PacketInfo.Quality)
|
||||
{
|
||||
health *= itr->Modifier;
|
||||
power *= itr->Modifier;
|
||||
speed *= itr->Modifier;
|
||||
break;
|
||||
}
|
||||
// TOOD: add check if pet has existing quality
|
||||
}
|
||||
|
||||
// scale stats depending on level
|
||||
health *= PacketInfo.Level;
|
||||
power *= PacketInfo.Level;
|
||||
speed *= PacketInfo.Level;
|
||||
|
||||
// set stats
|
||||
// round, ceil or floor? verify this
|
||||
PacketInfo.MaxHealth = uint32((round(health / 20) + 100));
|
||||
PacketInfo.Power = uint32(round(power / 100));
|
||||
PacketInfo.Speed = uint32(round(speed / 100));
|
||||
}
|
||||
|
||||
std::unordered_map<uint16 /*BreedID*/, std::unordered_map<BattlePetState /*state*/, int32 /*value*/, std::hash<std::underlying_type<BattlePetState>::type> >> BattlePetMgr::_battlePetBreedStates;
|
||||
std::unordered_map<uint32 /*SpeciesID*/, std::unordered_map<BattlePetState /*state*/, int32 /*value*/, std::hash<std::underlying_type<BattlePetState>::type> >> BattlePetMgr::_battlePetSpeciesStates;
|
||||
std::unordered_map<uint32 /*SpeciesID*/, std::unordered_set<uint8 /*breed*/>> BattlePetMgr::_availableBreedsPerSpecies;
|
||||
std::unordered_map<uint32 /*SpeciesID*/, uint8 /*quality*/> BattlePetMgr::_defaultQualityPerSpecies;
|
||||
|
||||
void BattlePetMgr::Initialize()
|
||||
{
|
||||
if (QueryResult result = LoginDatabase.Query("SELECT MAX(guid) FROM battle_pets"))
|
||||
sObjectMgr->GetGenerator<HighGuid::BattlePet>().Set((*result)[0].GetUInt64() + 1);
|
||||
|
||||
for (auto itr : sBattlePetBreedStateStore)
|
||||
_battlePetBreedStates[itr->BreedID][BattlePetState(itr->State)] = itr->Value;
|
||||
|
||||
for (auto itr : sBattlePetSpeciesStateStore)
|
||||
_battlePetSpeciesStates[itr->SpeciesID][BattlePetState(itr->State)] = itr->Value;
|
||||
|
||||
LoadAvailablePetBreeds();
|
||||
LoadDefaultPetQualities();
|
||||
}
|
||||
|
||||
void BattlePetMgr::LoadAvailablePetBreeds()
|
||||
{
|
||||
QueryResult result = WorldDatabase.Query("SELECT speciesId, breedId FROM battle_pet_breeds");
|
||||
if (!result)
|
||||
{
|
||||
TC_LOG_INFO("server.loading", ">> Loaded 0 battle pet breeds. DB table `battle_pet_breeds` is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 count = 0;
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
uint32 speciesId = fields[0].GetUInt32();
|
||||
uint16 breedId = fields[1].GetUInt16();
|
||||
|
||||
if (!sBattlePetSpeciesStore.LookupEntry(speciesId))
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "Non-existing BattlePetSpecies.db2 entry %u was referenced in `battle_pet_breeds` by row (%u, %u).", speciesId, speciesId, breedId);
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO: verify breed id (3 - 12 (male) or 3 - 22 (male and female)) if needed
|
||||
|
||||
_availableBreedsPerSpecies[speciesId].insert(breedId);
|
||||
++count;
|
||||
} while (result->NextRow());
|
||||
|
||||
TC_LOG_INFO("server.loading", ">> Loaded %u battle pet breeds.", count);
|
||||
}
|
||||
|
||||
void BattlePetMgr::LoadDefaultPetQualities()
|
||||
{
|
||||
QueryResult result = WorldDatabase.Query("SELECT speciesId, quality FROM battle_pet_quality");
|
||||
if (!result)
|
||||
{
|
||||
TC_LOG_INFO("server.loading", ">> Loaded 0 battle pet qualities. DB table `battle_pet_quality` is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
uint32 speciesId = fields[0].GetUInt32();
|
||||
uint8 quality = fields[1].GetUInt8();
|
||||
|
||||
if (!sBattlePetSpeciesStore.LookupEntry(speciesId))
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "Non-existing BattlePetSpecies.db2 entry %u was referenced in `battle_pet_quality` by row (%u, %u).", speciesId, speciesId, quality);
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO: verify quality (0 - 3 for player pets or 0 - 5 for both player and tamer pets) if needed
|
||||
|
||||
_defaultQualityPerSpecies[speciesId] = quality;
|
||||
} while (result->NextRow());
|
||||
|
||||
TC_LOG_INFO("server.loading", ">> Loaded %u battle pet qualities.", uint32(_defaultQualityPerSpecies.size()));
|
||||
}
|
||||
|
||||
uint16 BattlePetMgr::RollPetBreed(uint32 species)
|
||||
{
|
||||
auto itr = _availableBreedsPerSpecies.find(species);
|
||||
if (itr == _availableBreedsPerSpecies.end())
|
||||
return 3; // default B/B
|
||||
|
||||
return Trinity::Containers::SelectRandomContainerElement(itr->second);
|
||||
}
|
||||
|
||||
uint8 BattlePetMgr::GetDefaultPetQuality(uint32 species)
|
||||
{
|
||||
auto itr = _defaultQualityPerSpecies.find(species);
|
||||
if (itr == _defaultQualityPerSpecies.end())
|
||||
return 0; // default poor
|
||||
|
||||
return itr->second;
|
||||
}
|
||||
|
||||
BattlePetMgr::BattlePetMgr(WorldSession* owner)
|
||||
{
|
||||
_owner = owner;
|
||||
for (uint8 i = 0; i < MAX_PET_BATTLE_SLOTS; ++i)
|
||||
{
|
||||
WorldPackets::BattlePet::BattlePetSlot slot;
|
||||
slot.Index = i;
|
||||
_slots.push_back(slot);
|
||||
}
|
||||
}
|
||||
|
||||
void BattlePetMgr::LoadFromDB(PreparedQueryResult pets, PreparedQueryResult slots)
|
||||
{
|
||||
if (pets)
|
||||
{
|
||||
do
|
||||
{
|
||||
Field* fields = pets->Fetch();
|
||||
uint32 species = fields[1].GetUInt32();
|
||||
|
||||
if (BattlePetSpeciesEntry const* speciesEntry = sBattlePetSpeciesStore.LookupEntry(species))
|
||||
{
|
||||
if (GetPetCount(species) >= MAX_BATTLE_PETS_PER_SPECIES)
|
||||
{
|
||||
TC_LOG_ERROR("misc", "Battlenet account with id %u has more than 3 battle pets of species %u", _owner->GetBattlenetAccountId(), species);
|
||||
continue;
|
||||
}
|
||||
|
||||
BattlePet pet;
|
||||
pet.PacketInfo.Guid = ObjectGuid::Create<HighGuid::BattlePet>(fields[0].GetUInt64());
|
||||
pet.PacketInfo.Species = species;
|
||||
pet.PacketInfo.Breed = fields[2].GetUInt16();
|
||||
pet.PacketInfo.Level = fields[3].GetUInt16();
|
||||
pet.PacketInfo.Exp = fields[4].GetUInt16();
|
||||
pet.PacketInfo.Health = fields[5].GetUInt32();
|
||||
pet.PacketInfo.Quality = fields[6].GetUInt8();
|
||||
pet.PacketInfo.Flags = fields[7].GetUInt16();
|
||||
pet.PacketInfo.Name = fields[8].GetString();
|
||||
pet.PacketInfo.CreatureID = speciesEntry->CreatureID;
|
||||
pet.SaveInfo = BATTLE_PET_UNCHANGED;
|
||||
pet.CalculateStats();
|
||||
_pets[pet.PacketInfo.Guid.GetCounter()] = pet;
|
||||
}
|
||||
} while (pets->NextRow());
|
||||
}
|
||||
|
||||
if (slots)
|
||||
{
|
||||
uint8 i = 0; // slots->GetRowCount() should equal MAX_BATTLE_PET_SLOTS
|
||||
|
||||
do
|
||||
{
|
||||
Field* fields = slots->Fetch();
|
||||
_slots[i].Index = fields[0].GetUInt8();
|
||||
auto itr = _pets.find(fields[1].GetUInt64());
|
||||
if (itr != _pets.end())
|
||||
_slots[i].Pet = itr->second.PacketInfo;
|
||||
_slots[i].Locked = fields[2].GetBool();
|
||||
i++;
|
||||
} while (slots->NextRow());
|
||||
}
|
||||
}
|
||||
|
||||
void BattlePetMgr::SaveToDB(SQLTransaction& trans)
|
||||
{
|
||||
PreparedStatement* stmt = nullptr;
|
||||
|
||||
for (auto itr = _pets.begin(); itr != _pets.end();)
|
||||
{
|
||||
switch (itr->second.SaveInfo)
|
||||
{
|
||||
case BATTLE_PET_NEW:
|
||||
stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_BATTLE_PETS);
|
||||
stmt->setUInt64(0, itr->first);
|
||||
stmt->setUInt32(1, _owner->GetBattlenetAccountId());
|
||||
stmt->setUInt32(2, itr->second.PacketInfo.Species);
|
||||
stmt->setUInt16(3, itr->second.PacketInfo.Breed);
|
||||
stmt->setUInt16(4, itr->second.PacketInfo.Level);
|
||||
stmt->setUInt16(5, itr->second.PacketInfo.Exp);
|
||||
stmt->setUInt32(6, itr->second.PacketInfo.Health);
|
||||
stmt->setUInt8(7, itr->second.PacketInfo.Quality);
|
||||
stmt->setUInt16(8, itr->second.PacketInfo.Flags);
|
||||
stmt->setString(9, itr->second.PacketInfo.Name);
|
||||
trans->Append(stmt);
|
||||
itr->second.SaveInfo = BATTLE_PET_UNCHANGED;
|
||||
++itr;
|
||||
break;
|
||||
case BATTLE_PET_CHANGED:
|
||||
stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BATTLE_PETS);
|
||||
stmt->setUInt16(0, itr->second.PacketInfo.Level);
|
||||
stmt->setUInt16(1, itr->second.PacketInfo.Exp);
|
||||
stmt->setUInt32(2, itr->second.PacketInfo.Health);
|
||||
stmt->setUInt8(3, itr->second.PacketInfo.Quality);
|
||||
stmt->setUInt16(4, itr->second.PacketInfo.Flags);
|
||||
stmt->setString(5, itr->second.PacketInfo.Name);
|
||||
stmt->setUInt32(6, _owner->GetBattlenetAccountId());
|
||||
stmt->setUInt64(7, itr->first);
|
||||
trans->Append(stmt);
|
||||
itr->second.SaveInfo = BATTLE_PET_UNCHANGED;
|
||||
++itr;
|
||||
break;
|
||||
case BATTLE_PET_REMOVED:
|
||||
stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_BATTLE_PETS);
|
||||
stmt->setUInt32(0, _owner->GetBattlenetAccountId());
|
||||
stmt->setUInt64(1, itr->first);
|
||||
trans->Append(stmt);
|
||||
itr = _pets.erase(itr);
|
||||
break;
|
||||
default:
|
||||
++itr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_BATTLE_PET_SLOTS);
|
||||
stmt->setUInt32(0, _owner->GetBattlenetAccountId());
|
||||
trans->Append(stmt);
|
||||
|
||||
for (WorldPackets::BattlePet::BattlePetSlot const& slot : _slots)
|
||||
{
|
||||
stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_BATTLE_PET_SLOTS);
|
||||
stmt->setUInt8(0, slot.Index);
|
||||
stmt->setUInt32(1, _owner->GetBattlenetAccountId());
|
||||
stmt->setUInt64(2, slot.Pet.Guid.GetCounter());
|
||||
stmt->setBool(3, slot.Locked);
|
||||
trans->Append(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
BattlePetMgr::BattlePet* BattlePetMgr::GetPet(ObjectGuid guid)
|
||||
{
|
||||
auto itr = _pets.find(guid.GetCounter());
|
||||
if (itr != _pets.end())
|
||||
return &itr->second;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void BattlePetMgr::AddPet(uint32 species, uint32 creatureId, uint16 breed, uint8 quality, uint16 level /*= 1*/)
|
||||
{
|
||||
BattlePetSpeciesEntry const* battlePetSpecies = sBattlePetSpeciesStore.LookupEntry(species);
|
||||
if (!battlePetSpecies) // should never happen
|
||||
return;
|
||||
|
||||
BattlePet pet;
|
||||
pet.PacketInfo.Guid = ObjectGuid::Create<HighGuid::BattlePet>(sObjectMgr->GetGenerator<HighGuid::BattlePet>().Generate());
|
||||
pet.PacketInfo.Species = species;
|
||||
pet.PacketInfo.CreatureID = creatureId;
|
||||
pet.PacketInfo.Level = level;
|
||||
pet.PacketInfo.Exp = 0;
|
||||
pet.PacketInfo.Flags = 0;
|
||||
pet.PacketInfo.Breed = breed;
|
||||
pet.PacketInfo.Quality = quality;
|
||||
pet.PacketInfo.Name = "";
|
||||
pet.CalculateStats();
|
||||
pet.PacketInfo.Health = pet.PacketInfo.MaxHealth;
|
||||
pet.SaveInfo = BATTLE_PET_NEW;
|
||||
|
||||
_pets[pet.PacketInfo.Guid.GetCounter()] = pet;
|
||||
|
||||
std::vector<BattlePet> updates;
|
||||
updates.push_back(pet);
|
||||
SendUpdates(updates, true);
|
||||
|
||||
_owner->GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_OWN_BATTLE_PET, species);
|
||||
}
|
||||
|
||||
void BattlePetMgr::RemovePet(ObjectGuid guid)
|
||||
{
|
||||
BattlePet* pet = GetPet(guid);
|
||||
if (!pet)
|
||||
return;
|
||||
|
||||
pet->SaveInfo = BATTLE_PET_REMOVED;
|
||||
|
||||
// spell is not unlearned on retail
|
||||
/*if (GetPetCount(pet->PacketInfo.Species) == 0)
|
||||
if (BattlePetSpeciesEntry const* speciesEntry = sBattlePetSpeciesStore.LookupEntry(pet->PacketInfo.Species))
|
||||
_owner->GetPlayer()->RemoveSpell(speciesEntry->SummonSpellID);*/
|
||||
}
|
||||
|
||||
uint8 BattlePetMgr::GetPetCount(uint32 species) const
|
||||
{
|
||||
uint8 count = 0;
|
||||
for (auto& itr : _pets)
|
||||
if (itr.second.PacketInfo.Species == species && itr.second.SaveInfo != BATTLE_PET_REMOVED)
|
||||
count++;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
void BattlePetMgr::UnlockSlot(uint8 slot)
|
||||
{
|
||||
if (!_slots[slot].Locked)
|
||||
return;
|
||||
|
||||
_slots[slot].Locked = false;
|
||||
|
||||
WorldPackets::BattlePet::PetBattleSlotUpdates updates;
|
||||
updates.Slots.push_back(_slots[slot]);
|
||||
updates.AutoSlotted = false; // what's this?
|
||||
updates.NewSlot = true; // causes the "new slot unlocked" bubble to appear
|
||||
_owner->SendPacket(updates.Write());
|
||||
}
|
||||
|
||||
std::vector<BattlePetMgr::BattlePet> BattlePetMgr::GetLearnedPets() const
|
||||
{
|
||||
std::vector<BattlePet> pets;
|
||||
for (auto& pet : _pets)
|
||||
if (pet.second.SaveInfo != BATTLE_PET_REMOVED)
|
||||
pets.push_back(pet.second);
|
||||
|
||||
return pets;
|
||||
}
|
||||
|
||||
void BattlePetMgr::CageBattlePet(ObjectGuid guid)
|
||||
{
|
||||
BattlePet* pet = GetPet(guid);
|
||||
if (!pet)
|
||||
return;
|
||||
|
||||
ItemPosCountVec dest;
|
||||
|
||||
if (_owner->GetPlayer()->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, BATTLE_PET_CAGE_ITEM_ID, 1) != EQUIP_ERR_OK)
|
||||
return;
|
||||
|
||||
Item* item = _owner->GetPlayer()->StoreNewItem(dest, BATTLE_PET_CAGE_ITEM_ID, true);
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
item->SetModifier(ITEM_MODIFIER_BATTLE_PET_SPECIES_ID, pet->PacketInfo.Species);
|
||||
item->SetModifier(ITEM_MODIFIER_BATTLE_PET_BREED_DATA, pet->PacketInfo.Breed | (pet->PacketInfo.Quality << 24));
|
||||
item->SetModifier(ITEM_MODIFIER_BATTLE_PET_LEVEL, pet->PacketInfo.Level);
|
||||
item->SetModifier(ITEM_MODIFIER_BATTLE_PET_DISPLAY_ID, pet->PacketInfo.CreatureID);
|
||||
|
||||
// FIXME: "You create: ." - item name missing in chat
|
||||
_owner->GetPlayer()->SendNewItem(item, 1, true, true);
|
||||
|
||||
RemovePet(guid);
|
||||
|
||||
WorldPackets::BattlePet::BattlePetDeleted deletePet;
|
||||
deletePet.PetGuid = guid;
|
||||
_owner->SendPacket(deletePet.Write());
|
||||
}
|
||||
|
||||
void BattlePetMgr::HealBattlePetsPct(uint8 pct)
|
||||
{
|
||||
// TODO: After each Pet Battle, any injured companion will automatically
|
||||
// regain 50 % of the damage that was taken during combat
|
||||
std::vector<BattlePet> updates;
|
||||
|
||||
for (auto& pet : _pets)
|
||||
if (pet.second.PacketInfo.Health != pet.second.PacketInfo.MaxHealth)
|
||||
{
|
||||
pet.second.PacketInfo.Health += CalculatePct(pet.second.PacketInfo.MaxHealth, pct);
|
||||
// don't allow Health to be greater than MaxHealth
|
||||
pet.second.PacketInfo.Health = std::min(pet.second.PacketInfo.Health, pet.second.PacketInfo.MaxHealth);
|
||||
if (pet.second.SaveInfo != BATTLE_PET_NEW)
|
||||
pet.second.SaveInfo = BATTLE_PET_CHANGED;
|
||||
updates.push_back(pet.second);
|
||||
}
|
||||
|
||||
SendUpdates(updates, false);
|
||||
}
|
||||
|
||||
void BattlePetMgr::SummonPet(ObjectGuid guid)
|
||||
{
|
||||
BattlePet* pet = GetPet(guid);
|
||||
if (!pet)
|
||||
return;
|
||||
|
||||
BattlePetSpeciesEntry const* speciesEntry = sBattlePetSpeciesStore.LookupEntry(pet->PacketInfo.Species);
|
||||
if (!speciesEntry)
|
||||
return;
|
||||
|
||||
// TODO: set proper CreatureID for spell DEFAULT_SUMMON_BATTLE_PET_SPELL (default EffectMiscValueA is 40721 - Murkimus the Gladiator)
|
||||
_owner->GetPlayer()->CastSpell(_owner->GetPlayer(), speciesEntry->SummonSpellID ? speciesEntry->SummonSpellID : DEFAULT_SUMMON_BATTLE_PET_SPELL);
|
||||
|
||||
// TODO: set pet level, quality... update fields
|
||||
}
|
||||
|
||||
void BattlePetMgr::SendUpdates(std::vector<BattlePet> pets, bool petAdded)
|
||||
{
|
||||
WorldPackets::BattlePet::BattlePetUpdates updates;
|
||||
for (auto pet : pets)
|
||||
updates.Pets.push_back(pet.PacketInfo);
|
||||
|
||||
updates.PetAdded = petAdded;
|
||||
_owner->SendPacket(updates.Write());
|
||||
}
|
||||
|
||||
void BattlePetMgr::SendError(BattlePetError error, uint32 creatureId)
|
||||
{
|
||||
WorldPackets::BattlePet::BattlePetError battlePetError;
|
||||
battlePetError.Result = error;
|
||||
battlePetError.CreatureID = creatureId;
|
||||
_owner->SendPacket(battlePetError.Write());
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BattlePetMgr_h__
|
||||
#define BattlePetMgr_h__
|
||||
|
||||
#include "DB2Stores.h"
|
||||
#include "BattlePetPackets.h"
|
||||
|
||||
enum BattlePetMisc
|
||||
{
|
||||
MAX_PET_BATTLE_SLOTS = 3,
|
||||
MAX_BATTLE_PETS_PER_SPECIES = 3,
|
||||
BATTLE_PET_CAGE_ITEM_ID = 82800,
|
||||
DEFAULT_SUMMON_BATTLE_PET_SPELL = 118301
|
||||
};
|
||||
|
||||
// TODO: fix values in this enum
|
||||
enum BattlePetError
|
||||
{
|
||||
BATTLEPETRESULT_CANT_HAVE_MORE_PETS_OF_THAT_TYPE = 9,
|
||||
BATTLEPETRESULT_TOO_HIGH_LEVEL_TO_UNCAGE = 12,
|
||||
BATTLEPETRESULT_CANT_HAVE_MORE_PETS = 13,
|
||||
|
||||
// wrong order
|
||||
BATTLEPETRESULT_DUPLICATE_CONVERTED_PET,
|
||||
BATTLEPETRESULT_NEED_TO_UNLOCK,
|
||||
BATTLEPETRESULT_BAD_PARAM,
|
||||
BATTLEPETRESULT_LOCKED_PET_ALREADY_EXISTS,
|
||||
BATTLEPETRESULT_OK,
|
||||
BATTLEPETRESULT_UNCAPTURABLE,
|
||||
BATTLEPETRESULT_CANT_INVALID_CHARACTER_GUID
|
||||
};
|
||||
|
||||
// taken from BattlePetState.db2 - it seems to store some initial values for battle pets
|
||||
// there are only values used in BattlePetSpeciesState.db2 and BattlePetBreedState.db2
|
||||
// TODO: expand this enum if needed
|
||||
enum BattlePetState
|
||||
{
|
||||
STATE_MAX_HEALTH_BONUS = 2,
|
||||
STATE_INTERNAL_INITIAL_LEVEL = 17,
|
||||
STATE_STAT_POWER = 18,
|
||||
STATE_STAT_STAMINA = 19,
|
||||
STATE_STAT_SPEED = 20,
|
||||
STATE_MOD_DAMAGE_DEALT_PERCENT = 23,
|
||||
STATE_GENDER = 78, // 1 - male, 2 - female
|
||||
STATE_COSMETIC_WATER_BUBBLED = 85,
|
||||
STATE_SPECIAL_IS_COCKROACH = 93,
|
||||
STATE_COSMETIC_FLY_TIER = 128,
|
||||
STATE_COSMETIC_BIGGLESWORTH = 144,
|
||||
STATE_PASSIVE_ELITE = 153,
|
||||
STATE_PASSIVE_BOSS = 162,
|
||||
STATE_COSMETIC_TREASURE_GOBLIN = 176,
|
||||
// these are not in BattlePetState.db2 but are used in BattlePetSpeciesState.db2
|
||||
STATE_START_WITH_BUFF = 183,
|
||||
STATE_START_WITH_BUFF_2 = 184
|
||||
};
|
||||
|
||||
enum BattlePetSaveInfo
|
||||
{
|
||||
BATTLE_PET_UNCHANGED = 0,
|
||||
BATTLE_PET_CHANGED = 1,
|
||||
BATTLE_PET_NEW = 2,
|
||||
BATTLE_PET_REMOVED = 3
|
||||
};
|
||||
|
||||
class BattlePetMgr
|
||||
{
|
||||
public:
|
||||
struct BattlePet
|
||||
{
|
||||
void CalculateStats();
|
||||
|
||||
WorldPackets::BattlePet::BattlePet PacketInfo;
|
||||
BattlePetSaveInfo SaveInfo;
|
||||
};
|
||||
|
||||
explicit BattlePetMgr(WorldSession* owner);
|
||||
|
||||
static void Initialize();
|
||||
|
||||
static uint16 RollPetBreed(uint32 species);
|
||||
static uint8 GetDefaultPetQuality(uint32 species);
|
||||
|
||||
void LoadFromDB(PreparedQueryResult pets, PreparedQueryResult slots);
|
||||
void SaveToDB(SQLTransaction& trans);
|
||||
|
||||
BattlePet* GetPet(ObjectGuid guid);
|
||||
void AddPet(uint32 species, uint32 creatureId, uint16 breed, uint8 quality, uint16 level = 1);
|
||||
void RemovePet(ObjectGuid guid);
|
||||
|
||||
uint8 GetPetCount(uint32 species) const;
|
||||
|
||||
WorldPackets::BattlePet::BattlePetSlot* GetSlot(uint8 slot) { return &_slots[slot]; }
|
||||
void UnlockSlot(uint8 slot);
|
||||
|
||||
WorldSession* GetOwner() const { return _owner; }
|
||||
|
||||
uint16 GetTrapLevel() const { return _trapLevel; }
|
||||
std::vector<BattlePet> GetLearnedPets() const;
|
||||
std::vector<WorldPackets::BattlePet::BattlePetSlot> GetSlots() const { return _slots; }
|
||||
|
||||
void CageBattlePet(ObjectGuid guid);
|
||||
void HealBattlePetsPct(uint8 pct);
|
||||
|
||||
void SummonPet(ObjectGuid guid);
|
||||
|
||||
void SendUpdates(std::vector<BattlePet> pets, bool petAdded);
|
||||
void SendError(BattlePetError error, uint32 creatureId);
|
||||
|
||||
private:
|
||||
WorldSession* _owner;
|
||||
uint16 _trapLevel = 0;
|
||||
std::unordered_map<uint64 /*battlePetGuid*/, BattlePet> _pets;
|
||||
std::vector<WorldPackets::BattlePet::BattlePetSlot> _slots;
|
||||
|
||||
static void LoadAvailablePetBreeds();
|
||||
static void LoadDefaultPetQualities();
|
||||
|
||||
// hash no longer required in C++14
|
||||
static std::unordered_map<uint16 /*BreedID*/, std::unordered_map<BattlePetState /*state*/, int32 /*value*/, std::hash<std::underlying_type<BattlePetState>::type> >> _battlePetBreedStates;
|
||||
static std::unordered_map<uint32 /*SpeciesID*/, std::unordered_map<BattlePetState /*state*/, int32 /*value*/, std::hash<std::underlying_type<BattlePetState>::type> >> _battlePetSpeciesStates;
|
||||
static std::unordered_map<uint32 /*SpeciesID*/, std::unordered_set<uint8 /*breed*/>> _availableBreedsPerSpecies;
|
||||
static std::unordered_map<uint32 /*SpeciesID*/, uint8 /*quality*/> _defaultQualityPerSpecies;
|
||||
};
|
||||
|
||||
#endif // BattlePetMgr_h__
|
||||
@@ -16,6 +16,7 @@ file(GLOB_RECURSE sources_AuctionHouse AuctionHouse/*.cpp AuctionHouse/*.h)
|
||||
file(GLOB_RECURSE sources_AuctionHouseBot AuctionHouseBot/*.cpp AuctionHouseBot/*.h)
|
||||
file(GLOB_RECURSE sources_Battlefield Battlefield/*.cpp Battlefield/*.h)
|
||||
file(GLOB_RECURSE sources_Battlegrounds Battlegrounds/*.cpp Battlegrounds/*.h)
|
||||
file(GLOB_RECURSE sources_BattlePets BattlePets/*.cpp BattlePets/*.h)
|
||||
file(GLOB_RECURSE sources_Calendar Calendar/*.cpp Calendar/*.h)
|
||||
file(GLOB_RECURSE sources_Chat Chat/*.cpp Chat/*.h)
|
||||
file(GLOB_RECURSE sources_Combat Combat/*.cpp Combat/*.h)
|
||||
@@ -68,6 +69,7 @@ set(game_STAT_SRCS
|
||||
${sources_AuctionHouseBot}
|
||||
${sources_Battlefield}
|
||||
${sources_Battlegrounds}
|
||||
${sources_BattlePets}
|
||||
${sources_Calendar}
|
||||
${sources_Chat}
|
||||
${sources_Combat}
|
||||
@@ -118,6 +120,7 @@ include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Battlefield/Zones
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Battlegrounds
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Battlegrounds/Zones
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/BattlePets
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Calendar
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Chat
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Chat/Channels
|
||||
|
||||
@@ -29,6 +29,10 @@ DB2Storage<AreaGroupEntry> sAreaGroupStore("AreaGroup.db2",
|
||||
DB2Storage<AreaGroupMemberEntry> sAreaGroupMemberStore("AreaGroupMember.db2", AreaGroupMemberFormat, HOTFIX_SEL_AREA_GROUP_MEMBER);
|
||||
DB2Storage<AuctionHouseEntry> sAuctionHouseStore("AuctionHouse.db2", AuctionHouseFormat, HOTFIX_SEL_AUCTION_HOUSE);
|
||||
DB2Storage<BarberShopStyleEntry> sBarberShopStyleStore("BarberShopStyle.db2", BarberShopStyleFormat, HOTFIX_SEL_BARBER_SHOP_STYLE);
|
||||
DB2Storage<BattlePetBreedQualityEntry> sBattlePetBreedQualityStore("BattlePetBreedQuality.db2", BattlePetBreedQualityFormat, HOTFIX_SEL_BATTLE_PET_BREED_QUALITY);
|
||||
DB2Storage<BattlePetBreedStateEntry> sBattlePetBreedStateStore("BattlePetBreedState.db2", BattlePetBreedStateFormat, HOTFIX_SEL_BATTLE_PET_BREED_STATE);
|
||||
DB2Storage<BattlePetSpeciesEntry> sBattlePetSpeciesStore("BattlePetSpecies.db2", BattlePetSpeciesFormat, HOTFIX_SEL_BATTLE_PET_SPECIES);
|
||||
DB2Storage<BattlePetSpeciesStateEntry> sBattlePetSpeciesStateStore("BattlePetSpeciesState.db2", BattlePetSpeciesStateFormat, HOTFIX_SEL_BATTLE_PET_SPECIES_STATE);
|
||||
DB2Storage<BroadcastTextEntry> sBroadcastTextStore("BroadcastText.db2", BroadcastTextFormat, HOTFIX_SEL_BROADCAST_TEXT);
|
||||
DB2Storage<CharStartOutfitEntry> sCharStartOutfitStore("CharStartOutfit.db2", CharStartOutfitFormat, HOTFIX_SEL_CHAR_START_OUTFIT);
|
||||
DB2Storage<ChrClassesXPowerTypesEntry> sChrClassesXPowerTypesStore("ChrClassesXPowerTypes.db2", ChrClassesXPowerTypesFormat, HOTFIX_SEL_CHR_CLASSES_X_POWER_TYPES);
|
||||
@@ -78,6 +82,7 @@ DB2Storage<ItemRandomSuffixEntry> sItemRandomSuffixStore("ItemRand
|
||||
DB2Storage<ItemSparseEntry> sItemSparseStore("Item-sparse.db2", ItemSparseFormat, HOTFIX_SEL_ITEM_SPARSE);
|
||||
DB2Storage<ItemSpecEntry> sItemSpecStore("ItemSpec.db2", ItemSpecFormat, HOTFIX_SEL_ITEM_SPEC);
|
||||
DB2Storage<ItemSpecOverrideEntry> sItemSpecOverrideStore("ItemSpecOverride.db2", ItemSpecOverrideFormat, HOTFIX_SEL_ITEM_SPEC_OVERRIDE);
|
||||
DB2Storage<ItemToBattlePetSpeciesEntry> sItemToBattlePetSpeciesStore("ItemToBattlePetSpecies.db2", ItemToBattlePetSpeciesFormat, HOTFIX_SEL_ITEM_TO_BATTLE_PET_SPECIES);
|
||||
DB2Storage<ItemXBonusTreeEntry> sItemXBonusTreeStore("ItemXBonusTree.db2", ItemXBonusTreeFormat, HOTFIX_SEL_ITEM_X_BONUS_TREE);
|
||||
DB2Storage<KeyChainEntry> sKeyChainStore("KeyChain.db2", KeyChainFormat, HOTFIX_SEL_KEY_CHAIN);
|
||||
DB2Storage<MailTemplateEntry> sMailTemplateStore("MailTemplate.db2", MailTemplateFormat, HOTFIX_SEL_MAIL_TEMPLATE);
|
||||
@@ -196,8 +201,12 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale)
|
||||
LOAD_DB2(sAchievementStore);
|
||||
LOAD_DB2(sAreaGroupMemberStore);
|
||||
LOAD_DB2(sAreaGroupStore);
|
||||
LOAD_DB2(sBattlePetBreedQualityStore);
|
||||
LOAD_DB2(sBattlePetBreedStateStore);
|
||||
LOAD_DB2(sAuctionHouseStore);
|
||||
LOAD_DB2(sBarberShopStyleStore);
|
||||
LOAD_DB2(sBattlePetSpeciesStore);
|
||||
LOAD_DB2(sBattlePetSpeciesStateStore);
|
||||
LOAD_DB2(sBroadcastTextStore);
|
||||
LOAD_DB2(sCharStartOutfitStore);
|
||||
LOAD_DB2(sChrClassesXPowerTypesStore);
|
||||
@@ -247,6 +256,7 @@ void DB2Manager::LoadStores(std::string const& dataPath, uint32 defaultLocale)
|
||||
LOAD_DB2(sItemSpecOverrideStore);
|
||||
LOAD_DB2(sItemSpecStore);
|
||||
LOAD_DB2(sItemStore);
|
||||
LOAD_DB2(sItemToBattlePetSpeciesStore);
|
||||
LOAD_DB2(sItemXBonusTreeStore);
|
||||
LOAD_DB2(sKeyChainStore);
|
||||
LOAD_DB2(sMailTemplateStore);
|
||||
|
||||
@@ -27,6 +27,10 @@
|
||||
extern DB2Storage<AchievementEntry> sAchievementStore;
|
||||
extern DB2Storage<AuctionHouseEntry> sAuctionHouseStore;
|
||||
extern DB2Storage<BarberShopStyleEntry> sBarberShopStyleStore;
|
||||
extern DB2Storage<BattlePetBreedQualityEntry> sBattlePetBreedQualityStore;
|
||||
extern DB2Storage<BattlePetBreedStateEntry> sBattlePetBreedStateStore;
|
||||
extern DB2Storage<BattlePetSpeciesEntry> sBattlePetSpeciesStore;
|
||||
extern DB2Storage<BattlePetSpeciesStateEntry> sBattlePetSpeciesStateStore;
|
||||
extern DB2Storage<BroadcastTextEntry> sBroadcastTextStore;
|
||||
extern DB2Storage<CharStartOutfitEntry> sCharStartOutfitStore;
|
||||
extern DB2Storage<CinematicSequencesEntry> sCinematicSequencesStore;
|
||||
@@ -70,6 +74,7 @@ extern DB2Storage<ItemRandomSuffixEntry> sItemRandomSuffixStore;
|
||||
extern DB2Storage<ItemSparseEntry> sItemSparseStore;
|
||||
extern DB2Storage<ItemSpecEntry> sItemSpecStore;
|
||||
extern DB2Storage<ItemSpecOverrideEntry> sItemSpecOverrideStore;
|
||||
extern DB2Storage<ItemToBattlePetSpeciesEntry> sItemToBattlePetSpeciesStore;
|
||||
extern DB2Storage<MailTemplateEntry> sMailTemplateStore;
|
||||
extern DB2Storage<ModifierTreeEntry> sModifierTreeStore;
|
||||
extern DB2Storage<MountCapabilityEntry> sMountCapabilityStore;
|
||||
|
||||
@@ -77,6 +77,42 @@ struct BarberShopStyleEntry
|
||||
uint32 Data; // 7 (real ID to hair/facial hair)
|
||||
};
|
||||
|
||||
struct BattlePetBreedQualityEntry
|
||||
{
|
||||
uint32 ID; // 0
|
||||
uint32 Quality; // 1
|
||||
float Modifier; // 2
|
||||
};
|
||||
|
||||
struct BattlePetBreedStateEntry
|
||||
{
|
||||
uint32 ID; // 0
|
||||
uint32 BreedID; // 1
|
||||
uint32 State; // 2
|
||||
int32 Value; // 3
|
||||
};
|
||||
|
||||
struct BattlePetSpeciesEntry
|
||||
{
|
||||
uint32 ID; // 0
|
||||
uint32 CreatureID; // 1
|
||||
uint32 IconFileID; // 2
|
||||
uint32 SummonSpellID; // 3
|
||||
uint32 PetType; // 4
|
||||
int32 Source; // 5
|
||||
uint32 Flags; // 6
|
||||
LocalizedString* SourceText; // 7
|
||||
LocalizedString* Description; // 8
|
||||
};
|
||||
|
||||
struct BattlePetSpeciesStateEntry
|
||||
{
|
||||
uint32 ID; // 0
|
||||
uint32 SpeciesID; // 1
|
||||
uint32 State; // 2
|
||||
int32 Value; // 3
|
||||
};
|
||||
|
||||
#define MAX_BROADCAST_TEXT_EMOTES 3
|
||||
|
||||
struct BroadcastTextEntry
|
||||
@@ -830,6 +866,12 @@ struct ItemSpecOverrideEntry
|
||||
uint32 SpecID; // 2
|
||||
};
|
||||
|
||||
struct ItemToBattlePetSpeciesEntry
|
||||
{
|
||||
uint32 ID; // 0
|
||||
uint32 BattlePetSpeciesID; // 1
|
||||
};
|
||||
|
||||
struct ItemXBonusTreeEntry
|
||||
{
|
||||
uint32 ID; // 0
|
||||
|
||||
@@ -23,6 +23,10 @@ char const AreaGroupFormat[] = "n";
|
||||
char const AreaGroupMemberFormat[] = "nii";
|
||||
char const AuctionHouseFormat[] = "niiis";
|
||||
char const BarberShopStyleFormat[] = "nissfiii";
|
||||
char const BattlePetBreedQualityFormat[] = "nif";
|
||||
char const BattlePetBreedStateFormat[] = "niii";
|
||||
char const BattlePetSpeciesFormat[] = "niiiiiiss";
|
||||
char const BattlePetSpeciesStateFormat[] = "niii";
|
||||
char const BroadcastTextFormat[] = "nissiiiiiiiii";
|
||||
char const CharStartOutfitFormat[] = "nbbbbiiiiiiiiiiiiiiiiiiiiiiiiii";
|
||||
char const ChrClassesXPowerTypesFormat[] = "iii";
|
||||
@@ -72,6 +76,7 @@ char const ItemRandomSuffixFormat[] = "nssiiiiiiiiii";
|
||||
char const ItemSparseFormat[] = "niiiiffiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffffffffffiiifisssssiiiiiiiiiiiiiiiiiiifiiifiii";
|
||||
char const ItemSpecFormat[] = "niiiiii";
|
||||
char const ItemSpecOverrideFormat[] = "nii";
|
||||
char const ItemToBattlePetSpeciesFormat[] = "ni";
|
||||
char const ItemXBonusTreeFormat[] = "nii";
|
||||
char const KeyChainFormat[] = "nbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
|
||||
char const MailTemplateFormat[] = "ns";
|
||||
|
||||
@@ -159,6 +159,7 @@ enum AchievementCriteriaAdditionalCondition
|
||||
ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_RATED_BATTLEGROUND = 63, // NYI
|
||||
ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_PROJECT_RARITY = 65,
|
||||
ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_PROJECT_RACE = 66,
|
||||
ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_BATTLE_PET_SPECIES = 91,
|
||||
ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_QUALITY = 145,
|
||||
ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_GARRISON_FOLLOWER_LEVEL = 146,
|
||||
ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_GARRISON_RARE_MISSION = 147, // NYI
|
||||
|
||||
@@ -351,6 +351,10 @@ void Item::SaveToDB(SQLTransaction& trans)
|
||||
stmt->setUInt32(++index, GetModifier(ITEM_MODIFIER_TRANSMOG_ITEM_ID) | (GetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_MOD) << 24));
|
||||
stmt->setUInt32(++index, GetModifier(ITEM_MODIFIER_UPGRADE_ID));
|
||||
stmt->setUInt32(++index, GetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION));
|
||||
stmt->setUInt32(++index, GetModifier(ITEM_MODIFIER_BATTLE_PET_SPECIES_ID));
|
||||
stmt->setUInt32(++index, GetModifier(ITEM_MODIFIER_BATTLE_PET_BREED_DATA));
|
||||
stmt->setUInt32(++index, GetModifier(ITEM_MODIFIER_BATTLE_PET_LEVEL));
|
||||
stmt->setUInt32(++index, GetModifier(ITEM_MODIFIER_BATTLE_PET_DISPLAY_ID));
|
||||
|
||||
std::ostringstream bonusListIDs;
|
||||
for (uint32 bonusListID : GetDynamicValues(ITEM_DYNAMIC_FIELD_BONUSLIST_IDS))
|
||||
@@ -405,8 +409,10 @@ void Item::SaveToDB(SQLTransaction& trans)
|
||||
|
||||
bool Item::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid ownerGuid, Field* fields, uint32 entry)
|
||||
{
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
||||
//result = CharacterDatabase.PQuery("SELECT guid, itemEntry, creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text, transmogrification, upgradeId, enchantIllusion, bonusListIDs FROM item_instance WHERE guid = '%u'", guid);
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12
|
||||
//result = CharacterDatabase.PQuery("SELECT guid, itemEntry, creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text,
|
||||
// 13 14 15 16 17 18 19 20
|
||||
// transmogrification, upgradeId, enchantIllusion, battlePetSpeciesId, battlePetBreedData, battlePetLevel, battlePetDisplayId, bonusListIDs FROM item_instance WHERE guid = '%u'", guid);
|
||||
|
||||
// create item before any checks for store correct guid
|
||||
// and allow use "FSetState(ITEM_REMOVED); SaveToDB();" for deleting item from DB
|
||||
@@ -482,8 +488,12 @@ bool Item::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid ownerGuid, Field* fie
|
||||
}
|
||||
SetModifier(ITEM_MODIFIER_UPGRADE_ID, fields[14].GetUInt32());
|
||||
SetModifier(ITEM_MODIFIER_ENCHANT_ILLUSION, fields[15].GetUInt32());
|
||||
SetModifier(ITEM_MODIFIER_BATTLE_PET_SPECIES_ID, fields[16].GetUInt32());
|
||||
SetModifier(ITEM_MODIFIER_BATTLE_PET_BREED_DATA, fields[17].GetUInt32());
|
||||
SetModifier(ITEM_MODIFIER_BATTLE_PET_LEVEL, fields[18].GetUInt16());
|
||||
SetModifier(ITEM_MODIFIER_BATTLE_PET_DISPLAY_ID, fields[19].GetUInt32());
|
||||
|
||||
Tokenizer bonusListIDs(fields[16].GetString(), ' ');
|
||||
Tokenizer bonusListIDs(fields[20].GetString(), ' ');
|
||||
for (char const* token : bonusListIDs)
|
||||
{
|
||||
uint32 bonusListID = atoul(token);
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "Battleground.h"
|
||||
#include "BattlegroundMgr.h"
|
||||
#include "BattlegroundScore.h"
|
||||
#include "BattlePetMgr.h"
|
||||
#include "CellImpl.h"
|
||||
#include "ChannelMgr.h"
|
||||
#include "CharacterDatabaseCleaner.h"
|
||||
@@ -13699,10 +13700,10 @@ void Player::SendNewItem(Item* item, uint32 quantity, bool pushed, bool created,
|
||||
packet.Quantity = quantity;
|
||||
packet.QuantityInInventory = GetItemCount(item->GetEntry());
|
||||
//packet.DungeonEncounterID;
|
||||
//packet.BattlePetBreedID;
|
||||
//packet.BattlePetBreedQuality;
|
||||
//packet.BattlePetSpeciesID;
|
||||
//packet.BattlePetLevel;
|
||||
packet.BattlePetBreedID = item->GetModifier(ITEM_MODIFIER_BATTLE_PET_BREED_DATA) & 0xFFFFFF;
|
||||
packet.BattlePetBreedQuality = (item->GetModifier(ITEM_MODIFIER_BATTLE_PET_BREED_DATA) >> 24) & 0xFF;
|
||||
packet.BattlePetSpeciesID = item->GetModifier(ITEM_MODIFIER_BATTLE_PET_SPECIES_ID);
|
||||
packet.BattlePetLevel = item->GetModifier(ITEM_MODIFIER_BATTLE_PET_LEVEL);
|
||||
|
||||
packet.ItemGUID = item->GetGUID();
|
||||
|
||||
@@ -17650,8 +17651,10 @@ void Player::LoadCorpse()
|
||||
|
||||
void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff)
|
||||
{
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
||||
// SELECT ii.guid, ii.itemEntry, ii.creatorGuid, ii.giftCreatorGuid, ii.count, ii.duration, ii.charges, ii.flags, ii.enchantments, ii.randomPropertyId, ii.durability, ii.playedTime, ii.text, ii.transmogrification, ii.upgradeId, ii.enchantIllusion, ii.bonusListIDs, bag, slot FROM character_inventory ci JOIN item_instance ii ON ci.item = ii.guid WHERE ci.guid = ? ORDER BY bag, slot
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
||||
// SELECT ii.guid, ii.itemEntry, ii.creatorGuid, ii.giftCreatorGuid, ii.count, ii.duration, ii.charges, ii.flags, ii.enchantments, ii.randomPropertyId, ii.durability, ii.playedTime, ii.text, ii.transmogrification, ii.upgradeId
|
||||
// 15 16 17 18 19 20 21 22
|
||||
// ii.enchantIllusion, battlePetSpeciesId, battlePetBreedData, battlePetLevel, battlePetDisplayId, ii.bonusListIDs, bag, slot FROM character_inventory ci JOIN item_instance ii ON ci.item = ii.guid WHERE ci.guid = ? ORDER BY bag, slot
|
||||
//NOTE: the "order by `bag`" is important because it makes sure
|
||||
//the bagMap is filled before items in the bags are loaded
|
||||
//NOTE2: the "order by `slot`" is needed because mainhand weapons are (wrongly?)
|
||||
@@ -17673,8 +17676,8 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff)
|
||||
Field* fields = result->Fetch();
|
||||
if (Item* item = _LoadItem(trans, zoneId, timeDiff, fields))
|
||||
{
|
||||
ObjectGuid bagGuid = fields[17].GetUInt64() ? ObjectGuid::Create<HighGuid::Item>(fields[17].GetUInt64()) : ObjectGuid::Empty;
|
||||
uint8 slot = fields[18].GetUInt8();
|
||||
ObjectGuid bagGuid = fields[21].GetUInt64() ? ObjectGuid::Create<HighGuid::Item>(fields[21].GetUInt64()) : ObjectGuid::Empty;
|
||||
uint8 slot = fields[22].GetUInt8();
|
||||
|
||||
uint8 err = EQUIP_ERR_OK;
|
||||
// Item is not in bag
|
||||
@@ -17995,7 +17998,7 @@ void Player::_LoadMailedItems(Mail* mail)
|
||||
|
||||
Item* item = NewItemOrBag(proto);
|
||||
|
||||
ObjectGuid ownerGuid = fields[17].GetUInt64() ? ObjectGuid::Create<HighGuid::Player>(fields[17].GetUInt64()) : ObjectGuid::Empty;
|
||||
ObjectGuid ownerGuid = fields[21].GetUInt64() ? ObjectGuid::Create<HighGuid::Player>(fields[21].GetUInt64()) : ObjectGuid::Empty;
|
||||
if (!item->LoadFromDB(itemGuid, ownerGuid, fields, itemEntry))
|
||||
{
|
||||
TC_LOG_ERROR("entities.player", "Player::_LoadMailedItems - Item in mail (%u) doesn't exist !!!! - item guid: " UI64FMTD ", deleted from mail", mail->messageID, itemGuid);
|
||||
@@ -19188,9 +19191,11 @@ void Player::SaveToDB(bool create /*=false*/)
|
||||
|
||||
CharacterDatabase.CommitTransaction(trans);
|
||||
|
||||
SQLTransaction transLogin = LoginDatabase.BeginTransaction();
|
||||
GetSession()->SaveAccountToys(transLogin);
|
||||
LoginDatabase.CommitTransaction(transLogin);
|
||||
// TODO: Move this out
|
||||
trans = LoginDatabase.BeginTransaction();
|
||||
GetSession()->SaveAccountToys(trans);
|
||||
GetSession()->GetBattlePetMgr()->SaveToDB(trans);
|
||||
LoginDatabase.CommitTransaction(trans);
|
||||
|
||||
// save pet (hunter pet level and experience and all type pets health/mana).
|
||||
if (Pet* pet = GetPet())
|
||||
|
||||
@@ -532,7 +532,7 @@ enum PlayerFlags
|
||||
PLAYER_FLAGS_UNK21 = 0x00200000,
|
||||
PLAYER_FLAGS_COMMENTATOR2 = 0x00400000,
|
||||
PLAYER_ALLOW_ONLY_ABILITY = 0x00800000, // used by bladestorm and killing spree, allowed only spells with SPELL_ATTR0_REQ_AMMO, SPELL_EFFECT_ATTACK, checked only for active player
|
||||
PLAYER_FLAGS_UNK24 = 0x01000000, // disabled all melee ability on tab include autoattack
|
||||
PLAYER_FLAGS_PET_BATTLES_UNLOCKED = 0x01000000, // enables pet battles
|
||||
PLAYER_FLAGS_NO_XP_GAIN = 0x02000000,
|
||||
PLAYER_FLAGS_UNK26 = 0x04000000,
|
||||
PLAYER_FLAGS_AUTO_DECLINE_GUILD = 0x08000000, // Automatically declines guild invites
|
||||
|
||||
@@ -368,7 +368,7 @@ void Guild::BankTab::LoadFromDB(Field* fields)
|
||||
|
||||
bool Guild::BankTab::LoadItemFromDB(Field* fields)
|
||||
{
|
||||
uint8 slotId = fields[19].GetUInt8();
|
||||
uint8 slotId = fields[23].GetUInt8();
|
||||
ObjectGuid::LowType itemGuid = fields[0].GetUInt64();
|
||||
uint32 itemEntry = fields[1].GetUInt32();
|
||||
if (slotId >= GUILD_BANK_MAX_SLOTS)
|
||||
@@ -2395,7 +2395,7 @@ void Guild::LoadBankTabFromDB(Field* fields)
|
||||
|
||||
bool Guild::LoadBankItemFromDB(Field* fields)
|
||||
{
|
||||
uint8 tabId = fields[18].GetUInt8();
|
||||
uint8 tabId = fields[22].GetUInt8();
|
||||
if (tabId >= _GetPurchasedTabsSize())
|
||||
{
|
||||
TC_LOG_ERROR("guild", "Invalid tab for item (GUID: %u, id: #%u) in guild bank, skipped.",
|
||||
|
||||
@@ -395,10 +395,10 @@ void GuildMgr::LoadGuilds()
|
||||
// Delete orphan guild bank items
|
||||
CharacterDatabase.DirectExecute("DELETE gbi FROM guild_bank_item gbi LEFT JOIN guild g ON gbi.guildId = g.guildId WHERE g.guildId IS NULL");
|
||||
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
||||
// SELECT guid, itemEntry, creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text, transmogrification, upgradeId, enchantIllusion, bonusListIDs,
|
||||
// 17 18 19
|
||||
// guildid, TabId, SlotId FROM guild_bank_item gbi INNER JOIN item_instance ii ON gbi.item_guid = ii.guid
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
// SELECT guid, itemEntry, creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text, transmogrification, upgradeId, enchantIllusion,
|
||||
// 17 18 19 20 21 22 23
|
||||
// battlePetSpeciesId, battlePetBreedData, battlePetLevel, battlePetDisplayId, guildid, TabId, SlotId FROM guild_bank_item gbi INNER JOIN item_instance ii ON gbi.item_guid = ii.guid
|
||||
|
||||
PreparedQueryResult result = CharacterDatabase.Query(CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_BANK_ITEMS));
|
||||
if (!result)
|
||||
@@ -411,7 +411,7 @@ void GuildMgr::LoadGuilds()
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
uint64 guildId = fields[17].GetUInt64();
|
||||
uint64 guildId = fields[21].GetUInt64();
|
||||
|
||||
if (Guild* guild = GetGuildById(guildId))
|
||||
guild->LoadBankItemFromDB(fields);
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "WorldSession.h"
|
||||
#include "BattlePetMgr.h"
|
||||
#include "BattlePetPackets.h"
|
||||
#include "Player.h"
|
||||
|
||||
void WorldSession::HandleBattlePetRequestJournal(WorldPackets::BattlePet::BattlePetRequestJournal& /*battlePetRequestJournal*/)
|
||||
{
|
||||
// TODO: Move this to BattlePetMgr::SendJournal() just to have all packets in one file
|
||||
WorldPackets::BattlePet::BattlePetJournal battlePetJournal;
|
||||
battlePetJournal.Trap = GetBattlePetMgr()->GetTrapLevel();
|
||||
|
||||
for (auto itr : GetBattlePetMgr()->GetLearnedPets())
|
||||
battlePetJournal.Pets.push_back(itr.PacketInfo);
|
||||
|
||||
battlePetJournal.Slots = GetBattlePetMgr()->GetSlots();
|
||||
SendPacket(battlePetJournal.Write());
|
||||
}
|
||||
|
||||
void WorldSession::HandleBattlePetSetBattleSlot(WorldPackets::BattlePet::BattlePetSetBattleSlot& battlePetSetBattleSlot)
|
||||
{
|
||||
if (BattlePetMgr::BattlePet* pet = GetBattlePetMgr()->GetPet(battlePetSetBattleSlot.PetGuid))
|
||||
GetBattlePetMgr()->GetSlot(battlePetSetBattleSlot.Slot)->Pet = pet->PacketInfo;
|
||||
}
|
||||
|
||||
void WorldSession::HandleBattlePetModifyName(WorldPackets::BattlePet::BattlePetModifyName& battlePetModifyName)
|
||||
{
|
||||
if (BattlePetMgr::BattlePet* pet = GetBattlePetMgr()->GetPet(battlePetModifyName.PetGuid))
|
||||
{
|
||||
pet->PacketInfo.Name = battlePetModifyName.Name;
|
||||
|
||||
if (pet->SaveInfo != BATTLE_PET_NEW)
|
||||
pet->SaveInfo = BATTLE_PET_CHANGED;
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::HandleBattlePetDeletePet(WorldPackets::BattlePet::BattlePetDeletePet& battlePetDeletePet)
|
||||
{
|
||||
GetBattlePetMgr()->RemovePet(battlePetDeletePet.PetGuid);
|
||||
}
|
||||
|
||||
void WorldSession::HandleBattlePetSetFlags(WorldPackets::BattlePet::BattlePetSetFlags& battlePetSetFlags)
|
||||
{
|
||||
if (BattlePetMgr::BattlePet* pet = GetBattlePetMgr()->GetPet(battlePetSetFlags.PetGuid))
|
||||
{
|
||||
if (battlePetSetFlags.ControlType == 2) // 2 - apply
|
||||
pet->PacketInfo.Flags |= battlePetSetFlags.Flags;
|
||||
else // 3 - remove
|
||||
pet->PacketInfo.Flags &= ~battlePetSetFlags.Flags;
|
||||
|
||||
if (pet->SaveInfo != BATTLE_PET_NEW)
|
||||
pet->SaveInfo = BATTLE_PET_CHANGED;
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::HandleCageBattlePet(WorldPackets::BattlePet::CageBattlePet& cageBattlePet)
|
||||
{
|
||||
GetBattlePetMgr()->CageBattlePet(cageBattlePet.PetGuid);
|
||||
}
|
||||
|
||||
void WorldSession::HandleBattlePetSummon(WorldPackets::BattlePet::BattlePetSummon& battlePetSummon)
|
||||
{
|
||||
GetBattlePetMgr()->SummonPet(battlePetSummon.PetGuid);
|
||||
}
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "AuthenticationPackets.h"
|
||||
#include "Battleground.h"
|
||||
#include "BattlenetServerManager.h"
|
||||
#include "BattlePetPackets.h"
|
||||
#include "CalendarMgr.h"
|
||||
#include "CharacterPackets.h"
|
||||
#include "Chat.h"
|
||||
@@ -985,6 +986,10 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
|
||||
hotfixInfo.Hotfixes = sDB2Manager.GetHotfixData();
|
||||
SendPacket(hotfixInfo.Write());
|
||||
|
||||
// TODO: Move this to BattlePetMgr::SendJournalLock() just to have all packets in one file
|
||||
WorldPackets::BattlePet::BattlePetJournalLockAcquired lock;
|
||||
SendPacket(lock.Write());
|
||||
|
||||
pCurrChar->SendInitialPacketsBeforeAddToMap();
|
||||
|
||||
//Show cinematic at the first time that player login
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "DB2Stores.h"
|
||||
#include "NPCPackets.h"
|
||||
#include "ItemPackets.h"
|
||||
#include "BattlePetMgr.h"
|
||||
|
||||
void WorldSession::HandleSplitItemOpcode(WorldPackets::Item::SplitItem& splitItem)
|
||||
{
|
||||
@@ -1264,3 +1265,21 @@ bool WorldSession::CanUseBank(ObjectGuid bankerGUID) const
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WorldSession::HandleUseCritterItem(WorldPackets::Item::UseCritterItem& useCritterItem)
|
||||
{
|
||||
Item* item = _player->GetItemByGuid(useCritterItem.ItemGuid);
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
ItemToBattlePetSpeciesEntry const* itemToBattlePetSpecies = sItemToBattlePetSpeciesStore.LookupEntry(item->GetEntry());
|
||||
if (!itemToBattlePetSpecies)
|
||||
return;
|
||||
|
||||
BattlePetSpeciesEntry const* battlePetSpecies = sBattlePetSpeciesStore.LookupEntry(itemToBattlePetSpecies->BattlePetSpeciesID);
|
||||
if (!battlePetSpecies)
|
||||
return;
|
||||
|
||||
GetBattlePetMgr()->AddPet(battlePetSpecies->ID, battlePetSpecies->CreatureID, BattlePetMgr::RollPetBreed(battlePetSpecies->ID), BattlePetMgr::GetDefaultPetQuality(battlePetSpecies->ID));
|
||||
_player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "BattlePetPackets.h"
|
||||
#include "World.h"
|
||||
|
||||
ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::BattlePet::BattlePetSlot const& slot)
|
||||
{
|
||||
data << (slot.Pet.Guid.IsEmpty() ? ObjectGuid::Create<HighGuid::BattlePet>(0) : slot.Pet.Guid);
|
||||
data << slot.CollarID;
|
||||
data << slot.Index;
|
||||
data.WriteBit(slot.Locked);
|
||||
data.FlushBits();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::BattlePet::BattlePet const& pet)
|
||||
{
|
||||
data << pet.Guid;
|
||||
data << pet.Species;
|
||||
data << pet.CreatureID;
|
||||
data << pet.CollarID;
|
||||
data << pet.Breed;
|
||||
data << pet.Level;
|
||||
data << pet.Exp;
|
||||
data << pet.Flags;
|
||||
data << pet.Power;
|
||||
data << pet.Health;
|
||||
data << pet.MaxHealth;
|
||||
data << pet.Speed;
|
||||
data << pet.Quality;
|
||||
data.WriteBits(pet.Name.size(), 7);
|
||||
data.WriteBit(!pet.Owner.IsEmpty()); // HasOwnerInfo
|
||||
data.WriteBit(pet.Name.empty()); // NoRename
|
||||
data.FlushBits();
|
||||
|
||||
if (!pet.Owner.IsEmpty())
|
||||
{
|
||||
data << pet.Owner;
|
||||
data << GetVirtualRealmAddress(); // Virtual
|
||||
data << GetVirtualRealmAddress(); // Native
|
||||
}
|
||||
|
||||
data.WriteString(pet.Name);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
WorldPacket const* WorldPackets::BattlePet::BattlePetJournal::Write()
|
||||
{
|
||||
_worldPacket << Trap;
|
||||
_worldPacket << Slots.size();
|
||||
_worldPacket << Pets.size();
|
||||
|
||||
for (auto const& slot : Slots)
|
||||
_worldPacket << slot;
|
||||
|
||||
for (auto const& pet : Pets)
|
||||
_worldPacket << pet;
|
||||
|
||||
_worldPacket.WriteBit(1); // HasJournalLock
|
||||
_worldPacket.FlushBits();
|
||||
|
||||
return &_worldPacket;
|
||||
}
|
||||
|
||||
WorldPacket const* WorldPackets::BattlePet::BattlePetUpdates::Write()
|
||||
{
|
||||
_worldPacket << Pets.size();
|
||||
|
||||
for (auto const& pet : Pets)
|
||||
_worldPacket << pet;
|
||||
|
||||
_worldPacket.WriteBit(PetAdded);
|
||||
_worldPacket.FlushBits();
|
||||
|
||||
return &_worldPacket;
|
||||
}
|
||||
|
||||
|
||||
WorldPacket const* WorldPackets::BattlePet::PetBattleSlotUpdates::Write()
|
||||
{
|
||||
_worldPacket << Slots.size();
|
||||
|
||||
for (auto const& slot : Slots)
|
||||
_worldPacket << slot;
|
||||
|
||||
_worldPacket.WriteBit(NewSlot);
|
||||
_worldPacket.WriteBit(AutoSlotted);
|
||||
_worldPacket.FlushBits();
|
||||
|
||||
return &_worldPacket;
|
||||
}
|
||||
|
||||
void WorldPackets::BattlePet::BattlePetSetBattleSlot::Read()
|
||||
{
|
||||
_worldPacket >> PetGuid;
|
||||
_worldPacket >> Slot;
|
||||
}
|
||||
|
||||
void WorldPackets::BattlePet::BattlePetModifyName::Read()
|
||||
{
|
||||
_worldPacket >> PetGuid;
|
||||
uint32 nameLength = _worldPacket.ReadBits(7);
|
||||
bool hasDeclinedNames = _worldPacket.ReadBit();
|
||||
Name = _worldPacket.ReadString(nameLength);
|
||||
|
||||
if (hasDeclinedNames)
|
||||
{
|
||||
uint8 declinedNameLengths[MAX_DECLINED_NAME_CASES];
|
||||
|
||||
for (uint8 i = 0; i < 5; ++i)
|
||||
declinedNameLengths[i] = _worldPacket.ReadBits(7);
|
||||
|
||||
for (uint8 i = 0; i < 5; ++i)
|
||||
Declined.name[i] = _worldPacket.ReadString(declinedNameLengths[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void WorldPackets::BattlePet::BattlePetDeletePet::Read()
|
||||
{
|
||||
_worldPacket >> PetGuid;
|
||||
}
|
||||
|
||||
void WorldPackets::BattlePet::BattlePetSetFlags::Read()
|
||||
{
|
||||
_worldPacket >> PetGuid;
|
||||
_worldPacket >> Flags;
|
||||
ControlType = _worldPacket.ReadBits(2);
|
||||
}
|
||||
|
||||
void WorldPackets::BattlePet::CageBattlePet::Read()
|
||||
{
|
||||
_worldPacket >> PetGuid;
|
||||
}
|
||||
|
||||
WorldPacket const* WorldPackets::BattlePet::BattlePetDeleted::Write()
|
||||
{
|
||||
_worldPacket << PetGuid;
|
||||
|
||||
return &_worldPacket;
|
||||
}
|
||||
|
||||
WorldPacket const* WorldPackets::BattlePet::BattlePetError::Write()
|
||||
{
|
||||
_worldPacket.WriteBits(Result, 4);
|
||||
_worldPacket.FlushBits();
|
||||
_worldPacket << CreatureID;
|
||||
|
||||
return &_worldPacket;
|
||||
}
|
||||
|
||||
void WorldPackets::BattlePet::BattlePetSummon::Read()
|
||||
{
|
||||
_worldPacket >> PetGuid;
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BattlePetPackets_h__
|
||||
#define BattlePetPackets_h__
|
||||
|
||||
#include "Packet.h"
|
||||
#include "ObjectGuid.h"
|
||||
|
||||
namespace WorldPackets
|
||||
{
|
||||
namespace BattlePet
|
||||
{
|
||||
struct BattlePet
|
||||
{
|
||||
ObjectGuid Guid;
|
||||
uint32 Species = 0;
|
||||
uint32 CreatureID = 0;
|
||||
uint32 CollarID = 0; // what's this?
|
||||
uint16 Breed = 0;
|
||||
uint16 Level = 0;
|
||||
uint16 Exp = 0;
|
||||
uint16 Flags = 0;
|
||||
uint32 Power = 0;
|
||||
uint32 Health = 0;
|
||||
uint32 MaxHealth = 0;
|
||||
uint32 Speed = 0;
|
||||
uint8 Quality = 0;
|
||||
ObjectGuid Owner; // for non-account wide pets only? (Guild Page, Guild Herald)
|
||||
std::string Name;
|
||||
};
|
||||
|
||||
struct BattlePetSlot
|
||||
{
|
||||
BattlePet Pet;
|
||||
uint32 CollarID = 0; // what's this?
|
||||
uint8 Index = 0;
|
||||
bool Locked = true;
|
||||
};
|
||||
|
||||
class BattlePetJournal final : public ServerPacket
|
||||
{
|
||||
public:
|
||||
BattlePetJournal() : ServerPacket(SMSG_BATTLE_PET_JOURNAL) { }
|
||||
|
||||
WorldPacket const* Write() override;
|
||||
|
||||
uint16 Trap = 0;
|
||||
std::vector<BattlePetSlot> Slots;
|
||||
std::vector<BattlePet> Pets;
|
||||
};
|
||||
|
||||
class BattlePetJournalLockAcquired final : public ServerPacket
|
||||
{
|
||||
public:
|
||||
BattlePetJournalLockAcquired() : ServerPacket(SMSG_BATTLE_PET_JOURNAL_LOCK_ACQUIRED, 0) { }
|
||||
|
||||
WorldPacket const* Write() override { return &_worldPacket; }
|
||||
};
|
||||
|
||||
class BattlePetRequestJournal final : public ClientPacket
|
||||
{
|
||||
public:
|
||||
BattlePetRequestJournal(WorldPacket&& packet) : ClientPacket(CMSG_BATTLE_PET_REQUEST_JOURNAL, std::move(packet)) { }
|
||||
|
||||
void Read() override { }
|
||||
};
|
||||
|
||||
class BattlePetUpdates final : public ServerPacket
|
||||
{
|
||||
public:
|
||||
BattlePetUpdates() : ServerPacket(SMSG_BATTLE_PET_UPDATES) { }
|
||||
|
||||
WorldPacket const* Write() override;
|
||||
|
||||
std::vector<BattlePet> Pets;
|
||||
bool PetAdded = false;
|
||||
};
|
||||
|
||||
class PetBattleSlotUpdates final : public ServerPacket
|
||||
{
|
||||
public:
|
||||
PetBattleSlotUpdates() : ServerPacket(SMSG_PET_BATTLE_SLOT_UPDATES) { }
|
||||
|
||||
WorldPacket const* Write() override;
|
||||
|
||||
std::vector<BattlePetSlot> Slots;
|
||||
bool AutoSlotted = false;
|
||||
bool NewSlot = false;
|
||||
};
|
||||
|
||||
class BattlePetSetBattleSlot final : public ClientPacket
|
||||
{
|
||||
public:
|
||||
BattlePetSetBattleSlot(WorldPacket&& packet) : ClientPacket(CMSG_BATTLE_PET_SET_BATTLE_SLOT, std::move(packet)) { }
|
||||
|
||||
void Read() override;
|
||||
|
||||
ObjectGuid PetGuid;
|
||||
uint8 Slot = 0;
|
||||
};
|
||||
|
||||
class BattlePetModifyName final : public ClientPacket
|
||||
{
|
||||
public:
|
||||
BattlePetModifyName(WorldPacket&& packet) : ClientPacket(CMSG_BATTLE_PET_MODIFY_NAME, std::move(packet)) { }
|
||||
|
||||
void Read() override;
|
||||
|
||||
ObjectGuid PetGuid;
|
||||
std::string Name;
|
||||
DeclinedName Declined;
|
||||
};
|
||||
|
||||
class BattlePetDeletePet final : public ClientPacket
|
||||
{
|
||||
public:
|
||||
BattlePetDeletePet(WorldPacket&& packet) : ClientPacket(CMSG_BATTLE_PET_DELETE_PET, std::move(packet)) { }
|
||||
|
||||
void Read() override;
|
||||
|
||||
ObjectGuid PetGuid;
|
||||
};
|
||||
|
||||
class BattlePetSetFlags final : public ClientPacket
|
||||
{
|
||||
public:
|
||||
BattlePetSetFlags(WorldPacket&& packet) : ClientPacket(CMSG_BATTLE_PET_SET_FLAGS, std::move(packet)) { }
|
||||
|
||||
void Read() override;
|
||||
|
||||
ObjectGuid PetGuid;
|
||||
uint32 Flags = 0;
|
||||
uint8 ControlType = 0;
|
||||
};
|
||||
|
||||
class CageBattlePet final : public ClientPacket
|
||||
{
|
||||
public:
|
||||
CageBattlePet(WorldPacket&& packet) : ClientPacket(CMSG_CAGE_BATTLE_PET, std::move(packet)) { }
|
||||
|
||||
void Read() override;
|
||||
|
||||
ObjectGuid PetGuid;
|
||||
};
|
||||
|
||||
class BattlePetDeleted final : public ServerPacket
|
||||
{
|
||||
public:
|
||||
BattlePetDeleted() : ServerPacket(SMSG_BATTLE_PET_DELETED, 16) { }
|
||||
|
||||
WorldPacket const* Write() override;
|
||||
|
||||
ObjectGuid PetGuid;
|
||||
};
|
||||
|
||||
class BattlePetError final : public ServerPacket
|
||||
{
|
||||
public:
|
||||
BattlePetError() : ServerPacket(SMSG_BATTLE_PET_ERROR, 5) { }
|
||||
|
||||
WorldPacket const* Write() override;
|
||||
|
||||
uint8 Result = 0;
|
||||
uint32 CreatureID = 0;
|
||||
};
|
||||
|
||||
class BattlePetSummon final : public ClientPacket
|
||||
{
|
||||
public:
|
||||
BattlePetSummon(WorldPacket&& packet) : ClientPacket(CMSG_BATTLE_PET_SUMMON, std::move(packet)) { }
|
||||
|
||||
void Read() override;
|
||||
|
||||
ObjectGuid PetGuid;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // BattlePetPackets_h__
|
||||
@@ -461,3 +461,8 @@ void WorldPackets::Item::TransmogrifyItems::Read()
|
||||
for (TransmogrifyItem& item : Items)
|
||||
_worldPacket >> item;
|
||||
}
|
||||
|
||||
void WorldPackets::Item::UseCritterItem::Read()
|
||||
{
|
||||
_worldPacket >> ItemGuid;
|
||||
}
|
||||
|
||||
@@ -428,6 +428,16 @@ namespace WorldPackets
|
||||
Array<TransmogrifyItem, MAX_TRANSMOGRIFY_ITEMS> Items;
|
||||
};
|
||||
|
||||
class UseCritterItem final : public ClientPacket
|
||||
{
|
||||
public:
|
||||
UseCritterItem(WorldPacket&& packet) : ClientPacket(CMSG_USE_CRITTER_ITEM, std::move(packet)) { }
|
||||
|
||||
void Read() override;
|
||||
|
||||
ObjectGuid ItemGuid;
|
||||
};
|
||||
|
||||
ByteBuffer& operator>>(ByteBuffer& data, InvUpdate& invUpdate);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "Packets/AuctionHousePackets.h"
|
||||
#include "Packets/BankPackets.h"
|
||||
#include "Packets/BattlegroundPackets.h"
|
||||
#include "Packets/BattlePetPackets.h"
|
||||
#include "Packets/BlackMarketPackets.h"
|
||||
#include "Packets/CalendarPackets.h"
|
||||
#include "Packets/ChannelPackets.h"
|
||||
@@ -205,14 +206,14 @@ void OpcodeTable::Initialize()
|
||||
DEFINE_HANDLER(CMSG_BATTLE_PAY_GET_PURCHASE_LIST, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
|
||||
DEFINE_HANDLER(CMSG_BATTLE_PAY_START_PURCHASE, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
|
||||
DEFINE_HANDLER(CMSG_BATTLE_PAY_START_VAS_PURCHASE, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
|
||||
DEFINE_HANDLER(CMSG_BATTLE_PET_DELETE_PET, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
|
||||
DEFINE_HANDLER(CMSG_BATTLE_PET_DELETE_PET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::BattlePet::BattlePetDeletePet, &WorldSession::HandleBattlePetDeletePet);
|
||||
DEFINE_HANDLER(CMSG_BATTLE_PET_DELETE_PET_CHEAT, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
|
||||
DEFINE_HANDLER(CMSG_BATTLE_PET_MODIFY_NAME, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
|
||||
DEFINE_HANDLER(CMSG_BATTLE_PET_REQUEST_JOURNAL, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
|
||||
DEFINE_HANDLER(CMSG_BATTLE_PET_MODIFY_NAME, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::BattlePet::BattlePetModifyName, &WorldSession::HandleBattlePetModifyName);
|
||||
DEFINE_HANDLER(CMSG_BATTLE_PET_REQUEST_JOURNAL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::BattlePet::BattlePetRequestJournal, &WorldSession::HandleBattlePetRequestJournal);
|
||||
DEFINE_HANDLER(CMSG_BATTLE_PET_REQUEST_JOURNAL_LOCK, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
|
||||
DEFINE_HANDLER(CMSG_BATTLE_PET_SET_BATTLE_SLOT, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
|
||||
DEFINE_HANDLER(CMSG_BATTLE_PET_SET_FLAGS, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
|
||||
DEFINE_HANDLER(CMSG_BATTLE_PET_SUMMON, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
|
||||
DEFINE_HANDLER(CMSG_BATTLE_PET_SET_BATTLE_SLOT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::BattlePet::BattlePetSetBattleSlot, &WorldSession::HandleBattlePetSetBattleSlot);
|
||||
DEFINE_HANDLER(CMSG_BATTLE_PET_SET_FLAGS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::BattlePet::BattlePetSetFlags, &WorldSession::HandleBattlePetSetFlags);
|
||||
DEFINE_HANDLER(CMSG_BATTLE_PET_SUMMON, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::BattlePet::BattlePetSummon, &WorldSession::HandleBattlePetSummon);
|
||||
DEFINE_HANDLER(CMSG_BATTLE_PET_UPDATE_NOTIFY, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
|
||||
DEFINE_HANDLER(CMSG_BEGIN_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Trade::BeginTrade, &WorldSession::HandleBeginTradeOpcode);
|
||||
DEFINE_OPCODE_HANDLER_OLD(CMSG_BF_MGR_ENTRY_INVITE_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleBfEntryInviteResponse );
|
||||
@@ -231,7 +232,7 @@ void OpcodeTable::Initialize()
|
||||
DEFINE_HANDLER(CMSG_BUY_REAGENT_BANK, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
|
||||
DEFINE_HANDLER(CMSG_BUY_WOW_TOKEN_CONFIRM, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
|
||||
DEFINE_HANDLER(CMSG_BUY_WOW_TOKEN_START, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
|
||||
DEFINE_HANDLER(CMSG_CAGE_BATTLE_PET, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
|
||||
DEFINE_HANDLER(CMSG_CAGE_BATTLE_PET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::BattlePet::CageBattlePet, &WorldSession::HandleCageBattlePet);
|
||||
DEFINE_HANDLER(CMSG_CALENDAR_ADD_EVENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Calendar::CalendarAddEvent, &WorldSession::HandleCalendarAddEvent);
|
||||
DEFINE_OPCODE_HANDLER_OLD(CMSG_CALENDAR_COMPLAIN, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarComplain );
|
||||
DEFINE_HANDLER(CMSG_CALENDAR_COPY_EVENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Calendar::CalendarCopyEvent, &WorldSession::HandleCalendarCopyEvent);
|
||||
@@ -813,7 +814,7 @@ void OpcodeTable::Initialize()
|
||||
DEFINE_HANDLER(CMSG_UPGRADE_GARRISON, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
|
||||
DEFINE_HANDLER(CMSG_UPGRADE_ITEM, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
|
||||
DEFINE_HANDLER(CMSG_USED_FOLLOW, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
|
||||
DEFINE_HANDLER(CMSG_USE_CRITTER_ITEM, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
|
||||
DEFINE_HANDLER(CMSG_USE_CRITTER_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::UseCritterItem, &WorldSession::HandleUseCritterItem);
|
||||
DEFINE_HANDLER(CMSG_USE_EQUIPMENT_SET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::EquipmentSet::UseEquipmentSet, &WorldSession::HandleUseEquipmentSet);
|
||||
DEFINE_HANDLER(CMSG_USE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Spells::UseItem, &WorldSession::HandleUseItemOpcode);
|
||||
DEFINE_HANDLER(CMSG_USE_TOY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Toy::UseToy, &WorldSession::HandleUseToy);
|
||||
@@ -916,16 +917,16 @@ void OpcodeTable::Initialize()
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PAY_START_PURCHASE_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PETS_HEALED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PET_CAGE_DATE_ERROR, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PET_DELETED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PET_ERROR, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PET_JOURNAL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PET_JOURNAL_LOCK_ACQUIRED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PET_DELETED, STATUS_NEVER, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PET_ERROR, STATUS_NEVER, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PET_JOURNAL, STATUS_NEVER, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PET_JOURNAL_LOCK_ACQUIRED, STATUS_NEVER, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PET_JOURNAL_LOCK_DENIED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PET_LICENSE_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PET_RESTORED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PET_REVOKED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PET_TRAP_LEVEL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PET_UPDATES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PET_UPDATES, STATUS_NEVER, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BF_MGR_DROP_TIMER_CANCELLED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BF_MGR_DROP_TIMER_STARTED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BF_MGR_EJECTED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
|
||||
@@ -1458,7 +1459,7 @@ void OpcodeTable::Initialize()
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_BATTLE_REPLACEMENTS_MADE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_BATTLE_REQUEST_FAILED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_BATTLE_ROUND_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_BATTLE_SLOT_UPDATES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_BATTLE_SLOT_UPDATES, STATUS_NEVER, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_CAST_FAILED, STATUS_NEVER, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_CLEAR_SPELLS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_DISMISS_SOUND, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "ClientConfigPackets.h"
|
||||
#include "MiscPackets.h"
|
||||
#include "ChatPackets.h"
|
||||
#include "BattlePetMgr.h"
|
||||
#include "PacketUtilities.h"
|
||||
|
||||
#include <zlib.h>
|
||||
@@ -130,7 +131,8 @@ WorldSession::WorldSession(uint32 id, std::string&& name, uint32 battlenetAccoun
|
||||
_RBACData(NULL),
|
||||
expireTime(60000), // 1 min after socket loss, session is deleted
|
||||
forceExit(false),
|
||||
m_currentBankerGUID()
|
||||
m_currentBankerGUID(),
|
||||
_battlePetMgr(Trinity::make_unique<BattlePetMgr>(this))
|
||||
{
|
||||
memset(_tutorials, 0, sizeof(_tutorials));
|
||||
|
||||
@@ -1191,6 +1193,8 @@ public:
|
||||
enum
|
||||
{
|
||||
GLOBAL_ACCOUNT_TOYS = 0,
|
||||
BATTLE_PETS,
|
||||
BATTLE_PET_SLOTS,
|
||||
|
||||
MAX_QUERIES
|
||||
};
|
||||
@@ -1205,6 +1209,14 @@ public:
|
||||
stmt->setUInt32(0, battlenetAccountId);
|
||||
ok = SetPreparedQuery(GLOBAL_ACCOUNT_TOYS, stmt) && ok;
|
||||
|
||||
stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BATTLE_PETS);
|
||||
stmt->setUInt32(0, battlenetAccountId);
|
||||
ok = SetPreparedQuery(BATTLE_PETS, stmt) && ok;
|
||||
|
||||
stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BATTLE_PET_SLOTS);
|
||||
stmt->setUInt32(0, battlenetAccountId);
|
||||
ok = SetPreparedQuery(BATTLE_PET_SLOTS, stmt) && ok;
|
||||
|
||||
return ok;
|
||||
}
|
||||
};
|
||||
@@ -1252,6 +1264,9 @@ void WorldSession::InitializeSessionCallback(SQLQueryHolder* realmHolder, SQLQue
|
||||
SendClientCacheVersion(sWorld->getIntConfig(CONFIG_CLIENTCACHE_VERSION));
|
||||
SendTutorialsData();
|
||||
|
||||
_battlePetMgr->LoadFromDB(holder->GetPreparedResult(AccountInfoQueryHolder::BATTLE_PETS),
|
||||
holder->GetPreparedResult(AccountInfoQueryHolder::BATTLE_PET_SLOTS));
|
||||
|
||||
delete realmHolder;
|
||||
delete holder;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "AccountMgr.h"
|
||||
#include <unordered_set>
|
||||
|
||||
class BattlePetMgr;
|
||||
class Channel;
|
||||
class Creature;
|
||||
class GameObject;
|
||||
@@ -117,6 +118,17 @@ namespace WorldPackets
|
||||
class ReportPvPPlayerAFK;
|
||||
}
|
||||
|
||||
namespace BattlePet
|
||||
{
|
||||
class BattlePetRequestJournal;
|
||||
class BattlePetSetBattleSlot;
|
||||
class BattlePetModifyName;
|
||||
class BattlePetDeletePet;
|
||||
class BattlePetSetFlags;
|
||||
class BattlePetSummon;
|
||||
class CageBattlePet;
|
||||
}
|
||||
|
||||
namespace BlackMarket
|
||||
{
|
||||
class BlackMarketOpen;
|
||||
@@ -320,6 +332,7 @@ namespace WorldPackets
|
||||
class WrapItem;
|
||||
class CancelTempEnchantment;
|
||||
class TransmogrifyItems;
|
||||
class UseCritterItem;
|
||||
}
|
||||
|
||||
namespace Loot
|
||||
@@ -987,6 +1000,9 @@ class WorldSession
|
||||
uint32 GetRecruiterId() const { return recruiterId; }
|
||||
bool IsARecruiter() const { return isRecruiter; }
|
||||
|
||||
// Battle Pets
|
||||
BattlePetMgr* GetBattlePetMgr() const { return _battlePetMgr.get(); }
|
||||
|
||||
public: // opcodes handlers
|
||||
|
||||
void Handle_NULL(WorldPackets::Null& null); // not used
|
||||
@@ -1306,6 +1322,7 @@ class WorldSession
|
||||
void HandleSwapItem(WorldPackets::Item::SwapItem& swapItem);
|
||||
void HandleBuybackItem(WorldPackets::Item::BuyBackItem& packet);
|
||||
void HandleWrapItem(WorldPackets::Item::WrapItem& packet);
|
||||
void HandleUseCritterItem(WorldPackets::Item::UseCritterItem& packet);
|
||||
|
||||
void HandleAttackSwingOpcode(WorldPackets::Combat::AttackSwing& packet);
|
||||
void HandleAttackStopOpcode(WorldPackets::Combat::AttackStop& packet);
|
||||
@@ -1581,6 +1598,15 @@ class WorldSession
|
||||
void HandleGarrisonRequestBlueprintAndSpecializationData(WorldPackets::Garrison::GarrisonRequestBlueprintAndSpecializationData& garrisonRequestBlueprintAndSpecializationData);
|
||||
void HandleGarrisonGetBuildingLandmarks(WorldPackets::Garrison::GarrisonGetBuildingLandmarks& garrisonGetBuildingLandmarks);
|
||||
|
||||
// Battle Pets
|
||||
void HandleBattlePetRequestJournal(WorldPackets::BattlePet::BattlePetRequestJournal& battlePetRequestJournal);
|
||||
void HandleBattlePetSetBattleSlot(WorldPackets::BattlePet::BattlePetSetBattleSlot& battlePetSetBattleSlot);
|
||||
void HandleBattlePetModifyName(WorldPackets::BattlePet::BattlePetModifyName& battlePetModifyName);
|
||||
void HandleBattlePetDeletePet(WorldPackets::BattlePet::BattlePetDeletePet& battlePetDeletePet);
|
||||
void HandleBattlePetSetFlags(WorldPackets::BattlePet::BattlePetSetFlags& battlePetSetFlags);
|
||||
void HandleBattlePetSummon(WorldPackets::BattlePet::BattlePetSummon& battlePetSummon);
|
||||
void HandleCageBattlePet(WorldPackets::BattlePet::CageBattlePet& cageBattlePet);
|
||||
|
||||
private:
|
||||
void InitializeQueryCallbackParameters();
|
||||
void ProcessQueryCallbacks();
|
||||
@@ -1694,6 +1720,8 @@ class WorldSession
|
||||
ObjectGuid m_currentBankerGUID;
|
||||
ToyBoxContainer _toys;
|
||||
|
||||
std::unique_ptr<BattlePetMgr> _battlePetMgr;
|
||||
|
||||
WorldSession(WorldSession const& right) = delete;
|
||||
WorldSession& operator=(WorldSession const& right) = delete;
|
||||
};
|
||||
|
||||
@@ -434,6 +434,9 @@ class Spell
|
||||
void EffectCreateGarrison(SpellEffIndex effIndex);
|
||||
void EffectAddGarrisonFollower(SpellEffIndex effIndex);
|
||||
void EffectActivateGarrisonBuilding(SpellEffIndex effIndex);
|
||||
void EffectHealBattlePetPct(SpellEffIndex effIndex);
|
||||
void EffectEnableBattlePets(SpellEffIndex effIndex);
|
||||
void EffectUncageBattlePet(SpellEffIndex effIndex);
|
||||
|
||||
typedef std::set<Aura*> UsedSpellMods;
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
#include "Guild.h"
|
||||
#include "ReputationMgr.h"
|
||||
#include "AreaTrigger.h"
|
||||
#include "BattlePetMgr.h"
|
||||
#include "Garrison.h"
|
||||
#include "CombatLogPackets.h"
|
||||
#include "DuelPackets.h"
|
||||
@@ -256,7 +257,7 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
|
||||
&Spell::EffectNULL, //189 SPELL_EFFECT_LOOT
|
||||
&Spell::EffectNULL, //190 SPELL_EFFECT_190
|
||||
&Spell::EffectNULL, //191 SPELL_EFFECT_TELEPORT_TO_DIGSITE
|
||||
&Spell::EffectNULL, //192 SPELL_EFFECT_UNCAGE_BATTLEPET
|
||||
&Spell::EffectUncageBattlePet, //192 SPELL_EFFECT_UNCAGE_BATTLEPET
|
||||
&Spell::EffectNULL, //193 SPELL_EFFECT_START_PET_BATTLE
|
||||
&Spell::EffectNULL, //194 SPELL_EFFECT_194
|
||||
&Spell::EffectNULL, //195 SPELL_EFFECT_195
|
||||
@@ -264,8 +265,8 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
|
||||
&Spell::EffectNULL, //197 SPELL_EFFECT_197
|
||||
&Spell::EffectNULL, //198 SPELL_EFFECT_198
|
||||
&Spell::EffectNULL, //199 SPELL_EFFECT_199
|
||||
&Spell::EffectNULL, //200 SPELL_EFFECT_HEAL_BATTLEPET_PCT
|
||||
&Spell::EffectNULL, //201 SPELL_EFFECT_ENABLE_BATTLE_PETS
|
||||
&Spell::EffectHealBattlePetPct, //200 SPELL_EFFECT_HEAL_BATTLEPET_PCT
|
||||
&Spell::EffectEnableBattlePets, //201 SPELL_EFFECT_ENABLE_BATTLE_PETS
|
||||
&Spell::EffectNULL, //202 SPELL_EFFECT_202
|
||||
&Spell::EffectNULL, //203 SPELL_EFFECT_203
|
||||
&Spell::EffectNULL, //204 SPELL_EFFECT_CHANGE_BATTLEPET_QUALITY
|
||||
@@ -2259,6 +2260,22 @@ void Spell::EffectLearnSpell(SpellEffIndex effIndex)
|
||||
uint32 spellToLearn = (m_spellInfo->Id == 483 || m_spellInfo->Id == 55884) ? damage : effectInfo->TriggerSpell;
|
||||
player->LearnSpell(spellToLearn, false);
|
||||
|
||||
if (m_spellInfo->Id == 55884)
|
||||
{
|
||||
if (BattlePetMgr* battlePetMgr = player->GetSession()->GetBattlePetMgr())
|
||||
{
|
||||
for (auto entry : sBattlePetSpeciesStore)
|
||||
{
|
||||
if (entry->SummonSpellID == spellToLearn)
|
||||
{
|
||||
battlePetMgr->AddPet(entry->ID, entry->CreatureID, BattlePetMgr::RollPetBreed(entry->ID), BattlePetMgr::GetDefaultPetQuality(entry->ID));
|
||||
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_OWN_BATTLE_PET_COUNT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TC_LOG_DEBUG("spells", "Spell: %s has learned spell %u from %s", player->GetGUID().ToString().c_str(), spellToLearn, m_caster->GetGUID().ToString().c_str());
|
||||
}
|
||||
|
||||
@@ -5861,3 +5878,85 @@ void Spell::EffectActivateGarrisonBuilding(SpellEffIndex effIndex)
|
||||
if (Garrison* garrison = unitTarget->ToPlayer()->GetGarrison())
|
||||
garrison->ActivateBuilding(GetEffect(effIndex)->MiscValue);
|
||||
}
|
||||
|
||||
void Spell::EffectHealBattlePetPct(SpellEffIndex effIndex)
|
||||
{
|
||||
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
|
||||
return;
|
||||
|
||||
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
if (BattlePetMgr* battlePetMgr = unitTarget->ToPlayer()->GetSession()->GetBattlePetMgr())
|
||||
battlePetMgr->HealBattlePetsPct(GetEffect(effIndex)->BasePoints);
|
||||
}
|
||||
|
||||
void Spell::EffectEnableBattlePets(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
|
||||
return;
|
||||
|
||||
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
Player* plr = unitTarget->ToPlayer();
|
||||
plr->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_PET_BATTLES_UNLOCKED);
|
||||
plr->GetSession()->GetBattlePetMgr()->UnlockSlot(0);
|
||||
}
|
||||
|
||||
void Spell::EffectUncageBattlePet(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT)
|
||||
return;
|
||||
|
||||
if (!m_CastItem || !m_caster || m_caster->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
Player* plr = m_caster->ToPlayer();
|
||||
|
||||
// are we allowed to learn battle pets without it?
|
||||
/*if (plr->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_PET_BATTLES_UNLOCKED))
|
||||
return; // send some error*/
|
||||
|
||||
uint32 speciesId = m_CastItem->GetModifier(ITEM_MODIFIER_BATTLE_PET_SPECIES_ID);
|
||||
uint16 breed = m_CastItem->GetModifier(ITEM_MODIFIER_BATTLE_PET_BREED_DATA) & 0xFFFFFF;
|
||||
uint8 quality = (m_CastItem->GetModifier(ITEM_MODIFIER_BATTLE_PET_BREED_DATA) >> 24) & 0xFF;
|
||||
uint16 level = m_CastItem->GetModifier(ITEM_MODIFIER_BATTLE_PET_LEVEL);
|
||||
uint32 creatureId = m_CastItem->GetModifier(ITEM_MODIFIER_BATTLE_PET_DISPLAY_ID);
|
||||
|
||||
BattlePetSpeciesEntry const* speciesEntry = sBattlePetSpeciesStore.LookupEntry(speciesId);
|
||||
if (!speciesEntry)
|
||||
return;
|
||||
|
||||
BattlePetMgr* battlePetMgr = plr->GetSession()->GetBattlePetMgr();
|
||||
if (!battlePetMgr)
|
||||
return;
|
||||
|
||||
uint16 maxLearnedLevel = 0;
|
||||
|
||||
for (auto pet : battlePetMgr->GetLearnedPets())
|
||||
maxLearnedLevel = std::max(pet.PacketInfo.Level, maxLearnedLevel);
|
||||
|
||||
// TODO: This means if you put your highest lvl pet into cage, you won't be able to uncage it again which is probably wrong.
|
||||
// We will need to store maxLearnedLevel somewhere to avoid this behaviour.
|
||||
if (maxLearnedLevel < level)
|
||||
{
|
||||
battlePetMgr->SendError(BATTLEPETRESULT_TOO_HIGH_LEVEL_TO_UNCAGE, creatureId); // or speciesEntry.CreatureID
|
||||
SendCastResult(SPELL_FAILED_CANT_ADD_BATTLE_PET);
|
||||
return;
|
||||
}
|
||||
|
||||
if (battlePetMgr->GetPetCount(speciesId) >= MAX_BATTLE_PETS_PER_SPECIES)
|
||||
{
|
||||
battlePetMgr->SendError(BATTLEPETRESULT_CANT_HAVE_MORE_PETS_OF_THAT_TYPE, creatureId); // or speciesEntry.CreatureID
|
||||
SendCastResult(SPELL_FAILED_CANT_ADD_BATTLE_PET);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!plr->HasSpell(speciesEntry->SummonSpellID))
|
||||
plr->LearnSpell(speciesEntry->SummonSpellID, false);
|
||||
|
||||
battlePetMgr->AddPet(speciesId, creatureId, breed, quality, level);
|
||||
plr->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
|
||||
m_CastItem = nullptr;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "AuctionHouseMgr.h"
|
||||
#include "BattlefieldMgr.h"
|
||||
#include "BattlegroundMgr.h"
|
||||
#include "BattlePetMgr.h"
|
||||
#include "CalendarMgr.h"
|
||||
#include "Channel.h"
|
||||
#include "CharacterDatabaseCleaner.h"
|
||||
@@ -2026,6 +2027,9 @@ void World::SetInitialWorldSettings()
|
||||
TC_LOG_INFO("server.loading", "Loading realm names...");
|
||||
sObjectMgr->LoadRealmNames();
|
||||
|
||||
TC_LOG_INFO("server.loading", "Loading battle pets info...");
|
||||
BattlePetMgr::Initialize();
|
||||
|
||||
uint32 startupDuration = GetMSTimeDiffToNow(startupBegin);
|
||||
|
||||
TC_LOG_INFO("server.worldserver", "World initialized in %u minutes %u seconds", (startupDuration / 60000), ((startupDuration % 60000) / 1000));
|
||||
|
||||
Reference in New Issue
Block a user