mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 13:37:05 +00:00
Merge branch 'master' into 310
Conflicts: src/game/Player.cpp
This commit is contained in:
commit
f6e2b55e2c
25 changed files with 382 additions and 240 deletions
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
DROP TABLE IF EXISTS `character_db_version`;
|
DROP TABLE IF EXISTS `character_db_version`;
|
||||||
CREATE TABLE `character_db_version` (
|
CREATE TABLE `character_db_version` (
|
||||||
`required_7887_01_characters_character_pet` bit(1) default NULL
|
`required_7903_01_characters_character_pet` bit(1) default NULL
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB';
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB';
|
||||||
|
|
||||||
--
|
--
|
||||||
|
|
@ -472,7 +472,6 @@ CREATE TABLE `character_pet` (
|
||||||
`level` int(11) unsigned NOT NULL default '1',
|
`level` int(11) unsigned NOT NULL default '1',
|
||||||
`exp` int(11) unsigned NOT NULL default '0',
|
`exp` int(11) unsigned NOT NULL default '0',
|
||||||
`Reactstate` tinyint(1) unsigned NOT NULL default '0',
|
`Reactstate` tinyint(1) unsigned NOT NULL default '0',
|
||||||
`talentpoints` int(11) unsigned NOT NULL default '0',
|
|
||||||
`name` varchar(100) default 'Pet',
|
`name` varchar(100) default 'Pet',
|
||||||
`renamed` tinyint(1) unsigned NOT NULL default '0',
|
`renamed` tinyint(1) unsigned NOT NULL default '0',
|
||||||
`slot` int(11) unsigned NOT NULL default '0',
|
`slot` int(11) unsigned NOT NULL default '0',
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ DROP TABLE IF EXISTS `db_version`;
|
||||||
CREATE TABLE `db_version` (
|
CREATE TABLE `db_version` (
|
||||||
`version` varchar(120) default NULL,
|
`version` varchar(120) default NULL,
|
||||||
`creature_ai_version` varchar(120) default NULL,
|
`creature_ai_version` varchar(120) default NULL,
|
||||||
`required_7893_01_mangos_command` bit(1) default NULL
|
`required_7902_02_mangos_pool_gameobject` bit(1) default NULL
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
|
||||||
|
|
||||||
--
|
--
|
||||||
|
|
@ -820,8 +820,8 @@ CREATE TABLE `creature_template` (
|
||||||
`family` tinyint(4) NOT NULL default '0',
|
`family` tinyint(4) NOT NULL default '0',
|
||||||
`trainer_type` tinyint(4) NOT NULL default '0',
|
`trainer_type` tinyint(4) NOT NULL default '0',
|
||||||
`trainer_spell` mediumint(8) unsigned NOT NULL default '0',
|
`trainer_spell` mediumint(8) unsigned NOT NULL default '0',
|
||||||
`class` tinyint(3) unsigned NOT NULL default '0',
|
`trainer_class` tinyint(3) unsigned NOT NULL default '0',
|
||||||
`race` tinyint(3) unsigned NOT NULL default '0',
|
`trainer_race` tinyint(3) unsigned NOT NULL default '0',
|
||||||
`minrangedmg` float NOT NULL default '0',
|
`minrangedmg` float NOT NULL default '0',
|
||||||
`maxrangedmg` float NOT NULL default '0',
|
`maxrangedmg` float NOT NULL default '0',
|
||||||
`rangedattackpower` smallint(5) unsigned NOT NULL default '0',
|
`rangedattackpower` smallint(5) unsigned NOT NULL default '0',
|
||||||
|
|
@ -12938,7 +12938,8 @@ CREATE TABLE `pool_creature` (
|
||||||
`pool_entry` mediumint(8) unsigned NOT NULL default '0',
|
`pool_entry` mediumint(8) unsigned NOT NULL default '0',
|
||||||
`chance` float unsigned NOT NULL default '0',
|
`chance` float unsigned NOT NULL default '0',
|
||||||
`description` varchar(255) NOT NULL,
|
`description` varchar(255) NOT NULL,
|
||||||
PRIMARY KEY (`pool_entry`,`guid`)
|
PRIMARY KEY (`pool_entry`,`guid`),
|
||||||
|
INDEX `idx_guid`(`guid`)
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -12961,7 +12962,8 @@ CREATE TABLE `pool_gameobject` (
|
||||||
`pool_entry` mediumint(8) unsigned NOT NULL default '0',
|
`pool_entry` mediumint(8) unsigned NOT NULL default '0',
|
||||||
`chance` float unsigned NOT NULL default '0',
|
`chance` float unsigned NOT NULL default '0',
|
||||||
`description` varchar(255) NOT NULL,
|
`description` varchar(255) NOT NULL,
|
||||||
PRIMARY KEY (`guid`,`pool_entry`)
|
PRIMARY KEY (`guid`,`pool_entry`),
|
||||||
|
INDEX `idx_guid`(`guid`)
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
--
|
--
|
||||||
|
|
|
||||||
4
sql/updates/7896_01_mangos_creature_template.sql
Normal file
4
sql/updates/7896_01_mangos_creature_template.sql
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
ALTER TABLE db_version CHANGE COLUMN required_7893_01_mangos_command required_7896_01_mangos_creature_template bit;
|
||||||
|
|
||||||
|
ALTER TABLE creature_template CHANGE COLUMN class trainer_class tinyint(3) unsigned NOT NULL default '0';
|
||||||
|
ALTER TABLE creature_template CHANGE COLUMN race trainer_race tinyint(3) unsigned NOT NULL default '0';
|
||||||
4
sql/updates/7902_01_mangos_pool_creature.sql
Normal file
4
sql/updates/7902_01_mangos_pool_creature.sql
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
ALTER TABLE db_version CHANGE COLUMN required_7896_01_mangos_creature_template required_7902_01_mangos_pool_creature bit;
|
||||||
|
|
||||||
|
ALTER TABLE `pool_creature`
|
||||||
|
ADD INDEX `idx_guid`(`guid`);
|
||||||
4
sql/updates/7902_02_mangos_pool_gameobject.sql
Normal file
4
sql/updates/7902_02_mangos_pool_gameobject.sql
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
ALTER TABLE db_version CHANGE COLUMN required_7902_01_mangos_pool_creature required_7902_02_mangos_pool_gameobject bit;
|
||||||
|
|
||||||
|
ALTER TABLE `pool_gameobject`
|
||||||
|
ADD INDEX `idx_guid`(`guid`);
|
||||||
4
sql/updates/7903_01_characters_character_pet.sql
Normal file
4
sql/updates/7903_01_characters_character_pet.sql
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
ALTER TABLE character_db_version CHANGE COLUMN required_7887_01_characters_character_pet required_7903_01_characters_character_pet bit;
|
||||||
|
|
||||||
|
ALTER TABLE `character_pet`
|
||||||
|
DROP `talentpoints`;
|
||||||
|
|
@ -200,6 +200,10 @@ pkgdata_DATA = \
|
||||||
7886_01_mangos_petcreateinfo_spell.sql \
|
7886_01_mangos_petcreateinfo_spell.sql \
|
||||||
7887_01_characters_character_pet.sql \
|
7887_01_characters_character_pet.sql \
|
||||||
7893_01_mangos_command.sql \
|
7893_01_mangos_command.sql \
|
||||||
|
7896_01_mangos_creature_template.sql \
|
||||||
|
7902_01_mangos_pool_creature.sql \
|
||||||
|
7902_02_mangos_pool_gameobject.sql \
|
||||||
|
7903_01_characters_character_pet.sql \
|
||||||
README
|
README
|
||||||
|
|
||||||
## Additional files to include when running 'make dist'
|
## Additional files to include when running 'make dist'
|
||||||
|
|
@ -380,4 +384,8 @@ EXTRA_DIST = \
|
||||||
7886_01_mangos_petcreateinfo_spell.sql \
|
7886_01_mangos_petcreateinfo_spell.sql \
|
||||||
7887_01_characters_character_pet.sql \
|
7887_01_characters_character_pet.sql \
|
||||||
7893_01_mangos_command.sql \
|
7893_01_mangos_command.sql \
|
||||||
|
7896_01_mangos_creature_template.sql \
|
||||||
|
7902_01_mangos_pool_creature.sql \
|
||||||
|
7902_02_mangos_pool_gameobject.sql \
|
||||||
|
7903_01_characters_character_pet.sql \
|
||||||
README
|
README
|
||||||
|
|
|
||||||
|
|
@ -605,12 +605,12 @@ bool Creature::isCanTrainingOf(Player* pPlayer, bool msg) const
|
||||||
switch(GetCreatureInfo()->trainer_type)
|
switch(GetCreatureInfo()->trainer_type)
|
||||||
{
|
{
|
||||||
case TRAINER_TYPE_CLASS:
|
case TRAINER_TYPE_CLASS:
|
||||||
if(pPlayer->getClass()!=GetCreatureInfo()->classNum)
|
if(pPlayer->getClass()!=GetCreatureInfo()->trainer_class)
|
||||||
{
|
{
|
||||||
if(msg)
|
if(msg)
|
||||||
{
|
{
|
||||||
pPlayer->PlayerTalkClass->ClearMenus();
|
pPlayer->PlayerTalkClass->ClearMenus();
|
||||||
switch(GetCreatureInfo()->classNum)
|
switch(GetCreatureInfo()->trainer_class)
|
||||||
{
|
{
|
||||||
case CLASS_DRUID: pPlayer->PlayerTalkClass->SendGossipMenu( 4913,GetGUID()); break;
|
case CLASS_DRUID: pPlayer->PlayerTalkClass->SendGossipMenu( 4913,GetGUID()); break;
|
||||||
case CLASS_HUNTER: pPlayer->PlayerTalkClass->SendGossipMenu(10090,GetGUID()); break;
|
case CLASS_HUNTER: pPlayer->PlayerTalkClass->SendGossipMenu(10090,GetGUID()); break;
|
||||||
|
|
@ -635,12 +635,12 @@ bool Creature::isCanTrainingOf(Player* pPlayer, bool msg) const
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TRAINER_TYPE_MOUNTS:
|
case TRAINER_TYPE_MOUNTS:
|
||||||
if(GetCreatureInfo()->race && pPlayer->getRace() != GetCreatureInfo()->race)
|
if(GetCreatureInfo()->trainer_race && pPlayer->getRace() != GetCreatureInfo()->trainer_race)
|
||||||
{
|
{
|
||||||
if(msg)
|
if(msg)
|
||||||
{
|
{
|
||||||
pPlayer->PlayerTalkClass->ClearMenus();
|
pPlayer->PlayerTalkClass->ClearMenus();
|
||||||
switch(GetCreatureInfo()->classNum)
|
switch(GetCreatureInfo()->trainer_class)
|
||||||
{
|
{
|
||||||
case RACE_DWARF: pPlayer->PlayerTalkClass->SendGossipMenu(5865,GetGUID()); break;
|
case RACE_DWARF: pPlayer->PlayerTalkClass->SendGossipMenu(5865,GetGUID()); break;
|
||||||
case RACE_GNOME: pPlayer->PlayerTalkClass->SendGossipMenu(4881,GetGUID()); break;
|
case RACE_GNOME: pPlayer->PlayerTalkClass->SendGossipMenu(4881,GetGUID()); break;
|
||||||
|
|
@ -710,7 +710,7 @@ bool Creature::isCanTrainingAndResetTalentsOf(Player* pPlayer) const
|
||||||
{
|
{
|
||||||
return pPlayer->getLevel() >= 10
|
return pPlayer->getLevel() >= 10
|
||||||
&& GetCreatureInfo()->trainer_type == TRAINER_TYPE_CLASS
|
&& GetCreatureInfo()->trainer_type == TRAINER_TYPE_CLASS
|
||||||
&& pPlayer->getClass() == GetCreatureInfo()->classNum;
|
&& pPlayer->getClass() == GetCreatureInfo()->trainer_class;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Creature::prepareGossipMenu( Player *pPlayer,uint32 gossipid )
|
void Creature::prepareGossipMenu( Player *pPlayer,uint32 gossipid )
|
||||||
|
|
@ -771,7 +771,7 @@ void Creature::prepareGossipMenu( Player *pPlayer,uint32 gossipid )
|
||||||
cantalking=false;
|
cantalking=false;
|
||||||
break;
|
break;
|
||||||
case GOSSIP_OPTION_UNLEARNPETSKILLS:
|
case GOSSIP_OPTION_UNLEARNPETSKILLS:
|
||||||
if(!pPlayer->GetPet() || pPlayer->GetPet()->getPetType() != HUNTER_PET || pPlayer->GetPet()->m_spells.size() <= 1 || GetCreatureInfo()->trainer_type != TRAINER_TYPE_PETS || GetCreatureInfo()->classNum != CLASS_HUNTER)
|
if(!pPlayer->GetPet() || pPlayer->GetPet()->getPetType() != HUNTER_PET || pPlayer->GetPet()->m_spells.size() <= 1 || GetCreatureInfo()->trainer_type != TRAINER_TYPE_PETS || GetCreatureInfo()->trainer_class != CLASS_HUNTER)
|
||||||
cantalking=false;
|
cantalking=false;
|
||||||
break;
|
break;
|
||||||
case GOSSIP_OPTION_TAXIVENDOR:
|
case GOSSIP_OPTION_TAXIVENDOR:
|
||||||
|
|
|
||||||
|
|
@ -190,8 +190,8 @@ struct CreatureInfo
|
||||||
uint32 family; // enum CreatureFamily values (optional)
|
uint32 family; // enum CreatureFamily values (optional)
|
||||||
uint32 trainer_type;
|
uint32 trainer_type;
|
||||||
uint32 trainer_spell;
|
uint32 trainer_spell;
|
||||||
uint32 classNum;
|
uint32 trainer_class;
|
||||||
uint32 race;
|
uint32 trainer_race;
|
||||||
float minrangedmg;
|
float minrangedmg;
|
||||||
float maxrangedmg;
|
float maxrangedmg;
|
||||||
uint32 rangedattackpower;
|
uint32 rangedattackpower;
|
||||||
|
|
|
||||||
|
|
@ -696,18 +696,19 @@ bool Item::IsEquipped() const
|
||||||
return !IsInBag() && m_slot < EQUIPMENT_SLOT_END;
|
return !IsInBag() && m_slot < EQUIPMENT_SLOT_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Item::CanBeTraded() const
|
bool Item::CanBeTraded(bool mail) const
|
||||||
{
|
{
|
||||||
if(IsSoulBound())
|
if ((!mail || !IsBoundAccountWide()) && IsSoulBound())
|
||||||
return false;
|
|
||||||
if(IsBag() && (Player::IsBagPos(GetPos()) || !((Bag const*)this)->IsEmpty()) )
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(Player* owner = GetOwner())
|
if (IsBag() && (Player::IsBagPos(GetPos()) || !((Bag const*)this)->IsEmpty()) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (Player* owner = GetOwner())
|
||||||
{
|
{
|
||||||
if(owner->CanUnequipItem(GetPos(),false) != EQUIP_ERR_OK )
|
if (owner->CanUnequipItem(GetPos(),false) != EQUIP_ERR_OK )
|
||||||
return false;
|
return false;
|
||||||
if(owner->GetLootGUID()==GetGUID())
|
if (owner->GetLootGUID()==GetGUID())
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -941,3 +942,29 @@ Item* Item::CloneItem( uint32 count, Player const* player ) const
|
||||||
newItem->SetItemRandomProperties(GetItemRandomPropertyId());
|
newItem->SetItemRandomProperties(GetItemRandomPropertyId());
|
||||||
return newItem;
|
return newItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Item::IsBindedNotWith( Player const* player ) const
|
||||||
|
{
|
||||||
|
// not binded item
|
||||||
|
if(!IsSoulBound())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// own item
|
||||||
|
if(GetOwnerGUID()== player->GetGUID())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// not BOA item case
|
||||||
|
if(!IsBoundAccountWide())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// online
|
||||||
|
if(Player* owner = objmgr.GetPlayer(GetOwnerGUID()))
|
||||||
|
{
|
||||||
|
return owner->GetSession()->GetAccountId() != player->GetSession()->GetAccountId();
|
||||||
|
}
|
||||||
|
// offline slow case
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return objmgr.GetPlayerAccountIdByGUID(GetOwnerGUID()) != player->GetSession()->GetAccountId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -116,8 +116,11 @@ enum InventoryChangeFailure
|
||||||
EQUIP_ERR_TOO_MUCH_GOLD = 77,
|
EQUIP_ERR_TOO_MUCH_GOLD = 77,
|
||||||
EQUIP_ERR_NOT_DURING_ARENA_MATCH = 78,
|
EQUIP_ERR_NOT_DURING_ARENA_MATCH = 78,
|
||||||
EQUIP_ERR_CANNOT_TRADE_THAT = 79,
|
EQUIP_ERR_CANNOT_TRADE_THAT = 79,
|
||||||
EQUIP_ERR_PERSONAL_ARENA_RATING_TOO_LOW = 80
|
EQUIP_ERR_PERSONAL_ARENA_RATING_TOO_LOW = 80,
|
||||||
// probably exist more
|
// no output = 81,
|
||||||
|
EQUIP_ERR_ARTEFACTS_ONLY_FOR_OWN_CHARACTERS = 82,
|
||||||
|
// no output = 83,
|
||||||
|
// crash client = 84,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum BuyFailure
|
enum BuyFailure
|
||||||
|
|
@ -212,8 +215,8 @@ class MANGOS_DLL_SPEC Item : public Object
|
||||||
|
|
||||||
void SetBinding(bool val) { ApplyModFlag(ITEM_FIELD_FLAGS,ITEM_FLAGS_BINDED,val); }
|
void SetBinding(bool val) { ApplyModFlag(ITEM_FIELD_FLAGS,ITEM_FLAGS_BINDED,val); }
|
||||||
bool IsSoulBound() const { return HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_BINDED); }
|
bool IsSoulBound() const { return HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_BINDED); }
|
||||||
bool IsAccountBound() const { return HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_BOA); }
|
bool IsBoundAccountWide() const { return HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_BOA); }
|
||||||
bool IsBindedNotWith(uint64 guid) const { return IsSoulBound() && GetOwnerGUID()!= guid; }
|
bool IsBindedNotWith(Player const* player) const;
|
||||||
bool IsBoundByEnchant() const;
|
bool IsBoundByEnchant() const;
|
||||||
virtual void SaveToDB();
|
virtual void SaveToDB();
|
||||||
virtual bool LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult *result = NULL);
|
virtual bool LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult *result = NULL);
|
||||||
|
|
@ -222,7 +225,7 @@ class MANGOS_DLL_SPEC Item : public Object
|
||||||
|
|
||||||
bool IsBag() const { return GetProto()->InventoryType == INVTYPE_BAG; }
|
bool IsBag() const { return GetProto()->InventoryType == INVTYPE_BAG; }
|
||||||
bool IsBroken() const { return GetUInt32Value(ITEM_FIELD_MAXDURABILITY) > 0 && GetUInt32Value(ITEM_FIELD_DURABILITY) == 0; }
|
bool IsBroken() const { return GetUInt32Value(ITEM_FIELD_MAXDURABILITY) > 0 && GetUInt32Value(ITEM_FIELD_DURABILITY) == 0; }
|
||||||
bool CanBeTraded() const;
|
bool CanBeTraded(bool mail = false) const;
|
||||||
void SetInTrade(bool b = true) { mb_in_trade = b; }
|
void SetInTrade(bool b = true) { mb_in_trade = b; }
|
||||||
bool IsInTrade() const { return mb_in_trade; }
|
bool IsInTrade() const { return mb_in_trade; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ enum ItemBondingType
|
||||||
// masks for ITEM_FIELD_FLAGS field
|
// masks for ITEM_FIELD_FLAGS field
|
||||||
enum ITEM_FLAGS
|
enum ITEM_FLAGS
|
||||||
{
|
{
|
||||||
ITEM_FLAGS_BINDED = 0x00000001,
|
ITEM_FLAGS_BINDED = 0x00000001, // set in game at binding, not set in template
|
||||||
ITEM_FLAGS_CONJURED = 0x00000002,
|
ITEM_FLAGS_CONJURED = 0x00000002,
|
||||||
ITEM_FLAGS_OPENABLE = 0x00000004,
|
ITEM_FLAGS_OPENABLE = 0x00000004,
|
||||||
ITEM_FLAGS_WRAPPED = 0x00000008,
|
ITEM_FLAGS_WRAPPED = 0x00000008,
|
||||||
|
|
@ -114,7 +114,7 @@ enum ITEM_FLAGS
|
||||||
ITEM_FLAGS_USEABLE_IN_ARENA = 0x00200000,
|
ITEM_FLAGS_USEABLE_IN_ARENA = 0x00200000,
|
||||||
ITEM_FLAGS_THROWABLE = 0x00400000, // not used in game for check trow possibility, only for item in game tooltip
|
ITEM_FLAGS_THROWABLE = 0x00400000, // not used in game for check trow possibility, only for item in game tooltip
|
||||||
ITEM_FLAGS_SPECIALUSE = 0x00800000, // last used flag in 2.3.0
|
ITEM_FLAGS_SPECIALUSE = 0x00800000, // last used flag in 2.3.0
|
||||||
ITEM_FLAGS_BOA = 0x08000000, // bind on account
|
ITEM_FLAGS_BOA = 0x08000000, // bind on account (set in template for items that can binded in like way)
|
||||||
ITEM_FLAGS_MILLABLE = 0x20000000
|
ITEM_FLAGS_MILLABLE = 0x20000000
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,10 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
||||||
recv_data >> items_count; // attached items count
|
recv_data >> items_count; // attached items count
|
||||||
|
|
||||||
if(items_count > 12) // client limit
|
if(items_count > 12) // client limit
|
||||||
|
{
|
||||||
|
GetPlayer()->SendMailResult(0, MAIL_SEND, MAIL_ERR_TOO_MANY_ATTACHMENTS);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// recheck
|
// recheck
|
||||||
CHECK_PACKET_SIZE(recv_data, 8+(receiver.size()+1)+(subject.size()+1)+(body.size()+1)+4+4+1+items_count*(1+8)+4+4+8+1);
|
CHECK_PACKET_SIZE(recv_data, 8+(receiver.size()+1)+(subject.size()+1)+(body.size()+1)+4+4+1+items_count*(1+8)+4+4+8+1);
|
||||||
|
|
@ -113,7 +116,7 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
||||||
{
|
{
|
||||||
sLog.outDetail("Player %u is sending mail to %s (GUID: not existed!) with subject %s and body %s includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u",
|
sLog.outDetail("Player %u is sending mail to %s (GUID: not existed!) with subject %s and body %s includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u",
|
||||||
pl->GetGUIDLow(), receiver.c_str(), subject.c_str(), body.c_str(), items_count, money, COD, unk1, unk2);
|
pl->GetGUIDLow(), receiver.c_str(), subject.c_str(), body.c_str(), items_count, money, COD, unk1, unk2);
|
||||||
pl->SendMailResult(0, 0, MAIL_ERR_RECIPIENT_NOT_FOUND);
|
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_NOT_FOUND);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -121,7 +124,7 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
||||||
|
|
||||||
if(pl->GetGUID() == rc)
|
if(pl->GetGUID() == rc)
|
||||||
{
|
{
|
||||||
pl->SendMailResult(0, 0, MAIL_ERR_CANNOT_SEND_TO_SELF);
|
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANNOT_SEND_TO_SELF);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -131,7 +134,7 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
||||||
|
|
||||||
if (pl->GetMoney() < reqmoney)
|
if (pl->GetMoney() < reqmoney)
|
||||||
{
|
{
|
||||||
pl->SendMailResult(0, 0, MAIL_ERR_NOT_ENOUGH_MONEY);
|
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_ENOUGH_MONEY);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -159,16 +162,22 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
||||||
//do not allow to have more than 100 mails in mailbox.. mails count is in opcode uint8!!! - so max can be 255..
|
//do not allow to have more than 100 mails in mailbox.. mails count is in opcode uint8!!! - so max can be 255..
|
||||||
if (mails_count > 100)
|
if (mails_count > 100)
|
||||||
{
|
{
|
||||||
pl->SendMailResult(0, 0, MAIL_ERR_INTERNAL_ERROR);
|
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_CAP_REACHED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// test the receiver's Faction...
|
// test the receiver's Faction...
|
||||||
if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL) && pl->GetTeam() != rc_team && GetSecurity() == SEC_PLAYER)
|
if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL) && pl->GetTeam() != rc_team && GetSecurity() == SEC_PLAYER)
|
||||||
{
|
{
|
||||||
pl->SendMailResult(0, 0, MAIL_ERR_NOT_YOUR_TEAM);
|
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_YOUR_TEAM);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 rc_account = 0;
|
||||||
|
if(receive)
|
||||||
|
rc_account = receive->GetSession()->GetAccountId();
|
||||||
|
else
|
||||||
|
rc_account = objmgr.GetPlayerAccountIdByGUID(rc);
|
||||||
|
|
||||||
if (items_count)
|
if (items_count)
|
||||||
{
|
{
|
||||||
for(MailItemMap::iterator mailItemIter = mi.begin(); mailItemIter != mi.end(); ++mailItemIter)
|
for(MailItemMap::iterator mailItemIter = mi.begin(); mailItemIter != mi.end(); ++mailItemIter)
|
||||||
|
|
@ -177,31 +186,44 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
||||||
|
|
||||||
if(!mailItem.item_guidlow)
|
if(!mailItem.item_guidlow)
|
||||||
{
|
{
|
||||||
pl->SendMailResult(0, 0, MAIL_ERR_INTERNAL_ERROR);
|
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mailItem.item = pl->GetItemByGuid(MAKE_NEW_GUID(mailItem.item_guidlow, 0, HIGHGUID_ITEM));
|
mailItem.item = pl->GetItemByGuid(MAKE_NEW_GUID(mailItem.item_guidlow, 0, HIGHGUID_ITEM));
|
||||||
// prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to mail)
|
// prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to mail)
|
||||||
if(!mailItem.item || !mailItem.item->CanBeTraded())
|
if(!mailItem.item)
|
||||||
{
|
{
|
||||||
pl->SendMailResult(0, 0, MAIL_ERR_INTERNAL_ERROR);
|
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!mailItem.item->CanBeTraded(true))
|
||||||
|
{
|
||||||
|
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_MAIL_BOUND_ITEM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mailItem.item->IsBoundAccountWide() && mailItem.item->IsSoulBound() && pl->GetSession()->GetAccountId() != rc_account)
|
||||||
|
{
|
||||||
|
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_ARTEFACTS_ONLY_FOR_OWN_CHARACTERS);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (mailItem.item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_CONJURED) || mailItem.item->GetUInt32Value(ITEM_FIELD_DURATION))
|
if (mailItem.item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_CONJURED) || mailItem.item->GetUInt32Value(ITEM_FIELD_DURATION))
|
||||||
{
|
{
|
||||||
pl->SendMailResult(0, 0, MAIL_ERR_INTERNAL_ERROR);
|
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_MAIL_BOUND_ITEM);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(COD && mailItem.item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED))
|
if(COD && mailItem.item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED))
|
||||||
{
|
{
|
||||||
pl->SendMailResult(0, 0, MAIL_ERR_CANT_SEND_WRAPPED_COD);
|
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANT_SEND_WRAPPED_COD);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pl->SendMailResult(0, 0, MAIL_OK);
|
pl->SendMailResult(0, MAIL_SEND, MAIL_OK);
|
||||||
|
|
||||||
uint32 itemTextId = 0;
|
uint32 itemTextId = 0;
|
||||||
if (!body.empty())
|
if (!body.empty())
|
||||||
|
|
@ -216,12 +238,6 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
||||||
|
|
||||||
if(items_count > 0 || money > 0)
|
if(items_count > 0 || money > 0)
|
||||||
{
|
{
|
||||||
uint32 rc_account = 0;
|
|
||||||
if(receive)
|
|
||||||
rc_account = receive->GetSession()->GetAccountId();
|
|
||||||
else
|
|
||||||
rc_account = objmgr.GetPlayerAccountIdByGUID(rc);
|
|
||||||
|
|
||||||
if (items_count > 0)
|
if (items_count > 0)
|
||||||
{
|
{
|
||||||
for(MailItemMap::iterator mailItemIter = mi.begin(); mailItemIter != mi.end(); ++mailItemIter)
|
for(MailItemMap::iterator mailItemIter = mi.begin(); mailItemIter != mi.end(); ++mailItemIter)
|
||||||
|
|
@ -313,7 +329,7 @@ void WorldSession::HandleMailDelete(WorldPacket & recv_data )
|
||||||
Mail *m = pl->GetMail(mailId);
|
Mail *m = pl->GetMail(mailId);
|
||||||
if(m)
|
if(m)
|
||||||
m->state = MAIL_STATE_DELETED;
|
m->state = MAIL_STATE_DELETED;
|
||||||
pl->SendMailResult(mailId, MAIL_DELETED, 0);
|
pl->SendMailResult(mailId, MAIL_DELETED, MAIL_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::HandleMailReturnToSender(WorldPacket & recv_data )
|
void WorldSession::HandleMailReturnToSender(WorldPacket & recv_data )
|
||||||
|
|
@ -365,7 +381,7 @@ void WorldSession::HandleMailReturnToSender(WorldPacket & recv_data )
|
||||||
SendReturnToSender(MAIL_NORMAL, GetAccountId(), m->receiver, m->sender, m->subject, m->itemTextId, &mi, m->money, m->mailTemplateId);
|
SendReturnToSender(MAIL_NORMAL, GetAccountId(), m->receiver, m->sender, m->subject, m->itemTextId, &mi, m->money, m->mailTemplateId);
|
||||||
|
|
||||||
delete m; //we can deallocate old mail
|
delete m; //we can deallocate old mail
|
||||||
pl->SendMailResult(mailId, MAIL_RETURNED_TO_SENDER, 0);
|
pl->SendMailResult(mailId, MAIL_RETURNED_TO_SENDER, MAIL_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::SendReturnToSender(uint8 messageType, uint32 sender_acc, uint32 sender_guid, uint32 receiver_guid, const std::string& subject, uint32 itemTextId, MailItemsInfo *mi, uint32 money, uint16 mailTemplateId )
|
void WorldSession::SendReturnToSender(uint8 messageType, uint32 sender_acc, uint32 sender_guid, uint32 receiver_guid, const std::string& subject, uint32 itemTextId, MailItemsInfo *mi, uint32 money, uint16 mailTemplateId )
|
||||||
|
|
@ -508,7 +524,7 @@ void WorldSession::HandleMailTakeItem(WorldPacket & recv_data )
|
||||||
pl->SendMailResult(mailId, MAIL_ITEM_TAKEN, MAIL_OK, 0, itemId, count);
|
pl->SendMailResult(mailId, MAIL_ITEM_TAKEN, MAIL_OK, 0, itemId, count);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
pl->SendMailResult(mailId, MAIL_ITEM_TAKEN, MAIL_ERR_BAG_FULL, msg);
|
pl->SendMailResult(mailId, MAIL_ITEM_TAKEN, MAIL_ERR_EQUIP_ERROR, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::HandleMailTakeMoney(WorldPacket & recv_data )
|
void WorldSession::HandleMailTakeMoney(WorldPacket & recv_data )
|
||||||
|
|
@ -532,7 +548,7 @@ void WorldSession::HandleMailTakeMoney(WorldPacket & recv_data )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pl->SendMailResult(mailId, MAIL_MONEY_TAKEN, 0);
|
pl->SendMailResult(mailId, MAIL_MONEY_TAKEN, MAIL_OK);
|
||||||
|
|
||||||
pl->ModifyMoney(m->money);
|
pl->ModifyMoney(m->money);
|
||||||
m->money = 0;
|
m->money = 0;
|
||||||
|
|
@ -725,11 +741,11 @@ void WorldSession::HandleMailCreateTextItem(WorldPacket & recv_data )
|
||||||
|
|
||||||
pl->StoreItem(dest, bodyItem, true);
|
pl->StoreItem(dest, bodyItem, true);
|
||||||
//bodyItem->SetState(ITEM_NEW, pl); is set automatically
|
//bodyItem->SetState(ITEM_NEW, pl); is set automatically
|
||||||
pl->SendMailResult(mailId, MAIL_MADE_PERMANENT, 0);
|
pl->SendMailResult(mailId, MAIL_MADE_PERMANENT, MAIL_OK);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pl->SendMailResult(mailId, MAIL_MADE_PERMANENT, MAIL_ERR_BAG_FULL, msg);
|
pl->SendMailResult(mailId, MAIL_MADE_PERMANENT, MAIL_ERR_EQUIP_ERROR, msg);
|
||||||
delete bodyItem;
|
delete bodyItem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,30 +26,6 @@ class Item;
|
||||||
#define MAIL_BODY_ITEM_TEMPLATE 8383 // - plain letter, A Dusty Unsent Letter: 889
|
#define MAIL_BODY_ITEM_TEMPLATE 8383 // - plain letter, A Dusty Unsent Letter: 889
|
||||||
#define MAX_MAIL_ITEMS 12
|
#define MAX_MAIL_ITEMS 12
|
||||||
|
|
||||||
enum MAIL_RESPONSE
|
|
||||||
{
|
|
||||||
MAIL_OK = 0,
|
|
||||||
MAIL_MONEY_TAKEN = 1,
|
|
||||||
MAIL_ITEM_TAKEN = 2,
|
|
||||||
MAIL_RETURNED_TO_SENDER = 3,
|
|
||||||
MAIL_DELETED = 4,
|
|
||||||
MAIL_MADE_PERMANENT = 5
|
|
||||||
};
|
|
||||||
|
|
||||||
enum MAIL_ERRORS
|
|
||||||
{
|
|
||||||
MAIL_ERR_BAG_FULL = 1,
|
|
||||||
MAIL_ERR_CANNOT_SEND_TO_SELF = 2,
|
|
||||||
MAIL_ERR_NOT_ENOUGH_MONEY = 3,
|
|
||||||
MAIL_ERR_RECIPIENT_NOT_FOUND = 4,
|
|
||||||
MAIL_ERR_NOT_YOUR_TEAM = 5,
|
|
||||||
MAIL_ERR_INTERNAL_ERROR = 6,
|
|
||||||
MAIL_ERR_DISABLED_FOR_TRIAL_ACC = 14,
|
|
||||||
MAIL_ERR_RECIPIENT_CAP_REACHED = 15,
|
|
||||||
MAIL_ERR_CANT_SEND_WRAPPED_COD = 16,
|
|
||||||
MAIL_ERR_MAIL_AND_CHAT_SUSPENDED = 17
|
|
||||||
};
|
|
||||||
|
|
||||||
enum MailCheckMask
|
enum MailCheckMask
|
||||||
{
|
{
|
||||||
MAIL_CHECK_MASK_NONE = 0,
|
MAIL_CHECK_MASK_NONE = 0,
|
||||||
|
|
|
||||||
|
|
@ -497,15 +497,15 @@ void ObjectMgr::LoadCreatureTemplates()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cInfo->classNum != heroicInfo->classNum)
|
if(cInfo->trainer_class != heroicInfo->trainer_class)
|
||||||
{
|
{
|
||||||
sLog.outErrorDb("Creature (Entry: %u) has different `classNum` in heroic mode (Entry: %u).",i,cInfo->HeroicEntry);
|
sLog.outErrorDb("Creature (Entry: %u) has different `trainer_class` in heroic mode (Entry: %u).",i,cInfo->HeroicEntry);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cInfo->race != heroicInfo->race)
|
if(cInfo->trainer_race != heroicInfo->trainer_race)
|
||||||
{
|
{
|
||||||
sLog.outErrorDb("Creature (Entry: %u) has different `race` in heroic mode (Entry: %u).",i,cInfo->HeroicEntry);
|
sLog.outErrorDb("Creature (Entry: %u) has different `trainer_race` in heroic mode (Entry: %u).",i,cInfo->HeroicEntry);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
142
src/game/Pet.cpp
142
src/game/Pet.cpp
|
|
@ -87,25 +87,25 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
||||||
QueryResult *result;
|
QueryResult *result;
|
||||||
|
|
||||||
if (petnumber)
|
if (petnumber)
|
||||||
// known petnumber entry 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
// known petnumber entry 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
||||||
result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType "
|
result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType "
|
||||||
"FROM character_pet WHERE owner = '%u' AND id = '%u'",
|
"FROM character_pet WHERE owner = '%u' AND id = '%u'",
|
||||||
ownerid, petnumber);
|
ownerid, petnumber);
|
||||||
else if (current)
|
else if (current)
|
||||||
// current pet (slot 0) 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
// current pet (slot 0) 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
||||||
result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType "
|
result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType "
|
||||||
"FROM character_pet WHERE owner = '%u' AND slot = '%u'",
|
"FROM character_pet WHERE owner = '%u' AND slot = '%u'",
|
||||||
ownerid, PET_SAVE_AS_CURRENT );
|
ownerid, PET_SAVE_AS_CURRENT );
|
||||||
else if (petentry)
|
else if (petentry)
|
||||||
// known petentry entry (unique for summoned pet, but non unique for hunter pet (only from current or not stabled pets)
|
// known petentry entry (unique for summoned pet, but non unique for hunter pet (only from current or not stabled pets)
|
||||||
// 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
// 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
||||||
result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType "
|
result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType "
|
||||||
"FROM character_pet WHERE owner = '%u' AND entry = '%u' AND (slot = '%u' OR slot > '%u') ",
|
"FROM character_pet WHERE owner = '%u' AND entry = '%u' AND (slot = '%u' OR slot > '%u') ",
|
||||||
ownerid, petentry,PET_SAVE_AS_CURRENT,PET_SAVE_LAST_STABLE_SLOT);
|
ownerid, petentry,PET_SAVE_AS_CURRENT,PET_SAVE_LAST_STABLE_SLOT);
|
||||||
else
|
else
|
||||||
// any current or other non-stabled pet (for hunter "call pet")
|
// any current or other non-stabled pet (for hunter "call pet")
|
||||||
// 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
// 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
||||||
result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType "
|
result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType "
|
||||||
"FROM character_pet WHERE owner = '%u' AND (slot = '%u' OR slot > '%u') ",
|
"FROM character_pet WHERE owner = '%u' AND (slot = '%u' OR slot > '%u') ",
|
||||||
ownerid,PET_SAVE_AS_CURRENT,PET_SAVE_LAST_STABLE_SLOT);
|
ownerid,PET_SAVE_AS_CURRENT,PET_SAVE_LAST_STABLE_SLOT);
|
||||||
|
|
||||||
|
|
@ -122,7 +122,7 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 summon_spell_id = fields[18].GetUInt32();
|
uint32 summon_spell_id = fields[17].GetUInt32();
|
||||||
SpellEntry const* spellInfo = sSpellStore.LookupEntry(summon_spell_id);
|
SpellEntry const* spellInfo = sSpellStore.LookupEntry(summon_spell_id);
|
||||||
|
|
||||||
bool is_temporary_summoned = spellInfo && GetSpellDuration(spellInfo) > 0;
|
bool is_temporary_summoned = spellInfo && GetSpellDuration(spellInfo) > 0;
|
||||||
|
|
@ -164,7 +164,7 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
setPetType(PetType(fields[19].GetUInt8()));
|
setPetType(PetType(fields[18].GetUInt8()));
|
||||||
SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, owner->getFaction());
|
SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, owner->getFaction());
|
||||||
SetUInt32Value(UNIT_CREATED_BY_SPELL, summon_spell_id);
|
SetUInt32Value(UNIT_CREATED_BY_SPELL, summon_spell_id);
|
||||||
|
|
||||||
|
|
@ -184,7 +184,7 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
||||||
SetNativeDisplayId(fields[3].GetUInt32());
|
SetNativeDisplayId(fields[3].GetUInt32());
|
||||||
uint32 petlevel = fields[4].GetUInt32();
|
uint32 petlevel = fields[4].GetUInt32();
|
||||||
SetUInt32Value(UNIT_NPC_FLAGS, 0);
|
SetUInt32Value(UNIT_NPC_FLAGS, 0);
|
||||||
SetName(fields[9].GetString());
|
SetName(fields[8].GetString());
|
||||||
|
|
||||||
switch (getPetType())
|
switch (getPetType())
|
||||||
{
|
{
|
||||||
|
|
@ -197,14 +197,13 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
||||||
break;
|
break;
|
||||||
case HUNTER_PET:
|
case HUNTER_PET:
|
||||||
SetUInt32Value(UNIT_FIELD_BYTES_0, 0x02020100);
|
SetUInt32Value(UNIT_FIELD_BYTES_0, 0x02020100);
|
||||||
SetByteValue(UNIT_FIELD_BYTES_1, 1, fields[7].GetUInt32());
|
|
||||||
SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE);
|
SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE);
|
||||||
SetByteValue(UNIT_FIELD_BYTES_2, 2, fields[10].GetBool() ? UNIT_RENAME_NOT_ALLOWED : UNIT_RENAME_ALLOWED);
|
SetByteValue(UNIT_FIELD_BYTES_2, 2, fields[9].GetBool() ? UNIT_RENAME_NOT_ALLOWED : UNIT_RENAME_ALLOWED);
|
||||||
|
|
||||||
SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
|
SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
|
||||||
// this enables popup window (pet abandon, cancel)
|
// this enables popup window (pet abandon, cancel)
|
||||||
SetMaxPower(POWER_HAPPINESS, GetCreatePowers(POWER_HAPPINESS));
|
SetMaxPower(POWER_HAPPINESS, GetCreatePowers(POWER_HAPPINESS));
|
||||||
SetPower(POWER_HAPPINESS, fields[13].GetUInt32());
|
SetPower(POWER_HAPPINESS, fields[12].GetUInt32());
|
||||||
setPowerType(POWER_FOCUS);
|
setPowerType(POWER_FOCUS);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -215,20 +214,22 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
||||||
SetPvP(true);
|
SetPvP(true);
|
||||||
|
|
||||||
InitStatsForLevel(petlevel);
|
InitStatsForLevel(petlevel);
|
||||||
|
InitTalentForLevel(); // set original talents points before spell loading
|
||||||
|
|
||||||
SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL));
|
SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL));
|
||||||
SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, fields[5].GetUInt32());
|
SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, fields[5].GetUInt32());
|
||||||
SetCreatorGUID(owner->GetGUID());
|
SetCreatorGUID(owner->GetGUID());
|
||||||
|
|
||||||
m_charmInfo->SetReactState(ReactStates(fields[6].GetUInt8()));
|
m_charmInfo->SetReactState(ReactStates(fields[6].GetUInt8()));
|
||||||
|
|
||||||
uint32 savedhealth = fields[11].GetUInt32();
|
uint32 savedhealth = fields[10].GetUInt32();
|
||||||
uint32 savedmana = fields[12].GetUInt32();
|
uint32 savedmana = fields[11].GetUInt32();
|
||||||
|
|
||||||
// set current pet as current
|
// set current pet as current
|
||||||
// 0=current
|
// 0=current
|
||||||
// 1..MAX_PET_STABLES in stable slot
|
// 1..MAX_PET_STABLES in stable slot
|
||||||
// PET_SAVE_NOT_IN_SLOT(100) = not stable slot (summoning))
|
// PET_SAVE_NOT_IN_SLOT(100) = not stable slot (summoning))
|
||||||
if (fields[8].GetUInt32() != 0)
|
if (fields[7].GetUInt32() != 0)
|
||||||
{
|
{
|
||||||
CharacterDatabase.BeginTransaction();
|
CharacterDatabase.BeginTransaction();
|
||||||
CharacterDatabase.PExecute("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND slot = '%u' AND id <> '%u'",
|
CharacterDatabase.PExecute("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND slot = '%u' AND id <> '%u'",
|
||||||
|
|
@ -240,30 +241,18 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
||||||
|
|
||||||
if (!is_temporary_summoned)
|
if (!is_temporary_summoned)
|
||||||
{
|
{
|
||||||
// permanent controlled pets store state in DB
|
if(!m_charmInfo->LoadActionBar(fields[13].GetCppString()))
|
||||||
Tokens tokens = StrSplit(fields[14].GetString(), " ");
|
|
||||||
|
|
||||||
if (tokens.size() != 20)
|
|
||||||
{
|
{
|
||||||
delete result;
|
delete result;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int index;
|
|
||||||
Tokens::iterator iter;
|
|
||||||
for(iter = tokens.begin(), index = 0; index < 10; ++iter, ++index )
|
|
||||||
{
|
|
||||||
m_charmInfo->GetActionBarEntry(index)->Type = atol((*iter).c_str());
|
|
||||||
++iter;
|
|
||||||
m_charmInfo->GetActionBarEntry(index)->SpellOrAction = atol((*iter).c_str());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// since last save (in seconds)
|
// since last save (in seconds)
|
||||||
uint32 timediff = (time(NULL) - fields[15].GetUInt32());
|
uint32 timediff = (time(NULL) - fields[14].GetUInt32());
|
||||||
|
|
||||||
m_resetTalentsCost = fields[16].GetUInt32();
|
m_resetTalentsCost = fields[15].GetUInt32();
|
||||||
m_resetTalentsTime = fields[17].GetUInt64();
|
m_resetTalentsTime = fields[16].GetUInt64();
|
||||||
|
|
||||||
delete result;
|
delete result;
|
||||||
|
|
||||||
|
|
@ -299,6 +288,10 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
||||||
|
|
||||||
// Spells should be loaded after pet is added to map, because in CheckCast is check on it
|
// Spells should be loaded after pet is added to map, because in CheckCast is check on it
|
||||||
_LoadSpells();
|
_LoadSpells();
|
||||||
|
InitLevelupSpellsForLevel();
|
||||||
|
|
||||||
|
CleanupActionBar(); // remove unknown spells from action bar after load
|
||||||
|
|
||||||
_LoadSpellCooldowns();
|
_LoadSpellCooldowns();
|
||||||
|
|
||||||
owner->SetPet(this); // in DB stored only full controlled creature
|
owner->SetPet(this); // in DB stored only full controlled creature
|
||||||
|
|
@ -329,8 +322,6 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InitLevelupSpellsForLevel();
|
|
||||||
|
|
||||||
m_loading = false;
|
m_loading = false;
|
||||||
|
|
||||||
SynchronizeLevelWithOwner();
|
SynchronizeLevelWithOwner();
|
||||||
|
|
@ -404,7 +395,7 @@ void Pet::SavePetToDB(PetSaveMode mode)
|
||||||
owner,PET_SAVE_AS_CURRENT,PET_SAVE_LAST_STABLE_SLOT);
|
owner,PET_SAVE_AS_CURRENT,PET_SAVE_LAST_STABLE_SLOT);
|
||||||
// save pet
|
// save pet
|
||||||
std::ostringstream ss;
|
std::ostringstream ss;
|
||||||
ss << "INSERT INTO character_pet ( id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType) "
|
ss << "INSERT INTO character_pet ( id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType) "
|
||||||
<< "VALUES ("
|
<< "VALUES ("
|
||||||
<< m_charmInfo->GetPetNumber() << ", "
|
<< m_charmInfo->GetPetNumber() << ", "
|
||||||
<< GetEntry() << ", "
|
<< GetEntry() << ", "
|
||||||
|
|
@ -413,7 +404,6 @@ void Pet::SavePetToDB(PetSaveMode mode)
|
||||||
<< getLevel() << ", "
|
<< getLevel() << ", "
|
||||||
<< GetUInt32Value(UNIT_FIELD_PETEXPERIENCE) << ", "
|
<< GetUInt32Value(UNIT_FIELD_PETEXPERIENCE) << ", "
|
||||||
<< uint32(m_charmInfo->GetReactState()) << ", "
|
<< uint32(m_charmInfo->GetReactState()) << ", "
|
||||||
<< uint32(GetFreeTalentPoints()) << ", "
|
|
||||||
<< uint32(mode) << ", '"
|
<< uint32(mode) << ", '"
|
||||||
<< name.c_str() << "', "
|
<< name.c_str() << "', "
|
||||||
<< uint32((GetByteValue(UNIT_FIELD_BYTES_2, 2) == UNIT_RENAME_ALLOWED)?0:1) << ", "
|
<< uint32((GetByteValue(UNIT_FIELD_BYTES_2, 2) == UNIT_RENAME_ALLOWED)?0:1) << ", "
|
||||||
|
|
@ -421,8 +411,12 @@ void Pet::SavePetToDB(PetSaveMode mode)
|
||||||
<< curmana << ", "
|
<< curmana << ", "
|
||||||
<< GetPower(POWER_HAPPINESS) << ", '";
|
<< GetPower(POWER_HAPPINESS) << ", '";
|
||||||
|
|
||||||
for(uint32 i = 0; i < 10; ++i)
|
for(uint32 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
|
||||||
ss << uint32(m_charmInfo->GetActionBarEntry(i)->Type) << " " << uint32(m_charmInfo->GetActionBarEntry(i)->SpellOrAction) << " ";
|
{
|
||||||
|
ss << uint32(m_charmInfo->GetActionBarEntry(i)->Type) << " "
|
||||||
|
<< uint32(m_charmInfo->GetActionBarEntry(i)->SpellOrAction) << " ";
|
||||||
|
};
|
||||||
|
|
||||||
ss << "', "
|
ss << "', "
|
||||||
<< time(NULL) << ", "
|
<< time(NULL) << ", "
|
||||||
<< uint32(m_resetTalentsCost) << ", "
|
<< uint32(m_resetTalentsCost) << ", "
|
||||||
|
|
@ -1099,7 +1093,17 @@ void Pet::_LoadSpells()
|
||||||
{
|
{
|
||||||
Field *fields = result->Fetch();
|
Field *fields = result->Fetch();
|
||||||
|
|
||||||
addSpell(fields[0].GetUInt32(), ActiveStates(fields[1].GetUInt16()), PETSPELL_UNCHANGED);
|
uint32 spell_id = fields[0].GetUInt32();
|
||||||
|
|
||||||
|
// load only pet talents, other spell types auto-learned
|
||||||
|
if(GetTalentSpellCost(spell_id)==0)
|
||||||
|
{
|
||||||
|
CharacterDatabase.PExecute("DELETE FROM pet_spell WHERE spell = '%u'",spell_id);
|
||||||
|
sLog.outError("Table `pet_spell` have non-talent spell %u , spell removed from table for all pets.",spell_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
addSpell(spell_id, ActiveStates(fields[1].GetUInt16()), PETSPELL_UNCHANGED,PETSPELL_TALENT);
|
||||||
}
|
}
|
||||||
while( result->NextRow() );
|
while( result->NextRow() );
|
||||||
|
|
||||||
|
|
@ -1113,8 +1117,8 @@ void Pet::_SaveSpells()
|
||||||
{
|
{
|
||||||
++next;
|
++next;
|
||||||
|
|
||||||
// prevent saving family passives to DB
|
// save only talent spells for pets, other spells auto-applied
|
||||||
if (itr->second.type == PETSPELL_FAMILY)
|
if (itr->second.type != PETSPELL_TALENT)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
switch(itr->second.state)
|
switch(itr->second.state)
|
||||||
|
|
@ -1325,6 +1329,9 @@ bool Pet::addSpell(uint32 spell_id,ActiveStates active /*= ACT_DECIDE*/, PetSpel
|
||||||
// talent: unlearn all other talent ranks (high and low)
|
// talent: unlearn all other talent ranks (high and low)
|
||||||
if(TalentSpellPos const* talentPos = GetTalentSpellPos(spell_id))
|
if(TalentSpellPos const* talentPos = GetTalentSpellPos(spell_id))
|
||||||
{
|
{
|
||||||
|
// propertly mark spell for allow save
|
||||||
|
newspell.type = PETSPELL_TALENT;
|
||||||
|
|
||||||
if(TalentEntry const *talentInfo = sTalentStore.LookupEntry( talentPos->talent_id ))
|
if(TalentEntry const *talentInfo = sTalentStore.LookupEntry( talentPos->talent_id ))
|
||||||
{
|
{
|
||||||
for(int i=0; i < MAX_TALENT_RANK; ++i)
|
for(int i=0; i < MAX_TALENT_RANK; ++i)
|
||||||
|
|
@ -1337,7 +1344,7 @@ bool Pet::addSpell(uint32 spell_id,ActiveStates active /*= ACT_DECIDE*/, PetSpel
|
||||||
// skip unknown ranks
|
// skip unknown ranks
|
||||||
if(!HasSpell(rankSpellId))
|
if(!HasSpell(rankSpellId))
|
||||||
continue;
|
continue;
|
||||||
removeSpell(rankSpellId,false);
|
removeSpell(rankSpellId,false,false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1358,7 +1365,7 @@ bool Pet::addSpell(uint32 spell_id,ActiveStates active /*= ACT_DECIDE*/, PetSpel
|
||||||
ToggleAutocast(itr2->first, false);
|
ToggleAutocast(itr2->first, false);
|
||||||
|
|
||||||
oldspell_id = itr2->first;
|
oldspell_id = itr2->first;
|
||||||
unlearnSpell(itr2->first,false);
|
unlearnSpell(itr2->first,false,false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// ignore new lesser rank
|
// ignore new lesser rank
|
||||||
|
|
@ -1373,7 +1380,7 @@ bool Pet::addSpell(uint32 spell_id,ActiveStates active /*= ACT_DECIDE*/, PetSpel
|
||||||
if (IsPassiveSpell(spell_id))
|
if (IsPassiveSpell(spell_id))
|
||||||
CastSpell(this, spell_id, true);
|
CastSpell(this, spell_id, true);
|
||||||
else
|
else
|
||||||
m_charmInfo->AddSpellToAB(oldspell_id, spell_id);
|
m_charmInfo->AddSpellToActionBar(spell_id);
|
||||||
|
|
||||||
if(newspell.active == ACT_ENABLED)
|
if(newspell.active == ACT_ENABLED)
|
||||||
ToggleAutocast(spell_id, true);
|
ToggleAutocast(spell_id, true);
|
||||||
|
|
@ -1396,16 +1403,17 @@ bool Pet::learnSpell(uint32 spell_id)
|
||||||
if (!addSpell(spell_id))
|
if (!addSpell(spell_id))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Unit* owner = GetOwner();
|
if(!m_loading)
|
||||||
if(owner && owner->GetTypeId() == TYPEID_PLAYER)
|
|
||||||
{
|
{
|
||||||
if(!m_loading)
|
Unit* owner = GetOwner();
|
||||||
|
if(owner && owner->GetTypeId() == TYPEID_PLAYER)
|
||||||
{
|
{
|
||||||
WorldPacket data(SMSG_PET_LEARNED_SPELL, 2);
|
WorldPacket data(SMSG_PET_LEARNED_SPELL, 2);
|
||||||
data << uint16(spell_id);
|
data << uint16(spell_id);
|
||||||
((Player*)owner)->GetSession()->SendPacket(&data);
|
((Player*)owner)->GetSession()->SendPacket(&data);
|
||||||
|
|
||||||
|
((Player*)owner)->PetSpellInitialize();
|
||||||
}
|
}
|
||||||
((Player*)owner)->PetSpellInitialize();
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -1441,7 +1449,7 @@ void Pet::InitLevelupSpellsForLevel()
|
||||||
|
|
||||||
// will called first if level down
|
// will called first if level down
|
||||||
if(spellEntry->spellLevel > level)
|
if(spellEntry->spellLevel > level)
|
||||||
unlearnSpell(spellEntry->Id,false);
|
unlearnSpell(spellEntry->Id,true);
|
||||||
// will called if level up
|
// will called if level up
|
||||||
else
|
else
|
||||||
learnSpell(spellEntry->Id);
|
learnSpell(spellEntry->Id);
|
||||||
|
|
@ -1449,9 +1457,9 @@ void Pet::InitLevelupSpellsForLevel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Pet::unlearnSpell(uint32 spell_id, bool learn_prev)
|
bool Pet::unlearnSpell(uint32 spell_id, bool learn_prev, bool clear_ab)
|
||||||
{
|
{
|
||||||
if(removeSpell(spell_id,learn_prev))
|
if(removeSpell(spell_id,learn_prev,clear_ab))
|
||||||
{
|
{
|
||||||
if(GetOwner()->GetTypeId() == TYPEID_PLAYER)
|
if(GetOwner()->GetTypeId() == TYPEID_PLAYER)
|
||||||
{
|
{
|
||||||
|
|
@ -1467,7 +1475,7 @@ bool Pet::unlearnSpell(uint32 spell_id, bool learn_prev)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Pet::removeSpell(uint32 spell_id, bool learn_prev)
|
bool Pet::removeSpell(uint32 spell_id, bool learn_prev, bool clear_ab)
|
||||||
{
|
{
|
||||||
PetSpellMap::iterator itr = m_spells.find(spell_id);
|
PetSpellMap::iterator itr = m_spells.find(spell_id);
|
||||||
if (itr == m_spells.end())
|
if (itr == m_spells.end())
|
||||||
|
|
@ -1498,29 +1506,35 @@ bool Pet::removeSpell(uint32 spell_id, bool learn_prev)
|
||||||
if (learn_prev)
|
if (learn_prev)
|
||||||
{
|
{
|
||||||
if (uint32 prev_id = spellmgr.GetPrevSpellInChain (spell_id))
|
if (uint32 prev_id = spellmgr.GetPrevSpellInChain (spell_id))
|
||||||
{
|
|
||||||
// replace to next spell
|
|
||||||
if(!talentCost && !IsPassiveSpell(prev_id))
|
|
||||||
m_charmInfo->AddSpellToAB(spell_id, prev_id);
|
|
||||||
|
|
||||||
learnSpell(prev_id);
|
learnSpell(prev_id);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
learn_prev = false;
|
learn_prev = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if remove last rank or non-ranked then update action bar at server and client if need
|
// if remove last rank or non-ranked then update action bar at server and client if need
|
||||||
if(!learn_prev && m_charmInfo->AddSpellToAB(spell_id, 0))
|
if (clear_ab && !learn_prev && m_charmInfo->RemoveSpellFromActionBar(spell_id))
|
||||||
{
|
{
|
||||||
// need update action bar for last removed rank
|
if(!m_loading)
|
||||||
if (Unit* owner = GetOwner())
|
{
|
||||||
if (owner->GetTypeId() == TYPEID_PLAYER)
|
// need update action bar for last removed rank
|
||||||
((Player*)owner)->PetSpellInitialize();
|
if (Unit* owner = GetOwner())
|
||||||
|
if (owner->GetTypeId() == TYPEID_PLAYER)
|
||||||
|
((Player*)owner)->PetSpellInitialize();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Pet::CleanupActionBar()
|
||||||
|
{
|
||||||
|
for(int i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
|
||||||
|
if(UnitActionBarEntry const* ab = m_charmInfo->GetActionBarEntry(i))
|
||||||
|
if(ab->SpellOrAction && ab->IsActionBarForSpell() && !HasSpell(ab->SpellOrAction))
|
||||||
|
m_charmInfo->SetActionBar(i,0,ACT_DISABLED);
|
||||||
|
}
|
||||||
|
|
||||||
void Pet::InitPetCreateSpells()
|
void Pet::InitPetCreateSpells()
|
||||||
{
|
{
|
||||||
m_charmInfo->InitPetActionBar();
|
m_charmInfo->InitPetActionBar();
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,7 @@ enum PetSpellType
|
||||||
{
|
{
|
||||||
PETSPELL_NORMAL = 0,
|
PETSPELL_NORMAL = 0,
|
||||||
PETSPELL_FAMILY = 1,
|
PETSPELL_FAMILY = 1,
|
||||||
|
PETSPELL_TALENT = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PetSpell
|
struct PetSpell
|
||||||
|
|
@ -198,8 +199,9 @@ class Pet : public Creature
|
||||||
bool learnSpell(uint32 spell_id);
|
bool learnSpell(uint32 spell_id);
|
||||||
void learnSpellHighRank(uint32 spellid);
|
void learnSpellHighRank(uint32 spellid);
|
||||||
void InitLevelupSpellsForLevel();
|
void InitLevelupSpellsForLevel();
|
||||||
bool unlearnSpell(uint32 spell_id, bool learn_prev);
|
bool unlearnSpell(uint32 spell_id, bool learn_prev, bool clear_ab = true);
|
||||||
bool removeSpell(uint32 spell_id, bool learn_prev);
|
bool removeSpell(uint32 spell_id, bool learn_prev, bool clear_ab = true);
|
||||||
|
void CleanupActionBar();
|
||||||
|
|
||||||
PetSpellMap m_spells;
|
PetSpellMap m_spells;
|
||||||
AutoSpellList m_autospells;
|
AutoSpellList m_autospells;
|
||||||
|
|
@ -248,4 +250,4 @@ class Pet : public Creature
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -357,7 +357,11 @@ void WorldSession::HandlePetSetAction( WorldPacket & recv_data )
|
||||||
|
|
||||||
sLog.outDetail( "Player %s has changed pet spell action. Position: %u, Spell: %u, State: 0x%X", _player->GetName(), position, spell_id, act_state);
|
sLog.outDetail( "Player %s has changed pet spell action. Position: %u, Spell: %u, State: 0x%X", _player->GetName(), position, spell_id, act_state);
|
||||||
|
|
||||||
//if it's act for spell (en/disable/cast) and there is a spell given (0 = remove spell) which pet doesn't know, don't add
|
//ignore invalid position
|
||||||
|
if(position >= MAX_UNIT_ACTION_BAR_INDEX)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//if it's act for spell (en/disable/cast) and there is a spell given (0 = remove spell) which pet doesn't know, don't add
|
||||||
if(!((act_state == ACT_ENABLED || act_state == ACT_DISABLED || act_state == ACT_PASSIVE) && spell_id && !pet->HasSpell(spell_id)))
|
if(!((act_state == ACT_ENABLED || act_state == ACT_DISABLED || act_state == ACT_PASSIVE) && spell_id && !pet->HasSpell(spell_id)))
|
||||||
{
|
{
|
||||||
//sign for autocast
|
//sign for autocast
|
||||||
|
|
@ -377,8 +381,7 @@ void WorldSession::HandlePetSetAction( WorldPacket & recv_data )
|
||||||
((Pet*)pet)->ToggleAutocast(spell_id, false);
|
((Pet*)pet)->ToggleAutocast(spell_id, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
charmInfo->GetActionBarEntry(position)->Type = act_state;
|
charmInfo->SetActionBar(position,spell_id,ActiveStates(act_state));
|
||||||
charmInfo->GetActionBarEntry(position)->SpellOrAction = spell_id;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -561,11 +564,7 @@ void WorldSession::HandlePetSpellAutocastOpcode( WorldPacket& recvPacket )
|
||||||
else
|
else
|
||||||
((Pet*)pet)->ToggleAutocast(spellid, state);
|
((Pet*)pet)->ToggleAutocast(spellid, state);
|
||||||
|
|
||||||
for(uint8 i = 0; i < 10; ++i)
|
charmInfo->SetSpellAutocast(spellid,state);
|
||||||
{
|
|
||||||
if((charmInfo->GetActionBarEntry(i)->Type == ACT_ENABLED || charmInfo->GetActionBarEntry(i)->Type == ACT_DISABLED) && spellid == charmInfo->GetActionBarEntry(i)->SpellOrAction)
|
|
||||||
charmInfo->GetActionBarEntry(i)->Type = state ? ACT_ENABLED : ACT_DISABLED;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket )
|
void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket )
|
||||||
|
|
|
||||||
|
|
@ -2600,13 +2600,13 @@ void Player::RemoveMail(uint32 id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::SendMailResult(uint32 mailId, uint32 mailAction, uint32 mailError, uint32 equipError, uint32 item_guid, uint32 item_count)
|
void Player::SendMailResult(uint32 mailId, MailResponseType mailAction, MailResponseResult mailError, uint32 equipError, uint32 item_guid, uint32 item_count)
|
||||||
{
|
{
|
||||||
WorldPacket data(SMSG_SEND_MAIL_RESULT, (4+4+4+(mailError == MAIL_ERR_BAG_FULL?4:(mailAction == MAIL_ITEM_TAKEN?4+4:0))));
|
WorldPacket data(SMSG_SEND_MAIL_RESULT, (4+4+4+(mailError == MAIL_ERR_EQUIP_ERROR?4:(mailAction == MAIL_ITEM_TAKEN?4+4:0))));
|
||||||
data << (uint32) mailId;
|
data << (uint32) mailId;
|
||||||
data << (uint32) mailAction;
|
data << (uint32) mailAction;
|
||||||
data << (uint32) mailError;
|
data << (uint32) mailError;
|
||||||
if ( mailError == MAIL_ERR_BAG_FULL )
|
if ( mailError == MAIL_ERR_EQUIP_ERROR )
|
||||||
data << (uint32) equipError;
|
data << (uint32) equipError;
|
||||||
else if( mailAction == MAIL_ITEM_TAKEN )
|
else if( mailAction == MAIL_ITEM_TAKEN )
|
||||||
{
|
{
|
||||||
|
|
@ -8877,7 +8877,7 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3
|
||||||
return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED :EQUIP_ERR_ITEM_NOT_FOUND;
|
return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED :EQUIP_ERR_ITEM_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pItem && pItem->IsBindedNotWith(GetGUID()))
|
if(pItem && pItem->IsBindedNotWith(this))
|
||||||
{
|
{
|
||||||
if(no_space_count)
|
if(no_space_count)
|
||||||
*no_space_count = count;
|
*no_space_count = count;
|
||||||
|
|
@ -9360,7 +9360,7 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
|
||||||
return EQUIP_ERR_ITEM_NOT_FOUND;
|
return EQUIP_ERR_ITEM_NOT_FOUND;
|
||||||
|
|
||||||
// item it 'bind'
|
// item it 'bind'
|
||||||
if(pItem->IsBindedNotWith(GetGUID()))
|
if(pItem->IsBindedNotWith(this))
|
||||||
return EQUIP_ERR_DONT_OWN_THAT_ITEM;
|
return EQUIP_ERR_DONT_OWN_THAT_ITEM;
|
||||||
|
|
||||||
Bag *pBag;
|
Bag *pBag;
|
||||||
|
|
@ -9562,7 +9562,7 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo
|
||||||
ItemPrototype const *pProto = pItem->GetProto();
|
ItemPrototype const *pProto = pItem->GetProto();
|
||||||
if( pProto )
|
if( pProto )
|
||||||
{
|
{
|
||||||
if(pItem->IsBindedNotWith(GetGUID()))
|
if(pItem->IsBindedNotWith(this))
|
||||||
return EQUIP_ERR_DONT_OWN_THAT_ITEM;
|
return EQUIP_ERR_DONT_OWN_THAT_ITEM;
|
||||||
|
|
||||||
// check count of items (skip for auto move for same player from bank)
|
// check count of items (skip for auto move for same player from bank)
|
||||||
|
|
@ -9735,7 +9735,7 @@ uint8 Player::CanBankItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *p
|
||||||
if (!pProto)
|
if (!pProto)
|
||||||
return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED : EQUIP_ERR_ITEM_NOT_FOUND;
|
return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED : EQUIP_ERR_ITEM_NOT_FOUND;
|
||||||
|
|
||||||
if (pItem->IsBindedNotWith(GetGUID()))
|
if (pItem->IsBindedNotWith(this))
|
||||||
return EQUIP_ERR_DONT_OWN_THAT_ITEM;
|
return EQUIP_ERR_DONT_OWN_THAT_ITEM;
|
||||||
|
|
||||||
// check count of items (skip for auto move for same player from bank)
|
// check count of items (skip for auto move for same player from bank)
|
||||||
|
|
@ -9915,7 +9915,7 @@ uint8 Player::CanUseItem( Item *pItem, bool not_loading ) const
|
||||||
ItemPrototype const *pProto = pItem->GetProto();
|
ItemPrototype const *pProto = pItem->GetProto();
|
||||||
if (pProto)
|
if (pProto)
|
||||||
{
|
{
|
||||||
if (pItem->IsBindedNotWith(GetGUID()))
|
if (pItem->IsBindedNotWith(this))
|
||||||
return EQUIP_ERR_DONT_OWN_THAT_ITEM;
|
return EQUIP_ERR_DONT_OWN_THAT_ITEM;
|
||||||
|
|
||||||
if ((pProto->AllowableClass & getClassMask()) == 0 || (pProto->AllowableRace & getRaceMask()) == 0)
|
if ((pProto->AllowableClass & getClassMask()) == 0 || (pProto->AllowableRace & getRaceMask()) == 0)
|
||||||
|
|
@ -16357,10 +16357,7 @@ void Player::PetSpellInitialize()
|
||||||
data << uint8(charmInfo->GetReactState()) << uint8(charmInfo->GetCommandState()) << uint16(0);
|
data << uint8(charmInfo->GetReactState()) << uint8(charmInfo->GetCommandState()) << uint16(0);
|
||||||
|
|
||||||
// action bar loop
|
// action bar loop
|
||||||
for(uint32 i = 0; i < 10; ++i)
|
charmInfo->BuildActionBar(&data);
|
||||||
{
|
|
||||||
data << uint32(charmInfo->GetActionBarEntry(i)->Raw);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t spellsCountPos = data.wpos();
|
size_t spellsCountPos = data.wpos();
|
||||||
|
|
||||||
|
|
@ -16433,10 +16430,7 @@ void Player::PossessSpellInitialize()
|
||||||
data << uint32(0);
|
data << uint32(0);
|
||||||
data << uint32(0);
|
data << uint32(0);
|
||||||
|
|
||||||
for(uint32 i = 0; i < 10; ++i)
|
charmInfo->BuildActionBar(&data);
|
||||||
{
|
|
||||||
data << uint16(charmInfo->GetActionBarEntry(i)->SpellOrAction) << uint16(charmInfo->GetActionBarEntry(i)->Type);
|
|
||||||
}
|
|
||||||
|
|
||||||
data << uint8(0); // spells count
|
data << uint8(0); // spells count
|
||||||
data << uint8(0); // cooldowns count
|
data << uint8(0); // cooldowns count
|
||||||
|
|
@ -16484,10 +16478,7 @@ void Player::CharmSpellInitialize()
|
||||||
else
|
else
|
||||||
data << uint8(0) << uint8(0) << uint16(0);
|
data << uint8(0) << uint8(0) << uint16(0);
|
||||||
|
|
||||||
for(uint32 i = 0; i < 10; ++i)
|
charmInfo->BuildActionBar(&data);
|
||||||
{
|
|
||||||
data << uint16(charmInfo->GetActionBarEntry(i)->SpellOrAction) << uint16(charmInfo->GetActionBarEntry(i)->Type);
|
|
||||||
}
|
|
||||||
|
|
||||||
data << uint8(addlist);
|
data << uint8(addlist);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1325,7 +1325,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
void ClearComboPoints();
|
void ClearComboPoints();
|
||||||
void SendComboPoints();
|
void SendComboPoints();
|
||||||
|
|
||||||
void SendMailResult(uint32 mailId, uint32 mailAction, uint32 mailError, uint32 equipError = 0, uint32 item_guid = 0, uint32 item_count = 0);
|
void SendMailResult(uint32 mailId, MailResponseType mailAction, MailResponseResult mailError, uint32 equipError = 0, uint32 item_guid = 0, uint32 item_count = 0);
|
||||||
void SendNewMail();
|
void SendNewMail();
|
||||||
void UpdateNextMailTimeAndUnreads();
|
void UpdateNextMailTimeAndUnreads();
|
||||||
void AddNewMailDeliverTime(time_t deliver_time);
|
void AddNewMailDeliverTime(time_t deliver_time);
|
||||||
|
|
|
||||||
|
|
@ -2515,4 +2515,32 @@ enum BattleGroundTypeId
|
||||||
};
|
};
|
||||||
#define MAX_BATTLEGROUND_TYPE_ID 12
|
#define MAX_BATTLEGROUND_TYPE_ID 12
|
||||||
|
|
||||||
|
enum MailResponseType
|
||||||
|
{
|
||||||
|
MAIL_SEND = 0,
|
||||||
|
MAIL_MONEY_TAKEN = 1,
|
||||||
|
MAIL_ITEM_TAKEN = 2,
|
||||||
|
MAIL_RETURNED_TO_SENDER = 3,
|
||||||
|
MAIL_DELETED = 4,
|
||||||
|
MAIL_MADE_PERMANENT = 5
|
||||||
|
};
|
||||||
|
|
||||||
|
enum MailResponseResult
|
||||||
|
{
|
||||||
|
MAIL_OK = 0,
|
||||||
|
MAIL_ERR_EQUIP_ERROR = 1,
|
||||||
|
MAIL_ERR_CANNOT_SEND_TO_SELF = 2,
|
||||||
|
MAIL_ERR_NOT_ENOUGH_MONEY = 3,
|
||||||
|
MAIL_ERR_RECIPIENT_NOT_FOUND = 4,
|
||||||
|
MAIL_ERR_NOT_YOUR_TEAM = 5,
|
||||||
|
MAIL_ERR_INTERNAL_ERROR = 6,
|
||||||
|
MAIL_ERR_DISABLED_FOR_TRIAL_ACC = 14,
|
||||||
|
MAIL_ERR_RECIPIENT_CAP_REACHED = 15,
|
||||||
|
MAIL_ERR_CANT_SEND_WRAPPED_COD = 16,
|
||||||
|
MAIL_ERR_MAIL_AND_CHAT_SUSPENDED = 17,
|
||||||
|
MAIL_ERR_TOO_MANY_ATTACHMENTS = 18,
|
||||||
|
MAIL_ERR_MAIL_ATTACHMENT_INVALID = 19,
|
||||||
|
MAIL_ERR_ITEM_HAS_EXPIRED = 21,
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -10281,28 +10281,18 @@ void CharmInfo::InitPetActionBar()
|
||||||
// the first 3 SpellOrActions are attack, follow and stay
|
// the first 3 SpellOrActions are attack, follow and stay
|
||||||
for(uint32 i = 0; i < 3; ++i)
|
for(uint32 i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
PetActionBar[i].Type = ACT_COMMAND;
|
SetActionBar(i,COMMAND_ATTACK - i,ACT_COMMAND);
|
||||||
PetActionBar[i].SpellOrAction = COMMAND_ATTACK - i;
|
SetActionBar(i + 7,COMMAND_ATTACK - i,ACT_REACTION);
|
||||||
|
|
||||||
PetActionBar[i + 7].Type = ACT_REACTION;
|
|
||||||
PetActionBar[i + 7].SpellOrAction = COMMAND_ATTACK - i;
|
|
||||||
}
|
|
||||||
for(uint32 i=0; i < 4; ++i)
|
|
||||||
{
|
|
||||||
PetActionBar[i + 3].Type = ACT_DISABLED;
|
|
||||||
PetActionBar[i + 3].SpellOrAction = 0;
|
|
||||||
}
|
}
|
||||||
|
for(uint32 i = 0; i < 4; ++i)
|
||||||
|
SetActionBar(i,0,ACT_DISABLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharmInfo::InitEmptyActionBar()
|
void CharmInfo::InitEmptyActionBar()
|
||||||
{
|
{
|
||||||
for(uint32 x = 1; x < 10; ++x)
|
SetActionBar(0,COMMAND_ATTACK,ACT_COMMAND);
|
||||||
{
|
for(uint32 x = 1; x < MAX_UNIT_ACTION_BAR_INDEX; ++x)
|
||||||
PetActionBar[x].Type = ACT_PASSIVE;
|
SetActionBar(x,0,ACT_PASSIVE);
|
||||||
PetActionBar[x].SpellOrAction = 0;
|
|
||||||
}
|
|
||||||
PetActionBar[0].Type = ACT_COMMAND;
|
|
||||||
PetActionBar[0].SpellOrAction = COMMAND_ATTACK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CharmInfo::InitPossessCreateSpells()
|
void CharmInfo::InitPossessCreateSpells()
|
||||||
|
|
@ -10317,7 +10307,7 @@ void CharmInfo::InitPossessCreateSpells()
|
||||||
if (IsPassiveSpell(((Creature*)m_unit)->m_spells[x]))
|
if (IsPassiveSpell(((Creature*)m_unit)->m_spells[x]))
|
||||||
m_unit->CastSpell(m_unit, ((Creature*)m_unit)->m_spells[x], true);
|
m_unit->CastSpell(m_unit, ((Creature*)m_unit)->m_spells[x], true);
|
||||||
else
|
else
|
||||||
AddSpellToAB(0, ((Creature*)m_unit)->m_spells[x], ACT_PASSIVE);
|
AddSpellToActionBar(((Creature*)m_unit)->m_spells[x], ACT_PASSIVE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -10362,39 +10352,56 @@ void CharmInfo::InitCharmCreateSpells()
|
||||||
else
|
else
|
||||||
newstate = ACT_PASSIVE;
|
newstate = ACT_PASSIVE;
|
||||||
|
|
||||||
AddSpellToAB(0, spellId, newstate);
|
AddSpellToActionBar(spellId, newstate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CharmInfo::AddSpellToAB(uint32 oldid, uint32 newid, ActiveStates newstate)
|
bool CharmInfo::AddSpellToActionBar(uint32 spell_id, ActiveStates newstate)
|
||||||
{
|
{
|
||||||
// new spell already listed for example in case prepered switch to lesser rank in Pet::removeSpell
|
uint32 first_id = spellmgr.GetFirstSpellInChain(spell_id);
|
||||||
for(uint8 i = 0; i < 10; ++i)
|
|
||||||
if (PetActionBar[i].Type == ACT_DISABLED || PetActionBar[i].Type == ACT_ENABLED || PetActionBar[i].Type == ACT_PASSIVE)
|
|
||||||
if (newid && PetActionBar[i].SpellOrAction == newid)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// old spell can be leasted for example in case learn high rank
|
// new spell rank can be already listed
|
||||||
for(uint8 i = 0; i < 10; ++i)
|
for(uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
|
||||||
{
|
{
|
||||||
if (PetActionBar[i].Type == ACT_DISABLED || PetActionBar[i].Type == ACT_ENABLED || PetActionBar[i].Type == ACT_PASSIVE)
|
if (PetActionBar[i].SpellOrAction && PetActionBar[i].IsActionBarForSpell())
|
||||||
{
|
{
|
||||||
if (PetActionBar[i].SpellOrAction == oldid)
|
if (spellmgr.GetFirstSpellInChain(PetActionBar[i].SpellOrAction) == first_id)
|
||||||
{
|
{
|
||||||
PetActionBar[i].SpellOrAction = newid;
|
PetActionBar[i].SpellOrAction = spell_id;
|
||||||
if (!oldid)
|
|
||||||
{
|
|
||||||
if (newstate == ACT_DECIDE)
|
|
||||||
PetActionBar[i].Type = ACT_DISABLED;
|
|
||||||
else
|
|
||||||
PetActionBar[i].Type = newstate;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// or use empty slot in other case
|
||||||
|
for(uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
|
||||||
|
{
|
||||||
|
if (!PetActionBar[i].SpellOrAction && PetActionBar[i].IsActionBarForSpell())
|
||||||
|
{
|
||||||
|
SetActionBar(i,spell_id,newstate == ACT_DECIDE ? ACT_DISABLED : newstate);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CharmInfo::RemoveSpellFromActionBar(uint32 spell_id)
|
||||||
|
{
|
||||||
|
uint32 first_id = spellmgr.GetFirstSpellInChain(spell_id);
|
||||||
|
|
||||||
|
for(uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
|
||||||
|
{
|
||||||
|
if (PetActionBar[i].SpellOrAction && PetActionBar[i].IsActionBarForSpell())
|
||||||
|
{
|
||||||
|
if (spellmgr.GetFirstSpellInChain(PetActionBar[i].SpellOrAction) == first_id)
|
||||||
|
{
|
||||||
|
SetActionBar(i,0,ACT_DISABLED);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -10421,6 +10428,50 @@ void CharmInfo::SetPetNumber(uint32 petnumber, bool statwindow)
|
||||||
m_unit->SetUInt32Value(UNIT_FIELD_PETNUMBER, 0);
|
m_unit->SetUInt32Value(UNIT_FIELD_PETNUMBER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CharmInfo::LoadActionBar( std::string data )
|
||||||
|
{
|
||||||
|
Tokens tokens = StrSplit(data, " ");
|
||||||
|
|
||||||
|
if (tokens.size() != MAX_UNIT_ACTION_BAR_INDEX*2)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int index;
|
||||||
|
Tokens::iterator iter;
|
||||||
|
for(iter = tokens.begin(), index = 0; index < MAX_UNIT_ACTION_BAR_INDEX; ++iter, ++index )
|
||||||
|
{
|
||||||
|
// use unsigned cast to avoid sign negative format use at long-> ActiveStates (int) conversion
|
||||||
|
PetActionBar[index].Type = atol((*iter).c_str());
|
||||||
|
++iter;
|
||||||
|
PetActionBar[index].SpellOrAction = atol((*iter).c_str());
|
||||||
|
|
||||||
|
// check correctness
|
||||||
|
if(PetActionBar[index].IsActionBarForSpell() && !sSpellStore.LookupEntry(PetActionBar[index].SpellOrAction))
|
||||||
|
SetActionBar(index,0,ACT_DISABLED);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CharmInfo::BuildActionBar( WorldPacket* data )
|
||||||
|
{
|
||||||
|
for(uint32 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
|
||||||
|
{
|
||||||
|
*data << uint16(PetActionBar[i].SpellOrAction);
|
||||||
|
*data << uint16(PetActionBar[i].Type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CharmInfo::SetSpellAutocast( uint32 spell_id, bool state )
|
||||||
|
{
|
||||||
|
for(int i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
|
||||||
|
{
|
||||||
|
if(spell_id == PetActionBar[i].SpellOrAction && PetActionBar[i].IsActionBarForSpell())
|
||||||
|
{
|
||||||
|
PetActionBar[i].Type = state ? ACT_ENABLED : ACT_DISABLED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Unit::isFrozen() const
|
bool Unit::isFrozen() const
|
||||||
{
|
{
|
||||||
return HasAuraState(AURA_STATE_FROZEN);
|
return HasAuraState(AURA_STATE_FROZEN);
|
||||||
|
|
|
||||||
|
|
@ -714,24 +714,6 @@ struct SpellNonMeleeDamage{
|
||||||
|
|
||||||
uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missCondition);
|
uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missCondition);
|
||||||
|
|
||||||
struct UnitActionBarEntry
|
|
||||||
{
|
|
||||||
UnitActionBarEntry() : Raw(0) {}
|
|
||||||
|
|
||||||
union
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint16 SpellOrAction;
|
|
||||||
uint16 Type;
|
|
||||||
};
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint32 Raw;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#define MAX_DECLINED_NAME_CASES 5
|
#define MAX_DECLINED_NAME_CASES 5
|
||||||
|
|
||||||
struct DeclinedName
|
struct DeclinedName
|
||||||
|
|
@ -774,12 +756,28 @@ enum CommandStates
|
||||||
COMMAND_ABANDON = 3
|
COMMAND_ABANDON = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct UnitActionBarEntry
|
||||||
|
{
|
||||||
|
UnitActionBarEntry() : SpellOrAction(0), Type(ACT_DISABLED) {}
|
||||||
|
|
||||||
|
uint16 SpellOrAction;
|
||||||
|
uint16 Type;
|
||||||
|
|
||||||
|
// helper
|
||||||
|
bool IsActionBarForSpell() const
|
||||||
|
{
|
||||||
|
return Type == ACT_DISABLED || Type == ACT_ENABLED || Type == ACT_PASSIVE;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct CharmSpellEntry
|
struct CharmSpellEntry
|
||||||
{
|
{
|
||||||
uint16 spellId;
|
uint16 spellId;
|
||||||
uint16 active;
|
uint16 active;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MAX_UNIT_ACTION_BAR_INDEX 10
|
||||||
|
|
||||||
struct CharmInfo
|
struct CharmInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -798,15 +796,27 @@ struct CharmInfo
|
||||||
void InitCharmCreateSpells();
|
void InitCharmCreateSpells();
|
||||||
void InitPetActionBar();
|
void InitPetActionBar();
|
||||||
void InitEmptyActionBar();
|
void InitEmptyActionBar();
|
||||||
|
|
||||||
//return true if successful
|
//return true if successful
|
||||||
bool AddSpellToAB(uint32 oldid, uint32 newid, ActiveStates newstate = ACT_DECIDE);
|
bool AddSpellToActionBar(uint32 spellid, ActiveStates newstate = ACT_DECIDE);
|
||||||
|
bool RemoveSpellFromActionBar(uint32 spell_id);
|
||||||
|
bool LoadActionBar(std::string data);
|
||||||
|
void BuildActionBar(WorldPacket* data);
|
||||||
|
void SetSpellAutocast(uint32 spell_id, bool state);
|
||||||
|
void SetActionBar(uint8 index, uint32 spellOrAction,ActiveStates type)
|
||||||
|
{
|
||||||
|
PetActionBar[index].Type = type;
|
||||||
|
PetActionBar[index].SpellOrAction = spellOrAction;
|
||||||
|
}
|
||||||
|
UnitActionBarEntry const* GetActionBarEntry(uint8 index) const { return &(PetActionBar[index]); }
|
||||||
|
|
||||||
void ToggleCreatureAutocast(uint32 spellid, bool apply);
|
void ToggleCreatureAutocast(uint32 spellid, bool apply);
|
||||||
|
|
||||||
UnitActionBarEntry* GetActionBarEntry(uint8 index) { return &(PetActionBar[index]); }
|
|
||||||
CharmSpellEntry* GetCharmSpell(uint8 index) { return &(m_charmspells[index]); }
|
CharmSpellEntry* GetCharmSpell(uint8 index) { return &(m_charmspells[index]); }
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Unit* m_unit;
|
Unit* m_unit;
|
||||||
UnitActionBarEntry PetActionBar[10];
|
UnitActionBarEntry PetActionBar[MAX_UNIT_ACTION_BAR_INDEX];
|
||||||
CharmSpellEntry m_charmspells[4];
|
CharmSpellEntry m_charmspells[4];
|
||||||
CommandStates m_CommandState;
|
CommandStates m_CommandState;
|
||||||
ReactStates m_reactState;
|
ReactStates m_reactState;
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,11 @@
|
||||||
#ifndef MANGOSSERVER_ERRORS_H
|
#ifndef MANGOSSERVER_ERRORS_H
|
||||||
#define MANGOSSERVER_ERRORS_H
|
#define MANGOSSERVER_ERRORS_H
|
||||||
|
|
||||||
#define WPAssert( assertion ) { if( !(assertion) ) { fprintf( stderr, "\n%s:%i ASSERTION FAILED:\n %s\n", __FILE__, __LINE__, #assertion ); assert( #assertion &&0 ); } }
|
#define WPAssert( assertion ) { if( !(assertion) ) { fprintf( stderr, "\n%s:%i in %s ASSERTION FAILED:\n %s\n", __FILE__, __LINE__,__FUNCTION__, #assertion ); assert( #assertion &&0 ); } }
|
||||||
#define WPError( assertion, errmsg ) if( ! (assertion) ) { sLog.outError( "%s:%i ERROR:\n %s\n", __FILE__, __LINE__, (char *)errmsg ); assert( false ); }
|
#define WPError( assertion, errmsg ) if( ! (assertion) ) { sLog.outError( "%\n%s:%i in %s ERROR:\n %s\n", __FILE__, __LINE__, __FUNCTION__, (char *)errmsg ); assert( false ); }
|
||||||
#define WPWarning( assertion, errmsg ) if( ! (assertion) ) { sLog.outError( "%s:%i WARNING:\n %s\n", __FILE__, __LINE__, (char *)errmsg ); }
|
#define WPWarning( assertion, errmsg ) if( ! (assertion) ) { sLog.outError( "\n%s:%i in %s WARNING:\n %s\n", __FILE__, __LINE__, __FUNCTION__, (char *)errmsg ); }
|
||||||
|
|
||||||
#define WPFatal( assertion, errmsg ) if( ! (assertion) ) { sLog.outError( "%s:%i FATAL ERROR:\n %s\n", __FILE__, __LINE__, (char *)errmsg ); assert( #assertion &&0 ); abort(); }
|
#define WPFatal( assertion, errmsg ) if( ! (assertion) ) { sLog.outError( "\n%s:%i in %s FATAL ERROR:\n %s\n", __FILE__, __LINE__, __FUNCTION__, (char *)errmsg ); assert( #assertion &&0 ); abort(); }
|
||||||
|
|
||||||
#define ASSERT WPAssert
|
#define ASSERT WPAssert
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "7895"
|
#define REVISION_NR "7903"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue