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`;
|
||||
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';
|
||||
|
||||
--
|
||||
|
|
@ -472,7 +472,6 @@ CREATE TABLE `character_pet` (
|
|||
`level` int(11) unsigned NOT NULL default '1',
|
||||
`exp` int(11) 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',
|
||||
`renamed` tinyint(1) 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` (
|
||||
`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';
|
||||
|
||||
--
|
||||
|
|
@ -820,8 +820,8 @@ CREATE TABLE `creature_template` (
|
|||
`family` tinyint(4) NOT NULL default '0',
|
||||
`trainer_type` tinyint(4) NOT NULL default '0',
|
||||
`trainer_spell` mediumint(8) unsigned NOT NULL default '0',
|
||||
`class` tinyint(3) unsigned NOT NULL default '0',
|
||||
`race` tinyint(3) unsigned NOT NULL default '0',
|
||||
`trainer_class` tinyint(3) unsigned NOT NULL default '0',
|
||||
`trainer_race` tinyint(3) unsigned NOT NULL default '0',
|
||||
`minrangedmg` float NOT NULL default '0',
|
||||
`maxrangedmg` float 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',
|
||||
`chance` float unsigned NOT NULL default '0',
|
||||
`description` varchar(255) NOT NULL,
|
||||
PRIMARY KEY (`pool_entry`,`guid`)
|
||||
PRIMARY KEY (`pool_entry`,`guid`),
|
||||
INDEX `idx_guid`(`guid`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
|
||||
|
||||
|
|
@ -12961,7 +12962,8 @@ CREATE TABLE `pool_gameobject` (
|
|||
`pool_entry` mediumint(8) unsigned NOT NULL default '0',
|
||||
`chance` float unsigned NOT NULL default '0',
|
||||
`description` varchar(255) NOT NULL,
|
||||
PRIMARY KEY (`guid`,`pool_entry`)
|
||||
PRIMARY KEY (`guid`,`pool_entry`),
|
||||
INDEX `idx_guid`(`guid`)
|
||||
) 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 \
|
||||
7887_01_characters_character_pet.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
|
||||
|
||||
## Additional files to include when running 'make dist'
|
||||
|
|
@ -380,4 +384,8 @@ EXTRA_DIST = \
|
|||
7886_01_mangos_petcreateinfo_spell.sql \
|
||||
7887_01_characters_character_pet.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
|
||||
|
|
|
|||
|
|
@ -605,12 +605,12 @@ bool Creature::isCanTrainingOf(Player* pPlayer, bool msg) const
|
|||
switch(GetCreatureInfo()->trainer_type)
|
||||
{
|
||||
case TRAINER_TYPE_CLASS:
|
||||
if(pPlayer->getClass()!=GetCreatureInfo()->classNum)
|
||||
if(pPlayer->getClass()!=GetCreatureInfo()->trainer_class)
|
||||
{
|
||||
if(msg)
|
||||
{
|
||||
pPlayer->PlayerTalkClass->ClearMenus();
|
||||
switch(GetCreatureInfo()->classNum)
|
||||
switch(GetCreatureInfo()->trainer_class)
|
||||
{
|
||||
case CLASS_DRUID: pPlayer->PlayerTalkClass->SendGossipMenu( 4913,GetGUID()); break;
|
||||
case CLASS_HUNTER: pPlayer->PlayerTalkClass->SendGossipMenu(10090,GetGUID()); break;
|
||||
|
|
@ -635,12 +635,12 @@ bool Creature::isCanTrainingOf(Player* pPlayer, bool msg) const
|
|||
}
|
||||
break;
|
||||
case TRAINER_TYPE_MOUNTS:
|
||||
if(GetCreatureInfo()->race && pPlayer->getRace() != GetCreatureInfo()->race)
|
||||
if(GetCreatureInfo()->trainer_race && pPlayer->getRace() != GetCreatureInfo()->trainer_race)
|
||||
{
|
||||
if(msg)
|
||||
{
|
||||
pPlayer->PlayerTalkClass->ClearMenus();
|
||||
switch(GetCreatureInfo()->classNum)
|
||||
switch(GetCreatureInfo()->trainer_class)
|
||||
{
|
||||
case RACE_DWARF: pPlayer->PlayerTalkClass->SendGossipMenu(5865,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
|
||||
&& GetCreatureInfo()->trainer_type == TRAINER_TYPE_CLASS
|
||||
&& pPlayer->getClass() == GetCreatureInfo()->classNum;
|
||||
&& pPlayer->getClass() == GetCreatureInfo()->trainer_class;
|
||||
}
|
||||
|
||||
void Creature::prepareGossipMenu( Player *pPlayer,uint32 gossipid )
|
||||
|
|
@ -771,7 +771,7 @@ void Creature::prepareGossipMenu( Player *pPlayer,uint32 gossipid )
|
|||
cantalking=false;
|
||||
break;
|
||||
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;
|
||||
break;
|
||||
case GOSSIP_OPTION_TAXIVENDOR:
|
||||
|
|
|
|||
|
|
@ -190,8 +190,8 @@ struct CreatureInfo
|
|||
uint32 family; // enum CreatureFamily values (optional)
|
||||
uint32 trainer_type;
|
||||
uint32 trainer_spell;
|
||||
uint32 classNum;
|
||||
uint32 race;
|
||||
uint32 trainer_class;
|
||||
uint32 trainer_race;
|
||||
float minrangedmg;
|
||||
float maxrangedmg;
|
||||
uint32 rangedattackpower;
|
||||
|
|
|
|||
|
|
@ -696,10 +696,11 @@ bool Item::IsEquipped() const
|
|||
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;
|
||||
|
||||
|
|
@ -941,3 +942,29 @@ Item* Item::CloneItem( uint32 count, Player const* player ) const
|
|||
newItem->SetItemRandomProperties(GetItemRandomPropertyId());
|
||||
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_NOT_DURING_ARENA_MATCH = 78,
|
||||
EQUIP_ERR_CANNOT_TRADE_THAT = 79,
|
||||
EQUIP_ERR_PERSONAL_ARENA_RATING_TOO_LOW = 80
|
||||
// probably exist more
|
||||
EQUIP_ERR_PERSONAL_ARENA_RATING_TOO_LOW = 80,
|
||||
// no output = 81,
|
||||
EQUIP_ERR_ARTEFACTS_ONLY_FOR_OWN_CHARACTERS = 82,
|
||||
// no output = 83,
|
||||
// crash client = 84,
|
||||
};
|
||||
|
||||
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); }
|
||||
bool IsSoulBound() const { return HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_BINDED); }
|
||||
bool IsAccountBound() const { return HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_BOA); }
|
||||
bool IsBindedNotWith(uint64 guid) const { return IsSoulBound() && GetOwnerGUID()!= guid; }
|
||||
bool IsBoundAccountWide() const { return HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_BOA); }
|
||||
bool IsBindedNotWith(Player const* player) const;
|
||||
bool IsBoundByEnchant() const;
|
||||
virtual void SaveToDB();
|
||||
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 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; }
|
||||
bool IsInTrade() const { return mb_in_trade; }
|
||||
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ enum ItemBondingType
|
|||
// masks for ITEM_FIELD_FLAGS field
|
||||
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_OPENABLE = 0x00000004,
|
||||
ITEM_FLAGS_WRAPPED = 0x00000008,
|
||||
|
|
@ -114,7 +114,7 @@ enum ITEM_FLAGS
|
|||
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_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
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -77,7 +77,10 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
|||
recv_data >> items_count; // attached items count
|
||||
|
||||
if(items_count > 12) // client limit
|
||||
{
|
||||
GetPlayer()->SendMailResult(0, MAIL_SEND, MAIL_ERR_TOO_MANY_ATTACHMENTS);
|
||||
return;
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
|
@ -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",
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -121,7 +124,7 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -131,7 +134,7 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
|||
|
||||
if (pl->GetMoney() < reqmoney)
|
||||
{
|
||||
pl->SendMailResult(0, 0, MAIL_ERR_NOT_ENOUGH_MONEY);
|
||||
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_ENOUGH_MONEY);
|
||||
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..
|
||||
if (mails_count > 100)
|
||||
{
|
||||
pl->SendMailResult(0, 0, MAIL_ERR_INTERNAL_ERROR);
|
||||
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_CAP_REACHED);
|
||||
return;
|
||||
}
|
||||
// test the receiver's Faction...
|
||||
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;
|
||||
}
|
||||
|
||||
uint32 rc_account = 0;
|
||||
if(receive)
|
||||
rc_account = receive->GetSession()->GetAccountId();
|
||||
else
|
||||
rc_account = objmgr.GetPlayerAccountIdByGUID(rc);
|
||||
|
||||
if (items_count)
|
||||
{
|
||||
for(MailItemMap::iterator mailItemIter = mi.begin(); mailItemIter != mi.end(); ++mailItemIter)
|
||||
|
|
@ -177,31 +186,44 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
|||
|
||||
if(!mailItem.item_guidlow)
|
||||
{
|
||||
pl->SendMailResult(0, 0, MAIL_ERR_INTERNAL_ERROR);
|
||||
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID);
|
||||
return;
|
||||
}
|
||||
|
||||
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)
|
||||
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;
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
pl->SendMailResult(0, 0, MAIL_ERR_INTERNAL_ERROR);
|
||||
pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_MAIL_BOUND_ITEM);
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
pl->SendMailResult(0, 0, MAIL_OK);
|
||||
pl->SendMailResult(0, MAIL_SEND, MAIL_OK);
|
||||
|
||||
uint32 itemTextId = 0;
|
||||
if (!body.empty())
|
||||
|
|
@ -216,12 +238,6 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
|
|||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
if(m)
|
||||
m->state = MAIL_STATE_DELETED;
|
||||
pl->SendMailResult(mailId, MAIL_DELETED, 0);
|
||||
pl->SendMailResult(mailId, MAIL_DELETED, MAIL_OK);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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 )
|
||||
|
|
@ -508,7 +524,7 @@ void WorldSession::HandleMailTakeItem(WorldPacket & recv_data )
|
|||
pl->SendMailResult(mailId, MAIL_ITEM_TAKEN, MAIL_OK, 0, itemId, count);
|
||||
}
|
||||
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 )
|
||||
|
|
@ -532,7 +548,7 @@ void WorldSession::HandleMailTakeMoney(WorldPacket & recv_data )
|
|||
return;
|
||||
}
|
||||
|
||||
pl->SendMailResult(mailId, MAIL_MONEY_TAKEN, 0);
|
||||
pl->SendMailResult(mailId, MAIL_MONEY_TAKEN, MAIL_OK);
|
||||
|
||||
pl->ModifyMoney(m->money);
|
||||
m->money = 0;
|
||||
|
|
@ -725,11 +741,11 @@ void WorldSession::HandleMailCreateTextItem(WorldPacket & recv_data )
|
|||
|
||||
pl->StoreItem(dest, bodyItem, true);
|
||||
//bodyItem->SetState(ITEM_NEW, pl); is set automatically
|
||||
pl->SendMailResult(mailId, MAIL_MADE_PERMANENT, 0);
|
||||
pl->SendMailResult(mailId, MAIL_MADE_PERMANENT, MAIL_OK);
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,30 +26,6 @@ class Item;
|
|||
#define MAIL_BODY_ITEM_TEMPLATE 8383 // - plain letter, A Dusty Unsent Letter: 889
|
||||
#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
|
||||
{
|
||||
MAIL_CHECK_MASK_NONE = 0,
|
||||
|
|
|
|||
|
|
@ -497,15 +497,15 @@ void ObjectMgr::LoadCreatureTemplates()
|
|||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
132
src/game/Pet.cpp
132
src/game/Pet.cpp
|
|
@ -87,25 +87,25 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
|||
QueryResult *result;
|
||||
|
||||
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
|
||||
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 "
|
||||
// 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, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType "
|
||||
"FROM character_pet WHERE owner = '%u' AND id = '%u'",
|
||||
ownerid, petnumber);
|
||||
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
|
||||
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 "
|
||||
// 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, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType "
|
||||
"FROM character_pet WHERE owner = '%u' AND slot = '%u'",
|
||||
ownerid, PET_SAVE_AS_CURRENT );
|
||||
else if (petentry)
|
||||
// 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
|
||||
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 "
|
||||
// 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, 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') ",
|
||||
ownerid, petentry,PET_SAVE_AS_CURRENT,PET_SAVE_LAST_STABLE_SLOT);
|
||||
else
|
||||
// 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
|
||||
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 "
|
||||
// 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, 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') ",
|
||||
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;
|
||||
}
|
||||
|
||||
uint32 summon_spell_id = fields[18].GetUInt32();
|
||||
uint32 summon_spell_id = fields[17].GetUInt32();
|
||||
SpellEntry const* spellInfo = sSpellStore.LookupEntry(summon_spell_id);
|
||||
|
||||
bool is_temporary_summoned = spellInfo && GetSpellDuration(spellInfo) > 0;
|
||||
|
|
@ -164,7 +164,7 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
|||
return false;
|
||||
}
|
||||
|
||||
setPetType(PetType(fields[19].GetUInt8()));
|
||||
setPetType(PetType(fields[18].GetUInt8()));
|
||||
SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, owner->getFaction());
|
||||
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());
|
||||
uint32 petlevel = fields[4].GetUInt32();
|
||||
SetUInt32Value(UNIT_NPC_FLAGS, 0);
|
||||
SetName(fields[9].GetString());
|
||||
SetName(fields[8].GetString());
|
||||
|
||||
switch (getPetType())
|
||||
{
|
||||
|
|
@ -197,14 +197,13 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
|||
break;
|
||||
case HUNTER_PET:
|
||||
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, 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);
|
||||
// this enables popup window (pet abandon, cancel)
|
||||
SetMaxPower(POWER_HAPPINESS, GetCreatePowers(POWER_HAPPINESS));
|
||||
SetPower(POWER_HAPPINESS, fields[13].GetUInt32());
|
||||
SetPower(POWER_HAPPINESS, fields[12].GetUInt32());
|
||||
setPowerType(POWER_FOCUS);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -215,20 +214,22 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
|||
SetPvP(true);
|
||||
|
||||
InitStatsForLevel(petlevel);
|
||||
InitTalentForLevel(); // set original talents points before spell loading
|
||||
|
||||
SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL));
|
||||
SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, fields[5].GetUInt32());
|
||||
SetCreatorGUID(owner->GetGUID());
|
||||
|
||||
m_charmInfo->SetReactState(ReactStates(fields[6].GetUInt8()));
|
||||
|
||||
uint32 savedhealth = fields[11].GetUInt32();
|
||||
uint32 savedmana = fields[12].GetUInt32();
|
||||
uint32 savedhealth = fields[10].GetUInt32();
|
||||
uint32 savedmana = fields[11].GetUInt32();
|
||||
|
||||
// set current pet as current
|
||||
// 0=current
|
||||
// 1..MAX_PET_STABLES in stable slot
|
||||
// PET_SAVE_NOT_IN_SLOT(100) = not stable slot (summoning))
|
||||
if (fields[8].GetUInt32() != 0)
|
||||
if (fields[7].GetUInt32() != 0)
|
||||
{
|
||||
CharacterDatabase.BeginTransaction();
|
||||
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)
|
||||
{
|
||||
// permanent controlled pets store state in DB
|
||||
Tokens tokens = StrSplit(fields[14].GetString(), " ");
|
||||
|
||||
if (tokens.size() != 20)
|
||||
if(!m_charmInfo->LoadActionBar(fields[13].GetCppString()))
|
||||
{
|
||||
delete result;
|
||||
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)
|
||||
uint32 timediff = (time(NULL) - fields[15].GetUInt32());
|
||||
uint32 timediff = (time(NULL) - fields[14].GetUInt32());
|
||||
|
||||
m_resetTalentsCost = fields[16].GetUInt32();
|
||||
m_resetTalentsTime = fields[17].GetUInt64();
|
||||
m_resetTalentsCost = fields[15].GetUInt32();
|
||||
m_resetTalentsTime = fields[16].GetUInt64();
|
||||
|
||||
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
|
||||
_LoadSpells();
|
||||
InitLevelupSpellsForLevel();
|
||||
|
||||
CleanupActionBar(); // remove unknown spells from action bar after load
|
||||
|
||||
_LoadSpellCooldowns();
|
||||
|
||||
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;
|
||||
|
||||
SynchronizeLevelWithOwner();
|
||||
|
|
@ -404,7 +395,7 @@ void Pet::SavePetToDB(PetSaveMode mode)
|
|||
owner,PET_SAVE_AS_CURRENT,PET_SAVE_LAST_STABLE_SLOT);
|
||||
// save pet
|
||||
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 ("
|
||||
<< m_charmInfo->GetPetNumber() << ", "
|
||||
<< GetEntry() << ", "
|
||||
|
|
@ -413,7 +404,6 @@ void Pet::SavePetToDB(PetSaveMode mode)
|
|||
<< getLevel() << ", "
|
||||
<< GetUInt32Value(UNIT_FIELD_PETEXPERIENCE) << ", "
|
||||
<< uint32(m_charmInfo->GetReactState()) << ", "
|
||||
<< uint32(GetFreeTalentPoints()) << ", "
|
||||
<< uint32(mode) << ", '"
|
||||
<< name.c_str() << "', "
|
||||
<< uint32((GetByteValue(UNIT_FIELD_BYTES_2, 2) == UNIT_RENAME_ALLOWED)?0:1) << ", "
|
||||
|
|
@ -421,8 +411,12 @@ void Pet::SavePetToDB(PetSaveMode mode)
|
|||
<< curmana << ", "
|
||||
<< GetPower(POWER_HAPPINESS) << ", '";
|
||||
|
||||
for(uint32 i = 0; i < 10; ++i)
|
||||
ss << uint32(m_charmInfo->GetActionBarEntry(i)->Type) << " " << uint32(m_charmInfo->GetActionBarEntry(i)->SpellOrAction) << " ";
|
||||
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 << "', "
|
||||
<< time(NULL) << ", "
|
||||
<< uint32(m_resetTalentsCost) << ", "
|
||||
|
|
@ -1099,7 +1093,17 @@ void Pet::_LoadSpells()
|
|||
{
|
||||
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() );
|
||||
|
||||
|
|
@ -1113,8 +1117,8 @@ void Pet::_SaveSpells()
|
|||
{
|
||||
++next;
|
||||
|
||||
// prevent saving family passives to DB
|
||||
if (itr->second.type == PETSPELL_FAMILY)
|
||||
// save only talent spells for pets, other spells auto-applied
|
||||
if (itr->second.type != PETSPELL_TALENT)
|
||||
continue;
|
||||
|
||||
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)
|
||||
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 ))
|
||||
{
|
||||
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
|
||||
if(!HasSpell(rankSpellId))
|
||||
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);
|
||||
|
||||
oldspell_id = itr2->first;
|
||||
unlearnSpell(itr2->first,false);
|
||||
unlearnSpell(itr2->first,false,false);
|
||||
break;
|
||||
}
|
||||
// ignore new lesser rank
|
||||
|
|
@ -1373,7 +1380,7 @@ bool Pet::addSpell(uint32 spell_id,ActiveStates active /*= ACT_DECIDE*/, PetSpel
|
|||
if (IsPassiveSpell(spell_id))
|
||||
CastSpell(this, spell_id, true);
|
||||
else
|
||||
m_charmInfo->AddSpellToAB(oldspell_id, spell_id);
|
||||
m_charmInfo->AddSpellToActionBar(spell_id);
|
||||
|
||||
if(newspell.active == ACT_ENABLED)
|
||||
ToggleAutocast(spell_id, true);
|
||||
|
|
@ -1396,17 +1403,18 @@ bool Pet::learnSpell(uint32 spell_id)
|
|||
if (!addSpell(spell_id))
|
||||
return false;
|
||||
|
||||
if(!m_loading)
|
||||
{
|
||||
Unit* owner = GetOwner();
|
||||
if(owner && owner->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
if(!m_loading)
|
||||
{
|
||||
WorldPacket data(SMSG_PET_LEARNED_SPELL, 2);
|
||||
data << uint16(spell_id);
|
||||
((Player*)owner)->GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
||||
((Player*)owner)->PetSpellInitialize();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1441,7 +1449,7 @@ void Pet::InitLevelupSpellsForLevel()
|
|||
|
||||
// will called first if level down
|
||||
if(spellEntry->spellLevel > level)
|
||||
unlearnSpell(spellEntry->Id,false);
|
||||
unlearnSpell(spellEntry->Id,true);
|
||||
// will called if level up
|
||||
else
|
||||
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)
|
||||
{
|
||||
|
|
@ -1467,7 +1475,7 @@ bool Pet::unlearnSpell(uint32 spell_id, bool learn_prev)
|
|||
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);
|
||||
if (itr == m_spells.end())
|
||||
|
|
@ -1498,29 +1506,35 @@ bool Pet::removeSpell(uint32 spell_id, bool learn_prev)
|
|||
if (learn_prev)
|
||||
{
|
||||
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);
|
||||
}
|
||||
else
|
||||
learn_prev = false;
|
||||
}
|
||||
|
||||
// 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))
|
||||
{
|
||||
if(!m_loading)
|
||||
{
|
||||
// need update action bar for last removed rank
|
||||
if (Unit* owner = GetOwner())
|
||||
if (owner->GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)owner)->PetSpellInitialize();
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
m_charmInfo->InitPetActionBar();
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ enum PetSpellType
|
|||
{
|
||||
PETSPELL_NORMAL = 0,
|
||||
PETSPELL_FAMILY = 1,
|
||||
PETSPELL_TALENT = 2,
|
||||
};
|
||||
|
||||
struct PetSpell
|
||||
|
|
@ -198,8 +199,9 @@ class Pet : public Creature
|
|||
bool learnSpell(uint32 spell_id);
|
||||
void learnSpellHighRank(uint32 spellid);
|
||||
void InitLevelupSpellsForLevel();
|
||||
bool unlearnSpell(uint32 spell_id, bool learn_prev);
|
||||
bool removeSpell(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 clear_ab = true);
|
||||
void CleanupActionBar();
|
||||
|
||||
PetSpellMap m_spells;
|
||||
AutoSpellList m_autospells;
|
||||
|
|
|
|||
|
|
@ -357,6 +357,10 @@ 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);
|
||||
|
||||
//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)))
|
||||
{
|
||||
|
|
@ -377,8 +381,7 @@ void WorldSession::HandlePetSetAction( WorldPacket & recv_data )
|
|||
((Pet*)pet)->ToggleAutocast(spell_id, false);
|
||||
}
|
||||
|
||||
charmInfo->GetActionBarEntry(position)->Type = act_state;
|
||||
charmInfo->GetActionBarEntry(position)->SpellOrAction = spell_id;
|
||||
charmInfo->SetActionBar(position,spell_id,ActiveStates(act_state));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -561,11 +564,7 @@ void WorldSession::HandlePetSpellAutocastOpcode( WorldPacket& recvPacket )
|
|||
else
|
||||
((Pet*)pet)->ToggleAutocast(spellid, state);
|
||||
|
||||
for(uint8 i = 0; i < 10; ++i)
|
||||
{
|
||||
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;
|
||||
}
|
||||
charmInfo->SetSpellAutocast(spellid,state);
|
||||
}
|
||||
|
||||
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) mailAction;
|
||||
data << (uint32) mailError;
|
||||
if ( mailError == MAIL_ERR_BAG_FULL )
|
||||
if ( mailError == MAIL_ERR_EQUIP_ERROR )
|
||||
data << (uint32) equipError;
|
||||
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;
|
||||
}
|
||||
|
||||
if(pItem && pItem->IsBindedNotWith(GetGUID()))
|
||||
if(pItem && pItem->IsBindedNotWith(this))
|
||||
{
|
||||
if(no_space_count)
|
||||
*no_space_count = count;
|
||||
|
|
@ -9360,7 +9360,7 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
|
|||
return EQUIP_ERR_ITEM_NOT_FOUND;
|
||||
|
||||
// item it 'bind'
|
||||
if(pItem->IsBindedNotWith(GetGUID()))
|
||||
if(pItem->IsBindedNotWith(this))
|
||||
return EQUIP_ERR_DONT_OWN_THAT_ITEM;
|
||||
|
||||
Bag *pBag;
|
||||
|
|
@ -9562,7 +9562,7 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo
|
|||
ItemPrototype const *pProto = pItem->GetProto();
|
||||
if( pProto )
|
||||
{
|
||||
if(pItem->IsBindedNotWith(GetGUID()))
|
||||
if(pItem->IsBindedNotWith(this))
|
||||
return EQUIP_ERR_DONT_OWN_THAT_ITEM;
|
||||
|
||||
// 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)
|
||||
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;
|
||||
|
||||
// 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();
|
||||
if (pProto)
|
||||
{
|
||||
if (pItem->IsBindedNotWith(GetGUID()))
|
||||
if (pItem->IsBindedNotWith(this))
|
||||
return EQUIP_ERR_DONT_OWN_THAT_ITEM;
|
||||
|
||||
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);
|
||||
|
||||
// action bar loop
|
||||
for(uint32 i = 0; i < 10; ++i)
|
||||
{
|
||||
data << uint32(charmInfo->GetActionBarEntry(i)->Raw);
|
||||
}
|
||||
charmInfo->BuildActionBar(&data);
|
||||
|
||||
size_t spellsCountPos = data.wpos();
|
||||
|
||||
|
|
@ -16433,10 +16430,7 @@ void Player::PossessSpellInitialize()
|
|||
data << uint32(0);
|
||||
data << uint32(0);
|
||||
|
||||
for(uint32 i = 0; i < 10; ++i)
|
||||
{
|
||||
data << uint16(charmInfo->GetActionBarEntry(i)->SpellOrAction) << uint16(charmInfo->GetActionBarEntry(i)->Type);
|
||||
}
|
||||
charmInfo->BuildActionBar(&data);
|
||||
|
||||
data << uint8(0); // spells count
|
||||
data << uint8(0); // cooldowns count
|
||||
|
|
@ -16484,10 +16478,7 @@ void Player::CharmSpellInitialize()
|
|||
else
|
||||
data << uint8(0) << uint8(0) << uint16(0);
|
||||
|
||||
for(uint32 i = 0; i < 10; ++i)
|
||||
{
|
||||
data << uint16(charmInfo->GetActionBarEntry(i)->SpellOrAction) << uint16(charmInfo->GetActionBarEntry(i)->Type);
|
||||
}
|
||||
charmInfo->BuildActionBar(&data);
|
||||
|
||||
data << uint8(addlist);
|
||||
|
||||
|
|
|
|||
|
|
@ -1325,7 +1325,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
void ClearComboPoints();
|
||||
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 UpdateNextMailTimeAndUnreads();
|
||||
void AddNewMailDeliverTime(time_t deliver_time);
|
||||
|
|
|
|||
|
|
@ -2515,4 +2515,32 @@ enum BattleGroundTypeId
|
|||
};
|
||||
#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
|
||||
|
|
|
|||
|
|
@ -10281,28 +10281,18 @@ void CharmInfo::InitPetActionBar()
|
|||
// the first 3 SpellOrActions are attack, follow and stay
|
||||
for(uint32 i = 0; i < 3; ++i)
|
||||
{
|
||||
PetActionBar[i].Type = ACT_COMMAND;
|
||||
PetActionBar[i].SpellOrAction = COMMAND_ATTACK - i;
|
||||
|
||||
PetActionBar[i + 7].Type = ACT_REACTION;
|
||||
PetActionBar[i + 7].SpellOrAction = COMMAND_ATTACK - i;
|
||||
SetActionBar(i,COMMAND_ATTACK - i,ACT_COMMAND);
|
||||
SetActionBar(i + 7,COMMAND_ATTACK - i,ACT_REACTION);
|
||||
}
|
||||
for(uint32 i = 0; i < 4; ++i)
|
||||
{
|
||||
PetActionBar[i + 3].Type = ACT_DISABLED;
|
||||
PetActionBar[i + 3].SpellOrAction = 0;
|
||||
}
|
||||
SetActionBar(i,0,ACT_DISABLED);
|
||||
}
|
||||
|
||||
void CharmInfo::InitEmptyActionBar()
|
||||
{
|
||||
for(uint32 x = 1; x < 10; ++x)
|
||||
{
|
||||
PetActionBar[x].Type = ACT_PASSIVE;
|
||||
PetActionBar[x].SpellOrAction = 0;
|
||||
}
|
||||
PetActionBar[0].Type = ACT_COMMAND;
|
||||
PetActionBar[0].SpellOrAction = COMMAND_ATTACK;
|
||||
SetActionBar(0,COMMAND_ATTACK,ACT_COMMAND);
|
||||
for(uint32 x = 1; x < MAX_UNIT_ACTION_BAR_INDEX; ++x)
|
||||
SetActionBar(x,0,ACT_PASSIVE);
|
||||
}
|
||||
|
||||
void CharmInfo::InitPossessCreateSpells()
|
||||
|
|
@ -10317,7 +10307,7 @@ void CharmInfo::InitPossessCreateSpells()
|
|||
if (IsPassiveSpell(((Creature*)m_unit)->m_spells[x]))
|
||||
m_unit->CastSpell(m_unit, ((Creature*)m_unit)->m_spells[x], true);
|
||||
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
|
||||
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
|
||||
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;
|
||||
uint32 first_id = spellmgr.GetFirstSpellInChain(spell_id);
|
||||
|
||||
// old spell can be leasted for example in case learn high rank
|
||||
for(uint8 i = 0; i < 10; ++i)
|
||||
// new spell rank can be already listed
|
||||
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;
|
||||
if (!oldid)
|
||||
{
|
||||
if (newstate == ACT_DECIDE)
|
||||
PetActionBar[i].Type = ACT_DISABLED;
|
||||
else
|
||||
PetActionBar[i].Type = newstate;
|
||||
}
|
||||
|
||||
PetActionBar[i].SpellOrAction = spell_id;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -10421,6 +10428,50 @@ void CharmInfo::SetPetNumber(uint32 petnumber, bool statwindow)
|
|||
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
|
||||
{
|
||||
return HasAuraState(AURA_STATE_FROZEN);
|
||||
|
|
|
|||
|
|
@ -714,24 +714,6 @@ struct SpellNonMeleeDamage{
|
|||
|
||||
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
|
||||
|
||||
struct DeclinedName
|
||||
|
|
@ -774,12 +756,28 @@ enum CommandStates
|
|||
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
|
||||
{
|
||||
uint16 spellId;
|
||||
uint16 active;
|
||||
};
|
||||
|
||||
#define MAX_UNIT_ACTION_BAR_INDEX 10
|
||||
|
||||
struct CharmInfo
|
||||
{
|
||||
public:
|
||||
|
|
@ -798,15 +796,27 @@ struct CharmInfo
|
|||
void InitCharmCreateSpells();
|
||||
void InitPetActionBar();
|
||||
void InitEmptyActionBar();
|
||||
|
||||
//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);
|
||||
|
||||
UnitActionBarEntry* GetActionBarEntry(uint8 index) { return &(PetActionBar[index]); }
|
||||
CharmSpellEntry* GetCharmSpell(uint8 index) { return &(m_charmspells[index]); }
|
||||
private:
|
||||
|
||||
Unit* m_unit;
|
||||
UnitActionBarEntry PetActionBar[10];
|
||||
UnitActionBarEntry PetActionBar[MAX_UNIT_ACTION_BAR_INDEX];
|
||||
CharmSpellEntry m_charmspells[4];
|
||||
CommandStates m_CommandState;
|
||||
ReactStates m_reactState;
|
||||
|
|
|
|||
|
|
@ -19,11 +19,11 @@
|
|||
#ifndef 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 WPError( assertion, errmsg ) if( ! (assertion) ) { sLog.outError( "%s:%i ERROR:\n %s\n", __FILE__, __LINE__, (char *)errmsg ); assert( false ); }
|
||||
#define WPWarning( assertion, errmsg ) if( ! (assertion) ) { sLog.outError( "%s:%i WARNING:\n %s\n", __FILE__, __LINE__, (char *)errmsg ); }
|
||||
#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( "%\n%s:%i in %s ERROR:\n %s\n", __FILE__, __LINE__, __FUNCTION__, (char *)errmsg ); assert( false ); }
|
||||
#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
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "7895"
|
||||
#define REVISION_NR "7903"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue