aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am22
-rw-r--r--sql/mangos.sql2
-rw-r--r--sql/updates/4382_8115_world_playercreateinfo_action.sql358
-rw-r--r--src/game/ItemHandler.cpp26
-rw-r--r--src/game/Level3.cpp7
-rw-r--r--src/game/Player.cpp147
-rw-r--r--src/game/Player.h7
-rw-r--r--src/game/SpellEffects.cpp36
-rw-r--r--src/game/SpellMgr.cpp20
-rw-r--r--src/game/Unit.cpp4
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