diff options
-rw-r--r-- | Makefile.am | 22 | ||||
-rw-r--r-- | sql/mangos.sql | 2 | ||||
-rw-r--r-- | sql/updates/4382_8115_world_playercreateinfo_action.sql | 358 | ||||
-rw-r--r-- | src/game/ItemHandler.cpp | 26 | ||||
-rw-r--r-- | src/game/Level3.cpp | 7 | ||||
-rw-r--r-- | src/game/Player.cpp | 147 | ||||
-rw-r--r-- | src/game/Player.h | 7 | ||||
-rw-r--r-- | src/game/SpellEffects.cpp | 36 | ||||
-rw-r--r-- | src/game/SpellMgr.cpp | 20 | ||||
-rw-r--r-- | src/game/Unit.cpp | 4 |
10 files changed, 509 insertions, 120 deletions
diff --git a/Makefile.am b/Makefile.am index eb58ac488f2..4edbad5947c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -22,17 +22,6 @@ SUBDIRS = dep doc src ## Additional files to include when running 'make dist' -# Win32 project workspace for Visual Studio .NET 2003 -EXTRA_DIST = \ - win/mangosdVC71.sln \ - win/VC71/framework.vcproj \ - win/VC71/game.vcproj \ - win/VC71/mangosd.vcproj \ - win/VC71/realmd.vcproj \ - win/VC71/shared.vcproj \ - win/VC71/zlib.vcproj \ - win/VC71/g3dlite.vcproj - # Win32 project workspace for Visual Studio .NET 2005 EXTRA_DIST += \ win/mangosdVC80.sln \ @@ -55,3 +44,14 @@ EXTRA_DIST += \ win/VC90/zlib.vcproj \ win/VC90/g3dlite.vcproj +# Win32 project workspace for Visual Studio .NET 2010 +EXTRA_DIST = \ + win/mangosdVC100.sln \ + win/VC100/framework.vcxproj \ + win/VC100/game.vcxproj \ + win/VC100/mangosd.vcxproj \ + win/VC100/realmd.vcxproj \ + win/VC100/shared.vcxproj \ + win/VC100/zlib.vcxproj \ + win/VC100/g3dlite.vcxproj + diff --git a/sql/mangos.sql b/sql/mangos.sql index 4f7970d1712..18babeabd2f 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -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_8098_02_mangos_playercreateinfo_action` bit(1) default NULL + `required_8115_01_mangos_playercreateinfo_action` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- diff --git a/sql/updates/4382_8115_world_playercreateinfo_action.sql b/sql/updates/4382_8115_world_playercreateinfo_action.sql new file mode 100644 index 00000000000..1af313a0626 --- /dev/null +++ b/sql/updates/4382_8115_world_playercreateinfo_action.sql @@ -0,0 +1,358 @@ +-- ALTER TABLE db_version CHANGE COLUMN required_8112_01_mangos_spell_proc_event required_8115_01_mangos_playercreateinfo_action bit; + +TRUNCATE TABLE `playercreateinfo_action`; +INSERT INTO `playercreateinfo_action` VALUES +(1,1,1,78,0), +(1,1,0,6603,0), +(1,1,11,117,128), +(1,2,2,635,0), +(1,2,0,6603,0), +(1,2,1,21084,0), +(1,2,10,159,128), +(1,2,11,2070,128), +(1,4,1,1752,0), +(1,4,2,2098,0), +(1,4,3,2764,0), +(1,4,0,6603,0), +(1,4,11,2070,128), +(1,5,1,585,0), +(1,5,2,2050,0), +(1,5,0,6603,0), +(1,5,10,159,128), +(1,5,11,2070,128), +(1,6,0,6603,0), +(1,6,1,49576,0), +(1,6,2,45477,0), +(1,6,3,45462,0), +(1,6,4,45902,0), +(1,6,5,47541,0), +(1,6,11,59752,0), +(1,8,1,133,0), +(1,8,2,168,0), +(1,8,0,6603,0), +(1,8,10,159,128), +(1,8,11,2070,128), +(1,9,1,686,0), +(1,9,2,687,0), +(1,9,0,6603,0), +(1,9,10,159,128), +(1,9,11,4604,128), +(2,1,1,78,0), +(2,1,0,6603,0), +(2,1,11,117,128), +(2,3,2,75,0), +(2,3,1,2973,0), +(2,3,0,6603,0), +(2,3,11,117,128), +(2,3,10,159,128), +(2,4,10,0,128), +(2,4,1,1752,0), +(2,4,2,2098,0), +(2,4,0,6603,0), +(2,4,11,117,128), +(2,6,0,6603,0), +(2,6,1,49576,0), +(2,6,2,45477,0), +(2,6,3,45462,0), +(2,6,4,45902,0), +(2,6,5,47541,0), +(2,6,10,20572,0), +(2,7,2,331,0), +(2,7,1,403,0), +(2,7,0,6603,0), +(2,7,11,117,128), +(2,7,10,159,128), +(2,9,1,686,0), +(2,9,2,687,0), +(2,9,0,6603,0), +(2,9,11,117,128), +(2,9,10,159,128), +(3,1,1,78,0), +(3,1,0,6603,0), +(3,1,11,117,128), +(3,2,2,635,0), +(3,2,0,6603,0), +(3,2,1,21084,0), +(3,2,10,159,128), +(3,2,11,4540,128), +(3,3,2,75,0), +(3,3,1,2973,0), +(3,3,0,6603,0), +(3,3,11,117,128), +(3,3,10,159,128), +(3,4,1,1752,0), +(3,4,2,2098,0), +(3,4,3,2764,0), +(3,4,0,6603,0), +(3,4,11,4540,128), +(3,5,1,585,0), +(3,5,2,2050,0), +(3,5,0,6603,0), +(3,5,10,159,128), +(3,5,11,4540,128), +(3,6,0,6603,0), +(3,6,1,49576,0), +(3,6,2,45477,0), +(3,6,3,45462,0), +(3,6,4,45902,0), +(3,6,5,47541,0), +(3,6,10,2481,0), +(4,1,1,78,0), +(4,1,0,6603,0), +(4,1,11,117,128), +(4,3,2,75,0), +(4,3,1,2973,0), +(4,3,0,6603,0), +(4,3,11,117,128), +(4,3,10,159,128), +(4,4,1,1752,0), +(4,4,2,2098,0), +(4,4,3,2764,0), +(4,4,0,6603,0), +(4,4,11,4540,128), +(4,5,1,585,0), +(4,5,2,2050,0), +(4,5,0,6603,0), +(4,5,10,159,128), +(4,5,11,2070,128), +(4,6,0,6603,0), +(4,6,1,49576,0), +(4,6,2,45477,0), +(4,6,3,45462,0), +(4,6,4,45902,0), +(4,6,5,47541,0), +(4,6,10,58984,0), +(4,6,83,58984,0), +(4,11,1,5176,0), +(4,11,2,5185,0), +(4,11,0,6603,0), +(4,11,10,159,128), +(4,11,11,4536,128), +(5,1,11,4604,128), +(5,1,0,6603,0), +(5,1,1,78,0), +(5,4,11,4604,128), +(5,4,3,2764,0), +(5,4,2,2098,0), +(5,4,1,1752,0), +(5,4,0,6603,0), +(5,5,10,159,128), +(5,5,2,2050,0), +(5,5,1,585,0), +(5,5,11,4604,128), +(5,5,0,6603,0), +(5,6,0,6603,0), +(5,6,1,49576,0), +(5,6,2,45477,0), +(5,6,3,45462,0), +(5,6,4,45902,0), +(5,6,5,47541,0), +(5,6,10,20577,0), +(5,8,11,4604,128), +(5,8,10,159,128), +(5,8,2,168,0), +(5,8,1,133,0), +(5,8,0,6603,0), +(5,9,1,686,0), +(5,9,10,159,128), +(5,9,2,687,0), +(5,9,11,4604,128), +(5,9,0,6603,0), +(6,1,1,78,0), +(6,1,2,20549,0), +(6,1,11,4540,128), +(6,1,0,6603,0), +(6,3,1,2973,0), +(6,3,10,159,128), +(6,3,2,75,0), +(6,3,3,20549,0), +(6,3,11,117,128), +(6,3,0,6603,0), +(6,6,0,6603,0), +(6,6,1,49576,0), +(6,6,2,45477,0), +(6,6,3,45462,0), +(6,6,4,45902,0), +(6,6,5,47541,0), +(6,6,10,20549,0), +(6,6,75,20549,0), +(6,7,1,403,0), +(6,7,10,159,128), +(6,7,2,331,0), +(6,7,3,20549,0), +(6,7,11,4604,128), +(6,7,0,6603,0), +(6,11,1,5176,0), +(6,11,10,159,128), +(6,11,2,5185,0), +(6,11,3,20549,0), +(6,11,11,4536,128), +(6,11,0,6603,0), +(7,1,11,117,128), +(7,1,1,78,0), +(7,1,0,6603,0), +(7,4,11,117,128), +(7,4,3,2764,0), +(7,4,1,1752,0), +(7,4,2,2098,0), +(7,4,0,6603,0), +(7,6,0,6603,0), +(7,6,1,49576,0), +(7,6,2,45477,0), +(7,6,3,45462,0), +(7,6,4,45902,0), +(7,6,5,47541,0), +(7,6,10,20589,0), +(7,6,72,6603,0), +(7,6,83,117,128), +(7,6,84,6603,0), +(7,6,96,6603,0), +(7,6,108,6603,0), +(7,8,11,4536,128), +(7,8,1,133,0), +(7,8,2,168,0), +(7,8,10,159,128), +(7,8,0,6603,0), +(7,9,11,4604,128), +(7,9,1,686,0), +(7,9,2,687,0), +(7,9,10,159,128), +(7,9,0,6603,0), +(8,1,11,117,128), +(8,1,1,78,0), +(8,1,3,2764,0), +(8,1,0,6603,0), +(8,3,10,159,128), +(8,3,11,4604,128), +(8,3,1,2973,0), +(8,3,2,75,0), +(8,3,0,6603,0), +(8,4,1,1752,0), +(8,4,3,2764,0), +(8,4,2,2098,0), +(8,4,11,117,128), +(8,4,0,6603,0), +(8,5,1,585,0), +(8,5,10,159,128), +(8,5,2,2050,0), +(8,5,11,4540,128), +(8,5,0,6603,0), +(8,6,0,6603,0), +(8,6,1,49576,0), +(8,6,2,45477,0), +(8,6,3,45462,0), +(8,6,4,45902,0), +(8,6,5,47541,0), +(8,6,10,50621,0), +(8,7,1,403,0), +(8,7,10,159,128), +(8,7,2,331,0), +(8,7,11,117,128), +(8,7,0,6603,0), +(8,8,1,133,0), +(8,8,10,159,128), +(8,8,2,168,0), +(8,8,11,117,128), +(8,8,0,6603,0), +(10,2,0,6603,0), +(10,2,1,21084,0), +(10,2,2,635,0), +(10,2,3,28734,0), +(10,2,4,28730,0), +(10,2,10,159,128), +(10,2,11,20857,128), +(10,3,0,6603,0), +(10,3,1,2973,0), +(10,3,2,75,0), +(10,3,3,28734,0), +(10,3,4,28730,0), +(10,3,10,159,128), +(10,3,11,20857,128), +(10,4,0,6603,0), +(10,4,1,1752,0), +(10,4,2,2098,0), +(10,4,3,2764,0), +(10,4,4,28734,0), +(10,4,5,25046,0), +(10,4,11,20857,128), +(10,5,0,6603,0), +(10,5,1,585,0), +(10,5,2,2050,0), +(10,5,3,28734,0), +(10,5,4,28730,0), +(10,5,10,159,128), +(10,5,11,20857,128), +(10,6,0,6603,0), +(10,6,1,49576,0), +(10,6,2,45477,0), +(10,6,3,45462,0), +(10,6,4,45902,0), +(10,6,5,47541,0), +(10,6,6,50613,0), +(10,8,0,6603,0), +(10,8,1,133,0), +(10,8,2,168,0), +(10,8,3,28734,0), +(10,8,4,28730,0), +(10,8,10,159,128), +(10,8,11,20857,128), +(10,9,11,20857,128), +(10,9,10,159,128), +(10,9,4,28730,0), +(10,9,3,28734,0), +(10,9,2,687,0), +(10,9,1,686,0), +(10,9,0,6603,0), +(11,1,0,6603,0), +(11,1,72,6603,0), +(11,1,73,78,0), +(11,1,74,28880,0), +(11,1,83,4540,128), +(11,1,84,6603,0), +(11,1,96,6603,0), +(11,1,108,6603,0), +(11,2,0,6603,0), +(11,2,1,21084,0), +(11,2,2,635,0), +(11,2,3,59542,0), +(11,2,10,159,128), +(11,2,11,4540,128), +(11,2,83,4540,128), +(11,3,0,6603,0), +(11,3,1,2973,0), +(11,3,2,75,0), +(11,3,3,59543,0), +(11,3,10,159,128), +(11,3,11,4540,128), +(11,3,72,6603,0), +(11,3,73,2973,0), +(11,3,74,75,0), +(11,3,82,159,128), +(11,3,83,4540,128), +(11,5,0,6603,0), +(11,5,1,585,0), +(11,5,2,2050,0), +(11,5,3,59544,0), +(11,5,10,159,128), +(11,5,11,4540,128), +(11,5,83,4540,128), +(11,6,0,6603,0), +(11,6,1,49576,0), +(11,6,2,45477,0), +(11,6,3,45462,0), +(11,6,4,45902,0), +(11,6,5,47541,0), +(11,6,6,59545,0), +(11,7,0,6603,0), +(11,7,1,403,0), +(11,7,2,331,0), +(11,7,3,59547,0), +(11,7,10,159,128), +(11,7,11,4540,128), +(11,8,0,6603,0), +(11,8,1,133,0), +(11,8,2,168,0), +(11,8,3,59548,0), +(11,8,10,159,128), +(11,8,11,4540,128), +(11,8,83,4540,128); diff --git a/src/game/ItemHandler.cpp b/src/game/ItemHandler.cpp index cf762dd0cb2..d886cda742b 100644 --- a/src/game/ItemHandler.cpp +++ b/src/game/ItemHandler.cpp @@ -674,7 +674,31 @@ void WorldSession::HandleBuyItemInSlotOpcode( WorldPacket & recv_data ) recv_data >> vendorguid >> item >> slot >> bagguid >> bagslot >> count; - GetPlayer()->BuyItemFromVendor(vendorguid,item,count,bagguid,bagslot); + uint8 bag = NULL_BAG; // init for case invalid bagGUID + + // find bag slot by bag guid + if (bagguid == _player->GetGUID()) + bag = INVENTORY_SLOT_BAG_0; + else + { + for (int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END;++i) + { + if (Bag *pBag = (Bag*)_player->GetItemByPos(INVENTORY_SLOT_BAG_0,i)) + { + if (bagguid == pBag->GetGUID()) + { + bag = i; + break; + } + } + } + } + + // bag not found, cheating? + if (bag == NULL_BAG) + return; + + GetPlayer()->BuyItemFromVendor(vendorguid,item,count,bag,bagslot); } void WorldSession::HandleBuyItemOpcode( WorldPacket & recv_data ) diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index ba956ac38f4..a099aa8f66c 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -1640,6 +1640,9 @@ bool ChatHandler::HandleUnLearnCommand(const char* args) else SendSysMessage(LANG_FORGET_SPELL); + if(GetTalentSpellCost(spell_id)) + target->SendTalentsInfoData(false); + return true; } @@ -2582,6 +2585,10 @@ bool ChatHandler::HandleLearnCommand(const char* args) else targetPlayer->learnSpell(spell,false); + uint32 first_spell = spellmgr.GetFirstSpellInChain(spell); + if(GetTalentSpellCost(first_spell)) + targetPlayer->SendTalentsInfoData(false); + return true; } diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 15dc3c69bd8..ea0c66843a8 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -2992,7 +2992,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen if(!rankSpellId || rankSpellId==spell_id) continue; - removeSpell(rankSpellId); + removeSpell(rankSpellId,false,false); } } } @@ -3268,7 +3268,7 @@ void Player::learnSpell(uint32 spell_id, bool dependent) GetSession()->SendPacket(&data); } -void Player::removeSpell(uint32 spell_id, bool disabled, bool update_action_bar_for_low_rank) +void Player::removeSpell(uint32 spell_id, bool disabled, bool learn_low_rank) { PlayerSpellMap::iterator itr = m_spells.find(spell_id); if (itr == m_spells.end()) @@ -3288,7 +3288,7 @@ void Player::removeSpell(uint32 spell_id, bool disabled, bool update_action_bar_ SpellsRequiringSpellMap const& reqMap = spellmgr.GetSpellsRequiringSpell(); SpellsRequiringSpellMap::const_iterator itr2 = reqMap.find(spell_id); for (uint32 i=reqMap.count(spell_id);i>0;i--,itr2++) - removeSpell(itr2->second,disabled); + removeSpell(itr2->second,disabled,false); // re-search, it can be corrupted in prev loop itr = m_spells.find(spell_id); @@ -3417,15 +3417,17 @@ void Player::removeSpell(uint32 spell_id, bool disabled, bool update_action_bar_ { SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id); - // if talent then lesser rank also talent and need learn + // if talent then lesser rank also talent and need learn if(talentCosts) { - //learnSpell (prev_id,false); + // I cannot see why mangos has these lines. + //if(learn_low_rank) + // learnSpell (prev_id,false); } - // if ranked non-stackable spell: need activate lesser rank and update dendence state + // if ranked non-stackable spell: need activate lesser rank and update dendence state else if(cur_active && !SpellMgr::canStackSpellRanks(spellInfo) && spellmgr.GetSpellRank(spellInfo->Id) != 0) { - // need manually update dependence state (learn spell ignore like attempts) + // need manually update dependence state (learn spell ignore like attempts) PlayerSpellMap::iterator prev_itr = m_spells.find(prev_id); if (prev_itr != m_spells.end()) { @@ -3437,19 +3439,16 @@ void Player::removeSpell(uint32 spell_id, bool disabled, bool update_action_bar_ } // now re-learn if need re-activate - if(cur_active && !prev_itr->second->active) + if(cur_active && !prev_itr->second->active && learn_low_rank) { if(addSpell(prev_id,true,false,prev_itr->second->dependent,prev_itr->second->disabled)) { - if(update_action_bar_for_low_rank) - { - // downgrade spell ranks in spellbook and action bar - WorldPacket data(SMSG_SUPERCEDED_SPELL, 4 + 4); - data << uint32(spell_id); - data << uint32(prev_id); - GetSession()->SendPacket( &data ); - prev_activate = true; - } + // downgrade spell ranks in spellbook and action bar + WorldPacket data(SMSG_SUPERCEDED_SPELL, 4 + 4); + data << uint32(spell_id); + data << uint32(prev_id); + GetSession()->SendPacket( &data ); + prev_activate = true; } } } @@ -3473,6 +3472,7 @@ void Player::RemoveSpellCooldown( uint32 spell_id, bool update /* = false */ ) SendClearCooldown(spell_id, this); } +// I am not sure which one is more efficient void Player::RemoveCategoryCooldown( uint32 cat ) { SpellCategoryStore::const_iterator i_scstore = sSpellCategoryStore.find(cat); @@ -3481,6 +3481,22 @@ void Player::RemoveCategoryCooldown( uint32 cat ) RemoveSpellCooldown(*i_scset, true); } +void Player::RemoveSpellCategoryCooldown(uint32 cat, bool update /* = false */) +{ + SpellCategoryStore::const_iterator ct = sSpellCategoryStore.find(cat); + if (ct == sSpellCategoryStore.end()) + return; + + const SpellCategorySet& ct_set = ct->second; + for (SpellCooldowns::const_iterator i = m_spellCooldowns.begin(); i != m_spellCooldowns.end();) + { + if (ct_set.find(i->first) != ct_set.end()) + RemoveSpellCooldown((i++)->first, update); + else + ++i; + } +} + void Player::RemoveArenaSpellCooldowns() { // remove cooldowns on spells that has < 15 min CD @@ -3664,7 +3680,13 @@ bool Player::resetTalents(bool no_cost) uint32 itrFirstId = spellmgr.GetFirstSpellInChain(itr->first); // unlearn if first rank is talent or learned by talent - if (itrFirstId == talentInfo->RankID[j] || spellmgr.IsSpellLearnToSpell(talentInfo->RankID[j],itrFirstId)) + if (itrFirstId == talentInfo->RankID[j]) + { + removeSpell(itr->first,!IsPassiveSpell(itr->first),false); + itr = GetSpellMap().begin(); + continue; + } + else if (spellmgr.IsSpellLearnToSpell(talentInfo->RankID[j],itrFirstId)) { removeSpell(itr->first,!IsPassiveSpell(itr->first)); itr = GetSpellMap().begin(); @@ -17849,20 +17871,20 @@ void Player::InitDataForForm(bool reapplyMods) } // Return true is the bought item has a max count to force refresh of window by caller -bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint64 bagguid, uint8 slot) +bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint8 bag, uint8 slot) { // cheating attempt - if(count < 1) count = 1; + if (count < 1) count = 1; // cheating attempt if(slot > MAX_BAG_SIZE && slot !=NULL_SLOT) return false; - if(!isAlive()) + if (!isAlive()) return false; ItemPrototype const *pProto = objmgr.GetItemPrototype( item ); - if( !pProto ) + if (!pProto) { SendBuyError( BUY_ERR_CANT_FIND_ITEM, NULL, item, 0); return false; @@ -17884,7 +17906,7 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint } size_t vendor_slot = vItems->FindItemSlot(item); - if(vendor_slot >= vItems->GetItemCount()) + if (vendor_slot >= vItems->GetItemCount()) { SendBuyError( BUY_ERR_CANT_FIND_ITEM, pCreature, item, 0); return false; @@ -17893,39 +17915,39 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint VendorItem const* crItem = vItems->m_items[vendor_slot]; // check current item amount if it limited - if( crItem->maxcount != 0 ) + if (crItem->maxcount != 0) { - if(pCreature->GetVendorItemCurrentCount(crItem) < pProto->BuyCount * count ) + if (pCreature->GetVendorItemCurrentCount(crItem) < pProto->BuyCount * count ) { SendBuyError( BUY_ERR_ITEM_ALREADY_SOLD, pCreature, item, 0); return false; } } - if( uint32(GetReputationRank(pProto->RequiredReputationFaction)) < pProto->RequiredReputationRank) + if (uint32(GetReputationRank(pProto->RequiredReputationFaction)) < pProto->RequiredReputationRank) { SendBuyError( BUY_ERR_REPUTATION_REQUIRE, pCreature, item, 0); return false; } - if(crItem->ExtendedCost) + if (crItem->ExtendedCost) { ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(crItem->ExtendedCost); - if(!iece) + if (!iece) { sLog.outError("Item %u have wrong ExtendedCost field value %u", pProto->ItemId, crItem->ExtendedCost); return false; } // honor points price - if(GetHonorPoints() < (iece->reqhonorpoints * count)) + if (GetHonorPoints() < (iece->reqhonorpoints * count)) { SendEquipError(EQUIP_ERR_NOT_ENOUGH_HONOR_POINTS, NULL, NULL); return false; } // arena points price - if(GetArenaPoints() < (iece->reqarenapoints * count)) + if (GetArenaPoints() < (iece->reqarenapoints * count)) { SendEquipError(EQUIP_ERR_NOT_ENOUGH_ARENA_POINTS, NULL, NULL); return false; @@ -17955,69 +17977,38 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint // reputation discount price = uint32(floor(price * GetReputationPriceDiscount(pCreature))); - if( GetMoney() < price ) + if (GetMoney() < price) { SendBuyError( BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, item, 0); return false; } - uint8 bag = 0; // init for case invalid bagGUID - - if (bagguid != NULL_BAG && slot != NULL_SLOT) - { - if( bagguid == GetGUID() ) - { - bag = INVENTORY_SLOT_BAG_0; - } - else - { - for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END;i++) - { - if( Bag *pBag = (Bag*)GetItemByPos(INVENTORY_SLOT_BAG_0,i) ) - { - if( bagguid == pBag->GetGUID() ) - { - // slot is counted from 0 but BagSize from 1 - if(slot+1 > pBag->GetBagSize()) - { - sLog.outDebug("CHEATING ATTEMPT slot > bagSize in BuyItemFromVendor playerGUID: "I64FMT" name: %s slot: %u", GetGUID(), GetName(), slot); - return false; - } - if(slot < pBag->GetBagSlot() && !pBag->GetItemByPos(slot)) - bag = i; - break; - } - } - } - } - } - - if( IsInventoryPos( bag, slot ) || (bagguid == NULL_BAG && slot == NULL_SLOT) ) + if ((bag == NULL_BAG && slot == NULL_SLOT) || IsInventoryPos(bag, slot)) { ItemPosCountVec dest; uint8 msg = CanStoreNewItem( bag, slot, dest, item, pProto->BuyCount * count ); - if( msg != EQUIP_ERR_OK ) + if (msg != EQUIP_ERR_OK) { SendEquipError( msg, NULL, NULL ); return false; } ModifyMoney( -(int32)price ); - if(crItem->ExtendedCost) // case for new honor system + if (crItem->ExtendedCost) // case for new honor system { ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(crItem->ExtendedCost); - if(iece->reqhonorpoints) + if (iece->reqhonorpoints) ModifyHonorPoints( - int32(iece->reqhonorpoints * count)); - if(iece->reqarenapoints) + if (iece->reqarenapoints) ModifyArenaPoints( - int32(iece->reqarenapoints * count)); for (uint8 i = 0; i < 5; ++i) { - if(iece->reqitem[i]) + if (iece->reqitem[i]) DestroyItemCount(iece->reqitem[i], (iece->reqitemcount[i] * count), true); } } - if(Item *it = StoreNewItem( dest, item, true )) + if (Item *it = StoreNewItem( dest, item, true )) { uint32 new_count = pCreature->UpdateVendorItemCurrentCount(crItem,pProto->BuyCount * count); @@ -18031,9 +18022,9 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint SendNewItem(it, pProto->BuyCount*count, true, false, false); } } - else if( IsEquipmentPos( bag, slot ) ) + else if (IsEquipmentPos(bag, slot)) { - if(pProto->BuyCount * count != 1) + if (pProto->BuyCount * count != 1) { SendEquipError( EQUIP_ERR_ITEM_CANT_BE_EQUIPPED, NULL, NULL ); return false; @@ -18041,19 +18032,19 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint uint16 dest; uint8 msg = CanEquipNewItem( slot, dest, item, false ); - if( msg != EQUIP_ERR_OK ) + if (msg != EQUIP_ERR_OK) { SendEquipError( msg, NULL, NULL ); return false; } ModifyMoney( -(int32)price ); - if(crItem->ExtendedCost) // case for new honor system + if (crItem->ExtendedCost) // case for new honor system { ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(crItem->ExtendedCost); - if(iece->reqhonorpoints) + if (iece->reqhonorpoints) ModifyHonorPoints( - int32(iece->reqhonorpoints)); - if(iece->reqarenapoints) + if (iece->reqarenapoints) ModifyArenaPoints( - int32(iece->reqarenapoints)); for (uint8 i = 0; i < 5; ++i) { @@ -18062,7 +18053,7 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint } } - if(Item *it = EquipNewItem( dest, item, true )) + if (Item *it = EquipNewItem( dest, item, true )) { uint32 new_count = pCreature->UpdateVendorItemCurrentCount(crItem,pProto->BuyCount * count); @@ -18084,7 +18075,7 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint return false; } - return crItem->maxcount!=0; + return crItem->maxcount != 0; } uint32 Player::GetMaxPersonalArenaRatingRequirement() @@ -19106,7 +19097,7 @@ void Player::resetSpells() PlayerSpellMap smap = GetSpellMap(); for(PlayerSpellMap::const_iterator iter = smap.begin();iter != smap.end(); ++iter) - removeSpell(iter->first); // only iter->first can be accessed, object by iter->second can be deleted already + removeSpell(iter->first,false,false); // only iter->first can be accessed, object by iter->second can be deleted already learnDefaultSpells(); learnQuestRewardedSpells(); diff --git a/src/game/Player.h b/src/game/Player.h index 38de51033c3..17563688da6 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1126,7 +1126,7 @@ class TRINITY_DLL_SPEC Player : public Unit return mainItem && mainItem->GetProto()->InventoryType == INVTYPE_2HWEAPON && !CanTitanGrip(); } void SendNewItem( Item *item, uint32 count, bool received, bool created, bool broadcast = false ); - bool BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint64 bagguid, uint8 slot); + bool BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint8 bag, uint8 slot); float GetReputationPriceDiscount( Creature const* pCreature ) const; Player* GetTrader() const { return pTrader; } @@ -1395,7 +1395,7 @@ class TRINITY_DLL_SPEC Player : public Unit void SendInitialSpells(); bool addSpell(uint32 spell_id, bool active, bool learning, bool dependent, bool disabled); void learnSpell(uint32 spell_id, bool dependent); - void removeSpell(uint32 spell_id, bool disabled = false, bool update_action_bar_for_low_rank = false); + void removeSpell(uint32 spell_id, bool disabled = false, bool learn_low_rank = true); void resetSpells(); void learnDefaultSpells(); void learnQuestRewardedSpells(); @@ -1437,6 +1437,8 @@ class TRINITY_DLL_SPEC Player : public Unit PlayerSpellMap const& GetSpellMap() const { return m_spells; } PlayerSpellMap & GetSpellMap() { return m_spells; } + SpellCooldowns const& GetSpellCooldownMap() const { return m_spellCooldowns; } + void AddSpellMod(SpellModifier* mod, bool apply); bool IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mod, Spell * spell = NULL); template <class T> T ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell * spell = NULL); @@ -1463,6 +1465,7 @@ class TRINITY_DLL_SPEC Player : public Unit void SendCooldownEvent(SpellEntry const *spellInfo, uint32 itemId = 0, Spell* spell = NULL); void ProhibitSpellScholl(SpellSchoolMask idSchoolMask, uint32 unTimeMs ); void RemoveSpellCooldown(uint32 spell_id, bool update = false); + void RemoveSpellCategoryCooldown(uint32 cat, bool update = false); void SendClearCooldown( uint32 spell_id, Unit* target ); void RemoveCategoryCooldown(uint32 cat); diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 67b87d7c93e..d8828e3f26b 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -1328,21 +1328,19 @@ void Spell::EffectDummy(uint32 i) return; // immediately finishes the cooldown on Frost spells - const PlayerSpellMap& sp_list = ((Player *)m_caster)->GetSpellMap(); - for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr) + const SpellCooldowns& cm = ((Player *)m_caster)->GetSpellCooldownMap(); + for (SpellCooldowns::const_iterator itr = cm.begin(); itr != cm.end();) { - if (itr->second->state == PLAYERSPELL_REMOVED) - continue; - - uint32 classspell = itr->first; - SpellEntry const *spellInfo = sSpellStore.LookupEntry(classspell); + SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first); if( spellInfo->SpellFamilyName == SPELLFAMILY_MAGE && (GetSpellSchoolMask(spellInfo) & SPELL_SCHOOL_MASK_FROST) && spellInfo->Id != 11958 && GetSpellRecoveryTime(spellInfo) > 0 ) { - ((Player*)m_caster)->RemoveSpellCooldown(classspell, true); + ((Player*)m_caster)->RemoveSpellCooldown((itr++)->first, true); } + else + ++itr; } return; } @@ -1619,14 +1617,15 @@ void Spell::EffectDummy(uint32 i) return; //immediately finishes the cooldown on certain Rogue abilities - const PlayerSpellMap& sp_list = ((Player *)m_caster)->GetSpellMap(); - for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr) + const SpellCooldowns& cm = ((Player *)m_caster)->GetSpellCooldownMap(); + for (SpellCooldowns::const_iterator itr = cm.begin(); itr != cm.end();) { - uint32 classspell = itr->first; - SpellEntry const *spellInfo = sSpellStore.LookupEntry(classspell); + SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first); if (spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && (spellInfo->SpellFamilyFlags[1] & 0x00000240 || spellInfo->SpellFamilyFlags[0] & 0x00000860)) - ((Player*)m_caster)->RemoveSpellCooldown(classspell,true); + ((Player*)m_caster)->RemoveSpellCooldown((itr++)->first,true); + else + ++itr; } return; } @@ -1646,14 +1645,15 @@ void Spell::EffectDummy(uint32 i) return; //immediately finishes the cooldown for hunter abilities - const PlayerSpellMap& sp_list = ((Player *)m_caster)->GetSpellMap(); - for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr) + const SpellCooldowns& cm = ((Player*)m_caster)->GetSpellCooldownMap(); + for (SpellCooldowns::const_iterator itr = cm.begin(); itr != cm.end();) { - uint32 classspell = itr->first; - SpellEntry const *spellInfo = sSpellStore.LookupEntry(classspell); + SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first); if (spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && spellInfo->Id != 23989 && GetSpellRecoveryTime(spellInfo) > 0 ) - ((Player*)m_caster)->RemoveSpellCooldown(classspell,true); + ((Player*)m_caster)->RemoveSpellCooldown((itr++)->first,true); + else + ++itr; } return; } diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index c4e521d4977..df583d098fc 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -2586,6 +2586,19 @@ DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellEntry const* spellproto // Explicit Diminishing Groups switch(spellproto->SpellFamilyName) { + case SPELLFAMILY_MAGE: + { + // Frostbite 0x80000000 + if (spellproto->SpellFamilyFlags[1] & 0x80000000) + return DIMINISHING_TRIGGER_ROOT; + // Shattered Barrier (triggered so doesn't share with Frost Nova) + else if (spellproto->SpellFamilyFlags[0] & 0x80000) + return DIMINISHING_TRIGGER_ROOT; + // Frost Nova / Freeze (Water Elemental) + else if (spellproto->SpellIconID == 193) + return DIMINISHING_CONTROL_ROOT; + break; + } case SPELLFAMILY_ROGUE: { // Sap 0x80 Gouge 0x8 @@ -2634,13 +2647,6 @@ DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellEntry const* spellproto return DIMINISHING_LIMITONLY; break; } - case SPELLFAMILY_MAGE: - { - // Frostbite - if (spellproto->SpellFamilyFlags[1] & 0x80000000) - return DIMINISHING_TRIGGER_ROOT; - break; - } case SPELLFAMILY_WARRIOR: { // Hamstring - limit duration to 10s in PvP diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 95efd29dc48..bdef7cb2d71 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -7792,9 +7792,9 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, AuraEffect* trig // Sword and Board case 50227: { - // remove cooldown of Shield Slam + // Remove cooldown on Shield Slam if (GetTypeId()==TYPEID_PLAYER) - ((Player*)this)->RemoveCategoryCooldown(1209); + ((Player*)this)->RemoveSpellCategoryCooldown(1209, true); break; } case 63375: // Improved Stormstrike |