From 5b50e2f9e89fb6f56ebbc573dec0b516e82369c9 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Tue, 13 Jan 2009 21:05:34 +0300 Subject: [PATCH 01/84] [7077] Implement support castable trainer spells for profession ranks. --- sql/characters.sql | 2 +- .../7077_01_characters_character_spell.sql | 214 ++++++++++++++++++ sql/updates/Makefile.am | 2 + src/game/Creature.h | 4 + src/game/NPCHandler.cpp | 38 ++-- src/game/ObjectMgr.cpp | 13 ++ src/game/Player.cpp | 10 +- src/shared/revision_nr.h | 2 +- 8 files changed, 262 insertions(+), 23 deletions(-) create mode 100644 sql/updates/7077_01_characters_character_spell.sql diff --git a/sql/characters.sql b/sql/characters.sql index 701a2cee8..da43adaf7 100644 --- a/sql/characters.sql +++ b/sql/characters.sql @@ -21,7 +21,7 @@ DROP TABLE IF EXISTS `character_db_version`; CREATE TABLE `character_db_version` ( - `required_7075_01_characters_character_spell` bit(1) default NULL + `required_7077_01_characters_character_spell` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB'; -- diff --git a/sql/updates/7077_01_characters_character_spell.sql b/sql/updates/7077_01_characters_character_spell.sql new file mode 100644 index 000000000..b68f99b1d --- /dev/null +++ b/sql/updates/7077_01_characters_character_spell.sql @@ -0,0 +1,214 @@ +ALTER TABLE character_db_version CHANGE COLUMN required_7075_01_characters_character_spell required_7077_01_characters_character_spell bit; + +UPDATE IGNORE character_spell SET spell = 2018 WHERE spell = 2020; +DELETE FROM character_spell WHERE spell = 2020; + +UPDATE IGNORE character_spell SET spell = 2018 WHERE spell = 2020; +DELETE FROM character_spell WHERE spell = 2020; + +UPDATE IGNORE character_spell SET spell = 3100 WHERE spell = 2021; +DELETE FROM character_spell WHERE spell = 2021; + +UPDATE IGNORE character_spell SET spell = 3104 WHERE spell = 2154; +DELETE FROM character_spell WHERE spell = 2154; + +UPDATE IGNORE character_spell SET spell = 2108 WHERE spell = 2155; +DELETE FROM character_spell WHERE spell = 2155; + +UPDATE IGNORE character_spell SET spell = 2259 WHERE spell = 2275; +DELETE FROM character_spell WHERE spell = 2275; + +UPDATE IGNORE character_spell SET spell = 3101 WHERE spell = 2280; +DELETE FROM character_spell WHERE spell = 2280; + +UPDATE IGNORE character_spell SET spell = 2366 WHERE spell = 2372; +DELETE FROM character_spell WHERE spell = 2372; + +UPDATE IGNORE character_spell SET spell = 2368 WHERE spell = 2373; +DELETE FROM character_spell WHERE spell = 2373; + +UPDATE IGNORE character_spell SET spell = 2550 WHERE spell = 2551; +DELETE FROM character_spell WHERE spell = 2551; + +UPDATE IGNORE character_spell SET spell = 2575 WHERE spell = 2581; +DELETE FROM character_spell WHERE spell = 2581; + +UPDATE IGNORE character_spell SET spell = 2576 WHERE spell = 2582; +DELETE FROM character_spell WHERE spell = 2582; + +UPDATE IGNORE character_spell SET spell = 3273 WHERE spell = 3279; +DELETE FROM character_spell WHERE spell = 3279; + +UPDATE IGNORE character_spell SET spell = 3274 WHERE spell = 3280; +DELETE FROM character_spell WHERE spell = 3280; + +UPDATE IGNORE character_spell SET spell = 3102 WHERE spell = 3412; +DELETE FROM character_spell WHERE spell = 3412; + +UPDATE IGNORE character_spell SET spell = 3464 WHERE spell = 3465; +DELETE FROM character_spell WHERE spell = 3465; + +UPDATE IGNORE character_spell SET spell = 3538 WHERE spell = 3539; +DELETE FROM character_spell WHERE spell = 3539; + +UPDATE IGNORE character_spell SET spell = 3564 WHERE spell = 3568; +DELETE FROM character_spell WHERE spell = 3568; + +UPDATE IGNORE character_spell SET spell = 3570 WHERE spell = 3571; +DELETE FROM character_spell WHERE spell = 3571; + +UPDATE IGNORE character_spell SET spell = 3811 WHERE spell = 3812; +DELETE FROM character_spell WHERE spell = 3812; + +UPDATE IGNORE character_spell SET spell = 3908 WHERE spell = 3911; +DELETE FROM character_spell WHERE spell = 3911; + +UPDATE IGNORE character_spell SET spell = 3909 WHERE spell = 3912; +DELETE FROM character_spell WHERE spell = 3912; + +UPDATE IGNORE character_spell SET spell = 3910 WHERE spell = 3913; +DELETE FROM character_spell WHERE spell = 3913; + +UPDATE IGNORE character_spell SET spell = 4036 WHERE spell = 4039; +DELETE FROM character_spell WHERE spell = 4039; + +UPDATE IGNORE character_spell SET spell = 4037 WHERE spell = 4040; +DELETE FROM character_spell WHERE spell = 4040; + +UPDATE IGNORE character_spell SET spell = 4038 WHERE spell = 4041; +DELETE FROM character_spell WHERE spell = 4041; + +UPDATE IGNORE character_spell SET spell = 7620 WHERE spell = 7733; +DELETE FROM character_spell WHERE spell = 7733; + +UPDATE IGNORE character_spell SET spell = 7731 WHERE spell = 7734; +DELETE FROM character_spell WHERE spell = 7734; + +UPDATE IGNORE character_spell SET spell = 8613 WHERE spell = 8615; +DELETE FROM character_spell WHERE spell = 8615; + +UPDATE IGNORE character_spell SET spell = 8617 WHERE spell = 8619; +DELETE FROM character_spell WHERE spell = 8619; + +UPDATE IGNORE character_spell SET spell = 8618 WHERE spell = 8620; +DELETE FROM character_spell WHERE spell = 8620; + +UPDATE IGNORE character_spell SET spell = 9785 WHERE spell = 9786; +DELETE FROM character_spell WHERE spell = 9786; + +UPDATE IGNORE character_spell SET spell = 10248 WHERE spell = 10249; +DELETE FROM character_spell WHERE spell = 10249; + +UPDATE IGNORE character_spell SET spell = 10662 WHERE spell = 10663; +DELETE FROM character_spell WHERE spell = 10663; + +UPDATE IGNORE character_spell SET spell = 10768 WHERE spell = 10769; +DELETE FROM character_spell WHERE spell = 10769; + +UPDATE IGNORE character_spell SET spell = 11611 WHERE spell = 11612; +DELETE FROM character_spell WHERE spell = 11612; + +UPDATE IGNORE character_spell SET spell = 11993 WHERE spell = 11994; +DELETE FROM character_spell WHERE spell = 11994; + +UPDATE IGNORE character_spell SET spell = 12180 WHERE spell = 12181; +DELETE FROM character_spell WHERE spell = 12181; + +UPDATE IGNORE character_spell SET spell = 12656 WHERE spell = 12657; +DELETE FROM character_spell WHERE spell = 12657; + +UPDATE IGNORE character_spell SET spell = 25229 WHERE spell = 25245; +DELETE FROM character_spell WHERE spell = 25245; + +UPDATE IGNORE character_spell SET spell = 25230 WHERE spell = 25246; +DELETE FROM character_spell WHERE spell = 25246; + +UPDATE IGNORE character_spell SET spell = 26790 WHERE spell = 26791; +DELETE FROM character_spell WHERE spell = 26791; + +UPDATE IGNORE character_spell SET spell = 28596 WHERE spell = 28597; +DELETE FROM character_spell WHERE spell = 28597; + +UPDATE IGNORE character_spell SET spell = 28695 WHERE spell = 28696; +DELETE FROM character_spell WHERE spell = 28696; + +UPDATE IGNORE character_spell SET spell = 28894 WHERE spell = 28896; +DELETE FROM character_spell WHERE spell = 28896; + +UPDATE IGNORE character_spell SET spell = 28895 WHERE spell = 28899; +DELETE FROM character_spell WHERE spell = 28899; + +UPDATE IGNORE character_spell SET spell = 28897 WHERE spell = 28901; +DELETE FROM character_spell WHERE spell = 28901; + +UPDATE IGNORE character_spell SET spell = 29354 WHERE spell = 29355; +DELETE FROM character_spell WHERE spell = 29355; + +UPDATE IGNORE character_spell SET spell = 29844 WHERE spell = 29845; +DELETE FROM character_spell WHERE spell = 29845; + +UPDATE IGNORE character_spell SET spell = 30350 WHERE spell = 30351; +DELETE FROM character_spell WHERE spell = 30351; + +UPDATE IGNORE character_spell SET spell = 32549 WHERE spell = 32550; +DELETE FROM character_spell WHERE spell = 32550; + +UPDATE IGNORE character_spell SET spell = 32678 WHERE spell = 32679; +DELETE FROM character_spell WHERE spell = 32679; + +UPDATE IGNORE character_spell SET spell = 45357 WHERE spell = 45375; +DELETE FROM character_spell WHERE spell = 45375; + +UPDATE IGNORE character_spell SET spell = 45358 WHERE spell = 45376; +DELETE FROM character_spell WHERE spell = 45376; + +UPDATE IGNORE character_spell SET spell = 45359 WHERE spell = 45377; +DELETE FROM character_spell WHERE spell = 45377; + +UPDATE IGNORE character_spell SET spell = 45360 WHERE spell = 45378; +DELETE FROM character_spell WHERE spell = 45378; + +UPDATE IGNORE character_spell SET spell = 45361 WHERE spell = 45379; +DELETE FROM character_spell WHERE spell = 45379; + +UPDATE IGNORE character_spell SET spell = 45363 WHERE spell = 45380; +DELETE FROM character_spell WHERE spell = 45380; + +UPDATE IGNORE character_spell SET spell = 45542 WHERE spell = 50299; +DELETE FROM character_spell WHERE spell = 50299; + +UPDATE IGNORE character_spell SET spell = 50305 WHERE spell = 50307; +DELETE FROM character_spell WHERE spell = 50307; + +UPDATE IGNORE character_spell SET spell = 50310 WHERE spell = 50309; +DELETE FROM character_spell WHERE spell = 50309; + +UPDATE IGNORE character_spell SET spell = 51294 WHERE spell = 51293; +DELETE FROM character_spell WHERE spell = 51293; + +UPDATE IGNORE character_spell SET spell = 51296 WHERE spell = 51295; +DELETE FROM character_spell WHERE spell = 51295; + +UPDATE IGNORE character_spell SET spell = 51300 WHERE spell = 51298; +DELETE FROM character_spell WHERE spell = 51298; + +UPDATE IGNORE character_spell SET spell = 51302 WHERE spell = 51301; +DELETE FROM character_spell WHERE spell = 51301; + +UPDATE IGNORE character_spell SET spell = 51304 WHERE spell = 51303; +DELETE FROM character_spell WHERE spell = 51303; + +UPDATE IGNORE character_spell SET spell = 51306 WHERE spell = 51305; +DELETE FROM character_spell WHERE spell = 51305; + +UPDATE IGNORE character_spell SET spell = 51309 WHERE spell = 51308; +DELETE FROM character_spell WHERE spell = 51308; + +UPDATE IGNORE character_spell SET spell = 51311 WHERE spell = 51310; +DELETE FROM character_spell WHERE spell = 51310; + +UPDATE IGNORE character_spell SET spell = 51313 WHERE spell = 51312; +DELETE FROM character_spell WHERE spell = 51312; + +UPDATE IGNORE character_spell SET spell = 33095 WHERE spell = 54084; +DELETE FROM character_spell WHERE spell = 54084; diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 33bc07947..1c9424256 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -135,6 +135,7 @@ pkgdata_DATA = \ 7074_01_mangos_playercreateinfo_spell.sql \ 7075_01_characters_character_spell.sql \ 7075_02_mangos_spell_learn_spell.sql \ + 7077_01_characters_character_spell.sql \ README ## Additional files to include when running 'make dist' @@ -250,4 +251,5 @@ EXTRA_DIST = \ 7074_01_mangos_playercreateinfo_spell.sql \ 7075_01_characters_character_spell.sql \ 7075_02_mangos_spell_learn_spell.sql \ + 7077_01_characters_character_spell.sql \ README diff --git a/src/game/Creature.h b/src/game/Creature.h index 8bb1f868d..3dec7c603 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -364,6 +364,10 @@ struct TrainerSpell uint32 reqskill; uint32 reqskillvalue; uint32 reqlevel; + uint32 learned_spell; + + // helpers + bool IsCastable() const { return learned_spell != spell; } }; typedef std::vector TrainerSpellList; diff --git a/src/game/NPCHandler.cpp b/src/game/NPCHandler.cpp index 498902ebe..5e3580088 100644 --- a/src/game/NPCHandler.cpp +++ b/src/game/NPCHandler.cpp @@ -164,16 +164,16 @@ void WorldSession::SendTrainerList( uint64 guid, const std::string& strTitle ) { TrainerSpell const* tSpell = *itr; - if(!_player->IsSpellFitByClassAndRace(tSpell->spell)) + if(!_player->IsSpellFitByClassAndRace(tSpell->learned_spell)) continue; ++count; - bool primary_prof_first_rank = spellmgr.IsPrimaryProfessionFirstRankSpell(tSpell->spell); + bool primary_prof_first_rank = spellmgr.IsPrimaryProfessionFirstRankSpell(tSpell->learned_spell); - SpellChainNode const* chain_node = spellmgr.GetSpellChainNode(tSpell->spell); + SpellChainNode const* chain_node = spellmgr.GetSpellChainNode(tSpell->learned_spell); - data << uint32(tSpell->spell); + data << uint32(tSpell->spell); // learned spell (or cast-spell in profession case) data << uint8(_player->GetTrainerSpellState(tSpell)); data << uint32(floor(tSpell->spellcost * fDiscountMod)); @@ -238,21 +238,27 @@ void WorldSession::HandleTrainerBuySpellOpcode( WorldPacket & recv_data ) if(_player->GetMoney() < nSpellCost ) return; - WorldPacket data(SMSG_PLAY_SPELL_VISUAL, 12); // visual effect on trainer - data << uint64(guid) << uint32(0xB3); - SendPacket(&data); - - data.Initialize(SMSG_PLAY_SPELL_IMPACT, 12); // visual effect on player - data << uint64(_player->GetGUID()) << uint32(0x016A); - SendPacket(&data); - _player->ModifyMoney( -int32(nSpellCost) ); - // learn explicitly to prevent lost money at lags, learning spell will be only show spell animation - _player->learnSpell(trainer_spell->spell); + // learn explicitly or cast explicitly + if(trainer_spell->IsCastable ()) + //FIXME: prof. spell entry in trainer list not marked gray until list re-open. + unit->CastSpell(_player,trainer_spell->spell,true); + else + { + WorldPacket data(SMSG_PLAY_SPELL_VISUAL, 12); // visual effect on trainer + data << uint64(guid) << uint32(0xB3); + SendPacket(&data); - data.Initialize(SMSG_TRAINER_BUY_SUCCEEDED, 12); - data << uint64(guid) << uint32(spellId); + data.Initialize(SMSG_PLAY_SPELL_IMPACT, 12); // visual effect on player + data << uint64(_player->GetGUID()) << uint32(0x016A); + SendPacket(&data); + + _player->learnSpell(spellId); + } + + WorldPacket data(SMSG_TRAINER_BUY_SUCCEEDED, 12); + data << uint64(guid) << uint32(trainer_spell->spell); SendPacket(&data); } diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 4566bf2a6..202abd374 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -7040,6 +7040,19 @@ void ObjectMgr::LoadTrainerSpell() if(!pTrainerSpell->reqlevel) pTrainerSpell->reqlevel = spellinfo->spellLevel; + // calculate learned spell for profession case when stored cast-spell + pTrainerSpell->learned_spell = spell; + for(int i = 0; i <3; ++i) + { + if(spellinfo->Effect[i]!=SPELL_EFFECT_LEARN_SPELL) + continue; + + if(SpellMgr::IsProfessionSpell(spellinfo->EffectTriggerSpell[i])) + { + pTrainerSpell->learned_spell = spellinfo->EffectTriggerSpell[i]; + break; + } + } TrainerSpellData& data = m_mCacheTrainerSpellMap[entry]; diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 5893d43ed..4c8398b9e 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -3451,22 +3451,22 @@ TrainerSpellState Player::GetTrainerSpellState(TrainerSpell const* trainer_spell if (!trainer_spell) return TRAINER_SPELL_RED; - if (!trainer_spell->spell) + if (!trainer_spell->learned_spell) return TRAINER_SPELL_RED; // known spell - if(HasSpell(trainer_spell->spell)) + if(HasSpell(trainer_spell->learned_spell)) return TRAINER_SPELL_GRAY; // check race/class requirement - if(!IsSpellFitByClassAndRace(trainer_spell->spell)) + if(!IsSpellFitByClassAndRace(trainer_spell->learned_spell)) return TRAINER_SPELL_RED; // check level requirement if(getLevel() < trainer_spell->reqlevel) return TRAINER_SPELL_RED; - if(SpellChainNode const* spell_chain = spellmgr.GetSpellChainNode(trainer_spell->spell)) + if(SpellChainNode const* spell_chain = spellmgr.GetSpellChainNode(trainer_spell->learned_spell)) { // check prev.rank requirement if(spell_chain->prev && !HasSpell(spell_chain->prev)) @@ -3482,7 +3482,7 @@ TrainerSpellState Player::GetTrainerSpellState(TrainerSpell const* trainer_spell return TRAINER_SPELL_RED; // exist, already checked at loading - SpellEntry const* spell = sSpellStore.LookupEntry(trainer_spell->spell); + SpellEntry const* spell = sSpellStore.LookupEntry(trainer_spell->learned_spell); // secondary prof. or not prof. spell uint32 skill = spell->EffectMiscValue[1]; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index f80374027..4a909f0aa 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7076" + #define REVISION_NR "7077" #endif // __REVISION_NR_H__ From 46a80e8eccd9f9b87e6a74f23f05a05615d3ede2 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Tue, 13 Jan 2009 21:59:11 +0300 Subject: [PATCH 02/84] Implement Paladin 31871 and ranks Signed-off-by: DiSlord --- src/game/Unit.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index fcc496a55..259b6cfd5 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -4719,6 +4719,30 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu target = this; break; } + // Divine purpose + case 31871: + case 31872: + { + // Roll chane + if (!roll_chance_i(triggeredByAura->GetModifier()->m_amount)) + return false; + + // Remove any stun effect on target + AuraMap& Auras = pVictim->GetAuras(); + for(AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end();) + { + SpellEntry const *spell = sSpellStore.LookupEntry(iter->second->GetSpellProto()->Id); + if( spell->Mechanic == MECHANIC_STUN || + spell->EffectMechanic[iter->second->GetEffIndex()] == MECHANIC_STUN) + { + pVictim->RemoveAurasDueToSpell(spell->Id); + iter = Auras.begin(); + } + else + ++iter; + } + return true; + } } break; } From 08864a72885863ef1789802293d7504b0fca33fd Mon Sep 17 00:00:00 2001 From: DiSlord Date: Tue, 13 Jan 2009 22:04:55 +0300 Subject: [PATCH 03/84] [7078] Restore work rogue 14185 after client switch Add data to proc table Signed-off-by: DiSlord --- sql/mangos.sql | 7 ++- .../7078_01_mangos_spell_proc_event.sql | 23 +++++++ sql/updates/Makefile.am | 2 + src/game/SpellEffects.cpp | 60 +++++++++---------- src/shared/revision_nr.h | 2 +- 5 files changed, 62 insertions(+), 32 deletions(-) create mode 100644 sql/updates/7078_01_mangos_spell_proc_event.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index 1854d1492..4d75aad4d 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -22,7 +22,7 @@ DROP TABLE IF EXISTS `db_version`; CREATE TABLE `db_version` ( `version` varchar(120) default NULL, - `required_7075_02_mangos_spell_learn_spell` bit(1) default NULL + `required_7078_01_mangos_spell_proc_event` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -16548,6 +16548,8 @@ INSERT INTO `spell_proc_event` VALUES (31833, 0x00000000, 10, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (31835, 0x00000000, 10, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (31836, 0x00000000, 10, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(31871, 0x00000000, 10, 0x00000010, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), +(31872, 0x00000000, 10, 0x00000010, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0), (31876, 0x00000000, 10, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (31877, 0x00000000, 10, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (31878, 0x00000000, 10, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), @@ -16722,6 +16724,9 @@ INSERT INTO `spell_proc_event` VALUES (43748, 0x00000000, 11, 0x90100000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (43750, 0x00000000, 11, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (43819, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(44394, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0.000000, 0.000000, 0), +(44395, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0.000000, 0.000000, 0), +(44396, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0.000000, 0.000000, 0), (44404, 0x00000000, 3, 0x20000021, 0x00009000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (44445, 0x00000000, 3, 0x00000013, 0x00001000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (44446, 0x00000000, 3, 0x00000013, 0x00001000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), diff --git a/sql/updates/7078_01_mangos_spell_proc_event.sql b/sql/updates/7078_01_mangos_spell_proc_event.sql new file mode 100644 index 000000000..b5df2f7fa --- /dev/null +++ b/sql/updates/7078_01_mangos_spell_proc_event.sql @@ -0,0 +1,23 @@ +ALTER TABLE db_version CHANGE COLUMN required_7075_02_mangos_spell_learn_spell required_7078_01_mangos_spell_proc_event bit; + +-- (31871) Divine Purpose (Rank 1) +DELETE FROM `spell_proc_event` WHERE `entry` IN (31871); +INSERT INTO `spell_proc_event` VALUES (31871, 0x00, 10, 0x00000010, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0); + +-- (31872) Divine Purpose (Rank 2) +DELETE FROM `spell_proc_event` WHERE `entry` IN (31872); +INSERT INTO `spell_proc_event` VALUES (31872, 0x00, 10, 0x00000010, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0); + +-- (44394) Incanter's Absorption (Rank 1) +DELETE FROM `spell_proc_event` WHERE `entry` IN (44394); +INSERT INTO `spell_proc_event` VALUES (44394, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0.000000, 0.000000, 0); + +-- (44395) Incanter's Absorption (Rank 2) +DELETE FROM `spell_proc_event` WHERE `entry` IN (44395); +INSERT INTO `spell_proc_event` VALUES (44395, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0.000000, 0.000000, 0); + +-- (44396) Incanter's Absorption (Rank 3) +DELETE FROM `spell_proc_event` WHERE `entry` IN (44396); +INSERT INTO `spell_proc_event` VALUES (44396, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0.000000, 0.000000, 0); + + \ No newline at end of file diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 1c9424256..84f20c9a6 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -136,6 +136,7 @@ pkgdata_DATA = \ 7075_01_characters_character_spell.sql \ 7075_02_mangos_spell_learn_spell.sql \ 7077_01_characters_character_spell.sql \ + 7078_01_mangos_spell_proc_event.sql \ README ## Additional files to include when running 'make dist' @@ -252,4 +253,5 @@ EXTRA_DIST = \ 7075_01_characters_character_spell.sql \ 7075_02_mangos_spell_learn_spell.sql \ 7077_01_characters_character_spell.sql \ + 7078_01_mangos_spell_proc_event.sql \ README diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 5dfdbb9d3..52a274878 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -763,30 +763,6 @@ void Spell::EffectDummy(uint32 i) } return; } - case 14185: // Preparation Rogue - { - if(m_caster->GetTypeId()!=TYPEID_PLAYER) - 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) - { - uint32 classspell = itr->first; - SpellEntry const *spellInfo = sSpellStore.LookupEntry(classspell); - - if (spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && (spellInfo->SpellFamilyFlags & 0x26000000860LL)) - { - ((Player*)m_caster)->RemoveSpellCooldown(classspell); - - WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8)); - data << uint32(classspell); - data << uint64(m_caster->GetGUID()); - ((Player*)m_caster)->GetSession()->SendPacket(&data); - } - } - return; - } case 15998: // Capture Worg Pup case 29435: // Capture Female Kaliri Hatchling { @@ -881,7 +857,7 @@ void Spell::EffectDummy(uint32 i) return; } - case 23074: // Arc. Dragonling + case 23074: // Arcanite Dragonling if (!m_CastItem) return; m_caster->CastSpell(m_caster,19804,true,m_CastItem); return; @@ -1425,11 +1401,6 @@ void Spell::EffectDummy(uint32 i) case SPELLFAMILY_ROGUE: switch(m_spellInfo->Id ) { - case 31231: // Cheat Death - { - m_caster->CastSpell(m_caster,45182,true); - return; - } case 5938: // Shiv { if(m_caster->GetTypeId() != TYPEID_PLAYER) @@ -1465,6 +1436,35 @@ void Spell::EffectDummy(uint32 i) m_caster->CastSpell(unitTarget, 5940, true); return; } + case 14185: // Preparation Rogue + { + if(m_caster->GetTypeId()!=TYPEID_PLAYER) + 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) + { + uint32 classspell = itr->first; + SpellEntry const *spellInfo = sSpellStore.LookupEntry(classspell); + + if (spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && (spellInfo->SpellFamilyFlags & 0x0000024000000860LL)) + { + ((Player*)m_caster)->RemoveSpellCooldown(classspell); + + WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8)); + data << uint32(classspell); + data << uint64(m_caster->GetGUID()); + ((Player*)m_caster)->GetSession()->SendPacket(&data); + } + } + return; + } + case 31231: // Cheat Death + { + m_caster->CastSpell(m_caster,45182,true); + return; + } } break; case SPELLFAMILY_HUNTER: diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 4a909f0aa..4dede7594 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7077" + #define REVISION_NR "7078" #endif // __REVISION_NR_H__ From e8d32763a697eb57967306b9e791350a2849466e Mon Sep 17 00:00:00 2001 From: ApoC Date: Tue, 13 Jan 2009 21:31:42 +0100 Subject: [PATCH 04/84] [7079] Redundant sSpellStore looking removed. Removed not used variable in for cycle. Signed-off-by: ApoC --- src/game/Unit.cpp | 4 ++-- src/shared/revision_nr.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 259b6cfd5..d12a7afea 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -4729,9 +4729,9 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu // Remove any stun effect on target AuraMap& Auras = pVictim->GetAuras(); - for(AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end();) + for(AuraMap::iterator iter = Auras.begin(); iter != Auras.end();) { - SpellEntry const *spell = sSpellStore.LookupEntry(iter->second->GetSpellProto()->Id); + SpellEntry const *spell = iter->second->GetSpellProto(); if( spell->Mechanic == MECHANIC_STUN || spell->EffectMechanic[iter->second->GetEffIndex()] == MECHANIC_STUN) { diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 4dede7594..31ea70372 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7078" + #define REVISION_NR "7079" #endif // __REVISION_NR_H__ From d53b43024a4121819e32872cad98af3ee0c52dc0 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Wed, 14 Jan 2009 00:29:06 +0300 Subject: [PATCH 05/84] [7080] More `item_template` data checks at loading. Not all checks can be 100% correct result possible. Plerase, report proved wrong output and this checks part will disabled. --- src/game/ObjectMgr.cpp | 18 ++++++++++++++++++ src/shared/Database/DBCStructure.h | 8 ++++---- src/shared/Database/DBCfmt.cpp | 2 +- src/shared/revision_nr.h | 2 +- 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 202abd374..55f9dc6df 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -1598,6 +1598,24 @@ void ObjectMgr::LoadItemPrototypes() if(dbcitem) { + if(proto->Class != dbcitem->Class || proto->SubClass != dbcitem->SubClass) + { + sLog.outErrorDb("Item (Entry: %u) not correct (Class: %u, Sub: %u) pair, must be (Class: %u, Sub: %u) (still using DB value).",i,proto->Class,proto->SubClass,dbcitem->Class,dbcitem->SubClass); + // It safe let use InventoryType from DB + } + + if(proto->Unk0 != dbcitem->Unk0) + { + sLog.outErrorDb("Item (Entry: %u) not correct %u Unk0, must be %u (still using DB value).",i,proto->Unk0,dbcitem->Unk0); + // It safe let use InventoryType from DB + } + + if(proto->Material != dbcitem->Material) + { + sLog.outErrorDb("Item (Entry: %u) not correct %u material, must be %u (still using DB value).",i,proto->Material,dbcitem->Material); + // It safe let use InventoryType from DB + } + if(proto->InventoryType != dbcitem->InventoryType) { sLog.outErrorDb("Item (Entry: %u) not correct %u inventory type, must be %u (still using DB value).",i,proto->InventoryType,dbcitem->InventoryType); diff --git a/src/shared/Database/DBCStructure.h b/src/shared/Database/DBCStructure.h index 5a2a96761..bbd7fc475 100644 --- a/src/shared/Database/DBCStructure.h +++ b/src/shared/Database/DBCStructure.h @@ -809,10 +809,10 @@ struct GtRegenMPPerSptEntry struct ItemEntry { uint32 ID; - //uint32 Class; - //uint32 SubClass; - //uint32 Unk0; - //uint32 Material; + uint32 Class; + uint32 SubClass; + uint32 Unk0; + uint32 Material; uint32 DisplayId; uint32 InventoryType; uint32 Sheath; diff --git a/src/shared/Database/DBCfmt.cpp b/src/shared/Database/DBCfmt.cpp index b5a1843bc..fdadc8173 100644 --- a/src/shared/Database/DBCfmt.cpp +++ b/src/shared/Database/DBCfmt.cpp @@ -51,7 +51,7 @@ const char GtOCTRegenHPfmt[]="f"; //const char GtOCTRegenMPfmt[]="f"; const char GtRegenHPPerSptfmt[]="f"; const char GtRegenMPPerSptfmt[]="f"; -const char Itemfmt[]="nxxxxiii"; +const char Itemfmt[]="niiiiiii"; //const char ItemDisplayTemplateEntryfmt[]="nxxxxxxxxxxixxxxxxxxxxx"; //const char ItemCondExtCostsEntryfmt[]="xiii"; const char ItemExtendedCostEntryfmt[]="niiiiiiiiiiiiix"; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 31ea70372..b921fbd5c 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7079" + #define REVISION_NR "7080" #endif // __REVISION_NR_H__ From d3615532b508a99208ff8db7952f9c9f3844a4db Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Wed, 14 Jan 2009 00:32:14 +0300 Subject: [PATCH 06/84] [7081] Fix comments in recent added code. --- src/game/ObjectMgr.cpp | 6 +++--- src/shared/revision_nr.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 55f9dc6df..04b818410 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -1601,19 +1601,19 @@ void ObjectMgr::LoadItemPrototypes() if(proto->Class != dbcitem->Class || proto->SubClass != dbcitem->SubClass) { sLog.outErrorDb("Item (Entry: %u) not correct (Class: %u, Sub: %u) pair, must be (Class: %u, Sub: %u) (still using DB value).",i,proto->Class,proto->SubClass,dbcitem->Class,dbcitem->SubClass); - // It safe let use InventoryType from DB + // It safe let use Class/Subclass from DB } if(proto->Unk0 != dbcitem->Unk0) { sLog.outErrorDb("Item (Entry: %u) not correct %u Unk0, must be %u (still using DB value).",i,proto->Unk0,dbcitem->Unk0); - // It safe let use InventoryType from DB + // It safe let use Unk0 from DB } if(proto->Material != dbcitem->Material) { sLog.outErrorDb("Item (Entry: %u) not correct %u material, must be %u (still using DB value).",i,proto->Material,dbcitem->Material); - // It safe let use InventoryType from DB + // It safe let use Material from DB } if(proto->InventoryType != dbcitem->InventoryType) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index b921fbd5c..87ab52f0b 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7080" + #define REVISION_NR "7081" #endif // __REVISION_NR_H__ From 246d45dc80f2d6734946db8a679c4ec6024d58f1 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Tue, 13 Jan 2009 22:46:23 +0300 Subject: [PATCH 07/84] Add AP bonus for warrior 5308 and ranks, also use 58367 dummy bonus Signed-off-by: DiSlord --- src/game/SpellEffects.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 52a274878..d26c67d9b 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -1265,7 +1265,13 @@ void Spell::EffectDummy(uint32 i) if(!unitTarget) return; - int32 basePoints0 = damage+int32(m_caster->GetPower(POWER_RAGE) * m_spellInfo->DmgMultiplier[i]); + uint32 rage = m_caster->GetPower(POWER_RAGE); + // Glyph of Execution bonus + if (Aura *aura = m_caster->GetDummyAura(58367)) + rage+=aura->GetModifier()->m_amount; + + int32 basePoints0 = damage+int32(rage * m_spellInfo->DmgMultiplier[i] + + m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2f); m_caster->CastCustomSpell(unitTarget, 20647, &basePoints0, NULL, NULL, true, 0); m_caster->SetPower(POWER_RAGE,0); return; From c97f8a675c9d6c4c6db10058137e0db5f2fab6dc Mon Sep 17 00:00:00 2001 From: DiSlord Date: Wed, 14 Jan 2009 01:01:33 +0300 Subject: [PATCH 08/84] Now 35395 not refresh seals Signed-off-by: DiSlord --- src/game/Unit.cpp | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index d12a7afea..b8af5a136 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -1123,17 +1123,6 @@ void Unit::DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss) return; } - // update at damage Judgement aura duration that applied by attacker at victim - if(damageInfo->damage && spellProto->Id == 35395) - { - AuraMap& vAuras = pVictim->GetAuras(); - for(AuraMap::iterator itr = vAuras.begin(); itr != vAuras.end(); ++itr) - { - SpellEntry const *spellInfo = (*itr).second->GetSpellProto(); - if( spellInfo->AttributesEx3 & 0x40000 && spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && ((*itr).second->GetCasterGUID() == GetGUID())) - (*itr).second->RefreshAura(); - } - } // Call default DealDamage CleanDamage cleanDamage(damageInfo->cleanDamage, BASE_ATTACK, MELEE_HIT_NORMAL); DealDamage(pVictim, damageInfo->damage, &cleanDamage, SPELL_DIRECT_DAMAGE, SpellSchoolMask(damageInfo->schoolMask), spellProto, durabilityLoss); From 5378d766f0224e26fd714b5acdce78358753d6d4 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Wed, 14 Jan 2009 01:54:06 +0300 Subject: [PATCH 09/84] Fix typo (now power gain % log correctly) Signed-off-by: DiSlord --- src/game/SpellEffects.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index d26c67d9b..1f8df1ba2 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -2821,7 +2821,7 @@ void Spell::EffectEnergisePct(uint32 i) uint32 gain = damage * maxPower / 100; unitTarget->ModifyPower(power, gain); - m_caster->SendEnergizeSpellLog(unitTarget, m_spellInfo->Id, damage, power); + m_caster->SendEnergizeSpellLog(unitTarget, m_spellInfo->Id, gain, power); } void Spell::SendLoot(uint64 guid, LootType loottype) From d544aec1db5e33764455c3e4a8618d81094b710b Mon Sep 17 00:00:00 2001 From: DiSlord Date: Wed, 14 Jan 2009 01:56:28 +0300 Subject: [PATCH 10/84] Implement 53720, 20185, 20186 dummy proc Fix 31892 (use correct %) Signed-off-by: DiSlord --- src/game/Unit.cpp | 75 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 55 insertions(+), 20 deletions(-) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index b8af5a136..3c350fe05 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -5232,29 +5232,30 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu basepoints0 = GetAttackTime(BASE_ATTACK) * int32(ap*0.022f + 0.044f * holy) / 1000; break; } - // Seal of Blood do damage trigger - if(dummySpell->SpellFamilyFlags & 0x0000040000000000LL) - { - switch(triggeredByAura->GetEffIndex()) - { - case 0: - triggered_spell_id = 31893; - break; - case 1: - { - // damage - damage += CalculateDamage(BASE_ATTACK, false) * 35 / 100; // add spell damage from prev effect (35%) - basepoints0 = triggeredByAura->GetModifier()->m_amount * damage / 100; - - target = this; - triggered_spell_id = 32221; - break; - } - } - } switch(dummySpell->Id) { + // Judgement of Light + case 20185: + { + // Get judgement caster + Unit *caster = triggeredByAura->GetCaster(); + if (!caster) + return false; + float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK); + int32 holy = caster->SpellBaseDamageBonus(SPELL_SCHOOL_MASK_HOLY) + + caster->SpellBaseDamageBonusForVictim(SPELL_SCHOOL_MASK_HOLY, this); + basepoints0 = int32(ap*0.10f + 0.10f*holy); + pVictim->CastCustomSpell(pVictim, 20267, &basepoints0, 0, 0, true, 0, triggeredByAura); + return true; + } + // Judgement of Wisdom + case 20186: + { + if (pVictim->getPowerType() == POWER_MANA) + pVictim->CastSpell(pVictim, 20268, true, 0, triggeredByAura); + return true; + } // Holy Power (Redemption Armor set) case 28789: { @@ -5309,6 +5310,40 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu triggered_spell_id = 31786; break; } + // Seal of Blood do damage trigger + case 31892: + { + if (triggeredByAura->GetEffIndex() == 0) // 0 effect - is proc on enemy + triggered_spell_id = 31893; + else if (triggeredByAura->GetEffIndex() == 1) // 1 effect - is proc on self + { + // add spell damage from prev effect (27%) + damage += CalculateDamage(BASE_ATTACK, false) * 27 / 100; + basepoints0 = triggeredByAura->GetModifier()->m_amount * damage / 100; + target = this; + triggered_spell_id = 32221; + } + else + return true; + break; + } + // Seal of the Martyr do damage trigger + case 53720: + { + if (triggeredByAura->GetEffIndex() == 0) // 0 effect - is proc on enemy + triggered_spell_id = 53719; + else if (triggeredByAura->GetEffIndex() == 1) // 1 effect - is proc on self + { + // add spell damage from prev effect (27%) + damage += CalculateDamage(BASE_ATTACK, false) * 27 / 100; + basepoints0 = triggeredByAura->GetModifier()->m_amount * damage / 100; + target = this; + triggered_spell_id = 53718; + } + else + return true; + break; + } // Paladin Tier 6 Trinket (Ashtongue Talisman of Zeal) case 40470: { From 7b6b0bb8169508b439aa8dfaaf15ddb665678763 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Wed, 14 Jan 2009 01:57:42 +0300 Subject: [PATCH 11/84] [7082] Implement paladin 53407, 20271, 53408 Remove dead code Signed-off-by: DiSlord --- src/game/SpellEffects.cpp | 87 +++++++++++++++++---------------------- src/shared/revision_nr.h | 2 +- 2 files changed, 38 insertions(+), 51 deletions(-) diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 1f8df1ba2..4aa98b7a3 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -4990,59 +4990,46 @@ void Spell::EffectScriptEffect(uint32 effIndex) } else if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN ) { - switch(m_spellInfo->SpellFamilyFlags) + // Judgement + if (m_spellInfo->SpellFamilyFlags & 0x0000000000800000LL) { - // Judgement - case 0x800000: - { - if(!unitTarget || !unitTarget->isAlive()) - return; - uint32 spellId2 = 0; - - // all seals have aura dummy - Unit::AuraList const& m_dummyAuras = m_caster->GetAurasByType(SPELL_AURA_DUMMY); - for(Unit::AuraList::const_iterator itr = m_dummyAuras.begin(); itr != m_dummyAuras.end(); ++itr) - { - SpellEntry const *spellInfo = (*itr)->GetSpellProto(); - - // search seal (all seals have judgement's aura dummy spell id in 2 effect - if ( !spellInfo || !IsSealSpell((*itr)->GetSpellProto()) || (*itr)->GetEffIndex() != 2 ) - continue; - - // must be calculated base at raw base points in spell proto, GetModifier()->m_value for S.Righteousness modified by SPELLMOD_DAMAGE - spellId2 = (*itr)->GetSpellProto()->EffectBasePoints[2]+1; - - if(spellId2 <= 1) - continue; - - // found, remove seal - m_caster->RemoveAurasDueToSpell((*itr)->GetId()); - - // Sanctified Judgement - Unit::AuraList const& m_auras = m_caster->GetAurasByType(SPELL_AURA_DUMMY); - for(Unit::AuraList::const_iterator i = m_auras.begin(); i != m_auras.end(); ++i) - { - if ((*i)->GetSpellProto()->SpellIconID == 205 && (*i)->GetSpellProto()->Attributes == 0x01D0LL) - { - int32 chance = (*i)->GetModifier()->m_amount; - if ( roll_chance_i(chance) ) - { - int32 mana = spellInfo->manaCost; - if ( Player* modOwner = m_caster->GetSpellModOwner() ) - modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_COST, mana); - mana = int32(mana* 0.8f); - m_caster->CastCustomSpell(m_caster,31930,&mana,NULL,NULL,true,NULL,*i); - } - break; - } - } - - break; - } - - m_caster->CastSpell(unitTarget,spellId2,true); + if(!unitTarget || !unitTarget->isAlive()) return; + uint32 spellId1 = 0; + uint32 spellId2 = 0; + + // Judgement self add switch + switch (m_spellInfo->Id) + { + case 41467: break; // Judgement + case 53407: spellId1 = 20184; break; // Judgement of Justice + case 20271: // Judgement of Light + case 57774: spellId1 = 20185; break; // Judgement of Light + case 53408: spellId1 = 20186; break; // Judgement of Wisdom + default: + return; } + // all seals have aura dummy in 2 effect + Unit::AuraList const& m_dummyAuras = m_caster->GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator itr = m_dummyAuras.begin(); itr != m_dummyAuras.end(); ++itr) + { + SpellEntry const *spellInfo = (*itr)->GetSpellProto(); + // search seal (all seals have judgement's aura dummy spell id in 2 effect + if ((*itr)->GetEffIndex() != 2 || !spellInfo || !IsSealSpell(spellInfo)) + continue; + spellId2 = (*itr)->GetModifier()->m_amount; + SpellEntry const *judge = sSpellStore.LookupEntry(spellId2); + if (!judge) + continue; + // found, remove seal + m_caster->RemoveAurasDueToSpell(spellInfo->Id); + break; + } + if (spellId1) + m_caster->CastSpell(unitTarget, spellId1, true); + if (spellId2) + m_caster->CastSpell(unitTarget, spellId2, true); + return; } } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 87ab52f0b..b3b1c9d41 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7081" + #define REVISION_NR "7082" #endif // __REVISION_NR_H__ From 950df723d7897edc8f87a5c5de08fc125df6d263 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Wed, 14 Jan 2009 02:32:24 +0300 Subject: [PATCH 12/84] [7083] Implement support for cast-spells in trainer lists for riding also. --- src/game/ObjectMgr.cpp | 2 +- src/game/Player.cpp | 13 +++++++++---- src/game/SpellMgr.cpp | 16 +++++++++++++++- src/game/SpellMgr.h | 6 ++++++ src/shared/revision_nr.h | 2 +- 5 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 04b818410..521c0d387 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -7065,7 +7065,7 @@ void ObjectMgr::LoadTrainerSpell() if(spellinfo->Effect[i]!=SPELL_EFFECT_LEARN_SPELL) continue; - if(SpellMgr::IsProfessionSpell(spellinfo->EffectTriggerSpell[i])) + if(SpellMgr::IsProfessionOrRidingSpell(spellinfo->EffectTriggerSpell[i])) { pTrainerSpell->learned_spell = spellinfo->EffectTriggerSpell[i]; break; diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 4c8398b9e..4948f713f 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -4929,7 +4929,7 @@ void Player::UpdateSkillsToMaxSkillsForLevel() if (GetUInt32Value(PLAYER_SKILL_INDEX(i))) { uint32 pskill = GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF; - if( IsProfessionSkill(pskill) || pskill == SKILL_RIDING ) + if( IsProfessionOrRidingSkill(pskill)) continue; uint32 data = GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i)); @@ -18206,18 +18206,23 @@ bool Player::IsSpellFitByClassAndRace( uint32 spell_id ) const SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(spell_id); SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(spell_id); + if(lower==upper) + return true; for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx) { // skip wrong race skills if( _spell_idx->second->racemask && (_spell_idx->second->racemask & racemask) == 0) - return false; + continue; // skip wrong class skills if( _spell_idx->second->classmask && (_spell_idx->second->classmask & classmask) == 0) - return false; + continue; + + return true; } - return true; + + return false; } bool Player::HasQuestForGO(int32 GOId) diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 0a136f4fd..1f511afd7 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -1018,7 +1018,7 @@ bool SpellMgr::canStackSpellRanks(SpellEntry const *spellInfo) { if(spellInfo->powerType != POWER_MANA && spellInfo->powerType != POWER_HEALTH) return false; - if(IsProfessionSpell(spellInfo->Id)) + if(IsProfessionOrRidingSpell(spellInfo->Id)) return false; // All stance spells. if any better way, change it. @@ -1399,6 +1399,20 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons return true; } +bool SpellMgr::IsProfessionOrRidingSpell(uint32 spellId) +{ + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); + if(!spellInfo) + return false; + + if(spellInfo->Effect[1] != SPELL_EFFECT_SKILL) + return false; + + uint32 skill = spellInfo->EffectMiscValue[1]; + + return IsProfessionOrRidingSkill(skill); +} + bool SpellMgr::IsProfessionSpell(uint32 spellId) { SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index 8189cd7cb..8354bdf40 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -721,6 +721,11 @@ inline bool IsProfessionSkill(uint32 skill) return IsPrimaryProfessionSkill(skill) || skill == SKILL_FISHING || skill == SKILL_COOKING || skill == SKILL_FIRST_AID; } +inline bool IsProfessionOrRidingSkill(uint32 skill) +{ + return IsProfessionSkill(skill) || skill == SKILL_RIDING; +} + class SpellMgr { // Constructors @@ -882,6 +887,7 @@ class SpellMgr return false; } + static bool IsProfessionOrRidingSpell(uint32 spellId); static bool IsProfessionSpell(uint32 spellId); static bool IsPrimaryProfessionSpell(uint32 spellId); bool IsPrimaryProfessionFirstRankSpell(uint32 spellId) const; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index b3b1c9d41..fc1f9a18e 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7082" + #define REVISION_NR "7083" #endif // __REVISION_NR_H__ From f876d66d74915969133b6eeeabd9b5cfc82eb555 Mon Sep 17 00:00:00 2001 From: NoFantasy Date: Wed, 14 Jan 2009 12:57:57 +0300 Subject: [PATCH 13/84] [7084] Fix 2.4.3->3.0.3 item conversion for gem sockets problems. This is avoid problem only for not converted items at conversion. Fix can't be applied to already converted DB. Near to impossible sort items in already converted DB to converted (and required fix) and newly created (and corrupted by fix). Signed-off-by: VladimirMangos --- sql/updates/2008_12_22_19_characters_item_instance.sql | 4 ++-- src/shared/revision_nr.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sql/updates/2008_12_22_19_characters_item_instance.sql b/sql/updates/2008_12_22_19_characters_item_instance.sql index 96f31ff47..e737e24da 100644 --- a/sql/updates/2008_12_22_19_characters_item_instance.sql +++ b/sql/updates/2008_12_22_19_characters_item_instance.sql @@ -4,8 +4,8 @@ UPDATE item_instance SET data = REPLACE(data,' ',' '); UPDATE item_instance SET data = CONCAT(TRIM(data),' '); UPDATE item_instance SET data= CONCAT( - SUBSTRING_INDEX(SUBSTRING_INDEX(data,' ',30),' ',-30),' 0 0 0 ', - SUBSTRING_INDEX(SUBSTRING_INDEX(data,' ',60),' ',-60+30),' 0 ') + SUBSTRING_INDEX(SUBSTRING_INDEX(data,' ',54),' ',-54),' 0 0 0 ', + SUBSTRING_INDEX(SUBSTRING_INDEX(data,' ',60),' ',-60+54),' 0 ') WHERE SUBSTRING_INDEX(data,' ',60) = data AND SUBSTRING_INDEX(data,' ',60-1) <> data; UPDATE item_instance SET data= CONCAT( diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index fc1f9a18e..875aa6b15 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7083" + #define REVISION_NR "7084" #endif // __REVISION_NR_H__ From b64ce9ea345584bb8ddf18cacc3f0e35b8ba30b5 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Wed, 14 Jan 2009 20:52:18 +0300 Subject: [PATCH 14/84] Fix pladin some abiblty - patch by Kirix Signed-off-by: DiSlord --- src/game/SpellEffects.cpp | 2 -- src/game/Unit.cpp | 12 ------------ 2 files changed, 14 deletions(-) diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 4aa98b7a3..505531750 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -5021,8 +5021,6 @@ void Spell::EffectScriptEffect(uint32 effIndex) SpellEntry const *judge = sSpellStore.LookupEntry(spellId2); if (!judge) continue; - // found, remove seal - m_caster->RemoveAurasDueToSpell(spellInfo->Id); break; } if (spellId1) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 3c350fe05..c46050999 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -1468,18 +1468,6 @@ void Unit::DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss) CastSpell(pVictim, 1604, true); } - // update at damage Judgement aura duration that applied by attacker at victim - if(damageInfo->damage) - { - AuraMap& vAuras = pVictim->GetAuras(); - for(AuraMap::iterator itr = vAuras.begin(); itr != vAuras.end(); ++itr) - { - SpellEntry const *spellInfo = (*itr).second->GetSpellProto(); - if( spellInfo->AttributesEx3 & 0x40000 && spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && ((*itr).second->GetCasterGUID() == GetGUID())) - (*itr).second->RefreshAura(); - } - } - // If not miss if (!(damageInfo->HitInfo & HITINFO_MISS)) { From c38db592ba1f3d4cb8329d14c3441cc950da32d4 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Wed, 14 Jan 2009 20:43:44 +0300 Subject: [PATCH 15/84] Fix Night Elf race ability on stealth path by Kirix Signed-off-by: DiSlord --- src/game/SpellAuras.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 79358118c..959dc5503 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -3434,8 +3434,8 @@ void Aura::HandleModStealth(bool apply, bool Real) m_target->SetVisibility(VISIBILITY_GROUP_STEALTH); } - // for RACE_NIGHTELF stealth - if(m_target->GetTypeId()==TYPEID_PLAYER && GetId()==20580) + // (RACE_NIGHTELF stealth apply also Elusiveness) + if(m_target->getRace() == RACE_NIGHTELF) m_target->CastSpell(m_target, 21009, true, NULL, this); } } @@ -3444,8 +3444,8 @@ void Aura::HandleModStealth(bool apply, bool Real) // only at real aura remove if(Real) { - // for RACE_NIGHTELF stealth - if(m_target->GetTypeId()==TYPEID_PLAYER && GetId()==20580) + // (RACE_NIGHTELF stealth remove Elusiveness) + if(m_target->getRace() == RACE_NIGHTELF) m_target->RemoveAurasDueToSpell(21009); // if last SPELL_AURA_MOD_STEALTH and no GM invisibility From 09659a0377caa2f6783a58d2a8f3048b2ac2c883 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Wed, 14 Jan 2009 20:42:44 +0300 Subject: [PATCH 16/84] Implement paladin 53601 dummy proc Signed-off-by: DiSlord --- src/game/Unit.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index c46050999..726e7d776 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -5220,7 +5220,13 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu basepoints0 = GetAttackTime(BASE_ATTACK) * int32(ap*0.022f + 0.044f * holy) / 1000; break; } - + // Sacred Shield + if (dummySpell->SpellFamilyFlags&0x0008000000000000LL) + { + triggered_spell_id = 58597; + target = this; + break; + } switch(dummySpell->Id) { // Judgement of Light @@ -7608,7 +7614,7 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM } // Glyph of Shadowburn if (spellProto->SpellFamilyName == SPELLFAMILY_WARLOCK && - spellProto->SpellFamilyFlags & 0x0000000000000080 && + spellProto->SpellFamilyFlags & 0x0000000000000080LL && pVictim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT)) { AuraList const& mOverrideClassScript = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); @@ -7616,6 +7622,14 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM if((*i)->GetModifier()->m_miscvalue == 7917) crit_chance+=(*i)->GetModifier()->m_amount; } + // Sacred Shield + if (spellProto->SpellFamilyName == SPELLFAMILY_PALADIN && + spellProto->SpellFamilyFlags & 0x0000000040000000LL) + { + Aura *aura = pVictim->GetDummyAura(58597); + if (aura && aura->GetCasterGUID() == GetGUID()) + crit_chance+=aura->GetModifier()->m_amount; + } } break; } From 31722c1c0cc6fd9fbdef57dee66bd5f47c76b137 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Wed, 14 Jan 2009 21:49:11 +0300 Subject: [PATCH 17/84] [7085] Restore work 12975 after client switch, patch by MaS0n Signed-off-by: DiSlord --- src/game/SpellEffects.cpp | 26 +++++++++++++++----------- src/shared/revision_nr.h | 2 +- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 505531750..fc5c8c809 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -721,12 +721,6 @@ void Spell::EffectDummy(uint32 i) m_caster->CastCustomSpell(unitTarget, 12721, &deepWoundsDotBasePoints0, NULL, NULL, true, NULL); return; } - case 12975: //Last Stand - { - int32 healthModSpellBasePoints0 = int32(m_caster->GetMaxHealth()*0.3); - m_caster->CastCustomSpell(m_caster, 12976, &healthModSpellBasePoints0, NULL, NULL, true, NULL); - return; - } case 13120: // net-o-matic { if(!unitTarget) @@ -1276,13 +1270,23 @@ void Spell::EffectDummy(uint32 i) m_caster->SetPower(POWER_RAGE,0); return; } - if(m_spellInfo->Id==21977) //Warrior's Wrath + switch(m_spellInfo->Id) { - if(!unitTarget) + // Warrior's Wrath + case 21977: + { + if(!unitTarget) + return; + m_caster->CastSpell(unitTarget,21887,true); // spell mod return; - - m_caster->CastSpell(unitTarget,21887,true); // spell mod - return; + } + // Last Stand + case 12975: + { + int32 healthModSpellBasePoints0 = int32(m_caster->GetMaxHealth()*0.3); + m_caster->CastCustomSpell(m_caster, 12976, &healthModSpellBasePoints0, NULL, NULL, true, NULL); + return; + } } break; case SPELLFAMILY_WARLOCK: diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 875aa6b15..c1233bb64 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7084" + #define REVISION_NR "7085" #endif // __REVISION_NR_H__ From 1b7b00a1f52dfa6662cda0d96fc2d70fdfe723b1 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Wed, 14 Jan 2009 23:08:41 +0300 Subject: [PATCH 18/84] [7086] Revert (remove not need code) from last commit (not need apply/remove racial passive aura) Signed-off-by: DiSlord --- src/game/SpellAuras.cpp | 8 -------- src/shared/revision_nr.h | 2 +- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 959dc5503..5dd05817f 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -3433,10 +3433,6 @@ void Aura::HandleModStealth(bool apply, bool Real) m_target->SetVisibility(VISIBILITY_GROUP_NO_DETECT); m_target->SetVisibility(VISIBILITY_GROUP_STEALTH); } - - // (RACE_NIGHTELF stealth apply also Elusiveness) - if(m_target->getRace() == RACE_NIGHTELF) - m_target->CastSpell(m_target, 21009, true, NULL, this); } } else @@ -3444,10 +3440,6 @@ void Aura::HandleModStealth(bool apply, bool Real) // only at real aura remove if(Real) { - // (RACE_NIGHTELF stealth remove Elusiveness) - if(m_target->getRace() == RACE_NIGHTELF) - m_target->RemoveAurasDueToSpell(21009); - // if last SPELL_AURA_MOD_STEALTH and no GM invisibility if(!m_target->HasAuraType(SPELL_AURA_MOD_STEALTH) && m_target->GetVisibility()!=VISIBILITY_OFF) { diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index c1233bb64..b3d863416 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7085" + #define REVISION_NR "7086" #endif // __REVISION_NR_H__ From c7a5537bac23abf5f00a87b8e30d994b275664cd Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Wed, 14 Jan 2009 23:24:58 +0300 Subject: [PATCH 19/84] [7087] Use signed type as expected for item material field. This also fix -1 value output for it. Also disable Class/Subclass item_template check by dbc data for avoid unexpected log spam (dbc have some wrong values for this fields). --- src/game/ItemHandler.cpp | 2 +- src/game/ItemPrototype.h | 2 +- src/game/ObjectMgr.cpp | 5 ++++- src/shared/Database/DBCStructure.h | 16 ++++++++-------- src/shared/Database/DBCfmt.cpp | 2 +- src/shared/revision_nr.h | 2 +- 6 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/game/ItemHandler.cpp b/src/game/ItemHandler.cpp index eb4303b23..57c8a7160 100644 --- a/src/game/ItemHandler.cpp +++ b/src/game/ItemHandler.cpp @@ -418,7 +418,7 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data ) data << pProto->PageMaterial; data << pProto->StartQuest; data << pProto->LockID; - data << pProto->Material; + data << int32(pProto->Material); data << pProto->Sheath; data << pProto->RandomProperty; data << pProto->RandomSuffix; diff --git a/src/game/ItemPrototype.h b/src/game/ItemPrototype.h index a4c0bb96e..a83456f68 100644 --- a/src/game/ItemPrototype.h +++ b/src/game/ItemPrototype.h @@ -535,7 +535,7 @@ struct ItemPrototype uint32 PageMaterial; uint32 StartQuest; // id from QuestCache.wdb uint32 LockID; - uint32 Material; // id from Material.dbc + int32 Material; // id from Material.dbc uint32 Sheath; uint32 RandomProperty; // id from ItemRandomProperties.dbc uint32 RandomSuffix; // id from ItemRandomSuffix.dbc diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 521c0d387..7387d8736 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -1598,11 +1598,14 @@ void ObjectMgr::LoadItemPrototypes() if(dbcitem) { + /* disabled: have some strange wrong cases for Class/Subclass values. + for enable also uncomment Class/Sublcas fields in ItemEntry structure and in Itemfmt[] if(proto->Class != dbcitem->Class || proto->SubClass != dbcitem->SubClass) { sLog.outErrorDb("Item (Entry: %u) not correct (Class: %u, Sub: %u) pair, must be (Class: %u, Sub: %u) (still using DB value).",i,proto->Class,proto->SubClass,dbcitem->Class,dbcitem->SubClass); // It safe let use Class/Subclass from DB } + */ if(proto->Unk0 != dbcitem->Unk0) { @@ -1612,7 +1615,7 @@ void ObjectMgr::LoadItemPrototypes() if(proto->Material != dbcitem->Material) { - sLog.outErrorDb("Item (Entry: %u) not correct %u material, must be %u (still using DB value).",i,proto->Material,dbcitem->Material); + sLog.outErrorDb("Item (Entry: %u) not correct %i material, must be %i (still using DB value).",i,proto->Material,dbcitem->Material); // It safe let use Material from DB } diff --git a/src/shared/Database/DBCStructure.h b/src/shared/Database/DBCStructure.h index bbd7fc475..6e4170d6f 100644 --- a/src/shared/Database/DBCStructure.h +++ b/src/shared/Database/DBCStructure.h @@ -808,14 +808,14 @@ struct GtRegenMPPerSptEntry struct ItemEntry { - uint32 ID; - uint32 Class; - uint32 SubClass; - uint32 Unk0; - uint32 Material; - uint32 DisplayId; - uint32 InventoryType; - uint32 Sheath; + uint32 ID; // 0 + //uint32 Class; // 1 + //uint32 SubClass; // 2 + uint32 Unk0; // 3 + int32 Material; // 4 + uint32 DisplayId; // 5 + uint32 InventoryType; // 6 + uint32 Sheath; // 7 }; struct ItemDisplayInfoEntry diff --git a/src/shared/Database/DBCfmt.cpp b/src/shared/Database/DBCfmt.cpp index fdadc8173..a646ef41f 100644 --- a/src/shared/Database/DBCfmt.cpp +++ b/src/shared/Database/DBCfmt.cpp @@ -51,7 +51,7 @@ const char GtOCTRegenHPfmt[]="f"; //const char GtOCTRegenMPfmt[]="f"; const char GtRegenHPPerSptfmt[]="f"; const char GtRegenMPPerSptfmt[]="f"; -const char Itemfmt[]="niiiiiii"; +const char Itemfmt[]="nxxiiiii"; //const char ItemDisplayTemplateEntryfmt[]="nxxxxxxxxxxixxxxxxxxxxx"; //const char ItemCondExtCostsEntryfmt[]="xiii"; const char ItemExtendedCostEntryfmt[]="niiiiiiiiiiiiix"; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index b3d863416..627a3188c 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7086" + #define REVISION_NR "7087" #endif // __REVISION_NR_H__ From 022e7ad2b51892c29adfb1d5434d525c4365b8ee Mon Sep 17 00:00:00 2001 From: arrai Date: Wed, 14 Jan 2009 14:42:38 +0100 Subject: [PATCH 20/84] Removed Unit::waterbreath. This information is not needed for creatures and can be obtained for players by Unit::HasAuraType(SPELL_AURA_WATER_BREATHING) in constant time --- src/game/Player.cpp | 2 +- src/game/SpellAuras.cpp | 6 +----- src/game/Unit.cpp | 1 - src/game/Unit.h | 1 - 4 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 4948f713f..3fe1bf6fa 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -872,7 +872,7 @@ void Player::HandleDrowning() return; //if player is GM, have waterbreath, is dead or if breathing is disabled then return - if(waterbreath || isGameMaster() || !isAlive() || GetSession()->GetSecurity() >= sWorld.getConfig(CONFIG_DISABLE_BREATHING)) + if(HasAuraType(SPELL_AURA_WATER_BREATHING) || isGameMaster() || !isAlive() || GetSession()->GetSecurity() >= sWorld.getConfig(CONFIG_DISABLE_BREATHING)) { StopMirrorTimer(BREATH_TIMER); m_isunderwater = 0; diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 5dd05817f..6ec13e581 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -2499,12 +2499,8 @@ void Aura::HandleAuraHover(bool apply, bool Real) void Aura::HandleWaterBreathing(bool apply, bool Real) { - if(apply) - m_target->waterbreath = true; - else if(m_target->GetAurasByType(SPELL_AURA_WATER_BREATHING).empty()) + if(!apply && m_target->GetAurasByType(SPELL_AURA_WATER_BREATHING).empty()) { - m_target->waterbreath = false; - // update for enable timer in case not moving target if(m_target->GetTypeId()==TYPEID_PLAYER && m_target->IsInWorld()) { diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 726e7d776..3dfffc4ef 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -102,7 +102,6 @@ Unit::Unit() //m_AurasCheck = 2000; //m_removeAuraTimer = 4; //tmpAura = NULL; - waterbreath = false; m_Visibility = VISIBILITY_ON; diff --git a/src/game/Unit.h b/src/game/Unit.h index 376e59cf8..6021c96c4 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1208,7 +1208,6 @@ class MANGOS_DLL_SPEC Unit : public WorldObject // function for low level grid visibility checks in player/creature cases virtual bool IsVisibleInGridForPlayer(Player* pl) const = 0; - bool waterbreath; AuraList & GetSingleCastAuras() { return m_scAuras; } AuraList const& GetSingleCastAuras() const { return m_scAuras; } SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY]; From b19c0da601ef95403fc6952bd58c813857a22dd6 Mon Sep 17 00:00:00 2001 From: arrai Date: Wed, 14 Jan 2009 20:41:07 +0100 Subject: [PATCH 21/84] [7088] Cleaned up Player::m_isunderwater, fixed a bug which caused SPELL_AURA_WATER_BREATHING to prevent lava damage --- src/game/Player.cpp | 64 +++++++++++++++++++++------------------- src/game/Player.h | 11 +++++++ src/game/SpellAuras.cpp | 2 +- src/shared/revision_nr.h | 2 +- 4 files changed, 47 insertions(+), 32 deletions(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 3fe1bf6fa..049ea3817 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -348,7 +348,7 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this) m_regenTimer = 0; m_weaponChangeTimer = 0; m_breathTimer = 0; - m_isunderwater = 0; + m_isunderwater = UNDERWATER_NONE; m_isInWater = false; m_drunkTimer = 0; m_drunk = 0; @@ -868,14 +868,15 @@ void Player::EnvironmentalDamage(uint64 guid, EnviromentalDamage type, uint32 da void Player::HandleDrowning() { - if(!m_isunderwater) + if(!(m_isunderwater&~UNDERWATER_INLAVA)) return; //if player is GM, have waterbreath, is dead or if breathing is disabled then return - if(HasAuraType(SPELL_AURA_WATER_BREATHING) || isGameMaster() || !isAlive() || GetSession()->GetSecurity() >= sWorld.getConfig(CONFIG_DISABLE_BREATHING)) + if(isGameMaster() || !isAlive() || HasAuraType(SPELL_AURA_WATER_BREATHING) || GetSession()->GetSecurity() >= sWorld.getConfig(CONFIG_DISABLE_BREATHING)) { StopMirrorTimer(BREATH_TIMER); - m_isunderwater = 0; + // drop every flag _except_ LAVA - otherwise waterbreathing will prevent lava damage + m_isunderwater &= UNDERWATER_INLAVA; return; } @@ -885,22 +886,22 @@ void Player::HandleDrowning() for(AuraList::const_iterator i = mModWaterBreathing.begin(); i != mModWaterBreathing.end(); ++i) UnderWaterTime = uint32(UnderWaterTime * (100.0f + (*i)->GetModifier()->m_amount) / 100.0f); - if ((m_isunderwater & 0x01) && !(m_isunderwater & 0x80) && isAlive()) + if ((m_isunderwater & UNDERWATER_INWATER) && !(m_isunderwater & UNDERWATER_INLAVA) && isAlive()) { //single trigger timer - if (!(m_isunderwater & 0x02)) + if (!(m_isunderwater & UNDERWATER_WATER_TRIGGER)) { - m_isunderwater|= 0x02; + m_isunderwater|= UNDERWATER_WATER_TRIGGER; m_breathTimer = UnderWaterTime + 1000; } - //single trigger "Breathbar" - if ( m_breathTimer <= UnderWaterTime && !(m_isunderwater & 0x04)) + //single trigger "show Breathbar" + if ( m_breathTimer <= UnderWaterTime && !(m_isunderwater & UNDERWATER_WATER_BREATHB)) { - m_isunderwater|= 0x04; + m_isunderwater|= UNDERWATER_WATER_BREATHB; StartMirrorTimer(BREATH_TIMER, UnderWaterTime); } //continuous trigger drowning "Damage" - if ((m_breathTimer == 0) && (m_isunderwater & 0x01)) + if ((m_breathTimer == 0) && (m_isunderwater & UNDERWATER_INWATER)) { //TODO: Check this formula uint64 guid = GetGUID(); @@ -911,33 +912,34 @@ void Player::HandleDrowning() } } //single trigger retract bar - else if (!(m_isunderwater & 0x01) && !(m_isunderwater & 0x08) && (m_isunderwater & 0x02) && (m_breathTimer > 0) && isAlive()) + else if (!(m_isunderwater & UNDERWATER_INWATER) && (m_isunderwater & UNDERWATER_WATER_TRIGGER) && (m_breathTimer > 0) && isAlive()) { - m_isunderwater = 0x08; - uint32 BreathRegen = 10; + // m_breathTimer will be reduced in ModifyMirrorTimer ModifyMirrorTimer(BREATH_TIMER, UnderWaterTime, m_breathTimer,BreathRegen); - m_isunderwater = 0x10; + m_isunderwater = UNDERWATER_WATER_BREATHB_RETRACTING; } //remove bar - else if ((m_breathTimer < 50) && !(m_isunderwater & 0x01) && (m_isunderwater == 0x10)) + else if ((m_breathTimer < 50) && !(m_isunderwater & UNDERWATER_INWATER) && (m_isunderwater == UNDERWATER_WATER_BREATHB_RETRACTING)) { StopMirrorTimer(BREATH_TIMER); - m_isunderwater = 0; + m_isunderwater = UNDERWATER_NONE; } } void Player::HandleLava() { - if ((m_isunderwater & 0x80) && isAlive()) + if ((m_isunderwater & UNDERWATER_INLAVA) && isAlive()) { + /* + * arrai: how is this supposed to work? UNDERWATER_INLAVA is always set in this scope! // Single trigger Set BreathTimer - if (!(m_isunderwater & 0x80)) + if (!(m_isunderwater & UNDERWATER_INLAVA)) { - m_isunderwater|= 0x04; + m_isunderwater|= UNDERWATER_WATER_BREATHB; m_breathTimer = 1000; } - + */ // Reset BreathTimer and still in the lava if (!m_breathTimer) { @@ -951,10 +953,10 @@ void Player::HandleLava() m_breathTimer = 1000; } } - else if (m_deathState == DEAD) // Disable breath timer and reset underwater flags + else if (!isAlive()) // Disable breath timer and reset underwater flags { m_breathTimer = 0; - m_isunderwater = 0; + m_isunderwater = UNDERWATER_NONE; } } @@ -18846,18 +18848,20 @@ PartyResult Player::CanUninviteFromGroup() const void Player::UpdateUnderwaterState( Map* m, float x, float y, float z ) { float water_z = m->GetWaterLevel(x,y); - float height_z = m->GetHeight(x,y,z, false); // use .map base surface height + float terrain_z = m->GetHeight(x,y,z, false); // use .map base surface height uint8 flag1 = m->GetTerrainType(x,y); - //!Underwater check, not in water if underground or above water level - if (height_z <= INVALID_HEIGHT || z < (height_z-2) || z > (water_z - 2) ) - m_isunderwater &= 0x7A; + //!Underwater check, not in water if underground or above water level - take UC royal quater for example + if (terrain_z <= INVALID_HEIGHT || z < (terrain_z-2) || z > (water_z - 2) ) + m_isunderwater &= ~UNDERWATER_INWATER; else if ((z < (water_z - 2)) && (flag1 & 0x01)) - m_isunderwater |= 0x01; + m_isunderwater |= UNDERWATER_INWATER; //!in lava check, anywhere under lava level - if ((height_z <= INVALID_HEIGHT || z < (height_z - 0)) && (flag1 == 0x00) && IsInWater()) - m_isunderwater |= 0x80; + if ((terrain_z <= INVALID_HEIGHT || z < (terrain_z - 0)) && (flag1 == 0x00) && IsInWater()) + m_isunderwater |= UNDERWATER_INLAVA; + else + m_isunderwater &= ~UNDERWATER_INLAVA; } void Player::SetCanParry( bool value ) diff --git a/src/game/Player.h b/src/game/Player.h index 659f70bb8..7f40f3ad0 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -62,6 +62,17 @@ enum SpellModType SPELLMOD_PCT = 108 // SPELL_AURA_ADD_PCT_MODIFIER }; +// 2^n values, Player::m_isunderwater is a bitmask. These are mangos internal values, they are never send to any client +enum PlayerUnderwaterState +{ + UNDERWATER_NONE = 0x00, + UNDERWATER_INWATER = 0x01, // terrain type is water and player is afflicted by it + UNDERWATER_WATER_TRIGGER = 0x02, // m_breathTimer has been initialized + UNDERWATER_WATER_BREATHB = 0x04, // breathbar has been send to client + UNDERWATER_WATER_BREATHB_RETRACTING = 0x10, // breathbar is currently refilling - the player is above water level + UNDERWATER_INLAVA = 0x80 // terrain type is lava and player is afflicted by it +}; + enum PlayerSpellState { PLAYERSPELL_UNCHANGED = 0, diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 6ec13e581..6b77cef44 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -2499,7 +2499,7 @@ void Aura::HandleAuraHover(bool apply, bool Real) void Aura::HandleWaterBreathing(bool apply, bool Real) { - if(!apply && m_target->GetAurasByType(SPELL_AURA_WATER_BREATHING).empty()) + if(!apply && !m_target->HasAuraType(SPELL_AURA_WATER_BREATHING)) { // update for enable timer in case not moving target if(m_target->GetTypeId()==TYPEID_PLAYER && m_target->IsInWorld()) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 627a3188c..6531fbd90 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7087" + #define REVISION_NR "7088" #endif // __REVISION_NR_H__ From c0824b35c6f45259a505d7488dd4ab3a523b61d0 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Thu, 15 Jan 2009 00:39:10 +0300 Subject: [PATCH 22/84] Fix item Unk0 field type as expected signed and related log output. Also restore item class check at server loading but not subclass check. Problems only with subclass check case. --- src/game/ItemHandler.cpp | 2 +- src/game/ItemPrototype.h | 4 ++-- src/game/ObjectMgr.cpp | 15 ++++++++++----- src/shared/Database/DBCStructure.h | 6 +++--- src/shared/Database/DBCfmt.cpp | 2 +- 5 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/game/ItemHandler.cpp b/src/game/ItemHandler.cpp index 57c8a7160..659421344 100644 --- a/src/game/ItemHandler.cpp +++ b/src/game/ItemHandler.cpp @@ -322,7 +322,7 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data ) data << pProto->ItemId; data << pProto->Class; data << pProto->SubClass; - data << pProto->Unk0; // new 2.0.3, not exist in wdb cache? + data << int32(pProto->Unk0); // new 2.0.3, not exist in wdb cache? data << Name; data << uint8(0x00); //pProto->Name2; // blizz not send name there, just uint8(0x00); <-- \0 = empty string = empty name... data << uint8(0x00); //pProto->Name3; // blizz not send name there, just uint8(0x00); diff --git a/src/game/ItemPrototype.h b/src/game/ItemPrototype.h index a83456f68..a62380833 100644 --- a/src/game/ItemPrototype.h +++ b/src/game/ItemPrototype.h @@ -489,7 +489,7 @@ struct ItemPrototype uint32 ItemId; uint32 Class; // id from ItemClass.dbc uint32 SubClass; // id from ItemSubClass.dbc - uint32 Unk0; + int32 Unk0; char* Name1; uint32 DisplayInfoID; // id from ItemDisplayInfo.dbc uint32 Quality; @@ -535,7 +535,7 @@ struct ItemPrototype uint32 PageMaterial; uint32 StartQuest; // id from QuestCache.wdb uint32 LockID; - int32 Material; // id from Material.dbc + int32 Material; // id from Material.dbc uint32 Sheath; uint32 RandomProperty; // id from ItemRandomProperties.dbc uint32 RandomSuffix; // id from ItemRandomSuffix.dbc diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 7387d8736..2bc096ccf 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -1598,18 +1598,23 @@ void ObjectMgr::LoadItemPrototypes() if(dbcitem) { - /* disabled: have some strange wrong cases for Class/Subclass values. - for enable also uncomment Class/Sublcas fields in ItemEntry structure and in Itemfmt[] - if(proto->Class != dbcitem->Class || proto->SubClass != dbcitem->SubClass) + if(proto->Class != dbcitem->Class) + { + sLog.outErrorDb("Item (Entry: %u) not correct ñlass %u, must be %u (still using DB value).",i,proto->Class,dbcitem->Class); + // It safe let use Class from DB + } + /* disabled: have some strange wrong cases for Subclass values. + for enable also uncomment Subclass field in ItemEntry structure and in Itemfmt[] + if(proto->SubClass != dbcitem->SubClass) { sLog.outErrorDb("Item (Entry: %u) not correct (Class: %u, Sub: %u) pair, must be (Class: %u, Sub: %u) (still using DB value).",i,proto->Class,proto->SubClass,dbcitem->Class,dbcitem->SubClass); - // It safe let use Class/Subclass from DB + // It safe let use Subclass from DB } */ if(proto->Unk0 != dbcitem->Unk0) { - sLog.outErrorDb("Item (Entry: %u) not correct %u Unk0, must be %u (still using DB value).",i,proto->Unk0,dbcitem->Unk0); + sLog.outErrorDb("Item (Entry: %u) not correct %i Unk0, must be %i (still using DB value).",i,proto->Unk0,dbcitem->Unk0); // It safe let use Unk0 from DB } diff --git a/src/shared/Database/DBCStructure.h b/src/shared/Database/DBCStructure.h index 6e4170d6f..b1997cd48 100644 --- a/src/shared/Database/DBCStructure.h +++ b/src/shared/Database/DBCStructure.h @@ -809,9 +809,9 @@ struct GtRegenMPPerSptEntry struct ItemEntry { uint32 ID; // 0 - //uint32 Class; // 1 - //uint32 SubClass; // 2 - uint32 Unk0; // 3 + uint32 Class; // 1 + //uint32 SubClass; // 2 some items have strnage subclasses + int32 Unk0; // 3 int32 Material; // 4 uint32 DisplayId; // 5 uint32 InventoryType; // 6 diff --git a/src/shared/Database/DBCfmt.cpp b/src/shared/Database/DBCfmt.cpp index a646ef41f..92f725ac0 100644 --- a/src/shared/Database/DBCfmt.cpp +++ b/src/shared/Database/DBCfmt.cpp @@ -51,7 +51,7 @@ const char GtOCTRegenHPfmt[]="f"; //const char GtOCTRegenMPfmt[]="f"; const char GtRegenHPPerSptfmt[]="f"; const char GtRegenMPPerSptfmt[]="f"; -const char Itemfmt[]="nxxiiiii"; +const char Itemfmt[]="nixiiiii"; //const char ItemDisplayTemplateEntryfmt[]="nxxxxxxxxxxixxxxxxxxxxx"; //const char ItemCondExtCostsEntryfmt[]="xiii"; const char ItemExtendedCostEntryfmt[]="niiiiiiiiiiiiix"; From 633cad5a56c8c02c3c4dbac20e01156df8c1784e Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Thu, 15 Jan 2009 03:03:19 +0300 Subject: [PATCH 23/84] [7089] Implement ITEM_ENCHANTMENT_TYPE_USE_SPELL support. This allow cast spells at item used from engineering recipes 54999, 54736, 54998, 55002, 55016, 54793. --- src/game/Item.h | 2 +- src/game/Player.cpp | 89 ++++++++++++++++++++++++++++++++++ src/game/Player.h | 2 + src/game/Spell.cpp | 2 +- src/game/Spell.h | 2 +- src/game/SpellHandler.cpp | 54 +-------------------- src/shared/Database/DBCEnums.h | 16 +++--- src/shared/revision_nr.h | 2 +- 8 files changed, 105 insertions(+), 64 deletions(-) diff --git a/src/game/Item.h b/src/game/Item.h index a124d318a..2bd91d55e 100644 --- a/src/game/Item.h +++ b/src/game/Item.h @@ -152,7 +152,7 @@ enum EnchantmentSlot SOCK_ENCHANTMENT_SLOT_2 = 3, SOCK_ENCHANTMENT_SLOT_3 = 4, BONUS_ENCHANTMENT_SLOT = 5, - WOTLK_ENCHANTMENT_SLOT = 6, + PRISMATIC_ENCHANTMENT_SLOT = 6, // added at apply special permanent enchantment MAX_INSPECTED_ENCHANTMENT_SLOT = 7, PROP_ENCHANTMENT_SLOT_0 = 7, // used with RandomSuffix diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 049ea3817..3c6284cf2 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -6947,6 +6947,92 @@ void Player::CastItemCombatSpell(Item *item,Unit* Target, WeaponAttackType attTy } } +void Player::CastItemUseSpell(Item *item,SpellCastTargets const& targets,uint8 cast_count, uint32 glyphIndex) +{ + ItemPrototype const* proto = item->GetProto(); + // special learning case + if(proto->Spells[0].SpellId==SPELL_ID_GENERIC_LEARN || proto->Spells[0].SpellId==SPELL_ID_GENERIC_LEARN_PET) + { + uint32 learn_spell_id = proto->Spells[0].SpellId; + uint32 learning_spell_id = proto->Spells[1].SpellId; + + SpellEntry const *spellInfo = sSpellStore.LookupEntry(learn_spell_id); + if(!spellInfo) + { + sLog.outError("Player::CastItemUseSpell: Item (Entry: %u) in have wrong spell id %u, ignoring ",proto->ItemId, learn_spell_id); + SendEquipError(EQUIP_ERR_NONE,item,NULL); + return; + } + + Spell *spell = new Spell(this, spellInfo, false); + spell->m_CastItem = item; + spell->m_cast_count = cast_count; //set count of casts + spell->m_currentBasePoints[0] = learning_spell_id; + spell->prepare(&targets); + return; + } + + // use triggered flag only for items with many spell casts and for not first cast + int count = 0; + + // item spells casted at use + for(int i = 0; i < 5; ++i) + { + _Spell const& spellData = proto->Spells[i]; + + // no spell + if(!spellData.SpellId) + continue; + + // wrong triggering type + if( spellData.SpellTrigger != ITEM_SPELLTRIGGER_ON_USE && spellData.SpellTrigger != ITEM_SPELLTRIGGER_ON_NO_DELAY_USE) + continue; + + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellData.SpellId); + if(!spellInfo) + { + sLog.outError("Player::CastItemUseSpell: Item (Entry: %u) in have wrong spell id %u, ignoring",proto->ItemId, spellData.SpellId); + continue; + } + + Spell *spell = new Spell(this, spellInfo, (count > 0)); + spell->m_CastItem = item; + spell->m_cast_count = cast_count; // set count of casts + spell->m_glyphIndex = glyphIndex; // glyph index + spell->prepare(&targets); + + ++count; + } + + // Item enchantments spells casted at use + for(int e_slot = 0; e_slot < MAX_ENCHANTMENT_SLOT; ++e_slot) + { + uint32 enchant_id = item->GetEnchantmentId(EnchantmentSlot(e_slot)); + SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); + if(!pEnchant) continue; + for (int s=0;s<3;s++) + { + if(pEnchant->type[s]!=ITEM_ENCHANTMENT_TYPE_USE_SPELL) + continue; + + SpellEntry const *spellInfo = sSpellStore.LookupEntry(pEnchant->spellid[s]); + if (!spellInfo) + { + sLog.outError("Player::CastItemUseSpell Enchant %i, cast unknown spell %i", pEnchant->ID, pEnchant->spellid[s]); + continue; + } + + Spell *spell = new Spell(this, spellInfo, (count > 0)); + spell->m_CastItem = item; + spell->m_cast_count = cast_count; // set count of casts + spell->m_glyphIndex = glyphIndex; // glyph index + spell->prepare(&targets); + + ++count; + } + } +} + void Player::_RemoveAllItemMods() { sLog.outDebug("_RemoveAllItemMods start."); @@ -11876,6 +11962,9 @@ void Player::ApplyEnchantment(Item *item,EnchantmentSlot slot,bool apply, bool a } break; } + case ITEM_ENCHANTMENT_TYPE_USE_SPELL: + // processed in Player::CastItemUseSpell + break; default: sLog.outError("Unknown item enchantment display type: %d",enchant_display_type); break; diff --git a/src/game/Player.h b/src/game/Player.h index 7f40f3ad0..b3a1bb406 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -46,6 +46,7 @@ class Pet; class PlayerMenu; class Transport; class UpdateMask; +class SpellCastTargets; class PlayerSocial; class AchievementMgr; class Vehicle; @@ -1871,6 +1872,7 @@ class MANGOS_DLL_SPEC Player : public Unit void ApplyEquipSpell(SpellEntry const* spellInfo, Item* item, bool apply, bool form_change = false); void UpdateEquipSpellsAtFormChange(); void CastItemCombatSpell(Item *item,Unit* Target, WeaponAttackType attType); + void CastItemUseSpell(Item *item,SpellCastTargets const& targets,uint8 cast_count, uint32 glyphIndex); void SendInitWorldStates(); void SendUpdateWorldState(uint32 Field, uint32 Value); diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 7bc7f0fba..ceb5c032c 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -2036,7 +2036,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list &TagUnitMap) } } -void Spell::prepare(SpellCastTargets * targets, Aura* triggeredByAura) +void Spell::prepare(SpellCastTargets const* targets, Aura* triggeredByAura) { m_targets = *targets; diff --git a/src/game/Spell.h b/src/game/Spell.h index e32e32d1f..24258e23c 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -321,7 +321,7 @@ class Spell Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 originalCasterGUID = 0, Spell** triggeringContainer = NULL ); ~Spell(); - void prepare(SpellCastTargets * targets, Aura* triggeredByAura = NULL); + void prepare(SpellCastTargets const* targets, Aura* triggeredByAura = NULL); void cancel(); void update(uint32 difftime); void cast(bool skipCheck = false); diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp index 2063fa34b..ab9b75917 100644 --- a/src/game/SpellHandler.cpp +++ b/src/game/SpellHandler.cpp @@ -125,59 +125,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) if(!Script->ItemUse(pUser,pItem,targets)) { // no script or script not process request by self - - // special learning case - if((pItem->GetProto()->Spells[0].SpellId==SPELL_ID_GENERIC_LEARN) || (pItem->GetProto()->Spells[0].SpellId==SPELL_ID_GENERIC_LEARN_PET)) - { - uint32 learn_spell_id = pItem->GetProto()->Spells[0].SpellId; - uint32 learning_spell_id = pItem->GetProto()->Spells[1].SpellId; - - SpellEntry const *spellInfo = sSpellStore.LookupEntry(learn_spell_id); - if(!spellInfo) - { - sLog.outError("Item (Entry: %u) in have wrong spell id %u, ignoring ",proto->ItemId, learn_spell_id); - pUser->SendEquipError(EQUIP_ERR_NONE,pItem,NULL); - return; - } - - Spell *spell = new Spell(pUser, spellInfo, false); - spell->m_CastItem = pItem; - spell->m_cast_count = cast_count; //set count of casts - spell->m_currentBasePoints[0] = learning_spell_id; - spell->prepare(&targets); - return; - } - - // use triggered flag only for items with many spell casts and for not first cast - int count = 0; - - for(int i = 0; i < 5; ++i) - { - _Spell const& spellData = pItem->GetProto()->Spells[i]; - - // no spell - if(!spellData.SpellId) - continue; - - // wrong triggering type - if( spellData.SpellTrigger != ITEM_SPELLTRIGGER_ON_USE && spellData.SpellTrigger != ITEM_SPELLTRIGGER_ON_NO_DELAY_USE) - continue; - - SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellData.SpellId); - if(!spellInfo) - { - sLog.outError("Item (Entry: %u) in have wrong spell id %u, ignoring ",proto->ItemId, spellData.SpellId); - continue; - } - - Spell *spell = new Spell(pUser, spellInfo, (count > 0)); - spell->m_CastItem = pItem; - spell->m_cast_count = cast_count; // set count of casts - spell->m_glyphIndex = glyphIndex; // glyph index - spell->prepare(&targets); - - ++count; - } + pUser->CastItemUseSpell(pItem,targets,cast_count,glyphIndex); } } diff --git a/src/shared/Database/DBCEnums.h b/src/shared/Database/DBCEnums.h index 69784cf22..e546b1f78 100644 --- a/src/shared/Database/DBCEnums.h +++ b/src/shared/Database/DBCEnums.h @@ -251,13 +251,15 @@ enum AbilytyLearnType enum ItemEnchantmentType { - ITEM_ENCHANTMENT_TYPE_NONE = 0, - ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL = 1, - ITEM_ENCHANTMENT_TYPE_DAMAGE = 2, - ITEM_ENCHANTMENT_TYPE_EQUIP_SPELL = 3, - ITEM_ENCHANTMENT_TYPE_RESISTANCE = 4, - ITEM_ENCHANTMENT_TYPE_STAT = 5, - ITEM_ENCHANTMENT_TYPE_TOTEM = 6 + ITEM_ENCHANTMENT_TYPE_NONE = 0, + ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL = 1, + ITEM_ENCHANTMENT_TYPE_DAMAGE = 2, + ITEM_ENCHANTMENT_TYPE_EQUIP_SPELL = 3, + ITEM_ENCHANTMENT_TYPE_RESISTANCE = 4, + ITEM_ENCHANTMENT_TYPE_STAT = 5, + ITEM_ENCHANTMENT_TYPE_TOTEM = 6, + ITEM_ENCHANTMENT_TYPE_USE_SPELL = 7, + ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET = 8 }; enum TotemCategoryType diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 6531fbd90..d2de4cc4d 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7088" + #define REVISION_NR "7089" #endif // __REVISION_NR_H__ From b7d11eb418e3ad01b5459332c7d413061a2ecb74 Mon Sep 17 00:00:00 2001 From: delavega Date: Thu, 15 Jan 2009 03:12:36 +0300 Subject: [PATCH 24/84] [7090] Crash fix CMSG_REQUEST_ACCOUNT_DATA in case empty data string. Signed-off-by: VladimirMangos --- src/game/MiscHandler.cpp | 2 +- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp index ac6f8ffe8..a2c791c6b 100644 --- a/src/game/MiscHandler.cpp +++ b/src/game/MiscHandler.cpp @@ -955,7 +955,7 @@ void WorldSession::HandleRequestAccountData(WorldPacket& recv_data) dest.resize(size); uLongf destSize = size; - if(compress(const_cast(dest.contents()), &destSize, (uint8*)adata->Data.c_str(), size) != Z_OK) + if(size && compress(const_cast(dest.contents()), &destSize, (uint8*)adata->Data.c_str(), size) != Z_OK) { sLog.outDebug("RAD: Failed to compress account data"); return; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index d2de4cc4d..22fa81770 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7089" + #define REVISION_NR "7090" #endif // __REVISION_NR_H__ From d6c58df0e67517fa6e624136395d7462f14de59c Mon Sep 17 00:00:00 2001 From: DiSlord Date: Thu, 15 Jan 2009 01:52:38 +0300 Subject: [PATCH 25/84] Allow use .modify bit on units Signed-off-by: DiSlord --- src/game/Level1.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/game/Level1.cpp b/src/game/Level1.cpp index 71888e8c0..7e68feb6b 100644 --- a/src/game/Level1.cpp +++ b/src/game/Level1.cpp @@ -1677,14 +1677,14 @@ bool ChatHandler::HandleModifyMoneyCommand(const char* args) return true; } -//Edit Player field +//Edit Unit field bool ChatHandler::HandleModifyBitCommand(const char* args) { if( !*args ) return false; - Player *chr = getSelectedPlayer(); - if (chr == NULL) + Unit *unit = this->getSelectedUnit(); + if (!unit) { SendSysMessage(LANG_NO_CHAR_SELECTED); SetSentErrorMessage(true); @@ -1692,7 +1692,7 @@ bool ChatHandler::HandleModifyBitCommand(const char* args) } // check online security - if (HasLowerSecurity(chr, 0)) + if (unit->GetTypeId() == TYPEID_PLAYER && HasLowerSecurity((Player *)unit, 0)) return false; char* pField = strtok((char*)args, " "); @@ -1706,13 +1706,12 @@ bool ChatHandler::HandleModifyBitCommand(const char* args) uint16 field = atoi(pField); uint32 bit = atoi(pBit); - if (field < 1 || field >= PLAYER_END) + if (field < OBJECT_END || field >= unit->GetValuesCount()) { SendSysMessage(LANG_BAD_VALUE); SetSentErrorMessage(true); return false; } - if (bit < 1 || bit > 32) { SendSysMessage(LANG_BAD_VALUE); @@ -1720,17 +1719,16 @@ bool ChatHandler::HandleModifyBitCommand(const char* args) return false; } - if ( chr->HasFlag( field, (1<<(bit-1)) ) ) + if ( unit->HasFlag( field, (1<<(bit-1)) ) ) { - chr->RemoveFlag( field, (1<<(bit-1)) ); + unit->RemoveFlag( field, (1<<(bit-1)) ); PSendSysMessage(LANG_REMOVE_BIT, bit, field); } else { - chr->SetFlag( field, (1<<(bit-1)) ); + unit->SetFlag( field, (1<<(bit-1)) ); PSendSysMessage(LANG_SET_BIT, bit, field); } - return true; } From 7cd3fa868067363e5fa30d5cbba3de7bf287f753 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Thu, 15 Jan 2009 01:53:49 +0300 Subject: [PATCH 26/84] Rename some UnitFlags Signed-off-by: DiSlord --- src/game/Player.cpp | 4 ++-- src/game/Player.h | 7 +++++++ src/game/SpellAuras.cpp | 8 ++++---- src/game/Unit.h | 24 +++++++++++++----------- 4 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 3c6284cf2..e5bc23984 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -19061,7 +19061,7 @@ void Player::EnterVehicle(Vehicle *vehicle) vehicle->SetCharmerGUID(GetGUID()); vehicle->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); - vehicle->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5); + vehicle->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24); vehicle->setFaction(getFaction()); SetCharm(vehicle); // charm @@ -19112,7 +19112,7 @@ void Player::ExitVehicle(Vehicle *vehicle) { vehicle->SetCharmerGUID(0); vehicle->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); - vehicle->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5); + vehicle->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24); vehicle->setFaction((GetTeam() == ALLIANCE) ? vehicle->GetCreatureInfo()->faction_A : vehicle->GetCreatureInfo()->faction_H); SetCharm(NULL); diff --git a/src/game/Player.h b/src/game/Player.h index b3a1bb406..ef3ab3d4e 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -439,6 +439,13 @@ enum PlayerFlags PLAYER_FLAGS_UNK17 = 0x00010000, // pre-3.0.3 PLAYER_FLAGS_SANCTUARY flag for player entered sanctuary PLAYER_FLAGS_UNK18 = 0x00020000, // taxi benchmark mode (on/off) (2.0.1) PLAYER_FLAGS_PVP_TIMER = 0x00040000, // 3.0.2, pvp timer active (after you disable pvp manually) + PLAYER_FLAGS_UNK20 = 0x00080000, + PLAYER_FLAGS_UNK21 = 0x00100000, + PLAYER_FLAGS_UNK22 = 0x00200000, + PLAYER_FLAGS_UNK23 = 0x00400000, + PLAYER_FLAGS_UNK24 = 0x00800000, // disabled all abilitys on tab except autoattack + PLAYER_FLAGS_UNK25 = 0x01000000, // disabled all melee ability on tab include autoattack + }; // used for PLAYER__FIELD_KNOWN_TITLES field (uint64), (1<SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5); + pet->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24); else - pet->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5); + pet->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24); ((Player*)caster)->SetFarSight(apply ? pet->GetGUID() : NULL); ((Player*)caster)->SetCharm(apply ? pet : NULL); @@ -3267,7 +3267,7 @@ void Aura::HandleFeignDeath(bool apply, bool Real) m_target->SendMessageToSet(&data,true); */ // blizz like 2.0.x - m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN6); + m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29); // blizz like 2.0.x m_target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH); // blizz like 2.0.x @@ -3291,7 +3291,7 @@ void Aura::HandleFeignDeath(bool apply, bool Real) m_target->SendMessageToSet(&data,true); */ // blizz like 2.0.x - m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN6); + m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29); // blizz like 2.0.x m_target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH); // blizz like 2.0.x diff --git a/src/game/Unit.h b/src/game/Unit.h index 6021c96c4..cf0d7c3ca 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -458,23 +458,23 @@ enum UnitVisibility // Value masks for UNIT_FIELD_FLAGS enum UnitFlags { - UNIT_FLAG_UNKNOWN7 = 0x00000001, + UNIT_FLAG_UNK_0 = 0x00000001, UNIT_FLAG_NON_ATTACKABLE = 0x00000002, // not attackable UNIT_FLAG_DISABLE_MOVE = 0x00000004, UNIT_FLAG_PVP_ATTACKABLE = 0x00000008, // allow apply pvp rules to attackable state in addition to faction dependent state UNIT_FLAG_RENAME = 0x00000010, UNIT_FLAG_PREPARATION = 0x00000020, // don't take reagents for spells with SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP - UNIT_FLAG_UNKNOWN9 = 0x00000040, + UNIT_FLAG_UNK_6 = 0x00000040, UNIT_FLAG_NOT_ATTACKABLE_1 = 0x00000080, // ?? (UNIT_FLAG_PVP_ATTACKABLE | UNIT_FLAG_NOT_ATTACKABLE_1) is NON_PVP_ATTACKABLE - UNIT_FLAG_UNKNOWN2 = 0x00000100, // 2.0.8 - UNIT_FLAG_UNKNOWN11 = 0x00000200, // 3.0.3 - makes you unable to attack everything + UNIT_FLAG_UNK_8 = 0x00000100, // 2.0.8 + UNIT_FLAG_UNK_9 = 0x00000200, // 3.0.3 - makes you unable to attack everything UNIT_FLAG_LOOTING = 0x00000400, // loot animation UNIT_FLAG_PET_IN_COMBAT = 0x00000800, // in combat?, 2.0.8 UNIT_FLAG_PVP = 0x00001000, // changed in 3.0.3 UNIT_FLAG_SILENCED = 0x00002000, // silenced, 2.1.1 - UNIT_FLAG_UNKNOWN4 = 0x00004000, // 2.0.8 - UNIT_FLAG_UNKNOWN13 = 0x00008000, - UNIT_FLAG_UNKNOWN14 = 0x00010000, + UNIT_FLAG_UNK_14 = 0x00004000, // 2.0.8 + UNIT_FLAG_UNK_15 = 0x00008000, + UNIT_FLAG_UNK_16 = 0x00010000, UNIT_FLAG_PACIFIED = 0x00020000, // 3.0.3 ok UNIT_FLAG_STUNNED = 0x00040000, // 3.0.3 ok UNIT_FLAG_IN_COMBAT = 0x00080000, @@ -482,19 +482,21 @@ enum UnitFlags UNIT_FLAG_DISARMED = 0x00200000, // 3.0.3, disable melee spells casting..., "Required melee weapon" added to melee spells tooltip. UNIT_FLAG_CONFUSED = 0x00400000, UNIT_FLAG_FLEEING = 0x00800000, - UNIT_FLAG_UNKNOWN5 = 0x01000000, // used in spell Eyes of the Beast for pet... + UNIT_FLAG_UNK_24 = 0x01000000, // used in spell Eyes of the Beast for pet... UNIT_FLAG_NOT_SELECTABLE = 0x02000000, UNIT_FLAG_SKINNABLE = 0x04000000, UNIT_FLAG_MOUNT = 0x08000000, - UNIT_FLAG_UNKNOWN17 = 0x10000000, - UNIT_FLAG_UNKNOWN6 = 0x20000000, // used in Feing Death spell - UNIT_FLAG_SHEATHE = 0x40000000 + UNIT_FLAG_UNK_28 = 0x10000000, + UNIT_FLAG_UNK_29 = 0x20000000, // used in Feing Death spell + UNIT_FLAG_SHEATHE = 0x40000000, + UNIT_FLAG_UNK_31 = 0x80000000 }; // Value masks for UNIT_FIELD_FLAGS_2 enum UnitFlags2 { UNIT_FLAG2_FEIGN_DEATH = 0x00000001, + UNIT_FLAG2_UNK1 = 0x00000002, // Hide unit model (show only player equip) UNIT_FLAG2_COMPREHEND_LANG = 0x00000008, UNIT_FLAG2_FORCE_MOVE = 0x00000040, UNIT_FLAG2_REGENERATE_POWER = 0x00000800 From 7cded2ed9c0dacf9c2cb64e880590dd0159c89a9 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Thu, 15 May 2008 20:27:42 +0400 Subject: [PATCH 27/84] [7091] Work vs spell attributes (compare 303 and 308) Add some comments Use correct flag for SPELL_ATTR_EX_NO_INITIAL_AGGRO Signed-off-by: DiSlord --- src/game/SharedDefines.h | 12 ++++++------ src/game/Spell.cpp | 36 +++++++++++++++--------------------- src/shared/revision_nr.h | 2 +- 3 files changed, 22 insertions(+), 28 deletions(-) diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index 84b0899ce..2e0ac63f4 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -252,7 +252,7 @@ enum ItemQualities #define SPELL_ATTR_EX_NEGATIVE 0x00000080 // 7 #define SPELL_ATTR_EX_NOT_IN_COMBAT_TARGET 0x00000100 // 8 Spell req target not to be in combat state #define SPELL_ATTR_EX_UNK9 0x00000200 // 9 -#define SPELL_ATTR_EX_UNK10 0x00000400 // 10 +#define SPELL_ATTR_EX_NO_INITIAL_AGGRO 0x00000400 // 10 no generates threat on cast 100% #define SPELL_ATTR_EX_UNK11 0x00000800 // 11 #define SPELL_ATTR_EX_UNK12 0x00001000 // 12 #define SPELL_ATTR_EX_UNK13 0x00002000 // 13 @@ -303,7 +303,7 @@ enum ItemQualities #define SPELL_ATTR_EX2_UNK25 0x02000000 // 25 #define SPELL_ATTR_EX2_UNK26 0x04000000 // 26 unaffected by school immunity #define SPELL_ATTR_EX2_UNK27 0x08000000 // 27 -#define SPELL_ATTR_EX2_UNK28 0x10000000 // 28 +#define SPELL_ATTR_EX2_UNK28 0x10000000 // 28 no breaks stealth if it fails?? #define SPELL_ATTR_EX2_CANT_CRIT 0x20000000 // 29 Spell can't crit #define SPELL_ATTR_EX2_UNK30 0x40000000 // 30 #define SPELL_ATTR_EX2_UNK31 0x80000000 // 31 @@ -324,8 +324,8 @@ enum ItemQualities #define SPELL_ATTR_EX3_UNK13 0x00002000 // 13 #define SPELL_ATTR_EX3_UNK14 0x00004000 // 14 "Honorless Target" only this spells have this flag #define SPELL_ATTR_EX3_UNK15 0x00008000 // 15 Auto Shoot, Shoot, Throw, - this is autoshot flag -#define SPELL_ATTR_EX3_UNK16 0x00010000 // 16 -#define SPELL_ATTR_EX3_NO_INITIAL_AGGRO 0x00020000 // 17 no initial aggro +#define SPELL_ATTR_EX3_UNK16 0x00010000 // 16 no triggers effects that trigger on casting a spell?? +#define SPELL_ATTR_EX3_UNK17 0x00020000 // 17 no triggers effects that trigger on casting a spell?? #define SPELL_ATTR_EX3_UNK18 0x00040000 // 18 #define SPELL_ATTR_EX3_UNK19 0x00080000 // 19 #define SPELL_ATTR_EX3_DEATH_PERSISTENT 0x00100000 // 20 Death persistent spells @@ -333,7 +333,7 @@ enum ItemQualities #define SPELL_ATTR_EX3_REQ_WAND 0x00400000 // 22 Req wand #define SPELL_ATTR_EX3_UNK23 0x00800000 // 23 #define SPELL_ATTR_EX3_REQ_OFFHAND 0x01000000 // 24 Req offhand weapon -#define SPELL_ATTR_EX3_UNK25 0x02000000 // 25 +#define SPELL_ATTR_EX3_UNK25 0x02000000 // 25 no cause spell pushback ? #define SPELL_ATTR_EX3_UNK26 0x04000000 // 26 #define SPELL_ATTR_EX3_UNK27 0x08000000 // 27 #define SPELL_ATTR_EX3_UNK28 0x10000000 // 28 @@ -345,7 +345,7 @@ enum ItemQualities #define SPELL_ATTR_EX4_UNK1 0x00000002 // 1 proc on finishing move? #define SPELL_ATTR_EX4_UNK2 0x00000004 // 2 #define SPELL_ATTR_EX4_UNK3 0x00000008 // 3 -#define SPELL_ATTR_EX4_UNK4 0x00000010 // 4 +#define SPELL_ATTR_EX4_UNK4 0x00000010 // 4 This will no longer cause guards to attack on use?? #define SPELL_ATTR_EX4_UNK5 0x00000020 // 5 #define SPELL_ATTR_EX4_UNK6 0x00000040 // 6 #define SPELL_ATTR_EX4_UNK7 0x00000080 // 7 diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index ceb5c032c..a39c53b51 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -1091,30 +1091,24 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask) return; } - // exclude Arcane Missiles Dummy Aura aura for now (attack on hit) - // TODO: find way to not need this? - if(!(m_spellInfo->SpellFamilyName == SPELLFAMILY_MAGE && - m_spellInfo->SpellFamilyFlags & 0x800LL)) + unit->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + + if( !(m_spellInfo->AttributesEx & SPELL_ATTR_EX_NO_INITIAL_AGGRO) ) { - unit->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + if(!unit->IsStandState() && !unit->hasUnitState(UNIT_STAT_STUNNED)) + unit->SetStandState(PLAYER_STATE_NONE); - if( !(m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_NO_INITIAL_AGGRO) ) + if(!unit->isInCombat() && unit->GetTypeId() != TYPEID_PLAYER && ((Creature*)unit)->AI()) + ((Creature*)unit)->AI()->AttackStart(m_caster); + + unit->SetInCombatWith(m_caster); + m_caster->SetInCombatWith(unit); + + if(Player *attackedPlayer = unit->GetCharmerOrOwnerPlayerOrPlayerItself()) { - if(!unit->IsStandState() && !unit->hasUnitState(UNIT_STAT_STUNNED)) - unit->SetStandState(PLAYER_STATE_NONE); - - if(!unit->isInCombat() && unit->GetTypeId() != TYPEID_PLAYER && ((Creature*)unit)->AI()) - ((Creature*)unit)->AI()->AttackStart(m_caster); - - unit->SetInCombatWith(m_caster); - m_caster->SetInCombatWith(unit); - - if(Player *attackedPlayer = unit->GetCharmerOrOwnerPlayerOrPlayerItself()) - { - m_caster->SetContestedPvP(attackedPlayer); - } - unit->AddThreat(m_caster, 0.0f); + m_caster->SetContestedPvP(attackedPlayer); } + unit->AddThreat(m_caster, 0.0f); } } else @@ -1129,7 +1123,7 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask) // assisting case, healing and resurrection if(unit->hasUnitState(UNIT_STAT_ATTACK_PLAYER)) m_caster->SetContestedPvP(); - if( unit->isInCombat() && !(m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_NO_INITIAL_AGGRO) ) + if( unit->isInCombat() && !(m_spellInfo->AttributesEx & SPELL_ATTR_EX_NO_INITIAL_AGGRO) ) { m_caster->SetInCombatState(unit->GetCombatTimer() > 0); unit->getHostilRefManager().threatAssist(m_caster, 0.0f); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 22fa81770..49be127c6 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7090" + #define REVISION_NR "7091" #endif // __REVISION_NR_H__ From 014ab283ddc11611c061ba56e9a04e7f0ae8ef5f Mon Sep 17 00:00:00 2001 From: DiSlord Date: Fri, 16 Jan 2009 00:59:12 +0300 Subject: [PATCH 28/84] [7092] Work vs XP per level data Add new table "player_xp_for_level" for this Fill table data 1-79 level Remove old code Signed-off-by: DiSlord --- sql/mangos.sql | 101 +++++++++++++++++- .../7092_01_mangos_player_xp_for_level.sql | 93 ++++++++++++++++ sql/updates/Makefile.am | 2 + src/game/Formulas.h | 60 ----------- src/game/ObjectMgr.cpp | 68 ++++++++++++ src/game/ObjectMgr.h | 4 + src/game/Pet.cpp | 6 +- src/game/Player.cpp | 4 +- src/game/World.cpp | 1 - src/game/World.h | 1 - src/mangosd/mangosd.conf.dist.in | 5 - src/shared/revision_nr.h | 2 +- 12 files changed, 273 insertions(+), 74 deletions(-) create mode 100644 sql/updates/7092_01_mangos_player_xp_for_level.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index 4d75aad4d..d6f890806 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -22,7 +22,7 @@ DROP TABLE IF EXISTS `db_version`; CREATE TABLE `db_version` ( `version` varchar(120) default NULL, - `required_7078_01_mangos_spell_proc_event` bit(1) default NULL + `required_7092_01_mangos_player_xp_for_level` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -9291,6 +9291,105 @@ INSERT INTO `player_levelstats` VALUES /*!40000 ALTER TABLE `player_levelstats` ENABLE KEYS */; UNLOCK TABLES; +-- ---------------------------- +-- Table structure for player_xp_for_level +-- ---------------------------- +DROP TABLE IF EXISTS `player_xp_for_level`; +CREATE TABLE `player_xp_for_level` ( + `lvl` int(3) unsigned NOT NULL, + `xp_for_next_level` int(10) unsigned NOT NULL, + PRIMARY KEY (`lvl`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `player_xp_for_level` +-- + +LOCK TABLES `player_xp_for_level` WRITE; +/*!40000 ALTER TABLE `player_xp_for_level` DISABLE KEYS */; +INSERT INTO `player_xp_for_level` VALUES +('1', '400'), +('2', '900'), +('3', '1400'), +('4', '2100'), +('5', '2800'), +('6', '3600'), +('7', '4500'), +('8', '5400'), +('9', '6500'), +('10', '7600'), +('11', '8700'), +('12', '9800'), +('13', '11000'), +('14', '12300'), +('15', '13600'), +('16', '15000'), +('17', '16400'), +('18', '17800'), +('19', '19300'), +('20', '20800'), +('21', '22400'), +('22', '24000'), +('23', '25500'), +('24', '27200'), +('25', '28900'), +('26', '30500'), +('27', '32200'), +('28', '33900'), +('29', '36300'), +('30', '38800'), +('31', '41600'), +('32', '44600'), +('33', '48000'), +('34', '51400'), +('35', '55000'), +('36', '58700'), +('37', '62400'), +('38', '66200'), +('39', '70200'), +('40', '74300'), +('41', '78500'), +('42', '82800'), +('43', '87100'), +('44', '91600'), +('45', '96300'), +('46', '101000'), +('47', '105800'), +('48', '110700'), +('49', '115700'), +('50', '120900'), +('51', '126100'), +('52', '131500'), +('53', '137000'), +('54', '142500'), +('55', '148200'), +('56', '154000'), +('57', '159900'), +('58', '165800'), +('59', '172000'), +('60', '290000'), +('61', '317000'), +('62', '349000'), +('63', '386000'), +('64', '428000'), +('65', '475000'), +('66', '527000'), +('67', '585000'), +('68', '648000'), +('69', '717000'), +('70', '1523800'), +('71', '1539600'), +('72', '1555700'), +('73', '1571800'), +('74', '1587900'), +('75', '1604200'), +('76', '1620700'), +('77', '1637400'), +('78', '1653900'), +('79', '1670800'); +/*!40000 ALTER TABLE `player_xp_for_level` ENABLE KEYS */; +UNLOCK TABLES; + -- -- Table structure for table `playercreateinfo` -- diff --git a/sql/updates/7092_01_mangos_player_xp_for_level.sql b/sql/updates/7092_01_mangos_player_xp_for_level.sql new file mode 100644 index 000000000..aa4fabd28 --- /dev/null +++ b/sql/updates/7092_01_mangos_player_xp_for_level.sql @@ -0,0 +1,93 @@ +ALTER TABLE db_version CHANGE COLUMN required_7078_01_mangos_spell_proc_event required_7092_01_mangos_player_xp_for_level bit; + +DROP TABLE IF EXISTS `player_xp_for_level`; +CREATE TABLE `player_xp_for_level` ( + `lvl` int(3) unsigned NOT NULL, + `xp_for_next_level` int(10) unsigned NOT NULL, + PRIMARY KEY (`lvl`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `player_xp_for_level` +-- + +INSERT INTO `player_xp_for_level` VALUES +('1', '400'), +('2', '900'), +('3', '1400'), +('4', '2100'), +('5', '2800'), +('6', '3600'), +('7', '4500'), +('8', '5400'), +('9', '6500'), +('10', '7600'), +('11', '8700'), +('12', '9800'), +('13', '11000'), +('14', '12300'), +('15', '13600'), +('16', '15000'), +('17', '16400'), +('18', '17800'), +('19', '19300'), +('20', '20800'), +('21', '22400'), +('22', '24000'), +('23', '25500'), +('24', '27200'), +('25', '28900'), +('26', '30500'), +('27', '32200'), +('28', '33900'), +('29', '36300'), +('30', '38800'), +('31', '41600'), +('32', '44600'), +('33', '48000'), +('34', '51400'), +('35', '55000'), +('36', '58700'), +('37', '62400'), +('38', '66200'), +('39', '70200'), +('40', '74300'), +('41', '78500'), +('42', '82800'), +('43', '87100'), +('44', '91600'), +('45', '96300'), +('46', '101000'), +('47', '105800'), +('48', '110700'), +('49', '115700'), +('50', '120900'), +('51', '126100'), +('52', '131500'), +('53', '137000'), +('54', '142500'), +('55', '148200'), +('56', '154000'), +('57', '159900'), +('58', '165800'), +('59', '172000'), +('60', '290000'), +('61', '317000'), +('62', '349000'), +('63', '386000'), +('64', '428000'), +('65', '475000'), +('66', '527000'), +('67', '585000'), +('68', '648000'), +('69', '717000'), +('70', '1523800'), +('71', '1539600'), +('72', '1555700'), +('73', '1571800'), +('74', '1587900'), +('75', '1604200'), +('76', '1620700'), +('77', '1637400'), +('78', '1653900'), +('79', '1670800'); \ No newline at end of file diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 84f20c9a6..25c460c9a 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -137,6 +137,7 @@ pkgdata_DATA = \ 7075_02_mangos_spell_learn_spell.sql \ 7077_01_characters_character_spell.sql \ 7078_01_mangos_spell_proc_event.sql \ + 7092_01_mangos_player_xp_for_level.sql \ README ## Additional files to include when running 'make dist' @@ -254,4 +255,5 @@ EXTRA_DIST = \ 7075_02_mangos_spell_learn_spell.sql \ 7077_01_characters_character_spell.sql \ 7078_01_mangos_spell_proc_event.sql \ + 7092_01_mangos_player_xp_for_level.sql \ README diff --git a/src/game/Formulas.h b/src/game/Formulas.h index a00e523d1..cea5346fe 100644 --- a/src/game/Formulas.h +++ b/src/game/Formulas.h @@ -116,66 +116,6 @@ namespace MaNGOS return (uint32)(xp_gain*sWorld.getRate(RATE_XP_KILL)); } - inline uint32 xp_Diff(uint32 lvl) - { - if( lvl < 29 ) - return 0; - if( lvl == 29 ) - return 1; - if( lvl == 30 ) - return 3; - if( lvl == 31 ) - return 6; - else - return (5*(lvl-30)); - } - - inline uint32 mxp(uint32 lvl) - { - if (lvl < 60) - { - return (45 + (5*lvl)); - } - else - { - return (235 + (5*lvl)); - } - } - - inline uint32 xp_to_level(uint32 lvl) - { - uint32 xp = 0; - if (lvl < 60) - { - xp = (8*lvl + xp_Diff(lvl)) * mxp(lvl); - } - else if (lvl == 60) - { - xp = (155 + mxp(lvl) * (1344 - 70 - ((69 - lvl) * (7 + (69 - lvl) * 8 - 1)/2))); - } - else if (lvl < 70) - { - xp = (155 + mxp(lvl) * (1344 - ((69-lvl) * (7 + (69 - lvl) * 8 - 1)/2))); - }else - { - // level higher than 70 is not supported - xp = (uint32)(779700 * (pow(sWorld.getRate(RATE_XP_PAST_70), (int32)lvl - 69))); - return ((xp < 0x7fffffff) ? xp : 0x7fffffff); - } - - // The XP to Level is always rounded to the nearest 100 points (50 rounded to high). - xp = ((xp + 50) / 100) * 100; // use additional () for prevent free association operations in C++ - - if ((lvl > 10) && (lvl < 60)) // compute discount added in 2.3.x - { - uint32 discount = (lvl < 28) ? (lvl - 10) : 18; - xp = (xp * (100 - discount)) / 100; // apply discount - xp = (xp / 100) * 100; // floor to hundreds - } - - return xp; - } - inline float xp_in_group_rate(uint32 count, bool isRaid) { if(isRaid) diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 2bc096ccf..c7d25cb1e 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -2559,6 +2559,67 @@ void ObjectMgr::LoadPlayerInfo() } } } + + // Loading xp per level data + { + mPlayerXPperLevel.resize(sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)); + for (uint32 level = 0; level < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL); ++level) + mPlayerXPperLevel[level] = 0; + + // 0 1 + QueryResult *result = WorldDatabase.Query("SELECT lvl, xp_for_next_level FROM player_xp_for_level"); + + uint32 count = 0; + + if (!result) + { + barGoLink bar( 1 ); + + sLog.outString(); + sLog.outString( ">> Loaded %u xp for level definitions", count ); + sLog.outErrorDb( "Error loading `player_xp_for_level` table or empty table."); + exit(1); + } + + barGoLink bar( result->GetRowCount() ); + + do + { + Field* fields = result->Fetch(); + + uint32 current_level = fields[0].GetUInt32(); + uint32 current_xp = fields[1].GetUInt32(); + + if(current_level >= sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)) + { + if(current_level > STRONG_MAX_LEVEL) // hardcoded level maximum + sLog.outErrorDb("Wrong (> %u) level %u in `player_xp_for_level` table, ignoring.", STRONG_MAX_LEVEL,current_level); + else + sLog.outDetail("Unused (> MaxPlayerLevel in mangosd.conf) level %u in `player_xp_for_levels` table, ignoring.",current_level); + continue; + } + //PlayerXPperLevel + mPlayerXPperLevel[current_level] = current_xp; + bar.step(); + ++count; + } + while (result->NextRow()); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u xp for level definitions", count ); + } + + // fill level gaps + for (uint32 level = 1; level < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL); ++level) + { + if( mPlayerXPperLevel[level] == 0) + { + sLog.outErrorDb("Level %i does not have XP for level data. Using data of level [%i] + 100.",level+1, level); + mPlayerXPperLevel[level] = mPlayerXPperLevel[level-1]+100; + } + } } void ObjectMgr::GetPlayerClassLevelInfo(uint32 class_, uint32 level, PlayerClassLevelInfo* info) const @@ -5714,6 +5775,13 @@ uint32 ObjectMgr::GetBaseXP(uint32 level) return mBaseXPTable[level] ? mBaseXPTable[level] : 0; } +uint32 ObjectMgr::GetXPForLevel(uint32 level) +{ + if (level < mPlayerXPperLevel.size()) + return mPlayerXPperLevel[level]; + return 0; +} + void ObjectMgr::LoadPetNames() { uint32 count = 0; diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index eac5a6bf2..b8b75f0ba 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -568,6 +568,7 @@ class ObjectMgr std::string GeneratePetName(uint32 entry); uint32 GetBaseXP(uint32 level); + uint32 GetXPForLevel(uint32 level); int32 GetFishingBaseSkillLevel(uint32 entry) const { @@ -862,6 +863,9 @@ class ObjectMgr void BuildPlayerLevelInfo(uint8 race, uint8 class_, uint8 level, PlayerLevelInfo* plinfo) const; PlayerInfo playerInfo[MAX_RACES][MAX_CLASSES]; + typedef std::vector PlayerXPperLevel; // [level] + PlayerXPperLevel mPlayerXPperLevel; + typedef std::map BaseXPMap; // [area level][base xp] BaseXPMap mBaseXPTable; diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index 93894e4d3..df8042603 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -700,7 +700,7 @@ void Pet::GivePetXP(uint32 xp) newXP -= nextLvlXP; SetLevel( level + 1 ); - SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, uint32((MaNGOS::XP::xp_to_level(level+1))/4)); + SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, objmgr.GetXPForLevel(level+1)/4); level = getLevel(); nextLvlXP = GetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP); @@ -763,7 +763,7 @@ bool Pet::CreateBaseAtCreature(Creature* creature) setPowerType(POWER_FOCUS); SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, 0); SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0); - SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, uint32((MaNGOS::XP::xp_to_level(creature->getLevel()))/4)); + SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, objmgr.GetXPForLevel(creature->getLevel())/4); SetUInt32Value(UNIT_NPC_FLAGS, 0); CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(creature->GetCreatureInfo()->family); @@ -906,7 +906,7 @@ bool Pet::InitStatsForLevel(uint32 petlevel) } case HUNTER_PET: { - SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, uint32((MaNGOS::XP::xp_to_level(petlevel))/4)); + SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, objmgr.GetXPForLevel(petlevel)/4); learnLevelupSpells(); //these formula may not be correct; however, it is designed to be close to what it should be //this makes dps 0.5 of pets level diff --git a/src/game/Player.cpp b/src/game/Player.cpp index e5bc23984..f71bc979c 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -2182,7 +2182,7 @@ void Player::GiveLevel(uint32 level) GetSession()->SendPacket(&data); - SetUInt32Value(PLAYER_NEXT_LEVEL_XP, MaNGOS::XP::xp_to_level(level)); + SetUInt32Value(PLAYER_NEXT_LEVEL_XP, objmgr.GetXPForLevel(level)); //update level, max level of skills if(getLevel()!= level) @@ -2261,7 +2261,7 @@ void Player::InitStatsForLevel(bool reapplyMods) objmgr.GetPlayerLevelInfo(getRace(),getClass(),getLevel(),&info); SetUInt32Value(PLAYER_FIELD_MAX_LEVEL, sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL) ); - SetUInt32Value(PLAYER_NEXT_LEVEL_XP, MaNGOS::XP::xp_to_level(getLevel())); + SetUInt32Value(PLAYER_NEXT_LEVEL_XP, objmgr.GetXPForLevel(getLevel())); UpdateSkillsForLevel (); diff --git a/src/game/World.cpp b/src/game/World.cpp index 74be1cbe8..6453715c6 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -464,7 +464,6 @@ void World::LoadConfigSettings(bool reload) rate_values[RATE_XP_KILL] = sConfig.GetFloatDefault("Rate.XP.Kill", 1.0f); rate_values[RATE_XP_QUEST] = sConfig.GetFloatDefault("Rate.XP.Quest", 1.0f); rate_values[RATE_XP_EXPLORE] = sConfig.GetFloatDefault("Rate.XP.Explore", 1.0f); - rate_values[RATE_XP_PAST_70] = sConfig.GetFloatDefault("Rate.XP.PastLevel70", 1.0f); rate_values[RATE_REPUTATION_GAIN] = sConfig.GetFloatDefault("Rate.Reputation.Gain", 1.0f); rate_values[RATE_CREATURE_NORMAL_DAMAGE] = sConfig.GetFloatDefault("Rate.Creature.Normal.Damage", 1.0f); rate_values[RATE_CREATURE_ELITE_ELITE_DAMAGE] = sConfig.GetFloatDefault("Rate.Creature.Elite.Elite.Damage", 1.0f); diff --git a/src/game/World.h b/src/game/World.h index 98622effe..f75118e8c 100644 --- a/src/game/World.h +++ b/src/game/World.h @@ -217,7 +217,6 @@ enum Rates RATE_XP_KILL, RATE_XP_QUEST, RATE_XP_EXPLORE, - RATE_XP_PAST_70, RATE_REPUTATION_GAIN, RATE_CREATURE_NORMAL_HP, RATE_CREATURE_ELITE_ELITE_HP, diff --git a/src/mangosd/mangosd.conf.dist.in b/src/mangosd/mangosd.conf.dist.in index c0f099640..241258ced 100644 --- a/src/mangosd/mangosd.conf.dist.in +++ b/src/mangosd/mangosd.conf.dist.in @@ -973,10 +973,6 @@ Visibility.Distance.Grey.Object = 10 # XP rates # Default: 1 # -# Rate.XP.PastLevel70 -# XP needed per level past 70 (Rates below 1 not recommended) -# Default: 1 -# # Rate.Rest.InGame # Rate.Rest.Offline.InTavernOrCity # Rate.Rest.Offline.InWilderness @@ -1086,7 +1082,6 @@ Rate.Drop.Money = 1 Rate.XP.Kill = 1 Rate.XP.Quest = 1 Rate.XP.Explore = 1 -Rate.XP.PastLevel70 = 1 Rate.Rest.InGame = 1 Rate.Rest.Offline.InTavernOrCity = 1 Rate.Rest.Offline.InWilderness = 1 diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 49be127c6..d159296e9 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7091" + #define REVISION_NR "7092" #endif // __REVISION_NR_H__ From ed14e59de411ebb6d1b016e6fac39dbabc651698 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Fri, 16 Jan 2009 18:09:55 +0300 Subject: [PATCH 29/84] Fixed typo in log output and misc code cleanups. --- src/game/ItemHandler.cpp | 10 +++----- src/game/ObjectMgr.cpp | 2 +- src/game/SpellEffects.cpp | 53 +++++++++++++++++++-------------------- 3 files changed, 31 insertions(+), 34 deletions(-) diff --git a/src/game/ItemHandler.cpp b/src/game/ItemHandler.cpp index 659421344..5715e319a 100644 --- a/src/game/ItemHandler.cpp +++ b/src/game/ItemHandler.cpp @@ -1112,10 +1112,6 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recv_data) CHECK_PACKET_SIZE(recv_data,8*4); uint64 guids[4]; - uint32 GemEnchants[3], OldEnchants[3]; - Item *Gems[3]; - bool SocketBonusActivated, SocketBonusToBeActivated; - for(int i = 0; i < 4; i++) recv_data >> guids[i]; @@ -1133,6 +1129,7 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recv_data) //this slot is excepted when applying / removing meta gem bonus uint8 slot = itemTarget->IsEquipped() ? itemTarget->GetSlot() : NULL_SLOT; + Item *Gems[3]; for(int i = 0; i < 3; i++) Gems[i] = guids[i + 1] ? _player->GetItemByGuid(guids[i + 1]) : NULL; @@ -1152,6 +1149,7 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recv_data) return; } + uint32 GemEnchants[3], OldEnchants[3]; for(int i = 0; i < 3; ++i) //get new and old enchantments { GemEnchants[i] = (GemProps[i]) ? GemProps[i]->spellitemenchantement : 0; @@ -1200,7 +1198,7 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recv_data) } } - SocketBonusActivated = itemTarget->GemsFitSockets(); //save state of socketbonus + bool SocketBonusActivated = itemTarget->GemsFitSockets(); //save state of socketbonus _player->ToggleMetaGemsActive(slot, false); //turn off all metagems (except for the target item) //if a meta gem is being equipped, all information has to be written to the item before testing if the conditions for the gem are met @@ -1222,7 +1220,7 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recv_data) for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot) _player->ApplyEnchantment(itemTarget,EnchantmentSlot(enchant_slot),true); - SocketBonusToBeActivated = itemTarget->GemsFitSockets();//current socketbonus state + bool SocketBonusToBeActivated = itemTarget->GemsFitSockets();//current socketbonus state if(SocketBonusActivated ^ SocketBonusToBeActivated) //if there was a change... { _player->ApplyEnchantment(itemTarget,BONUS_ENCHANTMENT_SLOT,false); diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index c7d25cb1e..3b86397a9 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -1600,7 +1600,7 @@ void ObjectMgr::LoadItemPrototypes() { if(proto->Class != dbcitem->Class) { - sLog.outErrorDb("Item (Entry: %u) not correct ñlass %u, must be %u (still using DB value).",i,proto->Class,dbcitem->Class); + sLog.outErrorDb("Item (Entry: %u) not correct class %u, must be %u (still using DB value).",i,proto->Class,dbcitem->Class); // It safe let use Class from DB } /* disabled: have some strange wrong cases for Subclass values. diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index fc5c8c809..a3ae35cc8 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -3807,35 +3807,34 @@ void Spell::EffectEnchantItemPerm(uint32 i) p_caster->UpdateCraftSkill(m_spellInfo->Id); - if (m_spellInfo->EffectMiscValue[i]) + uint32 enchant_id = m_spellInfo->EffectMiscValue[i]; + if (!enchant_id) + return; + + SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); + if(!pEnchant) + return; + + // item can be in trade slot and have owner diff. from caster + Player* item_owner = itemTarget->GetOwner(); + if(!item_owner) + return; + + if(item_owner!=p_caster && p_caster->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE) ) { - uint32 enchant_id = m_spellInfo->EffectMiscValue[i]; - - SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); - if(!pEnchant) - return; - - // item can be in trade slot and have owner diff. from caster - Player* item_owner = itemTarget->GetOwner(); - if(!item_owner) - return; - - if(item_owner!=p_caster && p_caster->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE) ) - { - sLog.outCommand(p_caster->GetSession()->GetAccountId(),"GM %s (Account: %u) enchanting(perm): %s (Entry: %d) for player: %s (Account: %u)", - p_caster->GetName(),p_caster->GetSession()->GetAccountId(), - itemTarget->GetProto()->Name1,itemTarget->GetEntry(), - item_owner->GetName(),item_owner->GetSession()->GetAccountId()); - } - - // remove old enchanting before applying new if equipped - item_owner->ApplyEnchantment(itemTarget,PERM_ENCHANTMENT_SLOT,false); - - itemTarget->SetEnchantment(PERM_ENCHANTMENT_SLOT, enchant_id, 0, 0); - - // add new enchanting if equipped - item_owner->ApplyEnchantment(itemTarget,PERM_ENCHANTMENT_SLOT,true); + sLog.outCommand(p_caster->GetSession()->GetAccountId(),"GM %s (Account: %u) enchanting(perm): %s (Entry: %d) for player: %s (Account: %u)", + p_caster->GetName(),p_caster->GetSession()->GetAccountId(), + itemTarget->GetProto()->Name1,itemTarget->GetEntry(), + item_owner->GetName(),item_owner->GetSession()->GetAccountId()); } + + // remove old enchanting before applying new if equipped + item_owner->ApplyEnchantment(itemTarget,PERM_ENCHANTMENT_SLOT,false); + + itemTarget->SetEnchantment(PERM_ENCHANTMENT_SLOT, enchant_id, 0, 0); + + // add new enchanting if equipped + item_owner->ApplyEnchantment(itemTarget,PERM_ENCHANTMENT_SLOT,true); } void Spell::EffectEnchantItemTmp(uint32 i) From a1e0900d375010df33d153f1ea23dd4e5dbc71af Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sat, 17 Jan 2009 00:22:49 +0300 Subject: [PATCH 30/84] [7093] Speedup spell learning code. --- src/game/Player.cpp | 13 ++++++++----- src/shared/revision_nr.h | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index f71bc979c..fdb03f95c 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -2855,12 +2855,15 @@ void Player::learnSpell(uint32 spell_id) bool learning = addSpell(spell_id,active,true,false); // learn all disabled higher ranks (recursive) - SpellChainMapNext const& nextMap = spellmgr.GetSpellChainNext(); - for(SpellChainMapNext::const_iterator i = nextMap.lower_bound(spell_id); i != nextMap.upper_bound(spell_id); ++i) + if(disabled) { - PlayerSpellMap::iterator iter = m_spells.find(i->second); - if (disabled && iter != m_spells.end() && iter->second->disabled) - learnSpell(i->second); + SpellChainMapNext const& nextMap = spellmgr.GetSpellChainNext(); + for(SpellChainMapNext::const_iterator i = nextMap.lower_bound(spell_id); i != nextMap.upper_bound(spell_id); ++i) + { + PlayerSpellMap::iterator iter = m_spells.find(i->second); + if (iter != m_spells.end() && iter->second->disabled) + learnSpell(i->second); + } } // prevent duplicated entires in spell book, also not send if not in world (loading) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index d159296e9..e80f58286 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7092" + #define REVISION_NR "7093" #endif // __REVISION_NR_H__ From 2cfebd6a57f360849455149dc989317f071c68c3 Mon Sep 17 00:00:00 2001 From: arrai Date: Sat, 17 Jan 2009 02:36:13 +0100 Subject: [PATCH 31/84] [7094] Implemented spell interrupt flag 0x10 --- src/game/ItemPrototype.h | 6 ++++++ src/game/Unit.cpp | 7 ++++++- src/game/Unit.h | 3 ++- src/shared/revision_nr.h | 2 +- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/game/ItemPrototype.h b/src/game/ItemPrototype.h index a62380833..28a57ec79 100644 --- a/src/game/ItemPrototype.h +++ b/src/game/ItemPrototype.h @@ -74,6 +74,12 @@ enum ItemSpelltriggerType ITEM_SPELLTRIGGER_ON_EQUIP = 1, ITEM_SPELLTRIGGER_CHANCE_ON_HIT = 2, ITEM_SPELLTRIGGER_SOULSTONE = 4, + /* + * ItemSpelltriggerType 5 might have changed on 2.4.3/3.0.3: Such auras + * will be applied on item pickup and removed on item loss - maybe on the + * other hand the item is destroyed if the aura is removed ("removed on + * death" of spell 57348 makes me think so) + */ ITEM_SPELLTRIGGER_ON_NO_DELAY_USE = 5, // no equip cooldown ITEM_SPELLTRIGGER_LEARN_SPELL_ID = 6 // used in item_template.spell_2 with spell_id with SPELL_GENERIC_LEARN in spell_1 }; diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 3dfffc4ef..09fe1faab 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -799,7 +799,12 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa if(Spell* spell = pVictim->m_currentSpells[i]) if(spell->getState() == SPELL_STATE_PREPARING) - spell->Delayed(); + { + if(spell->m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_ABORT_ON_DMG) + pVictim->InterruptSpell(i); + else + spell->Delayed(); + } } } diff --git a/src/game/Unit.h b/src/game/Unit.h index cf0d7c3ca..36eb900b3 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -40,7 +40,8 @@ enum SpellInterruptFlags SPELL_INTERRUPT_FLAG_DAMAGE = 0x02, SPELL_INTERRUPT_FLAG_INTERRUPT = 0x04, SPELL_INTERRUPT_FLAG_AUTOATTACK = 0x08, - //SPELL_INTERRUPT_FLAG_TURNING = 0x10 // not turning - maybe _complete_ interrupt on direct damage? + SPELL_INTERRUPT_FLAG_ABORT_ON_DMG = 0x10, // _complete_ interrupt on direct damage + //SPELL_INTERRUPT_UNK = 0x20 // unk, 564 of 727 spells having this spell start with "Glyph" }; enum SpellChannelInterruptFlags diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index e80f58286..73f701324 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7093" + #define REVISION_NR "7094" #endif // __REVISION_NR_H__ From 778d4f9741225e959f3a59d20264948e1240baec Mon Sep 17 00:00:00 2001 From: KiriX Date: Sat, 17 Jan 2009 17:18:54 +0300 Subject: [PATCH 32/84] [7095] Experience basic gain coefficient for expansion 2 zones. Signed-off-by: VladimirMangos --- src/game/Formulas.h | 13 +++++++++++-- src/shared/revision_nr.h | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/game/Formulas.h b/src/game/Formulas.h index cea5346fe..decad556f 100644 --- a/src/game/Formulas.h +++ b/src/game/Formulas.h @@ -78,8 +78,17 @@ namespace MaNGOS inline uint32 BaseGain(uint32 pl_level, uint32 mob_level, ContentLevels content) { - //TODO: need modifier for CONTENT_71_80 different from CONTENT_61_70? - const uint32 nBaseExp = content == CONTENT_1_60 ? 45 : 235; + uint32 nBaseExp; + switch(content) + { + case CONTENT_1_60: nBaseExp = 45; break; + case CONTENT_61_70: nBaseExp = 235; break; + case CONTENT_71_80: nBaseExp = 580; break; + default: + sLog.outError("BaseGain: Unsupported content level %u",content); + nBaseExp = 45; break; + } + if( mob_level >= pl_level ) { uint32 nLevelDiff = mob_level - pl_level; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 73f701324..9865d25e1 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7094" + #define REVISION_NR "7095" #endif // __REVISION_NR_H__ From 333395f90a00cc4b31a1582061183a4423918abc Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sat, 17 Jan 2009 19:38:13 +0300 Subject: [PATCH 33/84] [7096] Fixed unexpected expirience gain in starting zones for expansion 1 races. --- src/shared/Database/DBCStores.cpp | 2 +- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shared/Database/DBCStores.cpp b/src/shared/Database/DBCStores.cpp index 518765bd7..61278032b 100644 --- a/src/shared/Database/DBCStores.cpp +++ b/src/shared/Database/DBCStores.cpp @@ -566,7 +566,7 @@ uint32 GetAreaFlagByMapId(uint32 mapid) uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId) { - if(mapid != 530 || mapid != 571) // speed for most cases + if(mapid != 530 && mapid != 571) // speed for most cases return mapid; if(WorldMapAreaEntry const* wma = sWorldMapAreaStore.LookupEntry(zoneId)) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 9865d25e1..0562dc293 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7095" + #define REVISION_NR "7096" #endif // __REVISION_NR_H__ From 9f08095c26dff0167f26316b8585e1dbd7efd9cd Mon Sep 17 00:00:00 2001 From: DiSlord Date: Sat, 17 Jan 2009 17:18:03 +0300 Subject: [PATCH 34/84] Allow stack passive and not passive auras in all cases Signed-off-by: DiSlord --- src/game/SpellMgr.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 1f511afd7..cf0cbd65a 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -1062,6 +1062,10 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons if((spellInfo_1->Id == SPELL_ID_PASSIVE_RESURRECTION_SICKNESS) != (spellInfo_2->Id==SPELL_ID_PASSIVE_RESURRECTION_SICKNESS)) return false; + // Allow stack passive and not passive spells + if ((spellInfo_1->Attributes & SPELL_ATTR_PASSIVE)!=(spellInfo_2->Attributes & SPELL_ATTR_PASSIVE)) + return false; + // Specific spell family spells switch(spellInfo_1->SpellFamilyName) { From 7e6f7bf6e496e742fbb8dcdf4d7f4a0c7b59a740 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Sat, 17 Jan 2009 17:15:48 +0300 Subject: [PATCH 35/84] Fix/prevent cast if client send incorrect target for some spells Signed-off-by: DiSlord --- src/game/Spell.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index a39c53b51..ee9bed1d8 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -3639,6 +3639,20 @@ uint8 Spell::CanCast(bool strict) } } } + else if (m_caster->GetTypeId()==TYPEID_PLAYER) // Target - is player caster + { + // Additional check for some spells + // If 0 spell effect empty - client not send target data (need use selection) + // TODO: check it on next client version + if (m_targets.m_targetMask == TARGET_FLAG_SELF && + m_spellInfo->Effect[0] == 0 && m_spellInfo->EffectImplicitTargetA[1] != TARGET_SELF) + { + if (target = m_caster->GetUnit(*m_caster, ((Player *)m_caster)->GetSelection())) + m_targets.setUnitTarget(target); + else + return SPELL_FAILED_BAD_TARGETS; + } + } // check pet presents for(int j=0;j<3;j++) From 17e2bcc81d418debce9b9ecd9989406c64a821c2 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Sat, 17 Jan 2009 17:14:57 +0300 Subject: [PATCH 36/84] Enable triger from rogue poisons (need for some talents) Signed-off-by: DiSlord --- src/game/Spell.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index ee9bed1d8..d99aa96f6 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -672,15 +672,19 @@ void Spell::prepareDataForTriggerSystem() // Ñan spell trigger another or not ( m_canTrigger ) // Create base triggers flags for Attacker and Victim ( m_procAttacker and m_procVictim) //========================================================================================== - // Fill flag can spell trigger or not - if (!m_IsTriggeredSpell) + // TODO: possible exist spell attribute for this + m_canTrigger = false; + + if (m_CastItem) + m_canTrigger = false; // Do not trigger from item cast spell + else if (!m_IsTriggeredSpell) m_canTrigger = true; // Normal cast - can trigger else if (!m_triggeredByAuraSpell) m_canTrigger = true; // Triggered from SPELL_EFFECT_TRIGGER_SPELL - can trigger - else // Exceptions (some periodic triggers) + + if (!m_canTrigger) // Exceptions (some periodic triggers) { - m_canTrigger = false; // Triggered spells can`t trigger another switch (m_spellInfo->SpellFamilyName) { case SPELLFAMILY_MAGE: // Arcane Missles triggers need do it @@ -692,6 +696,9 @@ void Spell::prepareDataForTriggerSystem() case SPELLFAMILY_PRIEST: // For Penance heal/damage triggers need do it if (m_spellInfo->SpellFamilyFlags & 0x0001800000000000LL) m_canTrigger = true; break; + case SPELLFAMILY_ROGUE: // For poisons need do it + if (m_spellInfo->SpellFamilyFlags & 0x000000101001E000LL) m_canTrigger = true; + break; case SPELLFAMILY_HUNTER: // Hunter Explosive Trap Effect/Immolation Trap Effect/Frost Trap Aura/Snake Trap Effect if (m_spellInfo->SpellFamilyFlags & 0x0000200000000014LL) m_canTrigger = true; break; @@ -700,9 +707,6 @@ void Spell::prepareDataForTriggerSystem() break; } } - // Do not trigger from item cast spell - if (m_CastItem) - m_canTrigger = false; // Get data for type of attack and fill base info for trigger switch (m_spellInfo->DmgClass) From 2cd801a9efabc6eb2daf47c5e101c89618687c46 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Sat, 17 Jan 2009 17:25:25 +0300 Subject: [PATCH 37/84] Prevent (in some cases) remove aura state flag if exist similar aura. Signed-off-by: DiSlord --- src/game/SpellAuras.cpp | 86 ++++++++++++++++++++--------------------- src/game/SpellMgr.h | 3 +- 2 files changed, 43 insertions(+), 46 deletions(-) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 330c768b0..6a1707939 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -968,7 +968,7 @@ void Aura::_AddAura() if (!secondaura) { // Update Seals information - if( IsSealSpell(GetSpellProto()) ) + if (IsSealSpell(m_spellProto)) m_target->ModifyAuraState(AURA_STATE_JUDGEMENT, true); // Conflagrate aura state on Immolate @@ -976,15 +976,15 @@ void Aura::_AddAura() m_target->ModifyAuraState(AURA_STATE_IMMOLATE, true); // Faerie Fire (druid versions) - if( m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags & 0x0000000000000400LL) + if (m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags & 0x0000000000000400LL) m_target->ModifyAuraState(AURA_STATE_FAERIE_FIRE, true); // Victorious - if( m_spellProto->SpellFamilyName == SPELLFAMILY_WARRIOR && m_spellProto->SpellFamilyFlags & 0x0004000000000000LL) + if (m_spellProto->SpellFamilyName == SPELLFAMILY_WARRIOR && m_spellProto->SpellFamilyFlags & 0x0004000000000000LL) m_target->ModifyAuraState(AURA_STATE_WARRIOR_VICTORY_RUSH, true); // Swiftmend state on Regrowth & Rejuvenation - if(m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags & 0x50 ) + if (m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags & 0x50 ) m_target->ModifyAuraState(AURA_STATE_SWIFTMEND, true); // Deadly poison aura state @@ -1058,59 +1058,55 @@ void Aura::_RemoveAura() //***************************************************** // Update target aura state flag (at last aura remove) - // TODO: Make it easer //***************************************************** - // Update Seals information - if( IsSealSpell(GetSpellProto()) ) - m_target->ModifyAuraState(AURA_STATE_JUDGEMENT,false); - - // Conflagrate aura state - if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 4)) - m_target->ModifyAuraState(AURA_STATE_IMMOLATE, false); - - // Faerie Fire (druid versions) - if( m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags & 0x0000000000000400LL) - m_target->ModifyAuraState(AURA_STATE_FAERIE_FIRE, false); - - // Victorious - if( m_spellProto->SpellFamilyName == SPELLFAMILY_WARRIOR && m_spellProto->SpellFamilyFlags & 0x0004000000000000LL) - m_target->ModifyAuraState(AURA_STATE_WARRIOR_VICTORY_RUSH, false); - - // Swiftmend aura state - if(GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID && GetSpellProto()->SpellFamilyFlags & 0x50) + uint32 removeState = 0; + switch(m_spellProto->SpellFamilyName) { - bool found = false; - Unit::AuraList const& RejorRegr = m_target->GetAurasByType(SPELL_AURA_PERIODIC_HEAL); - for(Unit::AuraList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i) - { - if((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID && (*i)->GetSpellProto()->SpellFamilyFlags & 0x50 ) - { - found = true; - break; - } - } - if(!found) - m_target->ModifyAuraState(AURA_STATE_SWIFTMEND, false); + case SPELLFAMILY_PALADIN: + if (IsSealSpell(m_spellProto)) + removeState = AURA_STATE_JUDGEMENT; // Update Seals information + break; + case SPELLFAMILY_WARLOCK: + if(m_spellProto->SpellFamilyFlags & 4) + removeState = AURA_STATE_IMMOLATE; // Conflagrate aura state + break; + case SPELLFAMILY_DRUID: + if(m_spellProto->SpellFamilyFlags & 0x0000000000000400LL) + removeState = AURA_STATE_FAERIE_FIRE; // Faerie Fire (druid versions) + else if(m_spellProto->SpellFamilyFlags & 0x50) + removeState = AURA_STATE_SWIFTMEND; // Swiftmend aura state + break; + case SPELLFAMILY_WARRIOR: + if(m_spellProto->SpellFamilyFlags & 0x0004000000000000LL) + removeState = AURA_STATE_WARRIOR_VICTORY_RUSH; // Victorious + break; + case SPELLFAMILY_ROGUE: + if(m_spellProto->SpellFamilyFlags & 0x10000) + removeState = AURA_STATE_DEADLY_POISON; // Deadly poison aura state + break; + case SPELLFAMILY_HUNTER: + if(m_spellProto->SpellFamilyFlags & 0x1000000000000000LL) + removeState = AURA_STATE_FAERIE_FIRE; // Sting (hunter versions) + } - - // Deadly poison aura state - if(m_spellProto->SpellFamilyName == SPELLFAMILY_ROGUE && m_spellProto->SpellFamilyFlags & 0x10000) + // Remove state (but need check other auras for it) + if (removeState) { - // current aura already removed, search present of another bool found = false; - Unit::AuraList const& auras = m_target->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE); - for(Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + Unit::AuraMap& Auras = m_target->GetAuras(); + for(Unit::AuraMap::iterator i = Auras.begin(); i != Auras.end(); ++i) { - SpellEntry const* itr_spell = (*itr)->GetSpellProto(); - if(itr_spell && itr_spell->SpellFamilyName==SPELLFAMILY_ROGUE && itr_spell->SpellFamilyFlags & 0x10000) + SpellEntry const *auraSpellInfo = (*i).second->GetSpellProto(); + if(auraSpellInfo->SpellFamilyName == m_spellProto->SpellFamilyName && + auraSpellInfo->SpellFamilyFlags == m_spellProto->SpellFamilyFlags ) { found = true; break; } } - // this has been last deadly poison aura + // this has been last aura if(!found) - m_target->ModifyAuraState(AURA_STATE_DEADLY_POISON,false); + m_target->ModifyAuraState(AuraState(removeState), false); } // reset cooldown state for spells diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index 8354bdf40..1ae82e7c1 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -254,6 +254,7 @@ enum SpellFamilyNames #define SPELLFAMILYFLAG_ROGUE_KIDNEYSHOT 0x000200000LL #define SPELLFAMILYFLAG_ROGUE__FINISHING_MOVE 0x9003E0000LL +#define SPELLFAMILYFLAG_PALADIN_SEALS 0x26000C000A000000LL // Spell clasification enum SpellSpecific { @@ -302,7 +303,7 @@ inline bool IsSealSpell(SpellEntry const *spellInfo) { //Collection of all the seal family flags. No other paladin spell has any of those. return spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && - ( spellInfo->SpellFamilyFlags & 0x26000C000A000000LL ); + ( spellInfo->SpellFamilyFlags & SPELLFAMILYFLAG_PALADIN_SEALS ); } inline bool IsElementalShield(SpellEntry const *spellInfo) From a17dd3c0a0c6ca6911d0829d52224362df9d5543 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Sat, 17 Jan 2009 20:24:24 +0300 Subject: [PATCH 38/84] Fix one palain seal damage calculation (remove dead code) Signed-off-by: DiSlord --- src/game/SpellEffects.cpp | 8 ++++++++ src/game/Unit.cpp | 22 +++------------------- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index a3ae35cc8..d801bbd4c 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -1608,6 +1608,14 @@ void Spell::EffectDummy(uint32 i) switch(m_spellInfo->Id) { + // Judgement of Righteousness (0.2*$AP+0.32*$SPH) holy added in spellDamagBonus + case 20187: + { + if (!unitTarget) + return; + m_damage+=int32(0.2f*m_caster->GetTotalAttackPowerValue(BASE_ATTACK)); + return; + } case 31789: // Righteous Defense (step 1) { // 31989 -> dummy effect (step 1) + dummy effect (step 2) -> 31709 (taunt like spell for each target) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 09fe1faab..699d2886d 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -7375,21 +7375,10 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 DotFactor = 0.95f; CastingTime = 3500; } - // Seal of Righteousness - 10.2%/9.8% ( based on weapon type ) of Holy Damage, multiplied by weapon speed - else if((spellProto->SpellFamilyFlags & 0x8000000LL) && spellProto->SpellIconID == 25) + // Judgement of Righteousness - 32% + else if (spellProto->SpellFamilyFlags & 0x0000000000000400LL) { - Item *item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND); - float wspeed = GetAttackTime(BASE_ATTACK)/1000.0f; - - if( item && item->GetProto()->InventoryType == INVTYPE_2HWEAPON) - CastingTime = uint32(wspeed*3500*0.102f); - else - CastingTime = uint32(wspeed*3500*0.098f); - } - // Judgement of Righteousness - 73% - else if ((spellProto->SpellFamilyFlags & 1024) && spellProto->SpellIconID == 25) - { - CastingTime = 2555; + CastingTime = 1120; } // Seal of Vengeance - 17% per Fully Stacked Tick - 5 Applications else if ((spellProto->SpellFamilyFlags & 0x80000000000LL) && spellProto->SpellIconID == 2292) @@ -7407,11 +7396,6 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 { CastingTime = 0; } - // Seal of Righteousness trigger - already computed for parent spell - else if ( spellProto->SpellFamilyName==SPELLFAMILY_PALADIN && spellProto->SpellIconID==25 && spellProto->AttributesEx4 & 0x00800000LL ) - { - return pdamage; - } break; case SPELLFAMILY_SHAMAN: // totem attack From c01fe58723aaab4f29c012b940d21e66a655cb10 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Sat, 17 Jan 2009 20:51:45 +0300 Subject: [PATCH 39/84] Implement some dummy triggers Warior 42770, 58872 and ranks Warlock 47230 and ranks, for 39372 use m_amount instead hardcoded value Rogue 51669 and ranks, 51625 and ranks Hunter: 53290 and ranks (need handle regen amount for 57669) 56342 and ranks (from periodic) 53228 and ranks (only mana regen part) Shaman: 58877 (aura should on summoned wolf) 51556 and ranks (need handle dummy for 52759) 16180 and ranks, 51525 and ranks Death Knight 50365 and 50371, 48979 and ranks, 49005, 61257, 49217 Signed-off-by: DiSlord --- src/game/Level1.cpp | 2 +- src/game/Spell.cpp | 4 +- src/game/Unit.cpp | 216 +++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 206 insertions(+), 16 deletions(-) diff --git a/src/game/Level1.cpp b/src/game/Level1.cpp index 7e68feb6b..04639eda8 100644 --- a/src/game/Level1.cpp +++ b/src/game/Level1.cpp @@ -1683,7 +1683,7 @@ bool ChatHandler::HandleModifyBitCommand(const char* args) if( !*args ) return false; - Unit *unit = this->getSelectedUnit(); + Unit *unit = getSelectedUnit(); if (!unit) { SendSysMessage(LANG_NO_CHAR_SELECTED); diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index d99aa96f6..4d693bf9e 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -699,8 +699,8 @@ void Spell::prepareDataForTriggerSystem() case SPELLFAMILY_ROGUE: // For poisons need do it if (m_spellInfo->SpellFamilyFlags & 0x000000101001E000LL) m_canTrigger = true; break; - case SPELLFAMILY_HUNTER: // Hunter Explosive Trap Effect/Immolation Trap Effect/Frost Trap Aura/Snake Trap Effect - if (m_spellInfo->SpellFamilyFlags & 0x0000200000000014LL) m_canTrigger = true; + case SPELLFAMILY_HUNTER: // Hunter Rapid Killing/Explosive Trap Effect/Immolation Trap Effect/Frost Trap Aura/Snake Trap Effect + if (m_spellInfo->SpellFamilyFlags & 0x0100200000000014LL) m_canTrigger = true; break; case SPELLFAMILY_PALADIN: // For Holy Shock triggers need do it if (m_spellInfo->SpellFamilyFlags & 0x0001000000200000LL) m_canTrigger = true; diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 699d2886d..341b67397 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -4856,7 +4856,8 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu triggered_spell_id = 22858; break; } - else if (dummySpell->SpellIconID == 1697) // Second Wind + // Second Wind + if (dummySpell->SpellIconID == 1697) { // only for spells and hit/crit (trigger start always) and not start from self casted spells (5530 Mace Stun Effect for example) if (procSpell == 0 || !(procEx & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) || this == pVictim) @@ -4869,6 +4870,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu { case 29838: triggered_spell_id=29842; break; case 29834: triggered_spell_id=29841; break; + case 42770: triggered_spell_id=42771; break; default: sLog.outError("Unit::HandleDummyAuraProc: non handled spell id: %u (SW)",dummySpell->Id); return false; @@ -4877,6 +4879,13 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu target = this; break; } + // Damage Shield + if (dummySpell->SpellIconID == 3214) + { + triggered_spell_id = 59653; + basepoints0 = GetShieldBlockValue() * triggeredByAura->GetModifier()->m_amount / 100; + break; + } break; } case SPELLFAMILY_WARLOCK: @@ -4924,6 +4933,16 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu mod->m_amount-=damage; return true; } + // Fel Synergy + if (dummySpell->SpellIconID == 3222) + { + target = GetPet(); + if (!target) + return false; + triggered_spell_id = 54181; + basepoints0 = damage * triggeredByAura->GetModifier()->m_amount / 100; + break; + } switch(dummySpell->Id) { // Nightfall @@ -5044,7 +5063,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu return false; // heal amount - basepoints0 = int32(damage * 2 / 100); + basepoints0 = damage * triggeredByAura->GetModifier()->m_amount/100; target = this; triggered_spell_id = 39373; break; @@ -5176,6 +5195,31 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu break; } } + // Cut to the Chase + if( dummySpell->SpellIconID == 2909 ) + { + // "refresh your Slice and Dice duration to its 5 combo point maximum" + // lookup Slice and Dice + AuraList const& sd = GetAurasByType(SPELL_AURA_MOD_HASTE); + for(AuraList::const_iterator itr = sd.begin(); itr != sd.end(); ++itr) + { + SpellEntry const *spellProto = (*itr)->GetSpellProto(); + if( spellProto->SpellFamilyName == SPELLFAMILY_ROGUE && + spellProto->SpellFamilyFlags & 0x0000000000040000LL) + { + (*itr)->SetAuraMaxDuration(GetSpellMaxDuration(spellProto)); + (*itr)->RefreshAura(); + return true; + } + } + return false; + } + // Deadly Brew + if( dummySpell->SpellIconID == 2963 ) + { + triggered_spell_id = 25809; + break; + } // Quick Recovery if( dummySpell->SpellIconID == 2116 ) { @@ -5210,6 +5254,33 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu triggered_spell_id = 34720; break; } + // Hunting Party + if ( dummySpell->SpellIconID == 3406 ) + { + triggered_spell_id = 57669; + target = this; + return true; + } + // Lock and Load + if ( dummySpell->SpellIconID == 3579 ) + { + // Proc only from periodic (from trap activation proc another aura of this spell) + if (!(procFlag & PROC_FLAG_ON_DO_PERIODIC)) + return false; + if (!roll_chance_i(triggeredByAura->GetModifier()->m_amount)) + return false; + triggered_spell_id = 56453; + target = this; + break; + } + // Rapid Recuperation + if ( dummySpell->SpellIconID == 3560 ) + { + // mane regen from Rapid Killing + triggered_spell_id = 56654; + target = this; + break; + } break; } case SPELLFAMILY_PALADIN: @@ -5552,8 +5623,27 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu triggered_spell_id = 55533; break; } + // Spirit Hunt + case 58877: + { + // Cast on owner + target = GetOwner(); + if(!target) + return false; + basepoints0 = triggeredByAura->GetModifier()->m_amount * damage / 100; + triggered_spell_id = 58879; + break; + } + } + // Ancestral Awakening + if (dummySpell->SpellIconID == 2018) + { + // TODO: frite dummy fot triggered spell + triggered_spell_id = 52759; + basepoints0 = triggeredByAura->GetModifier()->m_amount * damage / 100; + target = this; + break; } - // Earth Shield if(dummySpell->SpellFamilyFlags & 0x0000040000000000LL) { @@ -5562,6 +5652,26 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu triggered_spell_id = 379; break; } + // Improved Water Shield + if (dummySpell->SpellIconID == 2287) + { + // lookup water shield + AuraList const& vs = GetAurasByType(SPELL_AURA_PROC_TRIGGER_SPELL); + for(AuraList::const_iterator itr = vs.begin(); itr != vs.end(); ++itr) + { + if( (*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && + (*itr)->GetSpellProto()->SpellFamilyFlags & 0x0000002000000000LL) + { + uint32 spell = (*itr)->GetSpellProto()->EffectTriggerSpell[(*itr)->GetEffIndex()]; + CastSpell(this, spell, true, castItem, triggeredByAura); + if ((*itr)->DropAuraCharge()) + RemoveAurasDueToSpell((*itr)->GetId()); + return true; + } + } + return false; + break; + } // Lightning Overload if (dummySpell->SpellIconID == 2018) // only this spell have SpellFamily Shaman SpellIconID == 2018 and dummy aura { @@ -5605,6 +5715,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu return false; } // No thread generated mod + // TODO: exist special flag in spell attributes for this, need found and use! SpellModifier *mod = new SpellModifier; mod->op = SPELLMOD_THREAT; mod->value = -100; @@ -5627,10 +5738,78 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu return true; } + // Static Shock + if(dummySpell->SpellIconID == 3059) + { + // lookup Lightning Shield + AuraList const& vs = GetAurasByType(SPELL_AURA_PROC_TRIGGER_SPELL); + for(AuraList::const_iterator itr = vs.begin(); itr != vs.end(); ++itr) + { + if( (*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && + (*itr)->GetSpellProto()->SpellFamilyFlags & 0x0000000000000400LL) + { + uint32 spell = 0; + switch ((*itr)->GetId()) + { + case 324: spell = 26364; break; + case 325: spell = 26365; break; + case 905: spell = 26366; break; + case 945: spell = 26367; break; + case 8134: spell = 26369; break; + case 10431: spell = 26370; break; + case 10432: spell = 26363; break; + case 25469: spell = 26371; break; + case 25472: spell = 26372; break; + default: + return false; + } + CastSpell(this, spell, true, castItem, triggeredByAura); + if ((*itr)->DropAuraCharge()) + RemoveAurasDueToSpell((*itr)->GetId()); + return true; + } + } + return false; + break; + } break; } case SPELLFAMILY_DEATHKNIGHT: { + // Blood Aura + if (dummySpell->SpellIconID == 2636) + { + if (GetTypeId() != TYPEID_PLAYER || !((Player*)this)->isHonorOrXPTarget(pVictim)) + return false; + basepoints0 = triggeredByAura->GetModifier()->m_amount * damage / 100; + triggered_spell_id = 53168; + break; + } + // Butchery + if (dummySpell->SpellIconID == 2664) + { + basepoints0 = triggeredByAura->GetModifier()->m_amount; + triggered_spell_id = 50163; + target = this; + break; + } + // Dancing Rune Weapon + if (dummySpell->Id == 49028) + { + // 1 dummy aura for dismiss rune blade + if (triggeredByAura->GetEffIndex()!=2) + return false; + // TODO: wite script for this "fights on its own, doing the same attacks" + // NOTE: Trigger here on every attack and spell cast + return false; + } + // Mark of Blood + if (dummySpell->Id == 49005) + { + // TODO: need more info (cooldowns/PPM) + triggered_spell_id = 50424; + break; + } // Vendetta if (dummySpell->SpellFamilyFlags & 0x0000000000010000LL) { @@ -5640,20 +5819,34 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu break; } // Necrosis - else if (dummySpell->SpellIconID == 2709) + if (dummySpell->SpellIconID == 2709) { basepoints0 = triggeredByAura->GetModifier()->m_amount * damage / 100; triggered_spell_id = 51460; break; } - // Butchery - else if (dummySpell->SpellIconID == 2664) + // Runic Power Back on Snare/Root + if (dummySpell->Id == 61257) { - basepoints0 = triggeredByAura->GetModifier()->m_amount; - triggered_spell_id = 50163; + // only for spells and hit/crit (trigger start always) and not start from self casted spells + if (procSpell == 0 || !(procEx & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) || this == pVictim) + return false; + // Need snare or root mechanic + if (!(GetAllSpellMechanicMask(procSpell) & ((1<SpellIconID == 1614) + { + if (!roll_chance_f(GetUnitCriticalChance(BASE_ATTACK, pVictim))) + return false; + basepoints0 = triggeredByAura->GetModifier()->m_amount * damage / 100; + triggered_spell_id = 50526; + break; + } break; } default: @@ -6122,10 +6315,6 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB trigger_spell_id = 26371; break; case 25472: // Rank 9 trigger_spell_id = 26372; break; - case 49280: // Rank 10 - trigger_spell_id = 49278; break; - case 49281: // Rank 11 - trigger_spell_id = 49279; break; default: sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in LShield", auraSpellInfo->Id); return false; @@ -6344,8 +6533,9 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB // Astral Shift case 52179: { - if(!procSpell) + if (procSpell == 0 || !(procEx & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) || this == pVictim) return false; + // Need stun, fear or silence mechanic if (!(GetAllSpellMechanicMask(procSpell) & ((1< Date: Sat, 17 Jan 2009 21:01:29 +0300 Subject: [PATCH 40/84] [7097] Fix some triggers changed on client switch Signed-off-by: DiSlord --- sql/mangos.sql | 28 ++++----- .../7097_01_mangos_spell_proc_event.sql | 58 +++++++++++++++++++ sql/updates/Makefile.am | 2 + src/shared/revision_nr.h | 2 +- 4 files changed, 76 insertions(+), 14 deletions(-) create mode 100644 sql/updates/7097_01_mangos_spell_proc_event.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index d6f890806..04f5babd9 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -22,7 +22,7 @@ DROP TABLE IF EXISTS `db_version`; CREATE TABLE `db_version` ( `version` varchar(120) default NULL, - `required_7092_01_mangos_player_xp_for_level` bit(1) default NULL + `required_7097_01_mangos_spell_proc_event` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -16423,7 +16423,7 @@ INSERT INTO `spell_proc_event` VALUES (15362, 0x00000000, 6, 0x10001E00, 0x00010004, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (15363, 0x00000000, 6, 0x10001E00, 0x00010004, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (15600, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1.000000, 0.000000, 0), -(16164, 0x00000000, 11, 0x90100003, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(16164, 0x00000000, 11, 0x901000C3, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (16176, 0x00000000, 11, 0x000001C0, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (16180, 0x00000000, 11, 0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (16196, 0x00000000, 11, 0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), @@ -16730,9 +16730,9 @@ INSERT INTO `spell_proc_event` VALUES (35080, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1.000000, 0.000000, 60), (35083, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 60), (35086, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 60), -(35100, 0x00000000, 9, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(35102, 0x00000000, 9, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(35103, 0x00000000, 9, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(35100, 0x00000000, 9, 0x00003001, 0x00000000, 0x00000000, 0x00010140, 0x00000000, 0.000000, 0.000000, 0), +(35102, 0x00000000, 9, 0x00003001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(35103, 0x00000000, 9, 0x00003001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (35121, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (36096, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000800, 0.000000, 0.000000, 0), (36111, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), @@ -16810,6 +16810,7 @@ INSERT INTO `spell_proc_event` VALUES (42136, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 90), (42368, 0x00000000, 10, 0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (42370, 0x00000000, 11, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(42770, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), (43019, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0.000000, 0.000000, 0), (43020, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0.000000, 0.000000, 0), (43338, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), @@ -16890,11 +16891,11 @@ INSERT INTO `spell_proc_event` VALUES (47515, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (47516, 0x00000000, 6, 0x00001800, 0x00010000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (47517, 0x00000000, 6, 0x00001800, 0x00010000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(47535, 0x00000000, 6, 0x00001800, 0x00800000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(47536, 0x00000000, 6, 0x00001800, 0x00800000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(47537, 0x00000000, 6, 0x00001800, 0x00800000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(47538, 0x00000000, 6, 0x00001800, 0x00800000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), -(47539, 0x00000000, 6, 0x00001800, 0x00800000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(47535, 0x00000000, 6, 0x00001800, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(47536, 0x00000000, 6, 0x00001800, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(47537, 0x00000000, 6, 0x00001800, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(47538, 0x00000000, 6, 0x00001800, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(47539, 0x00000000, 6, 0x00001800, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (47549, 0x00000000, 6, 0x00000000, 0x00020000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (47551, 0x00000000, 6, 0x00000000, 0x00020000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (47552, 0x00000000, 6, 0x00000000, 0x00020000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), @@ -16902,9 +16903,9 @@ INSERT INTO `spell_proc_event` VALUES (47556, 0x00000000, 6, 0x00001800, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (47557, 0x00000000, 6, 0x00001800, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (47572, 0x00000000, 6, 0x00010000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(47580, 0x00000000, 6, 0x00000000, 0x00000000, 0x00000040, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(47581, 0x00000000, 6, 0x00000000, 0x00000000, 0x00000040, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(47582, 0x00000000, 6, 0x00000000, 0x00000000, 0x00000040, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(47580, 0x00000000, 6, 0x00000000, 0x00000000, 0x00000040, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(47581, 0x00000000, 6, 0x00000000, 0x00000000, 0x00000040, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), +(47582, 0x00000000, 6, 0x00000000, 0x00000000, 0x00000040, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), (48110, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x000A02A8, 0x00000000, 0.000000, 0.000000, 0), (48111, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x000A02A8, 0x00000000, 0.000000, 0.000000, 0), (48112, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x000A02A8, 0x00000000, 0.000000, 0.000000, 0), @@ -17133,6 +17134,7 @@ INSERT INTO `spell_proc_event` VALUES (60818, 0x00000000, 10, 0x00000000, 0x00000200, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (60826, 0x00000000, 15, 0x01400000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (61188, 0x00000000, 5, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(61257, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x000202A8, 0x00010000, 0.000000, 0.000000, 0), (61324, 0x00000000, 10, 0x00000000, 0x00020000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0); /*!40000 ALTER TABLE `spell_proc_event` ENABLE KEYS */; UNLOCK TABLES; diff --git a/sql/updates/7097_01_mangos_spell_proc_event.sql b/sql/updates/7097_01_mangos_spell_proc_event.sql new file mode 100644 index 000000000..abccb36c5 --- /dev/null +++ b/sql/updates/7097_01_mangos_spell_proc_event.sql @@ -0,0 +1,58 @@ +ALTER TABLE db_version CHANGE COLUMN required_7092_01_mangos_player_xp_for_level required_7097_01_mangos_spell_proc_event bit; + +-- (35100) Concussive Barrage (Rank 1) +DELETE FROM `spell_proc_event` WHERE `entry` IN (35100); +INSERT INTO `spell_proc_event` VALUES (35100, 0x00, 9, 0x00003001, 0x00000000, 0x00000000, 0x00010140, 0x00000000, 0.000000, 0.000000, 0); + +-- (35102) Concussive Barrage (Rank 2) +DELETE FROM `spell_proc_event` WHERE `entry` IN (35102); +INSERT INTO `spell_proc_event` VALUES (35102, 0x00, 9, 0x00003001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0); + +-- (35103) Concussive Barrage (Rank 3) +DELETE FROM `spell_proc_event` WHERE `entry` IN (35103); +INSERT INTO `spell_proc_event` VALUES (35103, 0x00, 9, 0x00003001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0); + +-- (16164) Elemental Focus () +DELETE FROM `spell_proc_event` WHERE `entry` IN (16164); +INSERT INTO `spell_proc_event` VALUES (16164, 0x00, 11, 0x901000C3, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0); + +-- (42770) Second Wind (Rank 2) +DELETE FROM `spell_proc_event` WHERE `entry` IN (42770); +INSERT INTO `spell_proc_event` VALUES (42770, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0); + +-- (47580) Pain and Suffering (Rank 1) +DELETE FROM `spell_proc_event` WHERE `entry` IN (47580); +INSERT INTO `spell_proc_event` VALUES (47580, 0x00, 6, 0x00000000, 0x00000000, 0x00000040, 0x00000000, 0x00010000, 0.000000, 0.000000, 0); + +-- (47581) Pain and Suffering (Rank 2) +DELETE FROM `spell_proc_event` WHERE `entry` IN (47581); +INSERT INTO `spell_proc_event` VALUES (47581, 0x00, 6, 0x00000000, 0x00000000, 0x00000040, 0x00000000, 0x00010000, 0.000000, 0.000000, 0); + +-- (47582) Pain and Suffering (Rank 3) +DELETE FROM `spell_proc_event` WHERE `entry` IN (47582); +INSERT INTO `spell_proc_event` VALUES (47582, 0x00, 6, 0x00000000, 0x00000000, 0x00000040, 0x00000000, 0x00010000, 0.000000, 0.000000, 0); + +-- (47535) Rapture (Rank 1) +DELETE FROM `spell_proc_event` WHERE `entry` IN (47535); +INSERT INTO `spell_proc_event` VALUES (47535, 0x00, 6, 0x00001800, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0); + +-- (47536) Rapture (Rank 2) +DELETE FROM `spell_proc_event` WHERE `entry` IN (47536); +INSERT INTO `spell_proc_event` VALUES (47536, 0x00, 6, 0x00001800, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0); + +-- (47537) Rapture (Rank 3) +DELETE FROM `spell_proc_event` WHERE `entry` IN (47537); +INSERT INTO `spell_proc_event` VALUES (47537, 0x00, 6, 0x00001800, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0); + +-- (47538) Rapture (Rank 4) +DELETE FROM `spell_proc_event` WHERE `entry` IN (47538); +INSERT INTO `spell_proc_event` VALUES (47538, 0x00, 6, 0x00001800, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0); + +-- (47539) Rapture (Rank 5) +DELETE FROM `spell_proc_event` WHERE `entry` IN (47539); +INSERT INTO `spell_proc_event` VALUES (47539, 0x00, 6, 0x00001800, 0x00800000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0); + +-- (61257) Runic Power Back on Snare/Root (Rank 5) +DELETE FROM `spell_proc_event` WHERE `entry` IN (61257); +INSERT INTO `spell_proc_event` VALUES (61257, 0x00, 0, 0x00000000, 0x00000000, 0x00000000, 0x000202A8, 0x00010000, 0.000000, 0.000000, 0); + diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 25c460c9a..9522b1ec6 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -138,6 +138,7 @@ pkgdata_DATA = \ 7077_01_characters_character_spell.sql \ 7078_01_mangos_spell_proc_event.sql \ 7092_01_mangos_player_xp_for_level.sql \ + 7097_01_mangos_spell_proc_event.sql \ README ## Additional files to include when running 'make dist' @@ -256,4 +257,5 @@ EXTRA_DIST = \ 7077_01_characters_character_spell.sql \ 7078_01_mangos_spell_proc_event.sql \ 7092_01_mangos_player_xp_for_level.sql \ + 7097_01_mangos_spell_proc_event.sql \ README diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 0562dc293..e9dd89330 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7096" + #define REVISION_NR "7097" #endif // __REVISION_NR_H__ From cfde5746cb6d2fc73d328fc8d333ca57dcb2ba63 Mon Sep 17 00:00:00 2001 From: arrai Date: Sat, 17 Jan 2009 20:43:47 +0100 Subject: [PATCH 41/84] [7098] Changed build system of contrib/extractor to CMake --- contrib/Makefile.am | 23 ----------------------- contrib/extractor/CMakeLists.txt | 21 +++++++++++++++++++++ contrib/extractor/Makefile.am | 10 ---------- contrib/extractor/README.linux | 12 +++--------- contrib/extractor/libmpq/CMakeLists.txt | 13 +++++++++++++ contrib/extractor/libmpq/Makefile.am | 23 ----------------------- src/shared/revision_nr.h | 2 +- 7 files changed, 38 insertions(+), 66 deletions(-) delete mode 100644 contrib/Makefile.am create mode 100644 contrib/extractor/CMakeLists.txt delete mode 100644 contrib/extractor/Makefile.am create mode 100644 contrib/extractor/libmpq/CMakeLists.txt delete mode 100644 contrib/extractor/libmpq/Makefile.am diff --git a/contrib/Makefile.am b/contrib/Makefile.am deleted file mode 100644 index d39f2caa8..000000000 --- a/contrib/Makefile.am +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright (C) 2005-2009 MaNGOS -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -## Process this file with automake to produce Makefile.in - -## Sub-directories to parse -SUBDIRS = extractor - -## Additional files to include when running 'make dist' -# Nothing yet. diff --git a/contrib/extractor/CMakeLists.txt b/contrib/extractor/CMakeLists.txt new file mode 100644 index 000000000..a00dda120 --- /dev/null +++ b/contrib/extractor/CMakeLists.txt @@ -0,0 +1,21 @@ +# Copyright (C) 2005-2009 MaNGOS project +# +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +cmake_minimum_required (VERSION 2.6) +project (MANGOS_MAP_EXTRACTOR) + +add_subdirectory (libmpq) + +include_directories (${MANGOS_MAP_EXTRACTOR_SOURCE_DIR}/libmpq) +link_directories (${MANGOS_MAP_EXTRACTOR_SOURCE_DIR}/libmpq) + +add_executable (ad adt.cpp dbcfile.cpp mpq_libmpq.cpp System.cpp) + +target_link_libraries (ad libmpq) diff --git a/contrib/extractor/Makefile.am b/contrib/extractor/Makefile.am deleted file mode 100644 index b84617069..000000000 --- a/contrib/extractor/Makefile.am +++ /dev/null @@ -1,10 +0,0 @@ -# The top-level input Makefile for mpq-tools - -# Any directories which should be built and installed. -SUBDIRS = libmpq - -# The directories which are part of the distribution. -DIST_SUBDIRS = $(SUBDIRS) - -EXTRA_DIST = \ - README.linux diff --git a/contrib/extractor/README.linux b/contrib/extractor/README.linux index e1ebdb8bb..1986831e7 100644 --- a/contrib/extractor/README.linux +++ b/contrib/extractor/README.linux @@ -1,13 +1,7 @@ Linux instructions ------------------ -1. Configure and build MaNGOS. -2. cd contrib/map_extractor/libmpq/ +1. install cmake +2. cmake -i 3. make -4. cd .. -5. make -6. run ad - -if there are any problems create folder named .deps in contrib/map_extractor/ -it is old bug from first extractor and i am too lasy to fix it :) - +4. ./ad diff --git a/contrib/extractor/libmpq/CMakeLists.txt b/contrib/extractor/libmpq/CMakeLists.txt new file mode 100644 index 000000000..c00120c6e --- /dev/null +++ b/contrib/extractor/libmpq/CMakeLists.txt @@ -0,0 +1,13 @@ +# Copyright (C) 2005-2009 MaNGOS project +# +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +add_library (libmpq common.cpp explode.cpp extract.cpp huffman.cpp mpq.cpp parser.cpp wave.cpp ) +# link libmpq with zlib +target_link_libraries (libmpq z) diff --git a/contrib/extractor/libmpq/Makefile.am b/contrib/extractor/libmpq/Makefile.am deleted file mode 100644 index 192bd1369..000000000 --- a/contrib/extractor/libmpq/Makefile.am +++ /dev/null @@ -1,23 +0,0 @@ -# The input Makefile for the main mpq-tools - -lib_LTLIBRARIES = libmpq.la -noinst_HEADERS = explode.h huffman.h wave.h common.h - -# The directory where the include files will be installed. -libmpq_includedir = $(includedir)/libmpq - -# Which header files to install. -libmpq_include_HEADERS = mpq.h - -libmpq_la_SOURCES = $(GENERAL_SRCS) -libmpq_la_LDFLAGS = -release $(LIBMPQ_VERSION) -libmpq_la_LIBADD = @Z_LIBS@ - -GENERAL_SRCS = \ - common.c \ - huffman.c \ - extract.c \ - explode.c \ - mpq.c \ - parser.c \ - wave.c diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index e9dd89330..15372a7cd 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7097" + #define REVISION_NR "7098" #endif // __REVISION_NR_H__ From 4add3d2128d0ff1ffc15ae5dabc96ff93e4e3504 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Sun, 18 Jan 2009 01:33:06 +0300 Subject: [PATCH 42/84] [7099] Implement some item/enchants mods from 303: ITEM_MOD_ATTACK_POWER ITEM_MOD_RANGED_ATTACK_POWER ITEM_MOD_FERAL_ATTACK_POWER ITEM_MOD_SPELL_HEALING_DONE ITEM_MOD_SPELL_DAMAGE_DONE ITEM_MOD_MANA_REGENERATION ITEM_MOD_SPELL_POWER Signed-off-by: DiSlord --- src/game/Player.cpp | 56 ++++++++++++++++++++++++++++++++++++++++ src/game/Player.h | 10 +++++++ src/game/StatSystem.cpp | 35 ++++++++++++++++++++++--- src/game/Unit.cpp | 6 +++++ src/shared/revision_nr.h | 2 +- 5 files changed, 104 insertions(+), 5 deletions(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index fdb03f95c..a2b99047c 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -422,6 +422,11 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this) for (int i = 0; i < MAX_COMBAT_RATING; i++) m_baseRatingValue[i] = 0; + + m_baseSpellDamage = 0; + m_baseSpellHealing = 0; + m_baseFeralAP = 0; + m_baseManaRegen = 0; // Honor System m_lastHonorUpdateTime = time(NULL); @@ -6615,9 +6620,31 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl case ITEM_MOD_EXPERTISE_RATING: ApplyRatingMod(CR_EXPERTISE, int32(val), apply); break; + case ITEM_MOD_ATTACK_POWER: + HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(val), apply); + break; + case ITEM_MOD_RANGED_ATTACK_POWER: + HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(val), apply); + break; + case ITEM_MOD_FERAL_ATTACK_POWER: + ApplyFeralAPBonus(int32(val), apply); + break; + case ITEM_MOD_SPELL_HEALING_DONE: + ApplySpellHealingBonus(int32(val), apply); + break; + case ITEM_MOD_SPELL_DAMAGE_DONE: + ApplySpellDamageBonus(int32(val), apply); + break; + case ITEM_MOD_MANA_REGENERATION: + ApplyManaRegenBonus(int32(val), apply); + break; case ITEM_MOD_ARMOR_PENETRATION_RATING: ApplyRatingMod(CR_ARMOR_PENETRATION, int32(val), apply); break; + case ITEM_MOD_SPELL_POWER: + ApplySpellHealingBonus(int32(val), apply); + ApplySpellDamageBonus(int32(val), apply); + break; } } @@ -11938,10 +11965,39 @@ void Player::ApplyEnchantment(Item *item,EnchantmentSlot slot,bool apply, bool a ((Player*)this)->ApplyRatingMod(CR_EXPERTISE, enchant_amount, apply); sLog.outDebug("+ %u EXPERTISE", enchant_amount); break; + case ITEM_MOD_ATTACK_POWER: + HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(enchant_amount), apply); + sLog.outDebug("+ %u ATTACK_POWER", enchant_amount); + break; + case ITEM_MOD_RANGED_ATTACK_POWER: + HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(enchant_amount), apply); + sLog.outDebug("+ %u RANGED_ATTACK_POWER", enchant_amount); + break; + case ITEM_MOD_FERAL_ATTACK_POWER: + ((Player*)this)->ApplyFeralAPBonus(enchant_amount, apply); + sLog.outDebug("+ %u FERAL_ATTACK_POWER", enchant_amount); + break; + case ITEM_MOD_SPELL_HEALING_DONE: + ((Player*)this)->ApplySpellHealingBonus(enchant_amount, apply); + sLog.outDebug("+ %u SPELL_HEALING_DONE", enchant_amount); + break; + case ITEM_MOD_SPELL_DAMAGE_DONE: + ((Player*)this)->ApplySpellDamageBonus(enchant_amount, apply); + sLog.outDebug("+ %u SPELL_DAMAGE_DONE", enchant_amount); + break; + case ITEM_MOD_MANA_REGENERATION: + ((Player*)this)->ApplyManaRegenBonus(enchant_amount, apply); + sLog.outDebug("+ %u MANA_REGENERATION", enchant_amount); + break; case ITEM_MOD_ARMOR_PENETRATION_RATING: ((Player*)this)->ApplyRatingMod(CR_ARMOR_PENETRATION, enchant_amount, apply); sLog.outDebug("+ %u ARMOR PENETRATION", enchant_amount); break; + case ITEM_MOD_SPELL_POWER: + ((Player*)this)->ApplySpellHealingBonus(enchant_amount, apply); + ((Player*)this)->ApplySpellDamageBonus(enchant_amount, apply); + sLog.outDebug("+ %u SPELL_POWER", enchant_amount); + break; default: break; } diff --git a/src/game/Player.h b/src/game/Player.h index ef3ab3d4e..62ddf8e11 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1644,9 +1644,12 @@ class MANGOS_DLL_SPEC Player : public Unit void UpdateArmor(); void UpdateMaxHealth(); void UpdateMaxPower(Powers power); + void ApplyFeralAPBonus(int32 amount, bool apply); void UpdateAttackPowerAndDamage(bool ranged = false); void UpdateShieldBlockValue(); void UpdateDamagePhysical(WeaponAttackType attType); + void ApplySpellDamageBonus(int32 amount, bool apply); + void ApplySpellHealingBonus(int32 amount, bool apply); void UpdateSpellDamageAndHealingBonus(); void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, float& min_damage, float& max_damage); @@ -1664,6 +1667,8 @@ class MANGOS_DLL_SPEC Player : public Unit uint32 GetRangedCritDamageReduction(uint32 damage) const; uint32 GetSpellCritDamageReduction(uint32 damage) const; uint32 GetDotDamageReduction(uint32 damage) const; + uint32 GetBaseSpellDamageBonus() { return m_baseSpellDamage;} + uint32 GetBaseSpellHealingBonus() { return m_baseSpellHealing;} float GetExpertiseDodgeOrParryReduction(WeaponAttackType attType) const; void UpdateBlockPercentage(); @@ -1678,6 +1683,7 @@ class MANGOS_DLL_SPEC Player : public Unit void UpdateAllSpellCritChances(); void UpdateSpellCritChance(uint32 school); void UpdateExpertise(WeaponAttackType attType); + void ApplyManaRegenBonus(int32 amount, bool apply); void UpdateManaRegen(); const uint64& GetLootGUID() const { return m_lootGuid; } @@ -2315,6 +2321,10 @@ class MANGOS_DLL_SPEC Player : public Unit float m_auraBaseMod[BASEMOD_END][MOD_END]; int16 m_baseRatingValue[MAX_COMBAT_RATING]; + uint16 m_baseSpellDamage; + uint16 m_baseSpellHealing; + uint16 m_baseFeralAP; + uint16 m_baseManaRegen; SpellModList m_spellMods[MAX_SPELLMOD]; int32 m_SpellModRemoveCount; diff --git a/src/game/StatSystem.cpp b/src/game/StatSystem.cpp index a369bc3ec..a6f42c014 100644 --- a/src/game/StatSystem.cpp +++ b/src/game/StatSystem.cpp @@ -91,6 +91,21 @@ bool Player::UpdateStats(Stats stat) return true; } +void Player::ApplySpellDamageBonus(int32 amount, bool apply) +{ + m_baseSpellDamage+=apply?amount:-amount; + // For speed just update for client + ApplyModUInt32Value(PLAYER_FIELD_MOD_HEALING_DONE_POS, amount, apply); +} + +void Player::ApplySpellHealingBonus(int32 amount, bool apply) +{ + m_baseSpellHealing+=apply?amount:-amount; + // For speed just update for client + for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; i++) + ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+i, amount, apply);; +} + void Player::UpdateSpellDamageAndHealingBonus() { // Magic damage modifiers implemented in Unit::SpellDamageBonus @@ -221,6 +236,12 @@ void Player::UpdateMaxPower(Powers power) SetMaxPower(power, uint32(value)); } +void Player::ApplyFeralAPBonus(int32 amount, bool apply) +{ + m_baseFeralAP+= apply ? amount:-amount; + UpdateAttackPowerAndDamage(); +} + void Player::UpdateAttackPowerAndDamage(bool ranged ) { float val2 = 0.0f; @@ -295,12 +316,12 @@ void Player::UpdateAttackPowerAndDamage(bool ranged ) switch(m_form) { case FORM_CAT: - val2 = getLevel()*(mLevelMult+2.0f) + GetStat(STAT_STRENGTH)*2.0f + GetStat(STAT_AGILITY) - 20.0f; break; + val2 = getLevel()*(mLevelMult+2.0f) + GetStat(STAT_STRENGTH)*2.0f + GetStat(STAT_AGILITY) - 20.0f + m_baseFeralAP; break; case FORM_BEAR: case FORM_DIREBEAR: - val2 = getLevel()*(mLevelMult+3.0f) + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break; + val2 = getLevel()*(mLevelMult+3.0f) + GetStat(STAT_STRENGTH)*2.0f - 20.0f + m_baseFeralAP; break; case FORM_MOONKIN: - val2 = getLevel()*(mLevelMult+1.5f) + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break; + val2 = getLevel()*(mLevelMult+1.5f) + GetStat(STAT_STRENGTH)*2.0f - 20.0f + m_baseFeralAP; break; default: val2 = GetStat(STAT_STRENGTH)*2.0f - 20.0f; break; } @@ -625,6 +646,12 @@ void Player::UpdateExpertise(WeaponAttackType attack) } } +void Player::ApplyManaRegenBonus(int32 amount, bool apply) +{ + m_baseManaRegen+= apply ? amount : -amount; + UpdateManaRegen(); +} + void Player::UpdateManaRegen() { float Intellect = GetStat(STAT_INTELLECT); @@ -634,7 +661,7 @@ void Player::UpdateManaRegen() power_regen *= GetTotalAuraMultiplierByMiscValue(SPELL_AURA_MOD_POWER_REGEN_PERCENT, POWER_MANA); // Mana regen from SPELL_AURA_MOD_POWER_REGEN aura - float power_regen_mp5 = GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, POWER_MANA) / 5.0f; + float power_regen_mp5 = (GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, POWER_MANA) + m_baseManaRegen) / 5.0f; // Get bonus from SPELL_AURA_MOD_MANA_REGEN_FROM_STAT aura AuraList const& regenAura = GetAurasByType(SPELL_AURA_MOD_MANA_REGEN_FROM_STAT); diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 341b67397..826a21a3b 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -7702,6 +7702,9 @@ int32 Unit::SpellBaseDamageBonus(SpellSchoolMask schoolMask) if (GetTypeId() == TYPEID_PLAYER) { + // Base value + DoneAdvertisedBenefit +=((Player*)this)->GetBaseSpellDamageBonus(); + // Damage bonus from stats AuraList const& mDamageDoneOfStatPercent = GetAurasByType(SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT); for(AuraList::const_iterator i = mDamageDoneOfStatPercent.begin();i != mDamageDoneOfStatPercent.end(); ++i) @@ -8067,6 +8070,9 @@ int32 Unit::SpellBaseHealingBonus(SpellSchoolMask schoolMask) // Healing bonus of spirit, intellect and strength if (GetTypeId() == TYPEID_PLAYER) { + // Base value + AdvertisedBenefit +=((Player*)this)->GetBaseSpellHealingBonus(); + // Healing bonus from stats AuraList const& mHealingDoneOfStatPercent = GetAurasByType(SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT); for(AuraList::const_iterator i = mHealingDoneOfStatPercent.begin();i != mHealingDoneOfStatPercent.end(); ++i) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 15372a7cd..833dc7728 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7098" + #define REVISION_NR "7099" #endif // __REVISION_NR_H__ From bd30c1216969d470f00183cfe47143a4e519e107 Mon Sep 17 00:00:00 2001 From: Snow Date: Sun, 18 Jan 2009 01:38:45 +0300 Subject: [PATCH 43/84] [7100] More cleanups for `character_spell` from outdated data. Signed-off-by: Neo2003 --- sql/characters.sql | 2 +- .../7100_01_characters_character_spell.sql | 39 +++++++++++++++++++ sql/updates/Makefile.am | 2 + src/shared/revision_nr.h | 2 +- 4 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 sql/updates/7100_01_characters_character_spell.sql diff --git a/sql/characters.sql b/sql/characters.sql index da43adaf7..1548a6b11 100644 --- a/sql/characters.sql +++ b/sql/characters.sql @@ -21,7 +21,7 @@ DROP TABLE IF EXISTS `character_db_version`; CREATE TABLE `character_db_version` ( - `required_7077_01_characters_character_spell` bit(1) default NULL + `required_7100_01_characters_character_spell` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB'; -- diff --git a/sql/updates/7100_01_characters_character_spell.sql b/sql/updates/7100_01_characters_character_spell.sql new file mode 100644 index 000000000..4d65b6c15 --- /dev/null +++ b/sql/updates/7100_01_characters_character_spell.sql @@ -0,0 +1,39 @@ +ALTER TABLE character_db_version CHANGE COLUMN required_7077_01_characters_character_spell required_7100_01_characters_character_spell bit; + +/* Warrior cleanup */ +DELETE FROM `character_spell` WHERE `spell` IN (1715,7372,7373); /* Hamstring old */ +DELETE FROM `character_spell` WHERE `spell` IN (72,17671,1672); /* Mortar Disturb old */ +DELETE FROM `character_spell` WHERE `spell` IN (7384,7887,11584,11586); /* Overpower old */ +DELETE FROM `character_spell` WHERE `spell`=23881; /* Bloodthirst old */ +DELETE FROM `character_spell` WHERE `spell` IN (6552,6554); /* Pummel old */ +DELETE FROM `character_spell` WHERE `spell` IN (694,7400,7402,20559,20560,25266); /* Mocking Blow old */ +/* Druid cleanup */ +DELETE FROM `character_spell` WHERE `spell`=22842; /* Frenzied Regeneration old */ +/* Hunter cleanup */ +DELETE FROM `character_spell` WHERE `spell`=14268; /* Wing Clip r1 old */ +DELETE FROM `character_spell` WHERE `spell`=14267; /* Wing Clip r2 old */ +/* Rogue */ +DELETE FROM `character_spell` WHERE `spell` IN (1766,1767,1768,1769,38768); /* Kick old */ +DELETE FROM `character_spell` WHERE `spell` IN (1776,1777,8629,11285,11286,38764);/* Gouge old */ +DELETE FROM `character_spell` WHERE `spell`=2842; /* Poisons old */ + +/* Hunter's training spells for pets */ +DELETE FROM `character_spell` WHERE `spell` IN (2949,2975,2976,2977,2980,2981,2982,3666,3667,4630,6327,6359,6362, + 7370,7832,7833,7834,7835,7871,7872,7873,7876,7877,7878,7879,7880,7881,7882,7883,7884,7885,7886,8318,8319,11764, + 11765,11768,11769,11772,11773,11776,11777,11781,11782,11783,11786,11787,17254,17262,17263,17264,17265,17266, + 17267,17268,17736,17753,17754,17755,17776,17855,17856,17857,17859,17860,19439,19444,19445,19446,19447,19481, + 19577,19648,19650,19661,19662,19663,19664,19737,19738,19739,20270,20312,20313,20314,20315,20316,20317,20318, + 20319,20320,20321,20322,20323,20324,20326,20327,20329,20377,20378,20379,20380,20381,20382,20383,20384,20385, + 20386,20387,20388,20389,20390,20391,20392,20393,20394,20395,20396,20397,20398,20399,20400,20401,20402,20403, + 20404,20405,20406,20407,20408,20426,20427,20428,20429,20430,20431,20432,20433,20434,20435,23100,23111,23112, + 23146,23149,23150,24424,24440,24441,24451,24454,24455,24463,24464,24475,24476,24477,24580,24581,24582,24584, + 24588,24589,24599,24607,24608,24609,24641,26065,26094,26184,26185,26186,26189,26190,26202,27347,27348,27349, + 27361,27366,27484,27485,27486,27487,27488,27489,27490,27491,27492,27493,27494,27495,27496,27497,27500,28343, + 33703,35299,35300,35302,35303,35304,35305,35306,35307,35308); +DELETE FROM `character_spell` WHERE `spell` IN (1853,14922,14923,14924,14925,14926,14927,27344); +DELETE FROM `character_spell` WHERE `spell` IN (27353,24516,24515,24514,24490); +DELETE FROM `character_spell` WHERE `spell` IN (27354,24513,24512,24511,24494,2119); +UPDATE IGNORE character_spell SET spell = 2108 WHERE spell = 3104; +DELETE FROM character_spell WHERE spell = 3104; +/* This cleanup character_action. This is like delete from character_action where type=0 and action not in character_spell for same player */ +DELETE FROM ca,cs USING `character_action` ca LEFT JOIN `character_spell` cs ON ca.`guid`=cs.`guid` AND ca.`action`=cs.`spell` WHERE ca.`type`=0 AND cs.`guid` IS NULL; diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 9522b1ec6..0c540440c 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -139,6 +139,7 @@ pkgdata_DATA = \ 7078_01_mangos_spell_proc_event.sql \ 7092_01_mangos_player_xp_for_level.sql \ 7097_01_mangos_spell_proc_event.sql \ + 7100_01_characters_character_spell.sql \ README ## Additional files to include when running 'make dist' @@ -258,4 +259,5 @@ EXTRA_DIST = \ 7078_01_mangos_spell_proc_event.sql \ 7092_01_mangos_player_xp_for_level.sql \ 7097_01_mangos_spell_proc_event.sql \ + 7100_01_characters_character_spell.sql \ README diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 833dc7728..60f75e485 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7099" + #define REVISION_NR "7100" #endif // __REVISION_NR_H__ From c138b5462df5bcf6f260e42f495399d9fa2f1b2e Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sun, 18 Jan 2009 03:34:46 +0300 Subject: [PATCH 44/84] [7101] Fixed build at VC80/VC90 x64 with proper call getrevision.exe --- src/shared/revision_nr.h | 2 +- win/VC80/shared.vcproj | 20 ++++++++++---------- win/VC90/shared.vcproj | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 60f75e485..9df72dc01 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7100" + #define REVISION_NR "7101" #endif // __REVISION_NR_H__ diff --git a/win/VC80/shared.vcproj b/win/VC80/shared.vcproj index a85988454..12de20388 100644 --- a/win/VC80/shared.vcproj +++ b/win/VC80/shared.vcproj @@ -757,14 +757,6 @@ RelativePath="..\..\src\shared\Common.h" > - - - - @@ -785,7 +777,7 @@ @@ -807,7 +799,7 @@ @@ -817,6 +809,14 @@ RelativePath="..\..\src\shared\revision_nr.h" > + + + + diff --git a/win/VC90/shared.vcproj b/win/VC90/shared.vcproj index 3254e559c..32931be90 100644 --- a/win/VC90/shared.vcproj +++ b/win/VC90/shared.vcproj @@ -781,7 +781,7 @@ @@ -803,7 +803,7 @@ From 1d80a7a788ee7eb0bcb7bbdbc4f701a7963d5bff Mon Sep 17 00:00:00 2001 From: McBen Date: Sun, 18 Jan 2009 04:31:33 +0300 Subject: [PATCH 45/84] [7102] Fixed .showarea/,hodearea commands. Signed-off-by: VladimirMangos --- src/game/Level3.cpp | 10 ++++------ src/game/Player.cpp | 2 +- src/shared/revision_nr.h | 2 +- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 44f626210..0323b09af 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -3836,8 +3836,6 @@ bool ChatHandler::HandleShowAreaCommand(const char* args) if (!*args) return false; - int area = atoi((char*)args); - Player *chr = getSelectedPlayer(); if (chr == NULL) { @@ -3846,10 +3844,11 @@ bool ChatHandler::HandleShowAreaCommand(const char* args) return false; } + int area = GetAreaFlagByAreaID(atoi((char*)args)); int offset = area / 32; uint32 val = (uint32)(1 << (area % 32)); - if(offset >= 128) + if(area<0 || offset >= 128) { SendSysMessage(LANG_BAD_VALUE); SetSentErrorMessage(true); @@ -3868,8 +3867,6 @@ bool ChatHandler::HandleHideAreaCommand(const char* args) if (!*args) return false; - int area = atoi((char*)args); - Player *chr = getSelectedPlayer(); if (chr == NULL) { @@ -3878,10 +3875,11 @@ bool ChatHandler::HandleHideAreaCommand(const char* args) return false; } + int area = GetAreaFlagByAreaID(atoi((char*)args)); int offset = area / 32; uint32 val = (uint32)(1 << (area % 32)); - if(offset >= 128) + if(area<0 || offset >= 128) { SendSysMessage(LANG_BAD_VALUE); SetSentErrorMessage(true); diff --git a/src/game/Player.cpp b/src/game/Player.cpp index a2b99047c..f9ce04983 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -5322,7 +5322,7 @@ void Player::CheckExploreSystem() if(offset >= 128) { - sLog.outError("ERROR: Wrong area flag %u in map data for (X: %f Y: %f) point to field PLAYER_EXPLORED_ZONES_1 + %u ( %u must be < 64 ).",areaFlag,GetPositionX(),GetPositionY(),offset,offset); + sLog.outError("ERROR: Wrong area flag %u in map data for (X: %f Y: %f) point to field PLAYER_EXPLORED_ZONES_1 + %u ( %u must be < 128 ).",areaFlag,GetPositionX(),GetPositionY(),offset,offset); return; } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 9df72dc01..4ada821d6 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7101" + #define REVISION_NR "7102" #endif // __REVISION_NR_H__ From 383239b5957753f3f08fe0993942d0f0d9f88f7f Mon Sep 17 00:00:00 2001 From: arrai Date: Sun, 18 Jan 2009 14:52:58 +0100 Subject: [PATCH 46/84] [7103] replaced wrong delete by delete[] --- src/shared/Auth/AuthCrypt.cpp | 2 +- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shared/Auth/AuthCrypt.cpp b/src/shared/Auth/AuthCrypt.cpp index 7686cdd81..5c91a22bc 100644 --- a/src/shared/Auth/AuthCrypt.cpp +++ b/src/shared/Auth/AuthCrypt.cpp @@ -64,7 +64,7 @@ void AuthCrypt::SetKey(BigNumber *bn) GenerateKey(key, bn); _key.resize(SHA_DIGEST_LENGTH); std::copy(key, key + SHA_DIGEST_LENGTH, _key.begin()); - delete key; + delete[] key; } AuthCrypt::~AuthCrypt() diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 4ada821d6..0008ce903 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7102" + #define REVISION_NR "7103" #endif // __REVISION_NR_H__ From 125416d242f95640f03815296c0a47cd66019ac3 Mon Sep 17 00:00:00 2001 From: ApoC Date: Thu, 15 Jan 2009 19:30:30 +0100 Subject: [PATCH 47/84] [7104] Fixed creatures are not attacking with taunt aura. Improved target selection if more taunt auras are on target. Signed-off-by: ApoC --- src/game/Unit.cpp | 34 ++++++++++++++++++++++++++++++---- src/shared/revision_nr.h | 2 +- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 826a21a3b..65e5a7390 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -9255,20 +9255,46 @@ bool Unit::SelectHostilTarget() //threat list sorting etc. assert(GetTypeId()== TYPEID_UNIT); - Unit* target = NULL; //This function only useful once AI has been initialized if (!((Creature*)this)->AI()) return false; - if(!m_ThreatManager.isThreatListEmpty()) + Unit* target = NULL; + + // First checking if we have some taunt on us + const AuraList& tauntAuras = GetAurasByType(SPELL_AURA_MOD_TAUNT); + if ( !tauntAuras.empty() ) { - if(!HasAuraType(SPELL_AURA_MOD_TAUNT)) + Unit* caster; + + // The last taunt aura caster is alive an we are happy to attack him + if ( (caster = tauntAuras.back()->GetCaster()) && caster->isAlive() ) + return true; + else if (tauntAuras.size() > 1) { - target = m_ThreatManager.getHostilTarget(); + // We do not have last taunt aura caster but we have more taunt auras, + // so find first available target + + // Auras are pushed_back, last caster will be on the end + AuraList::const_iterator aura = --tauntAuras.end(); + do + { + --aura; + if ( (caster = (*aura)->GetCaster()) && + caster->IsInMap(this) && caster->isTargetableForAttack() && caster->isInAccessablePlaceFor(this) ) + { + target = caster; + break; + } + }while (aura != tauntAuras.begin()); } } + if ( !target && !m_ThreatManager.isThreatListEmpty() ) + // No taunt aura or taunt aura caster is dead standart target selection + target = m_ThreatManager.getHostilTarget(); + if(target) { if(!hasUnitState(UNIT_STAT_STUNNED)) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 0008ce903..cd34b43c9 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7103" + #define REVISION_NR "7104" #endif // __REVISION_NR_H__ From 39754133aa79227b929982410d5ad372533c99a0 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Sun, 18 Jan 2009 21:07:45 +0300 Subject: [PATCH 48/84] Code for Diminishing Returns optimize Signed-off-by: DiSlord --- src/game/SpellMgr.cpp | 49 +++++++++++++------------------------------ 1 file changed, 15 insertions(+), 34 deletions(-) diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index cf0cbd65a..009ddf4b1 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -2379,13 +2379,6 @@ DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellEntry const* spellproto // Explicit Diminishing Groups switch(spellproto->SpellFamilyName) { - case SPELLFAMILY_MAGE: - { - // Polymorph - if ((spellproto->SpellFamilyFlags & 0x00001000000LL) && spellproto->EffectApplyAuraName[0]==SPELL_AURA_MOD_CONFUSE) - return DIMINISHING_POLYMORPH; - break; - } case SPELLFAMILY_ROGUE: { // Kidney Shot @@ -2398,9 +2391,6 @@ DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellEntry const* spellproto } case SPELLFAMILY_WARLOCK: { - // Death Coil - if (spellproto->SpellFamilyFlags & 0x00000080000LL) - return DIMINISHING_DEATHCOIL; // Fear else if (spellproto->SpellFamilyFlags & 0x40840000000LL) return DIMINISHING_WARLOCK_FEAR; @@ -2428,30 +2418,21 @@ DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellEntry const* spellproto } // Get by mechanic - for (uint8 i=0;i<3;++i) - { - if (spellproto->Mechanic == MECHANIC_STUN || spellproto->EffectMechanic[i] == MECHANIC_STUN) - return triggered ? DIMINISHING_TRIGGER_STUN : DIMINISHING_CONTROL_STUN; - else if (spellproto->Mechanic == MECHANIC_SLEEP || spellproto->EffectMechanic[i] == MECHANIC_SLEEP) - return DIMINISHING_SLEEP; - else if (spellproto->Mechanic == MECHANIC_ROOT || spellproto->EffectMechanic[i] == MECHANIC_ROOT) - return triggered ? DIMINISHING_TRIGGER_ROOT : DIMINISHING_CONTROL_ROOT; - else if (spellproto->Mechanic == MECHANIC_FEAR || spellproto->EffectMechanic[i] == MECHANIC_FEAR) - return DIMINISHING_FEAR; - else if (spellproto->Mechanic == MECHANIC_CHARM || spellproto->EffectMechanic[i] == MECHANIC_CHARM) - return DIMINISHING_CHARM; - else if (spellproto->Mechanic == MECHANIC_SILENCE || spellproto->EffectMechanic[i] == MECHANIC_SILENCE) - return DIMINISHING_SILENCE; - else if (spellproto->Mechanic == MECHANIC_DISARM || spellproto->EffectMechanic[i] == MECHANIC_DISARM) - return DIMINISHING_DISARM; - else if (spellproto->Mechanic == MECHANIC_FREEZE || spellproto->EffectMechanic[i] == MECHANIC_FREEZE) - return DIMINISHING_FREEZE; - else if (spellproto->Mechanic == MECHANIC_KNOCKOUT|| spellproto->EffectMechanic[i] == MECHANIC_KNOCKOUT || - spellproto->Mechanic == MECHANIC_SAPPED || spellproto->EffectMechanic[i] == MECHANIC_SAPPED) - return DIMINISHING_KNOCKOUT; - else if (spellproto->Mechanic == MECHANIC_BANISH || spellproto->EffectMechanic[i] == MECHANIC_BANISH) - return DIMINISHING_BANISH; - } + uint32 mechanic = GetAllSpellMechanicMask(spellproto); + if (mechanic == MECHANIC_NONE) return DIMINISHING_NONE; + if (mechanic & (1< Date: Sun, 18 Jan 2009 19:37:06 +0100 Subject: [PATCH 49/84] [7105] Compile fix. Signed-off-by: ApoC --- src/game/Unit.cpp | 2 +- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 65e5a7390..6b021721d 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -9282,7 +9282,7 @@ bool Unit::SelectHostilTarget() { --aura; if ( (caster = (*aura)->GetCaster()) && - caster->IsInMap(this) && caster->isTargetableForAttack() && caster->isInAccessablePlaceFor(this) ) + caster->IsInMap(this) && caster->isTargetableForAttack() && caster->isInAccessablePlaceFor((Creature*)this) ) { target = caster; break; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index cd34b43c9..f0965187e 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7104" + #define REVISION_NR "7105" #endif // __REVISION_NR_H__ From e3ccd4b4b7caaa4f311d9937e38d7e83975c4c32 Mon Sep 17 00:00:00 2001 From: ApoC Date: Sun, 18 Jan 2009 19:54:18 +0100 Subject: [PATCH 50/84] [7106] Compile fix. Signed-off-by: ApoC --- src/game/SpellMgr.cpp | 2 +- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 009ddf4b1..47b96539e 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -2392,7 +2392,7 @@ DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellEntry const* spellproto case SPELLFAMILY_WARLOCK: { // Fear - else if (spellproto->SpellFamilyFlags & 0x40840000000LL) + if (spellproto->SpellFamilyFlags & 0x40840000000LL) return DIMINISHING_WARLOCK_FEAR; // Curses/etc else if (spellproto->SpellFamilyFlags & 0x00080000000LL) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index f0965187e..f5c9bcbae 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7105" + #define REVISION_NR "7106" #endif // __REVISION_NR_H__ From 64073f65c0780925ab64faea72d46ac1863eed26 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sun, 18 Jan 2009 22:14:08 +0300 Subject: [PATCH 51/84] [7107] Output skill points (current, max, perm/temp bonus) for known skill in .lookup skill. --- sql/mangos.sql | 9 +++++---- sql/updates/7107_01_mangos_string.sql | 7 +++++++ sql/updates/Makefile.am | 2 ++ src/game/Language.h | 3 ++- src/game/Level3.cpp | 14 ++++++++++++-- src/game/Player.cpp | 16 ++++++++++++++++ src/game/Player.h | 3 ++- src/shared/revision_nr.h | 2 +- 8 files changed, 47 insertions(+), 9 deletions(-) create mode 100644 sql/updates/7107_01_mangos_string.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index 04f5babd9..8d4088f95 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -22,7 +22,7 @@ DROP TABLE IF EXISTS `db_version`; CREATE TABLE `db_version` ( `version` varchar(120) default NULL, - `required_7097_01_mangos_spell_proc_event` bit(1) default NULL + `required_7107_01_mangos_string` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -2661,7 +2661,7 @@ INSERT INTO `mangos_string` VALUES (518,'%d - |cffffffff|Hitemset:%d|h[%s %s]|h|r ',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (519,'|cffffffff|Htele:%s|h[%s]|h|r ',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (520,'%d - |cffffffff|Hspell:%d|h[%s]|h|r ',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), -(521,'%d - |cffffffff|Hskill:%d|h[%s %s]|h|r %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(521,'%d - |cffffffff|Hskill:%d|h[%s %s]|h|r %s %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (522,'Game Object (GUID: %u) not found',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (523,'>> Game Object %s (GUID: %u) at %f %f %f. Orientation %f.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (524,'Selected object:\n|cffffffff|Hitemset:%d|h[%s]|h|r\nGUID: %u ID: %u\nX: %f Y: %f Z: %f MapId: %u\nOrientation: %f',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), @@ -2841,7 +2841,7 @@ INSERT INTO `mangos_string` VALUES (1106,'%d - %s %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1107,'%d - %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1108,'%d - %s %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), -(1109,'%d - %s %s %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1109,'%d - %s %s %s %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1110,'%d - %s X:%f Y:%f Z:%f MapId:%d',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1111,'%d - %s X:%f Y:%f Z:%f MapId:%d',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1112,'Failed to open file: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), @@ -2853,7 +2853,8 @@ INSERT INTO `mangos_string` VALUES (1118,'%d - guild: %s (guid: %u) %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1119,'You must use male or female as gender.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1120,'You change gender of %s to %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), -(1121,'Your gender changed to %s by %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); +(1121,'Your gender changed to %s by %s.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1122,'(%u/%u +perm %u +temp %u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); /*!40000 ALTER TABLE `mangos_string` ENABLE KEYS */; UNLOCK TABLES; diff --git a/sql/updates/7107_01_mangos_string.sql b/sql/updates/7107_01_mangos_string.sql new file mode 100644 index 000000000..bd4ee1ce6 --- /dev/null +++ b/sql/updates/7107_01_mangos_string.sql @@ -0,0 +1,7 @@ +ALTER TABLE db_version CHANGE COLUMN required_7097_01_mangos_spell_proc_event required_7107_01_mangos_string bit; + +DELETE FROM `mangos_string` WHERE `entry` IN (521,1109,1122); +INSERT INTO `mangos_string` VALUES +(521,'%d - |cffffffff|Hskill:%d|h[%s %s]|h|r %s %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1109,'%d - %s %s %s %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1122,'(%u/%u +perm %u +temp %u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 0c540440c..d8fed763e 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -140,6 +140,7 @@ pkgdata_DATA = \ 7092_01_mangos_player_xp_for_level.sql \ 7097_01_mangos_spell_proc_event.sql \ 7100_01_characters_character_spell.sql \ + 7107_01_mangos_string.sql \ README ## Additional files to include when running 'make dist' @@ -260,4 +261,5 @@ EXTRA_DIST = \ 7092_01_mangos_player_xp_for_level.sql \ 7097_01_mangos_spell_proc_event.sql \ 7100_01_characters_character_spell.sql \ + 7107_01_mangos_string.sql \ README diff --git a/src/game/Language.h b/src/game/Language.h index 207361889..4bb924f89 100644 --- a/src/game/Language.h +++ b/src/game/Language.h @@ -723,7 +723,8 @@ enum MangosStrings LANG_MUST_MALE_OR_FEMALE = 1119, LANG_YOU_CHANGE_GENDER = 1120, LANG_YOUR_GENDER_CHANGED = 1121, - // Room for more level 3 1122-1199 not used + LANG_SKILL_VALUES = 1122, + // Room for more level 3 1123-1199 not used // FREE IDS 1200-9999 diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 0323b09af..83f1ad0be 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -2632,15 +2632,25 @@ bool ChatHandler::HandleLookupSkillCommand(const char* args) if(loc < MAX_LOCALE) { + char valStr[50] = ""; char const* knownStr = ""; if(target && target->HasSkill(id)) + { knownStr = GetMangosString(LANG_KNOWN); + uint32 curValue = target->GetPureSkillValue(id); + uint32 maxValue = target->GetPureMaxSkillValue(id); + uint32 permValue = target->GetSkillPermBonusValue(id); + uint32 tempValue = target->GetSkillTempBonusValue(id); + + char const* valFormat = GetMangosString(LANG_SKILL_VALUES); + snprintf(valStr,50,valFormat,curValue,maxValue,permValue,tempValue); + } // send skill in "id - [namedlink locale]" format if (m_session) - PSendSysMessage(LANG_SKILL_LIST_CHAT,id,id,name.c_str(),localeNames[loc],knownStr); + PSendSysMessage(LANG_SKILL_LIST_CHAT,id,id,name.c_str(),localeNames[loc],knownStr,valStr); else - PSendSysMessage(LANG_SKILL_LIST_CONSOLE,id,name.c_str(),localeNames[loc],knownStr); + PSendSysMessage(LANG_SKILL_LIST_CONSOLE,id,name.c_str(),localeNames[loc],knownStr,valStr); ++counter; } diff --git a/src/game/Player.cpp b/src/game/Player.cpp index f9ce04983..995e4a43b 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -5134,6 +5134,22 @@ uint16 Player::GetPureSkillValue(uint32 skill) const return 0; } +int16 Player::GetSkillPermBonusValue(uint32 skill) const +{ + if(!skill) + return 0; + + for (int i = 0; i < PLAYER_MAX_SKILLS; i++) + { + if ((GetUInt32Value(PLAYER_SKILL_INDEX(i)) & 0x0000FFFF) == skill) + { + return SKILL_PERM_BONUS(GetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i))); + } + } + + return 0; +} + int16 Player::GetSkillTempBonusValue(uint32 skill) const { if(!skill) diff --git a/src/game/Player.h b/src/game/Player.h index 62ddf8e11..ff844d457 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1764,11 +1764,12 @@ class MANGOS_DLL_SPEC Player : public Unit void UpdateCombatSkills(Unit *pVictim, WeaponAttackType attType, bool defence); void SetSkill(uint32 id, uint16 currVal, uint16 maxVal); - uint16 GetMaxSkillValue(uint32 skill) const; // max + perm. bonus + uint16 GetMaxSkillValue(uint32 skill) const; // max + perm. bonus + temp bonus uint16 GetPureMaxSkillValue(uint32 skill) const; // max uint16 GetSkillValue(uint32 skill) const; // skill value + perm. bonus + temp bonus uint16 GetBaseSkillValue(uint32 skill) const; // skill value + perm. bonus uint16 GetPureSkillValue(uint32 skill) const; // skill value + int16 GetSkillPermBonusValue(uint32 skill) const; int16 GetSkillTempBonusValue(uint32 skill) const; bool HasSkill(uint32 skill) const; void learnSkillRewardedSpells( uint32 id ); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index f5c9bcbae..baeed9a4b 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7106" + #define REVISION_NR "7107" #endif // __REVISION_NR_H__ From 148b7fd3ab7ab5e06577d52f84013f21e1c676c4 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sun, 18 Jan 2009 22:15:14 +0300 Subject: [PATCH 52/84] [7108] Allow use shift-links to creature entries (from .lookup creature) in .npc add command. --- src/game/Level2.cpp | 4 ++-- src/shared/revision_nr.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index 6ea8c6b6d..1e6172b74 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -854,8 +854,8 @@ bool ChatHandler::HandleNpcAddCommand(const char* args) { if(!*args) return false; - char* charID = strtok((char*)args, " "); - if (!charID) + char* charID = extractKeyFromLink((char*)args,"Hcreature_entry"); + if(!charID) return false; char* team = strtok(NULL, " "); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index baeed9a4b..a5991c21b 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7107" + #define REVISION_NR "7108" #endif // __REVISION_NR_H__ From a5e948280b1ad3465ecdf95a91f67ed0e8d2d782 Mon Sep 17 00:00:00 2001 From: GriffonHeart Date: Sun, 18 Jan 2009 22:34:45 +0300 Subject: [PATCH 53/84] [7109] Correct show percentes at DBC loading. Signed-off-by: VladimirMangos --- src/shared/Database/DBCStores.cpp | 2 +- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shared/Database/DBCStores.cpp b/src/shared/Database/DBCStores.cpp index 61278032b..b10d89959 100644 --- a/src/shared/Database/DBCStores.cpp +++ b/src/shared/Database/DBCStores.cpp @@ -190,7 +190,7 @@ void LoadDBCStores(const std::string& dataPath) { std::string dbcPath = dataPath+"dbc/"; - const uint32 DBCFilesCount = 66; + const uint32 DBCFilesCount = 69; barGoLink bar( DBCFilesCount ); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index a5991c21b..63e6699f2 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7108" + #define REVISION_NR "7109" #endif // __REVISION_NR_H__ From c4dba30b516ad03774f1d5a6e1746b186ebd3493 Mon Sep 17 00:00:00 2001 From: ApoC Date: Sun, 18 Jan 2009 20:12:27 +0100 Subject: [PATCH 54/84] Use configuration values for arena directly instead of values cached in local variables. This should fix reloading arena configuration in runtime. Signed-off-by: ApoC --- src/game/BattleGroundMgr.cpp | 19 ++++++------------- src/game/BattleGroundMgr.h | 12 ++++-------- 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/src/game/BattleGroundMgr.cpp b/src/game/BattleGroundMgr.cpp index fe97ecca3..c4cef984b 100644 --- a/src/game/BattleGroundMgr.cpp +++ b/src/game/BattleGroundMgr.cpp @@ -37,7 +37,6 @@ #include "MapInstanced.h" #include "ObjectMgr.h" #include "ProgressBar.h" -#include "World.h" #include "Chat.h" #include "ArenaTeam.h" @@ -1075,16 +1074,10 @@ void BGQueueRemoveEvent::Abort(uint64 /*e_time*/) /*** BATTLEGROUND MANAGER ***/ /*********************************************************/ -BattleGroundMgr::BattleGroundMgr() +BattleGroundMgr::BattleGroundMgr() : m_AutoDistributionTimeChecker(0), m_ArenaTesting(false) { m_BattleGrounds.clear(); - m_AutoDistributePoints = (bool)sWorld.getConfig(CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS); - m_MaxRatingDifference = sWorld.getConfig(CONFIG_ARENA_MAX_RATING_DIFFERENCE); - m_RatingDiscardTimer = sWorld.getConfig(CONFIG_ARENA_RATING_DISCARD_TIMER); - m_PrematureFinishTimer = sWorld.getConfig(CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER); - m_NextRatingDiscardUpdate = m_RatingDiscardTimer; - m_AutoDistributionTimeChecker = 0; - m_ArenaTesting = false; + m_NextRatingDiscardUpdate = sWorld.getConfig(CONFIG_ARENA_RATING_DISCARD_TIMER); } BattleGroundMgr::~BattleGroundMgr() @@ -1120,7 +1113,7 @@ void BattleGroundMgr::Update(time_t diff) } } // if rating difference counts, maybe force-update queues - if(m_MaxRatingDifference) + if(sWorld.getConfig(CONFIG_ARENA_MAX_RATING_DIFFERENCE)) { // it's time to force update if(m_NextRatingDiscardUpdate < diff) @@ -1129,12 +1122,12 @@ void BattleGroundMgr::Update(time_t diff) m_BattleGroundQueues[BATTLEGROUND_QUEUE_2v2].Update(BATTLEGROUND_AA,6,ARENA_TYPE_2v2,true,0); m_BattleGroundQueues[BATTLEGROUND_QUEUE_3v3].Update(BATTLEGROUND_AA,6,ARENA_TYPE_3v3,true,0); m_BattleGroundQueues[BATTLEGROUND_QUEUE_5v5].Update(BATTLEGROUND_AA,6,ARENA_TYPE_5v5,true,0); - m_NextRatingDiscardUpdate = m_RatingDiscardTimer; + m_NextRatingDiscardUpdate = sWorld.getConfig(CONFIG_ARENA_RATING_DISCARD_TIMER); } else m_NextRatingDiscardUpdate -= diff; } - if(m_AutoDistributePoints) + if(sWorld.getConfig(CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS)) { if(m_AutoDistributionTimeChecker < diff) { @@ -1692,7 +1685,7 @@ void BattleGroundMgr::CreateInitialBattleGrounds() void BattleGroundMgr::InitAutomaticArenaPointDistribution() { - if(m_AutoDistributePoints) + if(sWorld.getConfig(CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS)) { sLog.outDebug("Initializing Automatic Arena Point Distribution"); QueryResult * result = CharacterDatabase.Query("SELECT NextArenaPointDistributionTime FROM saved_variables"); diff --git a/src/game/BattleGroundMgr.h b/src/game/BattleGroundMgr.h index ad11436fc..01f751020 100644 --- a/src/game/BattleGroundMgr.h +++ b/src/game/BattleGroundMgr.h @@ -20,7 +20,7 @@ #define __BATTLEGROUNDMGR_H #include "BattleGround.h" -#include "Policies/Singleton.h" +#include "World.h" class BattleGround; @@ -225,12 +225,12 @@ class BattleGroundMgr uint32 BGTemplateId(uint32 bgQueueTypeId) const; uint8 BGArenaType(uint32 bgQueueTypeId) const; - uint32 GetMaxRatingDifference() const {return m_MaxRatingDifference;} - uint32 GetRatingDiscardTimer() const {return m_RatingDiscardTimer;} + uint32 GetMaxRatingDifference() const {return sWorld.getConfig(CONFIG_ARENA_MAX_RATING_DIFFERENCE);} + uint32 GetRatingDiscardTimer() const {return sWorld.getConfig(CONFIG_ARENA_RATING_DISCARD_TIMER);} void InitAutomaticArenaPointDistribution(); void DistributeArenaPoints(); - uint32 GetPrematureFinishTime() const {return m_PrematureFinishTimer;} + uint32 GetPrematureFinishTime() const {return sWorld.getConfig(CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER);} void ToggleArenaTesting(); const bool isArenaTesting() const { return m_ArenaTesting; } @@ -238,13 +238,9 @@ class BattleGroundMgr /* Battlegrounds */ BattleGroundSet m_BattleGrounds; - uint32 m_MaxRatingDifference; - uint32 m_RatingDiscardTimer; uint32 m_NextRatingDiscardUpdate; - bool m_AutoDistributePoints; uint64 m_NextAutoDistributionTime; uint32 m_AutoDistributionTimeChecker; - uint32 m_PrematureFinishTimer; bool m_ArenaTesting; }; From aa2a454ca184eb128e7d95beb655f222ee8ce674 Mon Sep 17 00:00:00 2001 From: ApoC Date: Sun, 18 Jan 2009 20:27:26 +0100 Subject: [PATCH 55/84] Little clean up in BattleGroundMgr.h Changed uint64 in method parameters to be passed by const reference. Signed-off-by: ApoC --- src/game/BattleGroundMgr.cpp | 4 ++-- src/game/BattleGroundMgr.h | 26 +++++++++++++------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/game/BattleGroundMgr.cpp b/src/game/BattleGroundMgr.cpp index c4cef984b..b8a923f17 100644 --- a/src/game/BattleGroundMgr.cpp +++ b/src/game/BattleGroundMgr.cpp @@ -1754,7 +1754,7 @@ void BattleGroundMgr::DistributeArenaPoints() sWorld.SendGlobalText("Done flushing Arena points.", NULL); } -void BattleGroundMgr::BuildBattleGroundListPacket(WorldPacket *data, uint64 guid, Player* plr, uint32 bgTypeId) +void BattleGroundMgr::BuildBattleGroundListPacket(WorldPacket *data, const uint64& guid, Player* plr, uint32 bgTypeId) { uint32 PlayerLevel = 10; @@ -1810,7 +1810,7 @@ void BattleGroundMgr::SendToBattleGround(Player *pl, uint32 instanceId) } } -void BattleGroundMgr::SendAreaSpiritHealerQueryOpcode(Player *pl, BattleGround *bg, uint64 guid) +void BattleGroundMgr::SendAreaSpiritHealerQueryOpcode(Player *pl, BattleGround *bg, const uint64& guid) { WorldPacket data(SMSG_AREA_SPIRIT_HEALER_TIME, 12); uint32 time_ = 30000 - bg->GetLastResurrectTime(); // resurrect every 30 seconds diff --git a/src/game/BattleGroundMgr.h b/src/game/BattleGroundMgr.h index 01f751020..ebd6522da 100644 --- a/src/game/BattleGroundMgr.h +++ b/src/game/BattleGroundMgr.h @@ -153,7 +153,10 @@ class BGQueueInviteEvent : public BasicEvent class BGQueueRemoveEvent : public BasicEvent { public: - BGQueueRemoveEvent(uint64 pl_guid, uint32 bgInstanceGUID, uint32 playersTeam) : m_PlayerGuid(pl_guid), m_BgInstanceGUID(bgInstanceGUID), m_PlayersTeam(playersTeam) {}; + BGQueueRemoveEvent(const uint64& pl_guid, uint32 bgInstanceGUID, uint32 playersTeam) : + m_PlayerGuid(pl_guid), m_BgInstanceGUID(bgInstanceGUID), m_PlayersTeam(playersTeam) + { + }; virtual ~BGQueueRemoveEvent() {}; virtual bool Execute(uint64 e_time, uint32 p_time); @@ -175,28 +178,26 @@ class BattleGroundMgr /* Packet Building */ void BuildPlayerJoinedBattleGroundPacket(WorldPacket *data, Player *plr); void BuildPlayerLeftBattleGroundPacket(WorldPacket *data, Player *plr); - void BuildBattleGroundListPacket(WorldPacket *data, uint64 guid, Player *plr, uint32 bgTypeId); + void BuildBattleGroundListPacket(WorldPacket *data, const uint64& guid, Player *plr, uint32 bgTypeId); void BuildGroupJoinedBattlegroundPacket(WorldPacket *data, uint32 bgTypeId); void BuildUpdateWorldStatePacket(WorldPacket *data, uint32 field, uint32 value); void BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg); void BuildBattleGroundStatusPacket(WorldPacket *data, BattleGround *bg, uint32 team, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2, uint32 arenatype = 0, uint8 israted = 0); void BuildPlaySoundPacket(WorldPacket *data, uint32 soundid); + void SendAreaSpiritHealerQueryOpcode(Player *pl, BattleGround *bg, const uint64& guid); /* Player invitation */ // called from Queue update, or from Addplayer to queue void InvitePlayer(Player* plr, uint32 bgInstanceGUID, uint32 team); /* Battlegrounds */ BattleGroundSet::iterator GetBattleGroundsBegin() { return m_BattleGrounds.begin(); }; - BattleGroundSet::iterator GetBattleGroundsEnd() { return m_BattleGrounds.end(); }; + BattleGroundSet::iterator GetBattleGroundsEnd() { return m_BattleGrounds.end(); }; BattleGround* GetBattleGround(uint32 ID) { BattleGroundSet::iterator i = m_BattleGrounds.find(ID); - if(i != m_BattleGrounds.end()) - return i->second; - else - return NULL; + return ( (i != m_BattleGrounds.end()) ? i->second : NULL ); }; BattleGround * GetBattleGroundTemplate(uint32 bgTypeId); @@ -217,22 +218,21 @@ class BattleGroundMgr BGFreeSlotQueueType BGFreeSlotQueue[MAX_BATTLEGROUND_TYPES]; - void SendAreaSpiritHealerQueryOpcode(Player *pl, BattleGround *bg, uint64 guid); - bool IsArenaType(uint32 bgTypeId) const; bool IsBattleGroundType(uint32 bgTypeId) const; uint32 BGQueueTypeId(uint32 bgTypeId, uint8 arenaType) const; uint32 BGTemplateId(uint32 bgQueueTypeId) const; uint8 BGArenaType(uint32 bgQueueTypeId) const; - uint32 GetMaxRatingDifference() const {return sWorld.getConfig(CONFIG_ARENA_MAX_RATING_DIFFERENCE);} - uint32 GetRatingDiscardTimer() const {return sWorld.getConfig(CONFIG_ARENA_RATING_DISCARD_TIMER);} + uint32 GetMaxRatingDifference() const { return sWorld.getConfig(CONFIG_ARENA_MAX_RATING_DIFFERENCE); } + uint32 GetRatingDiscardTimer() const { return sWorld.getConfig(CONFIG_ARENA_RATING_DISCARD_TIMER); } + uint32 GetPrematureFinishTime() const { return sWorld.getConfig(CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER); } void InitAutomaticArenaPointDistribution(); void DistributeArenaPoints(); - uint32 GetPrematureFinishTime() const {return sWorld.getConfig(CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER);} void ToggleArenaTesting(); - const bool isArenaTesting() const { return m_ArenaTesting; } + + bool isArenaTesting() const { return m_ArenaTesting; } private: From 5d63453deb0323556f493151a67e476ec85764de Mon Sep 17 00:00:00 2001 From: ApoC Date: Sun, 18 Jan 2009 20:32:05 +0100 Subject: [PATCH 56/84] BattleGroundMgr::RemoveBattleGround inlined. Signed-off-by: ApoC --- src/game/BattleGroundMgr.cpp | 11 ++--------- src/game/BattleGroundMgr.h | 8 ++++---- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/game/BattleGroundMgr.cpp b/src/game/BattleGroundMgr.cpp index b8a923f17..293bb2463 100644 --- a/src/game/BattleGroundMgr.cpp +++ b/src/game/BattleGroundMgr.cpp @@ -245,7 +245,7 @@ void BattleGroundQueue::AddPlayer(Player *plr, GroupQueueInfo *ginfo) ginfo->Players[plr->GetGUID()] = &info; } -void BattleGroundQueue::RemovePlayer(uint64 guid, bool decreaseInvitedCount) +void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCount) { Player *plr = objmgr.GetPlayer(guid); @@ -361,7 +361,7 @@ void BattleGroundQueue::RemovePlayer(uint64 guid, bool decreaseInvitedCount) } } -void BattleGroundQueue::AnnounceWorld(GroupQueueInfo *ginfo, uint64 playerGUID, bool isAddedToQueue) +void BattleGroundQueue::AnnounceWorld(GroupQueueInfo *ginfo, const uint64& playerGUID, bool isAddedToQueue) { if(ginfo->ArenaType) //if Arena @@ -1820,13 +1820,6 @@ void BattleGroundMgr::SendAreaSpiritHealerQueryOpcode(Player *pl, BattleGround * pl->GetSession()->SendPacket(&data); } -void BattleGroundMgr::RemoveBattleGround(uint32 instanceID) -{ - BattleGroundSet::iterator itr = m_BattleGrounds.find(instanceID); - if(itr!=m_BattleGrounds.end()) - m_BattleGrounds.erase(itr); -} - bool BattleGroundMgr::IsArenaType(uint32 bgTypeId) const { return ( bgTypeId == BATTLEGROUND_AA || diff --git a/src/game/BattleGroundMgr.h b/src/game/BattleGroundMgr.h index ebd6522da..62c79c9ec 100644 --- a/src/game/BattleGroundMgr.h +++ b/src/game/BattleGroundMgr.h @@ -72,10 +72,10 @@ class BattleGroundQueue GroupQueueInfo * AddGroup(Player * leader, uint32 BgTypeId, uint8 ArenaType, bool isRated, uint32 ArenaRating, uint32 ArenaTeamId = 0); void AddPlayer(Player *plr, GroupQueueInfo *ginfo); - void RemovePlayer(uint64 guid, bool decreaseInvitedCount); + void RemovePlayer(const uint64& guid, bool decreaseInvitedCount); void DecreaseGroupLength(uint32 queueId, uint32 AsGroup); void BGEndedRemoveInvites(BattleGround * bg); - void AnnounceWorld(GroupQueueInfo *ginfo, uint64 playerGUID, bool isAddedToQueue); + void AnnounceWorld(GroupQueueInfo *ginfo, const uint64& playerGUID, bool isAddedToQueue); typedef std::map QueuedPlayersMap; QueuedPlayersMap m_QueuedPlayers[MAX_BATTLEGROUND_QUEUES]; @@ -137,7 +137,7 @@ class BattleGroundQueue class BGQueueInviteEvent : public BasicEvent { public: - BGQueueInviteEvent(uint64 pl_guid, uint32 BgInstanceGUID) : m_PlayerGuid(pl_guid), m_BgInstanceGUID(BgInstanceGUID) {}; + BGQueueInviteEvent(const uint64& pl_guid, uint32 BgInstanceGUID) : m_PlayerGuid(pl_guid), m_BgInstanceGUID(BgInstanceGUID) {}; virtual ~BGQueueInviteEvent() {}; virtual bool Execute(uint64 e_time, uint32 p_time); @@ -206,7 +206,7 @@ class BattleGroundMgr uint32 CreateBattleGround(uint32 bgTypeId, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam, uint32 LevelMin, uint32 LevelMax, char* BattleGroundName, uint32 MapID, float Team1StartLocX, float Team1StartLocY, float Team1StartLocZ, float Team1StartLocO, float Team2StartLocX, float Team2StartLocY, float Team2StartLocZ, float Team2StartLocO); inline void AddBattleGround(uint32 ID, BattleGround* BG) { m_BattleGrounds[ID] = BG; }; - void RemoveBattleGround(uint32 instanceID); + inline void RemoveBattleGround(uint32 instanceID) { m_BattleGrounds.erase(instanceID); } void CreateInitialBattleGrounds(); From d469a604eb27ed816219a197b7642bbb687e4c39 Mon Sep 17 00:00:00 2001 From: ApoC Date: Sun, 18 Jan 2009 21:13:22 +0100 Subject: [PATCH 57/84] [7110] Make some methods in BattleGroundMgr static. Signed-off-by: ApoC --- src/game/BattleGround.cpp | 8 +- src/game/BattleGroundHandler.cpp | 16 ++-- src/game/BattleGroundMgr.cpp | 127 +++++++++++++++---------------- src/game/BattleGroundMgr.h | 11 ++- src/shared/revision_nr.h | 2 +- 5 files changed, 79 insertions(+), 85 deletions(-) diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp index 24b64ad22..6962bd69c 100644 --- a/src/game/BattleGround.cpp +++ b/src/game/BattleGround.cpp @@ -552,7 +552,7 @@ void BattleGround::EndBattleGround(uint32 winner) sBattleGroundMgr.BuildPvpLogDataPacket(&data, this); plr->GetSession()->SendPacket(&data); - uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(GetTypeID(), GetArenaType()); + uint32 bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType()); sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime()); plr->GetSession()->SendPacket(&data); plr->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, 1); @@ -573,7 +573,7 @@ void BattleGround::EndBattleGround(uint32 winner) } // inform invited players about the removal - sBattleGroundMgr.m_BattleGroundQueues[sBattleGroundMgr.BGQueueTypeId(GetTypeID(), GetArenaType())].BGEndedRemoveInvites(this); + sBattleGroundMgr.m_BattleGroundQueues[BattleGroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType())].BGEndedRemoveInvites(this); if(Source) { @@ -769,7 +769,7 @@ void BattleGround::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac if(!team) team = plr->GetTeam(); uint32 bgTypeId = GetTypeID(); - uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(GetTypeID(), GetArenaType()); + uint32 bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType()); // if arena, remove the specific arena auras if(isArena()) { @@ -1403,7 +1403,7 @@ void BattleGround::EndNow() SetStatus(STATUS_WAIT_LEAVE); SetEndTime(TIME_TO_AUTOREMOVE); // inform invited players about the removal - sBattleGroundMgr.m_BattleGroundQueues[sBattleGroundMgr.BGQueueTypeId(GetTypeID(), GetArenaType())].BGEndedRemoveInvites(this); + sBattleGroundMgr.m_BattleGroundQueues[BattleGroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType())].BGEndedRemoveInvites(this); } // Battleground messages are localized using the dbc lang, they are not client language dependent diff --git a/src/game/BattleGroundHandler.cpp b/src/game/BattleGroundHandler.cpp index 323ec1a73..0158cd36b 100644 --- a/src/game/BattleGroundHandler.cpp +++ b/src/game/BattleGroundHandler.cpp @@ -94,7 +94,7 @@ void WorldSession::HandleBattleGroundJoinOpcode( WorldPacket & recv_data ) sLog.outDebug( "WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from: " I64FMT, guid); // can do this, since it's battleground, not arena - uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bgTypeId, 0); + uint32 bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, 0); // ignore if player is already in BG if(_player->InBattleGround()) @@ -368,7 +368,7 @@ void WorldSession::HandleBattleGroundPlayerPortOpcode( WorldPacket &recv_data ) uint32 bgQueueTypeId = 0; // get the bg what we were invited to BattleGroundQueue::QueuedPlayersMap::iterator itrPlayerStatus; - bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bgTypeId,type); + bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId,type); itrPlayerStatus = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers[_player->GetBattleGroundQueueIdFromLevel()].find(_player->GetGUID()); if(itrPlayerStatus == sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].m_QueuedPlayers[_player->GetBattleGroundQueueIdFromLevel()].end()) @@ -529,7 +529,7 @@ void WorldSession::HandleBattlefieldStatusOpcode( WorldPacket & /*recv_data*/ ) BattleGround *bg = _player->GetBattleGround(); if(bg) { - uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType()); + uint32 bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType()); uint32 queueSlot = _player->GetBattleGroundQueueIndex(bgQueueTypeId); if((bg->GetStatus() <= STATUS_IN_PROGRESS)) { @@ -539,7 +539,7 @@ void WorldSession::HandleBattlefieldStatusOpcode( WorldPacket & /*recv_data*/ ) for (uint32 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; i++) { uint32 queue_id = _player->GetBattleGroundQueueId(i); // battlegroundqueueid stores the type id, not the instance id, so this is definitely wrong - uint8 arenatype = sBattleGroundMgr.BGArenaType(queue_id); + uint8 arenatype = BattleGroundMgr::BGArenaType(queue_id); uint8 isRated = 0; if (i == queueSlot || !queue_id) // we need to get the instance ids continue; @@ -551,7 +551,7 @@ void WorldSession::HandleBattlefieldStatusOpcode( WorldPacket & /*recv_data*/ ) arenatype = itrPlayerStatus->second.GroupInfo->ArenaType; isRated = itrPlayerStatus->second.GroupInfo->IsRated; } - BattleGround *bg2 = sBattleGroundMgr.GetBattleGroundTemplate(sBattleGroundMgr.BGTemplateId(queue_id)); // try this + BattleGround *bg2 = sBattleGroundMgr.GetBattleGroundTemplate(BattleGroundMgr::BGTemplateId(queue_id)); // try this if(bg2) { //in this call is small bug, this call should be filled by player's waiting time in queue @@ -570,8 +570,8 @@ void WorldSession::HandleBattlefieldStatusOpcode( WorldPacket & /*recv_data*/ ) uint32 queue_id = _player->GetBattleGroundQueueId(i); if(!queue_id) continue; - uint32 bgTypeId = sBattleGroundMgr.BGTemplateId(queue_id); - uint8 arenatype = sBattleGroundMgr.BGArenaType(queue_id); + uint32 bgTypeId = BattleGroundMgr::BGTemplateId(queue_id); + uint8 arenatype = BattleGroundMgr::BGArenaType(queue_id); uint8 isRated = 0; BattleGround *bg = sBattleGroundMgr.GetBattleGroundTemplate(bgTypeId); BattleGroundQueue::QueuedPlayersMap::iterator itrPlayerStatus = sBattleGroundMgr.m_BattleGroundQueues[queue_id].m_QueuedPlayers[_player->GetBattleGroundQueueIdFromLevel()].find(_player->GetGUID()); @@ -699,7 +699,7 @@ void WorldSession::HandleBattleGroundArenaJoin( WorldPacket & recv_data ) } uint8 bgTypeId = bg->GetTypeID(); - uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bgTypeId, arenatype); + uint32 bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, arenatype); // check queueing conditions if(!asGroup) diff --git a/src/game/BattleGroundMgr.cpp b/src/game/BattleGroundMgr.cpp index 293bb2463..c21af527c 100644 --- a/src/game/BattleGroundMgr.cpp +++ b/src/game/BattleGroundMgr.cpp @@ -348,7 +348,7 @@ void BattleGroundQueue::RemovePlayer(const uint64& guid, bool decreaseInvitedCou if(Player *plr2 = objmgr.GetPlayer(group->Players.begin()->first)) { BattleGround * bg = sBattleGroundMgr.GetBattleGroundTemplate(group->BgTypeId); - uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(group->BgTypeId,group->ArenaType); + uint32 bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(group->BgTypeId,group->ArenaType); uint32 queueSlot = plr2->GetBattleGroundQueueIndex(bgQueueTypeId); plr2->RemoveBattleGroundQueueId(bgQueueTypeId); // must be called this way, because if you move this call to queue->removeplayer, it causes bugs WorldPacket data; @@ -451,7 +451,7 @@ bool BattleGroundQueue::InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * b // not yet invited // set invitation ginfo->IsInvitedToBGInstanceGUID = bg->GetInstanceID(); - uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType()); + uint32 bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType()); // loop through the players for(std::map::iterator itr = ginfo->Players.begin(); itr != ginfo->Players.end(); ++itr) { @@ -546,7 +546,7 @@ void BattleGroundQueue::BGEndedRemoveInvites(BattleGround *bg) { uint32 queue_id = bg->GetQueueType(); uint32 bgInstanceId = bg->GetInstanceID(); - uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType()); + uint32 bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType()); QueuedGroupsList::iterator itr, next; for(itr = m_QueuedGroups[queue_id].begin(); itr != m_QueuedGroups[queue_id].end(); itr = next) { @@ -616,7 +616,7 @@ void BattleGroundQueue::Update(uint32 bgTypeId, uint32 queue_id, uint8 arenatype if (m_QueuedGroups[queue_id].empty()) return; - uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bgTypeId, arenatype); + uint32 bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bgTypeId, arenatype); //battleground with free slot for player should be always the last in this queue BGFreeSlotQueueType::iterator itr, next; @@ -994,7 +994,7 @@ bool BGQueueInviteEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) uint32 queueSlot = plr->GetBattleGroundQueueIndex(bg->GetTypeID()); if (queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES) // player is in queue { - uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType()); + uint32 bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType()); uint32 queueSlot = plr->GetBattleGroundQueueIndex(bgQueueTypeId); if (queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES) // player is in queue { @@ -1031,7 +1031,7 @@ bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) sLog.outDebug("Battleground: removing player %u from bg queue for instance %u because of not pressing enter battle in time.",plr->GetGUIDLow(),m_BgInstanceGUID); - uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType()); + uint32 bgQueueTypeId = BattleGroundMgr::BGQueueTypeId(bg->GetTypeID(), bg->GetArenaType()); uint32 queueSlot = plr->GetBattleGroundQueueIndex(bgQueueTypeId); if (queueSlot < PLAYER_MAX_BATTLEGROUND_QUEUES) // player is in queue { @@ -1820,7 +1820,7 @@ void BattleGroundMgr::SendAreaSpiritHealerQueryOpcode(Player *pl, BattleGround * pl->GetSession()->SendPacket(&data); } -bool BattleGroundMgr::IsArenaType(uint32 bgTypeId) const +bool BattleGroundMgr::IsArenaType(uint32 bgTypeId) { return ( bgTypeId == BATTLEGROUND_AA || bgTypeId == BATTLEGROUND_BE || @@ -1828,82 +1828,77 @@ bool BattleGroundMgr::IsArenaType(uint32 bgTypeId) const bgTypeId == BATTLEGROUND_RL ); } -bool BattleGroundMgr::IsBattleGroundType(uint32 bgTypeId) const -{ - return !IsArenaType(bgTypeId); -} - -uint32 BattleGroundMgr::BGQueueTypeId(uint32 bgTypeId, uint8 arenaType) const +uint32 BattleGroundMgr::BGQueueTypeId(uint32 bgTypeId, uint8 arenaType) { switch(bgTypeId) { - case BATTLEGROUND_WS: - return BATTLEGROUND_QUEUE_WS; - case BATTLEGROUND_AB: - return BATTLEGROUND_QUEUE_AB; - case BATTLEGROUND_AV: - return BATTLEGROUND_QUEUE_AV; - case BATTLEGROUND_EY: - return BATTLEGROUND_QUEUE_EY; - case BATTLEGROUND_SA: - return BATTLEGROUND_QUEUE_SA; - case BATTLEGROUND_AA: - case BATTLEGROUND_NA: - case BATTLEGROUND_RL: - case BATTLEGROUND_BE: - case BATTLEGROUND_DS: - case BATTLEGROUND_RV: - switch(arenaType) - { - case ARENA_TYPE_2v2: - return BATTLEGROUND_QUEUE_2v2; - case ARENA_TYPE_3v3: - return BATTLEGROUND_QUEUE_3v3; - case ARENA_TYPE_5v5: - return BATTLEGROUND_QUEUE_5v5; + case BATTLEGROUND_WS: + return BATTLEGROUND_QUEUE_WS; + case BATTLEGROUND_AB: + return BATTLEGROUND_QUEUE_AB; + case BATTLEGROUND_AV: + return BATTLEGROUND_QUEUE_AV; + case BATTLEGROUND_EY: + return BATTLEGROUND_QUEUE_EY; + case BATTLEGROUND_SA: + return BATTLEGROUND_QUEUE_SA; + case BATTLEGROUND_AA: + case BATTLEGROUND_NA: + case BATTLEGROUND_RL: + case BATTLEGROUND_BE: + case BATTLEGROUND_DS: + case BATTLEGROUND_RV: + switch(arenaType) + { + case ARENA_TYPE_2v2: + return BATTLEGROUND_QUEUE_2v2; + case ARENA_TYPE_3v3: + return BATTLEGROUND_QUEUE_3v3; + case ARENA_TYPE_5v5: + return BATTLEGROUND_QUEUE_5v5; + default: + return 0; + } default: return 0; - } - default: - return 0; } } -uint32 BattleGroundMgr::BGTemplateId(uint32 bgQueueTypeId) const +uint32 BattleGroundMgr::BGTemplateId(uint32 bgQueueTypeId) { switch(bgQueueTypeId) { - case BATTLEGROUND_QUEUE_WS: - return BATTLEGROUND_WS; - case BATTLEGROUND_QUEUE_AB: - return BATTLEGROUND_AB; - case BATTLEGROUND_QUEUE_AV: - return BATTLEGROUND_AV; - case BATTLEGROUND_QUEUE_EY: - return BATTLEGROUND_EY; - case BATTLEGROUND_QUEUE_SA: - return BATTLEGROUND_SA; - case BATTLEGROUND_QUEUE_2v2: - case BATTLEGROUND_QUEUE_3v3: - case BATTLEGROUND_QUEUE_5v5: - return BATTLEGROUND_AA; - default: - return 0; + case BATTLEGROUND_QUEUE_WS: + return BATTLEGROUND_WS; + case BATTLEGROUND_QUEUE_AB: + return BATTLEGROUND_AB; + case BATTLEGROUND_QUEUE_AV: + return BATTLEGROUND_AV; + case BATTLEGROUND_QUEUE_EY: + return BATTLEGROUND_EY; + case BATTLEGROUND_QUEUE_SA: + return BATTLEGROUND_SA; + case BATTLEGROUND_QUEUE_2v2: + case BATTLEGROUND_QUEUE_3v3: + case BATTLEGROUND_QUEUE_5v5: + return BATTLEGROUND_AA; + default: + return 0; } } -uint8 BattleGroundMgr::BGArenaType(uint32 bgQueueTypeId) const +uint8 BattleGroundMgr::BGArenaType(uint32 bgQueueTypeId) { switch(bgQueueTypeId) { - case BATTLEGROUND_QUEUE_2v2: - return ARENA_TYPE_2v2; - case BATTLEGROUND_QUEUE_3v3: - return ARENA_TYPE_3v3; - case BATTLEGROUND_QUEUE_5v5: - return ARENA_TYPE_5v5; - default: - return 0; + case BATTLEGROUND_QUEUE_2v2: + return ARENA_TYPE_2v2; + case BATTLEGROUND_QUEUE_3v3: + return ARENA_TYPE_3v3; + case BATTLEGROUND_QUEUE_5v5: + return ARENA_TYPE_5v5; + default: + return 0; } } diff --git a/src/game/BattleGroundMgr.h b/src/game/BattleGroundMgr.h index 62c79c9ec..7a0738cef 100644 --- a/src/game/BattleGroundMgr.h +++ b/src/game/BattleGroundMgr.h @@ -218,12 +218,6 @@ class BattleGroundMgr BGFreeSlotQueueType BGFreeSlotQueue[MAX_BATTLEGROUND_TYPES]; - bool IsArenaType(uint32 bgTypeId) const; - bool IsBattleGroundType(uint32 bgTypeId) const; - uint32 BGQueueTypeId(uint32 bgTypeId, uint8 arenaType) const; - uint32 BGTemplateId(uint32 bgQueueTypeId) const; - uint8 BGArenaType(uint32 bgQueueTypeId) const; - uint32 GetMaxRatingDifference() const { return sWorld.getConfig(CONFIG_ARENA_MAX_RATING_DIFFERENCE); } uint32 GetRatingDiscardTimer() const { return sWorld.getConfig(CONFIG_ARENA_RATING_DISCARD_TIMER); } uint32 GetPrematureFinishTime() const { return sWorld.getConfig(CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER); } @@ -234,6 +228,11 @@ class BattleGroundMgr bool isArenaTesting() const { return m_ArenaTesting; } + static bool IsArenaType(uint32 bgTypeId); + static bool IsBattleGroundType(uint32 bgTypeId) { return !BattleGroundMgr::IsArenaType(bgTypeId); } + static uint32 BGQueueTypeId(uint32 bgTypeId, uint8 arenaType); + static uint32 BGTemplateId(uint32 bgQueueTypeId); + static uint8 BGArenaType(uint32 bgQueueTypeId); private: /* Battlegrounds */ diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 63e6699f2..6a0b95d7e 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7109" + #define REVISION_NR "7110" #endif // __REVISION_NR_H__ From c9ae3b8b5c71487fef396c7ad87ca89630cc220d Mon Sep 17 00:00:00 2001 From: DiSlord Date: Mon, 19 Jan 2009 01:24:45 +0300 Subject: [PATCH 58/84] Apply diminishing only on 1 spell aura add/begin timing only on last spell aura removed Signed-off-by: DiSlord --- src/game/SpellAuras.cpp | 16 ++++++++-------- src/game/Unit.cpp | 18 +++++++----------- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 6a1707939..a5e266fc4 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -941,10 +941,6 @@ void Aura::_AddAura() break; } - // register aura - if (getDiminishGroup() != DIMINISHING_NONE ) - m_target->ApplyDiminishingAura(getDiminishGroup(),true); - Unit* caster = GetCaster(); // passive auras (except totem auras) do not get placed in the slots @@ -967,6 +963,10 @@ void Aura::_AddAura() //***************************************************** if (!secondaura) { + // register aura diminishing on apply + if (getDiminishGroup() != DIMINISHING_NONE ) + m_target->ApplyDiminishingAura(getDiminishGroup(),true); + // Update Seals information if (IsSealSpell(m_spellProto)) m_target->ModifyAuraState(AURA_STATE_JUDGEMENT, true); @@ -1010,10 +1010,6 @@ void Aura::_RemoveAura() dynObj->RemoveAffected(m_target); } - // unregister aura - if (getDiminishGroup() != DIMINISHING_NONE ) - m_target->ApplyDiminishingAura(getDiminishGroup(),false); - //passive auras do not get put in slots // Note: but totem can be not accessible for aura target in time remove (to far for find in grid) //if(m_isPassive && !(caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem())) @@ -1048,6 +1044,10 @@ void Aura::_RemoveAura() // only remove icon when the last aura of the spell is removed (current aura already removed from list) if (lastaura) { + // unregister aura diminishing (and store last time) + if (getDiminishGroup() != DIMINISHING_NONE ) + m_target->ApplyDiminishingAura(getDiminishGroup(),false); + SetAura(true); SetAuraFlags(AFLAG_NONE); SetAuraLevel(0); diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 6b021721d..6ae1edc0f 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -9457,21 +9457,15 @@ DiminishingLevels Unit::GetDiminishing(DiminishingGroup group) void Unit::IncrDiminishing(DiminishingGroup group) { // Checking for existing in the table - bool IsExist = false; for(Diminishing::iterator i = m_Diminishing.begin(); i != m_Diminishing.end(); ++i) { if(i->DRGroup != group) continue; - - IsExist = true; if(i->hitCount < DIMINISHING_LEVEL_IMMUNE) i->hitCount += 1; - - break; + return; } - - if(!IsExist) - m_Diminishing.push_back(DiminishingReturn(group,getMSTime(),DIMINISHING_LEVEL_2)); + m_Diminishing.push_back(DiminishingReturn(group,getMSTime(),DIMINISHING_LEVEL_2)); } void Unit::ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration,Unit* caster,DiminishingLevels Level) @@ -9520,13 +9514,15 @@ void Unit::ApplyDiminishingAura( DiminishingGroup group, bool apply ) if(i->DRGroup != group) continue; - i->hitTime = getMSTime(); - if(apply) i->stack += 1; else if(i->stack) + { i->stack -= 1; - + // Remember time after last aura from group removed + if (i->stack == 0) + i->hitTime = getMSTime(); + } break; } } From 17004d59d42ebeb40cfaf562a1cfd9b6e919a0ab Mon Sep 17 00:00:00 2001 From: DiSlord Date: Mon, 19 Jan 2009 02:51:32 +0300 Subject: [PATCH 59/84] [7111] Fixes in Spell Effect immunes Correct totem immunes for dot/leech/Fear/Transform auras (immune only to effect) Correct log if all effects immuned by Effect Immune Move check for IMMUNITY_STATE to Unit::IsImmunedToSpellEffect Signed-off-by: DiSlord --- src/game/Creature.cpp | 6 ++--- src/game/Creature.h | 2 +- src/game/GridNotifiersImpl.h | 2 +- src/game/Spell.cpp | 43 ++++++++++++++++++++---------------- src/game/Spell.h | 2 -- src/game/SpellEffects.cpp | 8 ------- src/game/Totem.cpp | 22 +++++++++--------- src/game/Totem.h | 2 +- src/game/Unit.cpp | 23 ++++++++++++++----- src/game/Unit.h | 2 +- src/shared/revision_nr.h | 2 +- 11 files changed, 61 insertions(+), 53 deletions(-) diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 30195fa52..c8189cf14 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -1547,12 +1547,12 @@ bool Creature::IsImmunedToSpell(SpellEntry const* spellInfo) return Unit::IsImmunedToSpell(spellInfo); } -bool Creature::IsImmunedToSpellEffect(uint32 effect, uint32 mechanic) const +bool Creature::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const { - if (GetCreatureInfo()->MechanicImmuneMask & (1 << (mechanic-1))) + if (GetCreatureInfo()->MechanicImmuneMask & (1 << (spellInfo->EffectMechanic[index] - 1))) return true; - return Unit::IsImmunedToSpellEffect(effect, mechanic); + return Unit::IsImmunedToSpellEffect(spellInfo, index); } SpellEntry const *Creature::reachWithSpellAttack(Unit *pVictim) diff --git a/src/game/Creature.h b/src/game/Creature.h index 3dec7c603..cb444205e 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -433,7 +433,7 @@ class MANGOS_DLL_SPEC Creature : public Unit bool IsOutOfThreatArea(Unit* pVictim) const; bool IsImmunedToSpell(SpellEntry const* spellInfo); // redefine Unit::IsImmunedToSpell - bool IsImmunedToSpellEffect(uint32 effect, uint32 mechanic) const; + bool IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const; // redefine Unit::IsImmunedToSpellEffect bool isElite() const { diff --git a/src/game/GridNotifiersImpl.h b/src/game/GridNotifiersImpl.h index 8244f6371..590fc68c9 100644 --- a/src/game/GridNotifiersImpl.h +++ b/src/game/GridNotifiersImpl.h @@ -170,7 +170,7 @@ inline void MaNGOS::DynamicObjectUpdater::VisitHelper(Unit* target) SpellEntry const *spellInfo = sSpellStore.LookupEntry(i_dynobject.GetSpellId()); uint32 eff_index = i_dynobject.GetEffIndex(); // Check target immune to spell or aura - if (target->IsImmunedToSpell(spellInfo) || target->IsImmunedToSpellEffect(spellInfo->Effect[eff_index], spellInfo->EffectMechanic[eff_index])) + if (target->IsImmunedToSpell(spellInfo) || target->IsImmunedToSpellEffect(spellInfo, eff_index)) return; // Apply PersistentAreaAura on target PersistentAreaAura* Aur = new PersistentAreaAura(spellInfo, eff_index, NULL, target, i_dynobject.GetCaster()); diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 4d693bf9e..53a23275d 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -757,8 +757,6 @@ void Spell::CleanupTargetList() m_UniqueTargetInfo.clear(); m_UniqueGOTargetInfo.clear(); m_UniqueItemInfo.clear(); - m_countOfHit = 0; - m_countOfMiss = 0; m_delayMoment = 0; } @@ -767,6 +765,9 @@ void Spell::AddUnitTarget(Unit* pVictim, uint32 effIndex) if( m_spellInfo->Effect[effIndex]==0 ) return; + // Check for effect immune skip if immuned + bool immuned = pVictim->IsImmunedToSpellEffect(m_spellInfo, effIndex); + uint64 targetGUID = pVictim->GetGUID(); // Lookup target in already in list @@ -774,7 +775,8 @@ void Spell::AddUnitTarget(Unit* pVictim, uint32 effIndex) { if (targetGUID == ihit->targetGUID) // Found in list { - ihit->effectMask |= 1<effectMask |= 1<SpellHitResult(pVictim, m_spellInfo, m_canReflect); - if (target.missCondition == SPELL_MISS_NONE) - ++m_countOfHit; - else - ++m_countOfMiss; // Spell have speed - need calculate incoming time if (m_spellInfo->speed > 0.0f) @@ -872,8 +870,6 @@ void Spell::AddGOTarget(GameObject* pVictim, uint32 effIndex) else target.timeDelay = 0LL; - ++m_countOfHit; - // Add target to list m_UniqueGOTargetInfo.push_back(target); } @@ -916,8 +912,6 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target) // Get mask of effects for target uint32 mask = target->effectMask; - if (mask == 0) // No effects - return; Unit* unit = m_caster->GetGUID()==target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster,target->targetGUID); if (!unit) @@ -2985,7 +2979,23 @@ void Spell::WriteAmmoToPacket( WorldPacket * data ) void Spell::WriteSpellGoTargets( WorldPacket * data ) { - *data << (uint8)m_countOfHit; + uint32 hit = m_UniqueGOTargetInfo.size(); // Always hits on GO + uint32 miss = 0; + for(std::list::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit) + { + if ((*ihit).effectMask == 0) // No effect apply - all immuned add state + { + // possibly SPELL_MISS_IMMUNE2 for this?? + ihit->missCondition = SPELL_MISS_IMMUNE2; + miss++; + } + else if ((*ihit).missCondition == SPELL_MISS_NONE) + hit++; + else + miss++; + } + + *data << (uint8)hit; for(std::list::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit) if ((*ihit).missCondition == SPELL_MISS_NONE) // Add only hits *data << uint64(ihit->targetGUID); @@ -2993,7 +3003,7 @@ void Spell::WriteSpellGoTargets( WorldPacket * data ) for(std::list::iterator ighit= m_UniqueGOTargetInfo.begin();ighit != m_UniqueGOTargetInfo.end();++ighit) *data << uint64(ighit->targetGUID); // Always hits - *data << (uint8)m_countOfMiss; + *data << (uint8)miss; for(std::list::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit) { if( ihit->missCondition != SPELL_MISS_NONE ) // Add only miss @@ -3501,16 +3511,11 @@ void Spell::HandleEffects(Unit *pUnitTarget,Item *pItemTarget,GameObject *pGOTar gameObjTarget = pGOTarget; uint8 eff = m_spellInfo->Effect[i]; - uint32 mechanic = m_spellInfo->EffectMechanic[i]; damage = int32(CalculateDamage((uint8)i,unitTarget)*DamageMultiplier); sLog.outDebug( "Spell: Effect : %u", eff); - //Simply return. Do not display "immune" in red text on client - if(unitTarget && unitTarget->IsImmunedToSpellEffect(eff, mechanic)) - return; - if(effm_spellImmune[IMMUNITY_STATE]; - for(SpellImmuneList::const_iterator itr = list.begin(); itr != list.end(); ++itr) - if(itr->type == m_spellInfo->EffectApplyAuraName[i]) - return; - // ghost spell check, allow apply any auras at player loading in ghost mode (will be cleanup after load) if( !unitTarget->isAlive() && m_spellInfo->Id != 20584 && m_spellInfo->Id != 8326 && (unitTarget->GetTypeId()!=TYPEID_PLAYER || !((Player*)unitTarget)->GetSession()->PlayerLoading()) ) @@ -5342,9 +5337,6 @@ void Spell::EffectSummonTotem(uint32 i) if(m_caster->GetTypeId() == TYPEID_PLAYER) pTotem->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_PVP_ATTACKABLE); - pTotem->ApplySpellImmune(m_spellInfo->Id,IMMUNITY_STATE,SPELL_AURA_MOD_FEAR,true); - pTotem->ApplySpellImmune(m_spellInfo->Id,IMMUNITY_STATE,SPELL_AURA_TRANSFORM,true); - pTotem->Summon(m_caster); if(slot < MAX_TOTEM && m_caster->GetTypeId() == TYPEID_PLAYER) diff --git a/src/game/Totem.cpp b/src/game/Totem.cpp index 504e3ce3e..c5043a472 100644 --- a/src/game/Totem.cpp +++ b/src/game/Totem.cpp @@ -159,18 +159,18 @@ void Totem::SetTypeBySummonSpell(SpellEntry const * spellProto) m_type = TOTEM_STATUE; //Jewelery statue } -bool Totem::IsImmunedToSpell(SpellEntry const* spellInfo) +bool Totem::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const { - for (int i=0;i<3;i++) + // TODO: possibly all negative auras immuned? + switch(spellInfo->EffectApplyAuraName[index]) { - switch(spellInfo->EffectApplyAuraName[i]) - { - case SPELL_AURA_PERIODIC_DAMAGE: - case SPELL_AURA_PERIODIC_LEECH: - return true; - default: - continue; - } + case SPELL_AURA_PERIODIC_DAMAGE: + case SPELL_AURA_PERIODIC_LEECH: + case SPELL_AURA_MOD_FEAR: + case SPELL_AURA_TRANSFORM: + return true; + default: + break; } - return Creature::IsImmunedToSpell(spellInfo); + return Creature::IsImmunedToSpellEffect(spellInfo, index); } diff --git a/src/game/Totem.h b/src/game/Totem.h index df4abaada..98f071b90 100644 --- a/src/game/Totem.h +++ b/src/game/Totem.h @@ -53,7 +53,7 @@ class Totem : public Creature void UpdateAttackPowerAndDamage(bool /*ranged*/ ) {} void UpdateDamagePhysical(WeaponAttackType /*attType*/) {} - bool IsImmunedToSpell(SpellEntry const* spellInfo); + bool IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const; protected: TotemType m_type; diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 6ae1edc0f..4b26f4d98 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -8157,19 +8157,32 @@ bool Unit::IsImmunedToSpell(SpellEntry const* spellInfo) return false; } -bool Unit::IsImmunedToSpellEffect(uint32 effect, uint32 mechanic) const +bool Unit::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const { //If m_immuneToEffect type contain this effect type, IMMUNE effect. + uint32 effect = spellInfo->Effect[index]; SpellImmuneList const& effectList = m_spellImmune[IMMUNITY_EFFECT]; for (SpellImmuneList::const_iterator itr = effectList.begin(); itr != effectList.end(); ++itr) if(itr->type == effect) return true; - SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC]; - for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr) - if(itr->type == mechanic) - return true; + uint32 mechanic = spellInfo->EffectMechanic[index]; + if (mechanic) + { + SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC]; + for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr) + if(itr->type == mechanic) + return true; + } + uint32 aura = spellInfo->EffectApplyAuraName[index]; + if (aura) + { + SpellImmuneList const& list = m_spellImmune[IMMUNITY_STATE]; + for(SpellImmuneList::const_iterator itr = list.begin(); itr != list.end(); ++itr) + if(itr->type == aura) + return true; + } return false; } diff --git a/src/game/Unit.h b/src/game/Unit.h index 36eb900b3..8a6226579 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1319,7 +1319,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject virtual bool IsImmunedToSpell(SpellEntry const* spellInfo); // redefined in Creature bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask); - virtual bool IsImmunedToSpellEffect(uint32 effect, uint32 mechanic) const; + virtual bool IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const; // redefined in Creature uint32 CalcArmorReducedDamage(Unit* pVictim, const uint32 damage); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 6a0b95d7e..0dc131817 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7110" + #define REVISION_NR "7111" #endif // __REVISION_NR_H__ From be051a706cfcff2a0c7f88ee04d888b055e6b59f Mon Sep 17 00:00:00 2001 From: ApoC Date: Mon, 19 Jan 2009 02:07:04 +0100 Subject: [PATCH 60/84] [7112] Fixed glyphs apply on character load. Signed-off-by: ApoC --- src/game/CharacterHandler.cpp | 2 +- src/game/Player.cpp | 31 +++++++++++++++++++++++++++++++ src/game/Player.h | 1 + src/game/SharedDefines.h | 2 ++ src/shared/revision_nr.h | 2 +- 5 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index 42132fea2..3d04c8a26 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -1206,7 +1206,7 @@ void WorldSession::HandleRemoveGlyph( WorldPacket & recv_data ) uint32 slot; recv_data >> slot; - if(slot > 5) + if(slot > MAX_GLYPH_SLOT_INDEX) { sLog.outDebug("Client sent wrong glyph slot number in opcode CMSG_REMOVE_GLYPH %u", slot); return; diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 995e4a43b..cd8fe7680 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -14317,6 +14317,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder ) //_LoadMail(); _LoadAuras(holder->GetResult(PLAYER_LOGIN_QUERY_LOADAURAS), time_diff); + _LoadGlyphAuras(); // add ghost flag (must be after aura load: PLAYER_FLAGS_GHOST set in aura) if( HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST) ) @@ -14596,6 +14597,36 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff) CastSpell(this,SPELL_ID_PASSIVE_BATTLE_STANCE,true); } +void Player::_LoadGlyphAuras() +{ + for (uint8 i = 0; i <= MAX_GLYPH_SLOT_INDEX; ++i) + { + if (uint32 glyph = GetGlyph(i)) + { + if (GlyphPropertiesEntry const *gp = sGlyphPropertiesStore.LookupEntry(glyph)) + { + if (GlyphSlotEntry const *gs = sGlyphSlotStore.LookupEntry(GetGlyphSlot(i))) + { + if(gp->TypeFlags == gs->TypeFlags) + { + CastSpell(this, gp->SpellId, true); + continue; + } + else + sLog.outError("Player %s has glyph with typeflags %u in slot with typeflags %u, removing.", m_name.c_str(), gp->TypeFlags, gs->TypeFlags); + } + else + sLog.outError("Player %s has not existing glyph slot entry %u on index %u", m_name.c_str(), GetGlyphSlot(i), i); + } + else + sLog.outError("Player %s has not existing glyph entry %u on index %u", m_name.c_str(), glyph, i); + + // On any error remove glyph + SetGlyph(i, 0); + } + } +} + void Player::LoadCorpse() { if( isAlive() ) diff --git a/src/game/Player.h b/src/game/Player.h index ff844d457..732ba2498 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -2234,6 +2234,7 @@ class MANGOS_DLL_SPEC Player : public Unit void _LoadActions(QueryResult *result); void _LoadAuras(QueryResult *result, uint32 timediff); + void _LoadGlyphAuras(); void _LoadBoundInstances(QueryResult *result); void _LoadInventory(QueryResult *result, uint32 timediff); void _LoadMailInit(QueryResult *resultUnread, QueryResult *resultDelivery); diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index 2e0ac63f4..cf4c90549 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -440,6 +440,8 @@ enum ItemQualities #define SPELL_ATTR_EX6_UNK30 0x40000000 // 30 not set in 3.0.3 #define SPELL_ATTR_EX6_UNK31 0x80000000 // 31 not set in 3.0.3 +#define MAX_GLYPH_SLOT_INDEX 5 + enum SheathTypes { SHEATHETYPE_NONE = 0, diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 0dc131817..2599845fe 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7111" + #define REVISION_NR "7112" #endif // __REVISION_NR_H__ From 9fba64aeae2ab4fddea2ac17fa1c2bf5a52930b4 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Mon, 19 Jan 2009 13:25:57 +0300 Subject: [PATCH 61/84] [7113] Not update/store achievement progress for counter == 0 --- sql/characters.sql | 2 +- ...racters_character_achievement_progress.sql | 3 + sql/updates/Makefile.am | 2 + src/game/AchievementMgr.cpp | 65 +++++++++++++------ src/shared/revision_nr.h | 2 +- 5 files changed, 52 insertions(+), 22 deletions(-) create mode 100644 sql/updates/7113_01_characters_character_achievement_progress.sql diff --git a/sql/characters.sql b/sql/characters.sql index 1548a6b11..078afe024 100644 --- a/sql/characters.sql +++ b/sql/characters.sql @@ -21,7 +21,7 @@ DROP TABLE IF EXISTS `character_db_version`; CREATE TABLE `character_db_version` ( - `required_7100_01_characters_character_spell` bit(1) default NULL + `required_7113_01_characters_character_achievement_progress` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB'; -- diff --git a/sql/updates/7113_01_characters_character_achievement_progress.sql b/sql/updates/7113_01_characters_character_achievement_progress.sql new file mode 100644 index 000000000..6e38cd998 --- /dev/null +++ b/sql/updates/7113_01_characters_character_achievement_progress.sql @@ -0,0 +1,3 @@ +ALTER TABLE character_db_version CHANGE COLUMN required_7100_01_characters_character_spell required_7113_01_characters_character_achievement_progress bit; + +DELETE FROM character_achievement_progress WHERE counter=0; diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index d8fed763e..2cee52875 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -141,6 +141,7 @@ pkgdata_DATA = \ 7097_01_mangos_spell_proc_event.sql \ 7100_01_characters_character_spell.sql \ 7107_01_mangos_string.sql \ + 7113_01_characters_character_achievement_progress.sql \ README ## Additional files to include when running 'make dist' @@ -262,4 +263,5 @@ EXTRA_DIST = \ 7097_01_mangos_spell_proc_event.sql \ 7100_01_characters_character_spell.sql \ 7107_01_mangos_string.sql \ + 7113_01_characters_character_achievement_progress.sql \ README diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp index fb6684892..6fb0497db 100644 --- a/src/game/AchievementMgr.cpp +++ b/src/game/AchievementMgr.cpp @@ -141,7 +141,8 @@ void AchievementMgr::SaveToDB() if(!m_criteriaProgress.empty()) { /// prepare deleting and insert - bool need_execute = false; + bool need_execute_del = false; + bool need_execute_ins = false; std::ostringstream ssdel; std::ostringstream ssins; for(CriteriaProgressMap::iterator iter = m_criteriaProgress.begin(); iter!=m_criteriaProgress.end(); ++iter) @@ -149,36 +150,53 @@ void AchievementMgr::SaveToDB() if(!iter->second.changed) continue; - /// first new/changed record prefix - if(!need_execute) + // deleted data (including 0 progress state) { - ssdel << "DELETE FROM character_achievement_progress WHERE guid = " << GetPlayer()->GetGUIDLow() << " AND criteria IN ("; - ssins << "INSERT INTO character_achievement_progress (guid, criteria, counter, date) VALUES "; - need_execute = true; - } - /// next new/changed record prefix - else - { - ssdel << ", "; - ssins << ", "; + /// first new/changed record prefix (for any counter value) + if(!need_execute_del) + { + ssdel << "DELETE FROM character_achievement_progress WHERE guid = " << GetPlayer()->GetGUIDLow() << " AND criteria IN ("; + need_execute_del = true; + } + /// next new/changed record prefix + else + ssdel << ", "; + + // new/changed record data + ssdel << iter->first; } - // new/changed record data - ssdel << iter->first; - ssins << "(" << GetPlayer()->GetGUIDLow() << ", " << iter->first << ", " << iter->second.counter << ", " << iter->second.date << ")"; + // store data only for real progress + if(iter->second.counter != 0) + { + /// first new/changed record prefix + if(!need_execute_ins) + { + ssins << "INSERT INTO character_achievement_progress (guid, criteria, counter, date) VALUES "; + need_execute_ins = true; + } + /// next new/changed record prefix + else + ssins << ", "; - /// mark as saved in db + // new/changed record data + ssins << "(" << GetPlayer()->GetGUIDLow() << ", " << iter->first << ", " << iter->second.counter << ", " << iter->second.date << ")"; + } + + /// mark as updated in db iter->second.changed = false; } - if(need_execute) + if(need_execute_del) // DELETE ... IN (.... _)_ ssdel << ")"; - if(need_execute) + if(need_execute_del || need_execute_ins) { CharacterDatabase.BeginTransaction (); - CharacterDatabase.Execute( ssdel.str().c_str() ); - CharacterDatabase.Execute( ssins.str().c_str() ); + if(need_execute_del) + CharacterDatabase.Execute( ssdel.str().c_str() ); + if(need_execute_ins) + CharacterDatabase.Execute( ssins.str().c_str() ); CharacterDatabase.CommitTransaction (); } } @@ -729,6 +747,10 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, if(iter == m_criteriaProgress.end()) { + // not create record for 0 counter + if(newValue == 0) + return; + progress = &m_criteriaProgress[entry->ID]; progress->counter = newValue; progress->date = time(NULL); @@ -738,8 +760,11 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, progress = &iter->second; if(relative) newValue += progress->counter; + + // not update (not mark as changed) if counter will have same value if(progress->counter == newValue) return; + progress->counter = newValue; } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 2599845fe..b6502b1cb 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7112" + #define REVISION_NR "7113" #endif // __REVISION_NR_H__ From 9e590f7ceb12c4a74e968eea6d38c27d503c8da9 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Mon, 19 Jan 2009 15:08:06 +0300 Subject: [PATCH 62/84] [7114] Code cleanups. Remove redundant `inline` for in-class function definitions. Fixed float -> int implicit casts. --- src/framework/GameSystem/NGrid.h | 12 ++++---- src/framework/Policies/ObjectLifeTime.h | 4 +-- .../Utilities/LinkedReference/Reference.h | 14 +++++----- src/game/BattleGroundMgr.h | 4 +-- src/game/Cell.h | 4 +-- src/game/Map.h | 4 +-- src/game/MapManager.h | 12 ++++---- src/game/Player.cpp | 18 ++++++------ src/game/Player.h | 2 +- src/game/Spell.h | 2 +- src/game/SpellAuras.cpp | 10 +++---- src/game/SpellEffects.cpp | 2 +- src/game/ThreatManager.h | 8 +++--- src/game/Transports.h | 12 ++++---- src/game/Traveller.h | 8 +++--- src/game/Unit.cpp | 7 ++--- src/game/UpdateMask.h | 28 +++++++++---------- src/game/WaypointMovementGenerator.h | 4 +-- src/game/WorldLog.h | 4 +-- src/game/WorldSession.h | 2 +- src/shared/Database/SqlDelayThread.h | 2 +- src/shared/revision_nr.h | 2 +- 22 files changed, 82 insertions(+), 83 deletions(-) diff --git a/src/framework/GameSystem/NGrid.h b/src/framework/GameSystem/NGrid.h index b93e5d9a9..0271bd11a 100644 --- a/src/framework/GameSystem/NGrid.h +++ b/src/framework/GameSystem/NGrid.h @@ -74,12 +74,12 @@ class MANGOS_DLL_DECL NGrid const GridType& operator()(unsigned short x, unsigned short y) const { return i_cells[x][y]; } GridType& operator()(unsigned short x, unsigned short y) { return i_cells[x][y]; } - inline const uint32& GetGridId(void) const { return i_gridId; } - inline void SetGridId(const uint32 id) const { i_gridId = id; } - inline grid_state_t GetGridState(void) const { return i_cellstate; } - inline void SetGridState(grid_state_t s) { i_cellstate = s; } - inline int32 getX() const { return i_x; } - inline int32 getY() const { return i_y; } + const uint32& GetGridId(void) const { return i_gridId; } + void SetGridId(const uint32 id) const { i_gridId = id; } + grid_state_t GetGridState(void) const { return i_cellstate; } + void SetGridState(grid_state_t s) { i_cellstate = s; } + int32 getX() const { return i_x; } + int32 getY() const { return i_y; } void link(GridRefManager >* pTo) { diff --git a/src/framework/Policies/ObjectLifeTime.h b/src/framework/Policies/ObjectLifeTime.h index dab37a98c..82bf4ea8e 100644 --- a/src/framework/Policies/ObjectLifeTime.h +++ b/src/framework/Policies/ObjectLifeTime.h @@ -32,7 +32,7 @@ namespace MaNGOS class MANGOS_DLL_DECL ObjectLifeTime { public: - inline static void ScheduleCall(void (*destroyer)() ) + static void ScheduleCall(void (*destroyer)() ) { at_exit( destroyer ); } @@ -42,7 +42,7 @@ namespace MaNGOS }; template - inline void ObjectLifeTime::OnDeadReference(void)// We don't handle Dead Reference for now + void ObjectLifeTime::OnDeadReference(void) // We don't handle Dead Reference for now { throw std::runtime_error("Dead Reference"); } diff --git a/src/framework/Utilities/LinkedReference/Reference.h b/src/framework/Utilities/LinkedReference/Reference.h index d74723a42..42e4b0484 100644 --- a/src/framework/Utilities/LinkedReference/Reference.h +++ b/src/framework/Utilities/LinkedReference/Reference.h @@ -42,7 +42,7 @@ template class Reference : public LinkedListElement virtual ~Reference() {} // Create new link - inline void link(TO* toObj, FROM* fromObj) + void link(TO* toObj, FROM* fromObj) { assert(fromObj); // fromObj MUST not be NULL if(isValid()) @@ -57,16 +57,16 @@ template class Reference : public LinkedListElement // We don't need the reference anymore. Call comes from the refFrom object // Tell our refTo object, that the link is cut - inline void unlink() { targetObjectDestroyLink(); delink(); iRefTo = NULL; iRefFrom = NULL; } + void unlink() { targetObjectDestroyLink(); delink(); iRefTo = NULL; iRefFrom = NULL; } // Link is invalid due to destruction of referenced target object. Call comes from the refTo object // Tell our refFrom object, that the link is cut - inline void invalidate() // the iRefFrom MUST remain!! + void invalidate() // the iRefFrom MUST remain!! { sourceObjectDestroyLink(); delink(); iRefTo = NULL; } - inline bool isValid() const // Only check the iRefTo + bool isValid() const // Only check the iRefTo { return iRefTo != NULL; } @@ -81,10 +81,10 @@ template class Reference : public LinkedListElement Reference * nocheck_prev() { return((Reference *) LinkedListElement::nocheck_prev()); } Reference const * nocheck_prev() const { return((Reference const *) LinkedListElement::nocheck_prev()); } - inline TO* operator ->() const { return iRefTo; } - inline TO* getTarget() const { return iRefTo; } + TO* operator ->() const { return iRefTo; } + TO* getTarget() const { return iRefTo; } - inline FROM* getSource() const { return iRefFrom; } + FROM* getSource() const { return iRefFrom; } }; //===================================================== diff --git a/src/game/BattleGroundMgr.h b/src/game/BattleGroundMgr.h index 7a0738cef..f36c41ca8 100644 --- a/src/game/BattleGroundMgr.h +++ b/src/game/BattleGroundMgr.h @@ -205,8 +205,8 @@ class BattleGroundMgr uint32 CreateBattleGround(uint32 bgTypeId, uint32 MinPlayersPerTeam, uint32 MaxPlayersPerTeam, uint32 LevelMin, uint32 LevelMax, char* BattleGroundName, uint32 MapID, float Team1StartLocX, float Team1StartLocY, float Team1StartLocZ, float Team1StartLocO, float Team2StartLocX, float Team2StartLocY, float Team2StartLocZ, float Team2StartLocO); - inline void AddBattleGround(uint32 ID, BattleGround* BG) { m_BattleGrounds[ID] = BG; }; - inline void RemoveBattleGround(uint32 instanceID) { m_BattleGrounds.erase(instanceID); } + void AddBattleGround(uint32 ID, BattleGround* BG) { m_BattleGrounds[ID] = BG; }; + void RemoveBattleGround(uint32 instanceID) { m_BattleGrounds.erase(instanceID); } void CreateInitialBattleGrounds(); diff --git a/src/game/Cell.h b/src/game/Cell.h index f826b9e06..32dec557f 100644 --- a/src/game/Cell.h +++ b/src/game/Cell.h @@ -91,13 +91,13 @@ struct MANGOS_DLL_DECL Cell y = data.Part.grid_y*MAX_NUMBER_OF_CELLS + data.Part.cell_y; } - inline bool DiffCell(const Cell &cell) const + bool DiffCell(const Cell &cell) const { return( data.Part.cell_x != cell.data.Part.cell_x || data.Part.cell_y != cell.data.Part.cell_y ); } - inline bool DiffGrid(const Cell &cell) const + bool DiffGrid(const Cell &cell) const { return( data.Part.grid_x != cell.data.Part.grid_x || data.Part.grid_y != cell.data.Part.grid_y ); diff --git a/src/game/Map.h b/src/game/Map.h index 5b9c3781a..35e83969e 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -150,7 +150,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj template void Visit(const CellLock &cell, TypeContainerVisitor &visitor); - inline bool IsRemovalGrid(float x, float y) const + bool IsRemovalGrid(float x, float y) const { GridPair p = MaNGOS::ComputeGridPair(x, y); return( !getNGrid(p.x_coord, p.y_coord) || getNGrid(p.x_coord, p.y_coord)->GetGridState() == GRID_STATE_REMOVAL ); @@ -291,7 +291,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj bool isGridObjectDataLoaded(uint32 x, uint32 y) const { return getNGrid(x,y)->isGridObjectDataLoaded(); } void setGridObjectDataLoaded(bool pLoaded, uint32 x, uint32 y) { getNGrid(x,y)->setGridObjectDataLoaded(pLoaded); } - inline void setNGrid(NGridType* grid, uint32 x, uint32 y); + void setNGrid(NGridType* grid, uint32 x, uint32 y); protected: typedef MaNGOS::ObjectLevelLockable::Lock Guard; diff --git a/src/game/MapManager.h b/src/game/MapManager.h index 30bfead45..554634d33 100644 --- a/src/game/MapManager.h +++ b/src/game/MapManager.h @@ -45,18 +45,18 @@ class MANGOS_DLL_DECL MapManager : public MaNGOS::Singleton(this)->_GetBaseMap(id); } void DeleteInstance(uint32 mapid, uint32 instanceId); - inline uint16 GetAreaFlag(uint32 mapid, float x, float y, float z) const + uint16 GetAreaFlag(uint32 mapid, float x, float y, float z) const { Map const* m = GetBaseMap(mapid); return m->GetAreaFlag(x, y, z); } - inline uint32 GetAreaId(uint32 mapid, float x, float y, float z) { return Map::GetAreaId(GetAreaFlag(mapid, x, y, z),mapid); } - inline uint32 GetZoneId(uint32 mapid, float x, float y, float z) { return Map::GetZoneId(GetAreaFlag(mapid, x, y, z),mapid); } + uint32 GetAreaId(uint32 mapid, float x, float y, float z) const { return Map::GetAreaId(GetAreaFlag(mapid, x, y, z),mapid); } + uint32 GetZoneId(uint32 mapid, float x, float y, float z) const { return Map::GetZoneId(GetAreaFlag(mapid, x, y, z),mapid); } void Initialize(void); void Update(time_t); - inline void SetGridCleanUpDelay(uint32 t) + void SetGridCleanUpDelay(uint32 t) { if( t < MIN_GRID_DELAY ) i_gridCleanUpDelay = MIN_GRID_DELAY; @@ -64,7 +64,7 @@ class MANGOS_DLL_DECL MapManager : public MaNGOS::Singleton MIN_MAP_UPDATE_DELAY ) t = MIN_MAP_UPDATE_DELAY; @@ -106,7 +106,7 @@ class MANGOS_DLL_DECL MapManager : public MaNGOS::SingletonGetMiscValue() & (1<GetMiscBValue())) * (*i)->GetModifier()->m_amount / 100.0f; + amount += int32(GetStat(Stats((*i)->GetMiscBValue())) * (*i)->GetModifier()->m_amount / 100.0f); if (amount < 0) amount = 0; SetUInt32Value(PLAYER_FIELD_COMBAT_RATING_1 + cr, uint32(amount)); @@ -6503,7 +6503,7 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl uint32 level = ((getLevel() > ssd->MaxLevel) ? ssd->MaxLevel : getLevel()); if(ScalingStatValuesEntry const *ssv = sScalingStatValuesStore.LookupEntry(level)) { - int multiplier = ssv->Multiplier[proto->GetScalingStatValuesColumn()]; + uint32 multiplier = ssv->Multiplier[proto->GetScalingStatValuesColumn()]; val = (multiplier * modifier) / 10000; } } @@ -6512,7 +6512,7 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl else { statType = proto->ItemStat[i].ItemStatType; - val = float(proto->ItemStat[i].ItemStatValue); + val = proto->ItemStat[i].ItemStatValue; } if(val == 0) @@ -14264,12 +14264,12 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder ) // clear charm/summon related fields SetCharm(NULL); SetPet(NULL); - SetCharmerGUID(NULL); - SetOwnerGUID(NULL); - SetCreatorGUID(NULL); + SetCharmerGUID(0); + SetOwnerGUID(0); + SetCreatorGUID(0); // reset some aura modifiers before aura apply - SetFarSight(NULL); + SetFarSightGUID(0); SetUInt32Value(PLAYER_TRACK_CREATURES, 0 ); SetUInt32Value(PLAYER_TRACK_RESOURCES, 0 ); @@ -19171,7 +19171,7 @@ void Player::EnterVehicle(Vehicle *vehicle) vehicle->setFaction(getFaction()); SetCharm(vehicle); // charm - SetFarSight(vehicle->GetGUID()); // set view + SetFarSightGUID(vehicle->GetGUID()); // set view SetClientControl(vehicle, 1); // redirect controls to vehicle @@ -19222,7 +19222,7 @@ void Player::ExitVehicle(Vehicle *vehicle) vehicle->setFaction((GetTeam() == ALLIANCE) ? vehicle->GetCreatureInfo()->faction_A : vehicle->GetCreatureInfo()->faction_H); SetCharm(NULL); - SetFarSight(NULL); + SetFarSightGUID(0); SetClientControl(vehicle, 0); diff --git a/src/game/Player.h b/src/game/Player.h index 732ba2498..2e962a9f3 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -2064,7 +2064,7 @@ class MANGOS_DLL_SPEC Player : public Unit void ExitVehicle(Vehicle *vehicle); uint64 GetFarSight() const { return GetUInt64Value(PLAYER_FARSIGHT); } - void SetFarSight(uint64 guid) { SetUInt64Value(PLAYER_FARSIGHT, guid); } + void SetFarSightGUID(uint64 guid) { SetUInt64Value(PLAYER_FARSIGHT, guid); } // Transports Transport * GetTransport() const { return m_transport; } diff --git a/src/game/Spell.h b/src/game/Spell.h index 933ebc3f2..5befc6789 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -354,7 +354,7 @@ class Spell bool HaveTargetsForEffect(uint8 effect) const; void Delayed(); void DelayedChannel(); - inline uint32 getState() const { return m_spellState; } + uint32 getState() const { return m_spellState; } void setState(uint32 state) { m_spellState = state; } void DoCreateItem(uint32 i, uint32 itemtype); diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index a5e266fc4..08fef1f30 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -2081,7 +2081,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real) ( GetSpellProto()->EffectApplyAuraName[0]==1 || GetSpellProto()->EffectApplyAuraName[0]==128 ) ) ) { // spells with SpellEffect=72 and aura=4: 6196, 6197, 21171, 21425 - ((Player*)m_target)->SetFarSight(NULL); + ((Player*)m_target)->SetFarSightGUID(0); WorldPacket data(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, 0); ((Player*)m_target)->GetSession()->SendPacket(&data); return; @@ -2967,7 +2967,7 @@ void Aura::HandleBindSight(bool apply, bool Real) if(!caster || caster->GetTypeId() != TYPEID_PLAYER) return; - ((Player*)caster)->SetFarSight(apply ? m_target->GetGUID() : NULL); + ((Player*)caster)->SetFarSightGUID(apply ? m_target->GetGUID() : 0); } void Aura::HandleFarSight(bool apply, bool Real) @@ -2976,7 +2976,7 @@ void Aura::HandleFarSight(bool apply, bool Real) if(!caster || caster->GetTypeId() != TYPEID_PLAYER) return; - ((Player*)caster)->SetFarSight(apply ? m_target->GetGUID() : NULL); + ((Player*)caster)->SetFarSightGUID(apply ? m_target->GetGUID() : 0); } void Aura::HandleAuraTrackCreatures(bool apply, bool Real) @@ -3083,7 +3083,7 @@ void Aura::HandleModPossess(bool apply, bool Real) } } if(caster->GetTypeId() == TYPEID_PLAYER) - ((Player*)caster)->SetFarSight(apply ? m_target->GetGUID() : NULL); + ((Player*)caster)->SetFarSightGUID(apply ? m_target->GetGUID() : 0); } void Aura::HandleModPossessPet(bool apply, bool Real) @@ -3104,7 +3104,7 @@ void Aura::HandleModPossessPet(bool apply, bool Real) else pet->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24); - ((Player*)caster)->SetFarSight(apply ? pet->GetGUID() : NULL); + ((Player*)caster)->SetFarSightGUID(apply ? pet->GetGUID() : NULL); ((Player*)caster)->SetCharm(apply ? pet : NULL); ((Player*)caster)->SetClientControl(pet, apply ? 1 : 0); diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 9bb43c2ce..7c660274f 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -3564,7 +3564,7 @@ void Spell::EffectAddFarsight(uint32 i) m_caster->AddDynObject(dynObj); dynObj->GetMap()->Add(dynObj); if(m_caster->GetTypeId() == TYPEID_PLAYER) - ((Player*)m_caster)->SetFarSight(dynObj->GetGUID()); + ((Player*)m_caster)->SetFarSightGUID(dynObj->GetGUID()); } void Spell::EffectSummonWild(uint32 i) diff --git a/src/game/ThreatManager.h b/src/game/ThreatManager.h index b6e2d3da0..5191b2199 100644 --- a/src/game/ThreatManager.h +++ b/src/game/ThreatManager.h @@ -204,10 +204,10 @@ class MANGOS_DLL_SPEC ThreatManager // methods to access the lists from the outside to do sume dirty manipulation (scriping and such) // I hope they are used as little as possible. - inline std::list& getThreatList() { return iThreatContainer.getThreatList(); } - inline std::list& getOfflieThreatList() { return iThreatOfflineContainer.getThreatList(); } - inline ThreatContainer& getOnlineContainer() { return iThreatContainer; } - inline ThreatContainer& getOfflineContainer() { return iThreatOfflineContainer; } + std::list& getThreatList() { return iThreatContainer.getThreatList(); } + std::list& getOfflieThreatList() { return iThreatOfflineContainer.getThreatList(); } + ThreatContainer& getOnlineContainer() { return iThreatContainer; } + ThreatContainer& getOfflineContainer() { return iThreatOfflineContainer; } }; //================================================= diff --git a/src/game/Transports.h b/src/game/Transports.h index c6ef2a3a4..4d58a80de 100644 --- a/src/game/Transports.h +++ b/src/game/Transports.h @@ -36,16 +36,16 @@ class TransportPath uint32 delay; }; - inline void SetLength(const unsigned int sz) + void SetLength(const unsigned int sz) { i_nodes.resize( sz ); } - inline unsigned int Size(void) const { return i_nodes.size(); } - inline bool Empty(void) const { return i_nodes.empty(); } - inline void Resize(unsigned int sz) { i_nodes.resize(sz); } - inline void Clear(void) { i_nodes.clear(); } - inline PathNode* GetNodes(void) { return static_cast(&i_nodes[0]); } + unsigned int Size(void) const { return i_nodes.size(); } + bool Empty(void) const { return i_nodes.empty(); } + void Resize(unsigned int sz) { i_nodes.resize(sz); } + void Clear(void) { i_nodes.clear(); } + PathNode* GetNodes(void) { return static_cast(&i_nodes[0]); } PathNode& operator[](const unsigned int idx) { return i_nodes[idx]; } const PathNode& operator()(const unsigned int idx) const { return i_nodes[idx]; } diff --git a/src/game/Traveller.h b/src/game/Traveller.h index 51ea73651..3daa558da 100644 --- a/src/game/Traveller.h +++ b/src/game/Traveller.h @@ -44,10 +44,10 @@ struct MANGOS_DLL_DECL Traveller operator T&(void) { return i_traveller; } operator const T&(void) { return i_traveller; } - inline float GetPositionX() const { return i_traveller.GetPositionX(); } - inline float GetPositionY() const { return i_traveller.GetPositionY(); } - inline float GetPositionZ() const { return i_traveller.GetPositionZ(); } - inline T& GetTraveller(void) { return i_traveller; } + float GetPositionX() const { return i_traveller.GetPositionX(); } + float GetPositionY() const { return i_traveller.GetPositionY(); } + float GetPositionZ() const { return i_traveller.GetPositionZ(); } + T& GetTraveller(void) { return i_traveller; } float Speed(void) { assert(false); return 0.0f; } void Relocation(float x, float y, float z, float orientation) {} diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 4b26f4d98..abbe2729b 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -8166,8 +8166,7 @@ bool Unit::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) con if(itr->type == effect) return true; - uint32 mechanic = spellInfo->EffectMechanic[index]; - if (mechanic) + if(uint32 mechanic = spellInfo->EffectMechanic[index]) { SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC]; for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr) @@ -8175,14 +8174,14 @@ bool Unit::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) con return true; } - uint32 aura = spellInfo->EffectApplyAuraName[index]; - if (aura) + if(uint32 aura = spellInfo->EffectApplyAuraName[index]) { SpellImmuneList const& list = m_spellImmune[IMMUNITY_STATE]; for(SpellImmuneList::const_iterator itr = list.begin(); itr != list.end(); ++itr) if(itr->type == aura) return true; } + return false; } diff --git a/src/game/UpdateMask.h b/src/game/UpdateMask.h index d356799f6..5b844ad54 100644 --- a/src/game/UpdateMask.h +++ b/src/game/UpdateMask.h @@ -34,27 +34,27 @@ class UpdateMask delete [] mUpdateMask; } - inline void SetBit (uint32 index) + void SetBit (uint32 index) { ( (uint8 *)mUpdateMask )[ index >> 3 ] |= 1 << ( index & 0x7 ); } - inline void UnsetBit (uint32 index) + void UnsetBit (uint32 index) { ( (uint8 *)mUpdateMask )[ index >> 3 ] &= (0xff ^ (1 << ( index & 0x7 ) ) ); } - inline bool GetBit (uint32 index) + bool GetBit (uint32 index) const { return ( ( (uint8 *)mUpdateMask)[ index >> 3 ] & ( 1 << ( index & 0x7 ) )) != 0; } - inline uint32 GetBlockCount() { return mBlocks; } - inline uint32 GetLength() { return mBlocks << 2; } - inline uint32 GetCount() { return mCount; } - inline uint8* GetMask() { return (uint8*)mUpdateMask; } + uint32 GetBlockCount() const { return mBlocks; } + uint32 GetLength() const { return mBlocks << 2; } + uint32 GetCount() const { return mCount; } + uint8* GetMask() { return (uint8*)mUpdateMask; } - inline void SetCount (uint32 valuesCount) + void SetCount (uint32 valuesCount) { if(mUpdateMask) delete [] mUpdateMask; @@ -66,13 +66,13 @@ class UpdateMask memset(mUpdateMask, 0, mBlocks << 2); } - inline void Clear() + void Clear() { if (mUpdateMask) memset(mUpdateMask, 0, mBlocks << 2); } - inline UpdateMask& operator = ( const UpdateMask& mask ) + UpdateMask& operator = ( const UpdateMask& mask ) { SetCount(mask.mCount); memcpy(mUpdateMask, mask.mUpdateMask, mBlocks << 2); @@ -80,21 +80,21 @@ class UpdateMask return *this; } - inline void operator &= ( const UpdateMask& mask ) + void operator &= ( const UpdateMask& mask ) { ASSERT(mask.mCount <= mCount); for (uint32 i = 0; i < mBlocks; i++) mUpdateMask[i] &= mask.mUpdateMask[i]; } - inline void operator |= ( const UpdateMask& mask ) + void operator |= ( const UpdateMask& mask ) { ASSERT(mask.mCount <= mCount); for (uint32 i = 0; i < mBlocks; i++) mUpdateMask[i] |= mask.mUpdateMask[i]; } - inline UpdateMask operator & ( const UpdateMask& mask ) const + UpdateMask operator & ( const UpdateMask& mask ) const { ASSERT(mask.mCount <= mCount); @@ -105,7 +105,7 @@ class UpdateMask return newmask; } - inline UpdateMask operator | ( const UpdateMask& mask ) const + UpdateMask operator | ( const UpdateMask& mask ) const { ASSERT(mask.mCount <= mCount); diff --git a/src/game/WaypointMovementGenerator.h b/src/game/WaypointMovementGenerator.h index 785940d0f..cc552d974 100644 --- a/src/game/WaypointMovementGenerator.h +++ b/src/game/WaypointMovementGenerator.h @@ -46,7 +46,7 @@ class MANGOS_DLL_SPEC PathMovementBase PathMovementBase() : i_currentNode(0) {} virtual ~PathMovementBase() {}; - inline bool MovementInProgress(void) const { return i_currentNode < i_path.Size(); } + bool MovementInProgress(void) const { return i_currentNode < i_path.Size(); } // template pattern, not defined .. override required void LoadPath(T &); @@ -135,7 +135,7 @@ public PathMovementBase Path& GetPath() { return i_path; } uint32 GetPathAtMapEnd() const; - inline bool HasArrived() const { return (i_currentNode >= i_path.Size()); } + bool HasArrived() const { return (i_currentNode >= i_path.Size()); } void SetCurrentNodeAfterTeleport(); void SkipCurrentNode() { ++i_currentNode; } }; diff --git a/src/game/WorldLog.h b/src/game/WorldLog.h index de8475dd0..8a20d1018 100644 --- a/src/game/WorldLog.h +++ b/src/game/WorldLog.h @@ -49,9 +49,9 @@ class MANGOS_DLL_DECL WorldLog : public MaNGOS::Singleton Date: Mon, 19 Jan 2009 15:48:32 +0300 Subject: [PATCH 63/84] [7115] Sort spells by spellfamily cases for speedup most common (check fail) case. --- src/game/SpellEffects.cpp | 855 +++++++++++++++++++------------------- src/shared/revision_nr.h | 2 +- 2 files changed, 439 insertions(+), 418 deletions(-) diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 7c660274f..93067d835 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -4602,438 +4602,459 @@ void Spell::EffectScriptEffect(uint32 effIndex) // by spell id switch(m_spellInfo->Id) { - // PX-238 Winter Wondervolt TRAP - case 26275: + + } + + switch(m_spellInfo->SpellFamilyName) + { + case SPELLFAMILY_GENERIC: { - if( unitTarget->HasAura(26272,0) - || unitTarget->HasAura(26157,0) - || unitTarget->HasAura(26273,0) - || unitTarget->HasAura(26274,0)) - return; - - uint32 iTmpSpellId; - - switch(urand(0,3)) - { - case 0: - iTmpSpellId = 26272; - break; - case 1: - iTmpSpellId = 26157; - break; - case 2: - iTmpSpellId = 26273; - break; - case 3: - iTmpSpellId = 26274; - break; - } - - unitTarget->CastSpell(unitTarget, iTmpSpellId, true); - - return; - } - - // Bending Shinbone - case 8856: - { - if(!itemTarget && m_caster->GetTypeId()!=TYPEID_PLAYER) - return; - - uint32 spell_id = 0; - switch(urand(1,5)) - { - case 1: spell_id = 8854; break; - default: spell_id = 8855; break; - } - - m_caster->CastSpell(m_caster,spell_id,true,NULL); - return; - } - - // Healthstone creating spells - case 6201: - case 6202: - case 5699: - case 11729: - case 11730: - case 27230: - case 47871: - case 47878: - { - uint32 itemtype; - uint32 rank = 0; - Unit::AuraList const& mDummyAuras = unitTarget->GetAurasByType(SPELL_AURA_DUMMY); - for(Unit::AuraList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i) - { - if((*i)->GetId() == 18692) - { - rank = 1; - break; - } - else if((*i)->GetId() == 18693) - { - rank = 2; - break; - } - } - - static uint32 const itypes[8][3] = { - { 5512,19004,19005}, // Minor Healthstone - { 5511,19006,19007}, // Lesser Healthstone - { 5509,19008,19009}, // Healthstone - { 5510,19010,19011}, // Greater Healthstone - { 9421,19012,19013}, // Major Healthstone - {22103,22104,22105}, // Master Healthstone - {36889,36890,36891}, // Demonic Healthstone - {36892,36893,36894} // Fel Healthstone - }; - switch(m_spellInfo->Id) { - case 6201: itemtype=itypes[0][rank];break; // Minor Healthstone - case 6202: itemtype=itypes[1][rank];break; // Lesser Healthstone - case 5699: itemtype=itypes[2][rank];break; // Healthstone - case 11729: itemtype=itypes[3][rank];break; // Greater Healthstone - case 11730: itemtype=itypes[4][rank];break; // Major Healthstone - case 27230: itemtype=itypes[5][rank];break; // Master Healthstone - case 47871: itemtype=itypes[6][rank];break; // Demonic Healthstone - case 47878: itemtype=itypes[7][rank];break; // Fel Healthstone - default: - return; - } - DoCreateItem( effIndex, itemtype ); - return; - } - // Brittle Armor - need remove one 24575 Brittle Armor aura - case 24590: - unitTarget->RemoveSingleSpellAurasFromStack(24575); - return; - // Mercurial Shield - need remove one 26464 Mercurial Shield aura - case 26465: - unitTarget->RemoveSingleSpellAurasFromStack(26464); - return; - // Orb teleport spells - case 25140: - case 25143: - case 25650: - case 25652: - case 29128: - case 29129: - case 35376: - case 35727: - { - if(!unitTarget) - return; - - uint32 spellid; - switch(m_spellInfo->Id) - { - case 25140: spellid = 32571; break; - case 25143: spellid = 32572; break; - case 25650: spellid = 30140; break; - case 25652: spellid = 30141; break; - case 29128: spellid = 32568; break; - case 29129: spellid = 32569; break; - case 35376: spellid = 25649; break; - case 35727: spellid = 35730; break; - default: - return; - } - - unitTarget->CastSpell(unitTarget,spellid,false); - return; - } - - // Shadow Flame (All script effects, not just end ones to prevent player from dodging the last triggered spell) - case 22539: - case 22972: - case 22975: - case 22976: - case 22977: - case 22978: - case 22979: - case 22980: - case 22981: - case 22982: - case 22983: - case 22984: - case 22985: - { - if(!unitTarget || !unitTarget->isAlive()) - return; - - // Onyxia Scale Cloak - if(unitTarget->GetDummyAura(22683)) - return; - - // Shadow Flame - m_caster->CastSpell(unitTarget, 22682, true); - return; - } - break; - - // Summon Black Qiraji Battle Tank - case 26656: - { - if(!unitTarget) - return; - - // Prevent stacking of mounts - unitTarget->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); - - // Two separate mounts depending on area id (allows use both in and out of specific instance) - if (unitTarget->GetAreaId() == 3428) - unitTarget->CastSpell(unitTarget, 25863, false); - else - unitTarget->CastSpell(unitTarget, 26655, false); - break; - } - // Piccolo of the Flaming Fire - case 17512: - { - if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) - return; - unitTarget->HandleEmoteCommand(EMOTE_STATE_DANCE); - break; - } - - // Dreaming Glory - case 28698: - { - if(!unitTarget) - return; - unitTarget->CastSpell(unitTarget, 28694, true); - break; - } - - // Netherbloom - case 28702: - { - if(!unitTarget) - return; - // 25% chance of casting a random buff - if(roll_chance_i(75)) - return; - - // triggered spells are 28703 to 28707 - // Note: some sources say, that there was the possibility of - // receiving a debuff. However, this seems to be removed by a patch. - const uint32 spellid = 28703; - - // don't overwrite an existing aura - for(uint8 i=0; i<5; i++) - if(unitTarget->HasAura(spellid+i, 0)) - return; - unitTarget->CastSpell(unitTarget, spellid+urand(0, 4), true); - break; - } - - // Nightmare Vine - case 28720: - { - if(!unitTarget) - return; - // 25% chance of casting Nightmare Pollen - if(roll_chance_i(75)) - return; - unitTarget->CastSpell(unitTarget, 28721, true); - break; - } - - // Mirren's Drinking Hat - case 29830: - { - uint32 item = 0; - switch ( urand(1,6) ) - { - case 1: case 2: case 3: item = 23584; break;// Loch Modan Lager - case 4: case 5: item = 23585; break;// Stouthammer Lite - case 6: item = 23586; break;// Aerie Peak Pale Ale - } - if (item) - DoCreateItem(effIndex,item); - break; - } - // Improved Sprint - case 30918: - { - // Removes snares and roots. - uint32 mechanic_mask = (1<GetAuras(); - for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next) - { - next = iter; - ++next; - Aura *aur = iter->second; - if (!aur->IsPositive()) //only remove negative spells + // PX-238 Winter Wondervolt TRAP + case 26275: { - // check for mechanic mask - if(GetSpellMechanicMask(aur->GetSpellProto(), aur->GetEffIndex()) & mechanic_mask) + if (unitTarget->HasAura(26272,0) || + unitTarget->HasAura(26157,0) || + unitTarget->HasAura(26273,0) || + unitTarget->HasAura(26274,0)) + return; + + uint32 iTmpSpellId; + switch(urand(0,3)) { - unitTarget->RemoveAurasDueToSpell(aur->GetId()); - if(Auras.empty()) + case 0: iTmpSpellId = 26272; break; + case 1: iTmpSpellId = 26157; break; + case 2: iTmpSpellId = 26273; break; + case 3: iTmpSpellId = 26274; break; + } + + unitTarget->CastSpell(unitTarget, iTmpSpellId, true); + return; + } + // Bending Shinbone + case 8856: + { + if(!itemTarget && m_caster->GetTypeId()!=TYPEID_PLAYER) + return; + + uint32 spell_id = 0; + switch(urand(1,5)) + { + case 1: spell_id = 8854; break; + default: spell_id = 8855; break; + } + + m_caster->CastSpell(m_caster,spell_id,true,NULL); + return; + } + // Brittle Armor - need remove one 24575 Brittle Armor aura + case 24590: + unitTarget->RemoveSingleSpellAurasFromStack(24575); + return; + // Mercurial Shield - need remove one 26464 Mercurial Shield aura + case 26465: + unitTarget->RemoveSingleSpellAurasFromStack(26464); + return; + // Orb teleport spells + case 25140: + case 25143: + case 25650: + case 25652: + case 29128: + case 29129: + case 35376: + case 35727: + { + if(!unitTarget) + return; + + uint32 spellid; + switch(m_spellInfo->Id) + { + case 25140: spellid = 32571; break; + case 25143: spellid = 32572; break; + case 25650: spellid = 30140; break; + case 25652: spellid = 30141; break; + case 29128: spellid = 32568; break; + case 29129: spellid = 32569; break; + case 35376: spellid = 25649; break; + case 35727: spellid = 35730; break; + default: + return; + } + + unitTarget->CastSpell(unitTarget,spellid,false); + return; + } + // Shadow Flame (All script effects, not just end ones to prevent player from dodging the last triggered spell) + case 22539: + case 22972: + case 22975: + case 22976: + case 22977: + case 22978: + case 22979: + case 22980: + case 22981: + case 22982: + case 22983: + case 22984: + case 22985: + { + if(!unitTarget || !unitTarget->isAlive()) + return; + + // Onyxia Scale Cloak + if(unitTarget->GetDummyAura(22683)) + return; + + // Shadow Flame + m_caster->CastSpell(unitTarget, 22682, true); + return; + } + // Summon Black Qiraji Battle Tank + case 26656: + { + if(!unitTarget) + return; + + // Prevent stacking of mounts + unitTarget->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); + + // Two separate mounts depending on area id (allows use both in and out of specific instance) + if (unitTarget->GetAreaId() == 3428) + unitTarget->CastSpell(unitTarget, 25863, false); + else + unitTarget->CastSpell(unitTarget, 26655, false); + break; + } + // Piccolo of the Flaming Fire + case 17512: + { + if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + unitTarget->HandleEmoteCommand(EMOTE_STATE_DANCE); + break; + } + // Mirren's Drinking Hat + case 29830: + { + uint32 item = 0; + switch ( urand(1,6) ) + { + case 1:case 2:case 3: + item = 23584;break; // Loch Modan Lager + case 4:case 5: + item = 23585;break; // Stouthammer Lite + case 6: + item = 23586;break; // Aerie Peak Pale Ale + } + if (item) + DoCreateItem(effIndex,item); + break; + } + // Improved Sprint + case 30918: + { + // Removes snares and roots. + uint32 mechanic_mask = (1<GetAuras(); + for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next) + { + next = iter; + ++next; + Aura *aur = iter->second; + if (!aur->IsPositive()) //only remove negative spells + { + // check for mechanic mask + if(GetSpellMechanicMask(aur->GetSpellProto(), aur->GetEffIndex()) & mechanic_mask) + { + unitTarget->RemoveAurasDueToSpell(aur->GetId()); + if(Auras.empty()) + break; + else + next = Auras.begin(); + } + } + } + break; + } + // Flame Crash + case 41126: + { + if(!unitTarget) + return; + + unitTarget->CastSpell(unitTarget, 41131, true); + break; + } + // Force Cast - Portal Effect: Sunwell Isle + case 44876: + { + if(!unitTarget) + return; + + unitTarget->CastSpell(unitTarget, 44870, true); + break; + } + // Goblin Weather Machine + case 46203: + { + if(!unitTarget) + return; + + uint32 spellId; + switch(rand()%4) + { + case 0: + spellId=46740; + break; + case 1: + spellId=46739; + break; + case 2: + spellId=46738; + break; + case 3: + spellId=46736; + break; + } + unitTarget->CastSpell(unitTarget, spellId, true); + break; + } + //5,000 Gold + case 46642: + { + if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + ((Player*)unitTarget)->ModifyMoney(50000000); + + break; + } + case 51770: + { + if(!unitTarget) + return; + + unitTarget->CastSpell(unitTarget,51771,false); + break; + } + } + break; + } + case SPELLFAMILY_WARLOCK: + { + switch(m_spellInfo->Id) + { + // Healthstone creating spells + case 6201: + case 6202: + case 5699: + case 11729: + case 11730: + case 27230: + case 47871: + case 47878: + { + uint32 itemtype; + uint32 rank = 0; + Unit::AuraList const& mDummyAuras = unitTarget->GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i) + { + if((*i)->GetId() == 18692) + { + rank = 1; break; - else - next = Auras.begin(); + } + else if((*i)->GetId() == 18693) + { + rank = 2; + break; + } } - } - } - break; - } - case 41126: // Flame Crash - { - if(!unitTarget) - return; - unitTarget->CastSpell(unitTarget, 41131, true); - break; - } - case 44876: // Force Cast - Portal Effect: Sunwell Isle - { - if(!unitTarget) - return; + static uint32 const itypes[8][3] = { + { 5512,19004,19005}, // Minor Healthstone + { 5511,19006,19007}, // Lesser Healthstone + { 5509,19008,19009}, // Healthstone + { 5510,19010,19011}, // Greater Healthstone + { 9421,19012,19013}, // Major Healthstone + {22103,22104,22105}, // Master Healthstone + {36889,36890,36891}, // Demonic Healthstone + {36892,36893,36894} // Fel Healthstone + }; - unitTarget->CastSpell(unitTarget, 44870, true); - break; - } - - // Goblin Weather Machine - case 46203: - { - if(!unitTarget) - return; - - uint32 spellId; - switch(rand()%4) - { - case 0: - spellId=46740; - break; - case 1: - spellId=46739; - break; - case 2: - spellId=46738; - break; - case 3: - spellId=46736; - break; - } - unitTarget->CastSpell(unitTarget, spellId, true); - break; - } - //5,000 Gold - case 46642: - { - if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) - return; - - ((Player*)unitTarget)->ModifyMoney(50000000); - - break; - } - case 51770: - { - if(!unitTarget) - return; - - unitTarget->CastSpell(unitTarget,51771,false); - break; - } - } - if( m_spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER ) - { - switch(m_spellInfo->Id) - { - // Chimera Shot - case 53209: - { - uint32 spellId = 0; - int32 basePoint = 0; - Unit::AuraMap& Auras = unitTarget->GetAuras(); - for(Unit::AuraMap::iterator i = Auras.begin(); i != Auras.end(); ++i) - { - Aura *aura = (*i).second; - if (aura->GetCasterGUID() != m_caster->GetGUID()) - continue; - // Search only Serpent Sting, Viper Sting, Scorpid Sting auras - uint64 familyFlag = aura->GetSpellProto()->SpellFamilyFlags; - if (!(familyFlag & 0x000000800000C000LL)) - continue; - // Refresh aura duration - aura->RefreshAura(); - - // Serpent Sting - Instantly deals 40% of the damage done by your Serpent Sting. - if (familyFlag & 0x0000000000004000LL && aura->GetEffIndex() == 0) + switch(m_spellInfo->Id) { - spellId = 53353; // 53353 Chimera Shot - Serpent - basePoint = aura->GetModifier()->m_amount * 5 * 40 / 100; + case 6201: + itemtype=itypes[0][rank];break; // Minor Healthstone + case 6202: + itemtype=itypes[1][rank];break; // Lesser Healthstone + case 5699: + itemtype=itypes[2][rank];break; // Healthstone + case 11729: + itemtype=itypes[3][rank];break; // Greater Healthstone + case 11730: + itemtype=itypes[4][rank];break; // Major Healthstone + case 27230: + itemtype=itypes[5][rank];break; // Master Healthstone + case 47871: + itemtype=itypes[6][rank];break; // Demonic Healthstone + case 47878: + itemtype=itypes[7][rank];break; // Fel Healthstone + default: + return; } - // Viper Sting - Instantly restores mana to you equal to 60% of the total amount drained by your Viper Sting. - if (familyFlag & 0x0000008000000000LL && aura->GetEffIndex() == 0) - { - spellId = 53358; // 53358 Chimera Shot - Viper - basePoint = aura->GetModifier()->m_amount * 4 * 60 / 100; - } - // Scorpid Sting - Attempts to Disarm the target for 10 sec. This effect cannot occur more than once per 1 minute. - if (familyFlag & 0x0000000000008000LL) - spellId = 53359; // 53359 Chimera Shot - Scorpid - // ?? nothing say in spell desc (possibly need addition check) - //if (familyFlag & 0x0000010000000000LL || // dot - // familyFlag & 0x0000100000000000LL) // stun - //{ - // spellId = 53366; // 53366 Chimera Shot - Wyvern - //} - } - if (spellId) - m_caster->CastCustomSpell(unitTarget, spellId, &basePoint, 0, 0, false); - return; - } - default: - break; - } - } - else if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN ) - { - // Judgement - if (m_spellInfo->SpellFamilyFlags & 0x0000000000800000LL) - { - if(!unitTarget || !unitTarget->isAlive()) - return; - uint32 spellId1 = 0; - uint32 spellId2 = 0; - - // Judgement self add switch - switch (m_spellInfo->Id) - { - case 41467: break; // Judgement - case 53407: spellId1 = 20184; break; // Judgement of Justice - case 20271: // Judgement of Light - case 57774: spellId1 = 20185; break; // Judgement of Light - case 53408: spellId1 = 20186; break; // Judgement of Wisdom - default: + DoCreateItem( effIndex, itemtype ); return; + } } - // all seals have aura dummy in 2 effect - Unit::AuraList const& m_dummyAuras = m_caster->GetAurasByType(SPELL_AURA_DUMMY); - for(Unit::AuraList::const_iterator itr = m_dummyAuras.begin(); itr != m_dummyAuras.end(); ++itr) + break; + } + case SPELLFAMILY_HUNTER: + { + switch(m_spellInfo->Id) { - SpellEntry const *spellInfo = (*itr)->GetSpellProto(); - // search seal (all seals have judgement's aura dummy spell id in 2 effect - if ((*itr)->GetEffIndex() != 2 || !spellInfo || !IsSealSpell(spellInfo)) - continue; - spellId2 = (*itr)->GetModifier()->m_amount; - SpellEntry const *judge = sSpellStore.LookupEntry(spellId2); - if (!judge) - continue; - break; + // Chimera Shot + case 53209: + { + uint32 spellId = 0; + int32 basePoint = 0; + Unit::AuraMap& Auras = unitTarget->GetAuras(); + for(Unit::AuraMap::iterator i = Auras.begin(); i != Auras.end(); ++i) + { + Aura *aura = (*i).second; + if (aura->GetCasterGUID() != m_caster->GetGUID()) + continue; + // Search only Serpent Sting, Viper Sting, Scorpid Sting auras + uint64 familyFlag = aura->GetSpellProto()->SpellFamilyFlags; + if (!(familyFlag & 0x000000800000C000LL)) + continue; + // Refresh aura duration + aura->RefreshAura(); + + // Serpent Sting - Instantly deals 40% of the damage done by your Serpent Sting. + if (familyFlag & 0x0000000000004000LL && aura->GetEffIndex() == 0) + { + spellId = 53353; // 53353 Chimera Shot - Serpent + basePoint = aura->GetModifier()->m_amount * 5 * 40 / 100; + } + // Viper Sting - Instantly restores mana to you equal to 60% of the total amount drained by your Viper Sting. + if (familyFlag & 0x0000008000000000LL && aura->GetEffIndex() == 0) + { + spellId = 53358; // 53358 Chimera Shot - Viper + basePoint = aura->GetModifier()->m_amount * 4 * 60 / 100; + } + // Scorpid Sting - Attempts to Disarm the target for 10 sec. This effect cannot occur more than once per 1 minute. + if (familyFlag & 0x0000000000008000LL) + spellId = 53359; // 53359 Chimera Shot - Scorpid + // ?? nothing say in spell desc (possibly need addition check) + //if (familyFlag & 0x0000010000000000LL || // dot + // familyFlag & 0x0000100000000000LL) // stun + //{ + // spellId = 53366; // 53366 Chimera Shot - Wyvern + //} + } + if (spellId) + m_caster->CastCustomSpell(unitTarget, spellId, &basePoint, 0, 0, false); + return; + } + default: + break; } - if (spellId1) - m_caster->CastSpell(unitTarget, spellId1, true); - if (spellId2) - m_caster->CastSpell(unitTarget, spellId2, true); - return; + break; + } + case SPELLFAMILY_PALADIN: + { + // Judgement + if (m_spellInfo->SpellFamilyFlags & 0x0000000000800000LL) + { + if(!unitTarget || !unitTarget->isAlive()) + return; + uint32 spellId1 = 0; + uint32 spellId2 = 0; + + // Judgement self add switch + switch (m_spellInfo->Id) + { + case 41467: break; // Judgement + case 53407: spellId1 = 20184; break; // Judgement of Justice + case 20271: // Judgement of Light + case 57774: spellId1 = 20185; break; // Judgement of Light + case 53408: spellId1 = 20186; break; // Judgement of Wisdom + default: + return; + } + // all seals have aura dummy in 2 effect + Unit::AuraList const& m_dummyAuras = m_caster->GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator itr = m_dummyAuras.begin(); itr != m_dummyAuras.end(); ++itr) + { + SpellEntry const *spellInfo = (*itr)->GetSpellProto(); + // search seal (all seals have judgement's aura dummy spell id in 2 effect + if ((*itr)->GetEffIndex() != 2 || !spellInfo || !IsSealSpell(spellInfo)) + continue; + spellId2 = (*itr)->GetModifier()->m_amount; + SpellEntry const *judge = sSpellStore.LookupEntry(spellId2); + if (!judge) + continue; + break; + } + if (spellId1) + m_caster->CastSpell(unitTarget, spellId1, true); + if (spellId2) + m_caster->CastSpell(unitTarget, spellId2, true); + return; + } + } + case SPELLFAMILY_POTION: + { + switch(m_spellInfo->Id) + { + // Dreaming Glory + case 28698: + { + if(!unitTarget) + return; + unitTarget->CastSpell(unitTarget, 28694, true); + break; + } + // Netherbloom + case 28702: + { + if(!unitTarget) + return; + // 25% chance of casting a random buff + if(roll_chance_i(75)) + return; + + // triggered spells are 28703 to 28707 + // Note: some sources say, that there was the possibility of + // receiving a debuff. However, this seems to be removed by a patch. + const uint32 spellid = 28703; + + // don't overwrite an existing aura + for(uint8 i=0; i<5; i++) + if(unitTarget->HasAura(spellid+i, 0)) + return; + unitTarget->CastSpell(unitTarget, spellid+urand(0, 4), true); + break; + } + + // Nightmare Vine + case 28720: + { + if(!unitTarget) + return; + // 25% chance of casting Nightmare Pollen + if(roll_chance_i(75)) + return; + unitTarget->CastSpell(unitTarget, 28721, true); + break; + } + } + break; } } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index bb9ea8fa5..91f15976c 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7114" + #define REVISION_NR "7115" #endif // __REVISION_NR_H__ From 9af1caccd8480ee96267f2bc2891a50020a6f300 Mon Sep 17 00:00:00 2001 From: arrai Date: Mon, 19 Jan 2009 21:56:39 +0100 Subject: [PATCH 64/84] [7116] added support for spell 50977, still requires entry in `spell_target_position` for triggered spell 53822 --- src/game/SpellEffects.cpp | 10 ++++++++++ src/shared/revision_nr.h | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 93067d835..5e5412496 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -4841,6 +4841,16 @@ void Spell::EffectScriptEffect(uint32 effIndex) unitTarget->CastSpell(unitTarget,51771,false); break; } + // Death Gate + case 52751: + { + if(!unitTarget || unitTarget->getClass() != CLASS_DEATH_KNIGHT) + return; + // triggered spell is stored in m_spellInfo->EffectBasePoints[0] + unitTarget->CastSpell(unitTarget, damage, false); + break; + } + } break; } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 91f15976c..b6df063fc 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7115" + #define REVISION_NR "7116" #endif // __REVISION_NR_H__ From ac9b14d70ce27b78f11edb99957219e5734eeae7 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Mon, 19 Jan 2009 17:55:33 +0300 Subject: [PATCH 65/84] [7116] Correctly show quest/gossip menues. In case non defeault gossip text with quest only In case empty quest and gossip menus and gossip text. --- src/game/Creature.cpp | 4 +--- src/game/GossipDef.cpp | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index c8189cf14..28cb26d94 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -813,10 +813,8 @@ void Creature::sendPreparedGossip(Player* player) if(!player) return; - GossipMenu& gossipmenu = player->PlayerTalkClass->GetGossipMenu(); - // in case empty gossip menu open quest menu if any - if (gossipmenu.Empty() && GetNpcTextId() == 0) + if (player->PlayerTalkClass->GetGossipMenu().Empty() && !player->PlayerTalkClass->GetQuestMenu().Empty()) { player->SendPreparedQuest(GetGUID()); return; diff --git a/src/game/GossipDef.cpp b/src/game/GossipDef.cpp index 7b375f228..8a8dcb736 100644 --- a/src/game/GossipDef.cpp +++ b/src/game/GossipDef.cpp @@ -125,7 +125,7 @@ bool PlayerMenu::GossipOptionCoded( unsigned int Selection ) void PlayerMenu::SendGossipMenu( uint32 TitleTextId, uint64 npcGUID ) { WorldPacket data( SMSG_GOSSIP_MESSAGE, (100) ); // guess size - data << npcGUID; + data << uint64(npcGUID); data << uint32(0); // new 2.4.0 data << uint32( TitleTextId ); data << uint32( mGossipMenu.MenuItemCount() ); // max count 0x0F From ee6072f232a54bfbda5c4cd4c9a92dbd5377d6eb Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Mon, 19 Jan 2009 23:51:07 +0300 Subject: [PATCH 66/84] [7117] Implement explicit recipe discovery abilities. * Implement SPELL_EFFECT_CREATE_ITEM_2 (157). This alos let work many item creating spells. * Add `skill_discovery_template`.`reqClass` for allow clas specific racipes storing in table. * Make primary key for `skill_discovery_template` pair (spellId,reqSpell) that allow have duplicate recipes for different reqSpells. * Implement SPELL_EFFECT_SCRIPT (77) cases for explicit recipe discovery spells with learn spell selected by `skill_discovery_template` data. Note: as expected explicit recipe discovery abilities always return some spell while exist any not learned yet for player class. --- sql/mangos.sql | 5 +- ...117_01_mangos_skill_discovery_template.sql | 6 ++ sql/updates/Makefile.am | 2 + src/game/SharedDefines.h | 2 +- src/game/SkillDiscovery.cpp | 81 ++++++++++++++++--- src/game/Spell.cpp | 2 +- src/game/Spell.h | 1 - src/game/SpellEffects.cpp | 38 +++++++-- src/game/SpellMgr.h | 5 ++ src/shared/revision_nr.h | 2 +- 10 files changed, 118 insertions(+), 26 deletions(-) create mode 100644 sql/updates/7117_01_mangos_skill_discovery_template.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index 8d4088f95..b2e3c89e0 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -22,7 +22,7 @@ DROP TABLE IF EXISTS `db_version`; CREATE TABLE `db_version` ( `version` varchar(120) default NULL, - `required_7107_01_mangos_string` bit(1) default NULL + `required_7117_01_mangos_skill_discovery_template` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -12999,8 +12999,9 @@ DROP TABLE IF EXISTS `skill_discovery_template`; CREATE TABLE `skill_discovery_template` ( `spellId` mediumint(8) unsigned NOT NULL default '0' COMMENT 'SpellId of the discoverable spell', `reqSpell` mediumint(8) unsigned NOT NULL default '0' COMMENT 'spell requirement', + `reqClass` tinyint(2) unsigned NOT NULL default '0' COMMENT 'class requirement', `chance` float NOT NULL default '0' COMMENT 'chance to discover', - PRIMARY KEY (`spellId`) + PRIMARY KEY (`spellId`,`reqSpell`), ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Skill Discovery System'; -- diff --git a/sql/updates/7117_01_mangos_skill_discovery_template.sql b/sql/updates/7117_01_mangos_skill_discovery_template.sql new file mode 100644 index 000000000..c9cb8ad7c --- /dev/null +++ b/sql/updates/7117_01_mangos_skill_discovery_template.sql @@ -0,0 +1,6 @@ +ALTER TABLE db_version CHANGE COLUMN required_7107_01_mangos_string required_7117_01_mangos_skill_discovery_template bit; + +ALTER TABLE skill_discovery_template + DROP PRIMARY KEY, + ADD PRIMARY KEY (`spellId`,`reqSpell`), + ADD COLUMN reqClass tinyint(2) unsigned NOT NULL default '0' COMMENT 'class requirement' AFTER reqSpell; diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 2cee52875..648949442 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -142,6 +142,7 @@ pkgdata_DATA = \ 7100_01_characters_character_spell.sql \ 7107_01_mangos_string.sql \ 7113_01_characters_character_achievement_progress.sql \ + 7117_01_mangos_skill_discovery_template.sql \ README ## Additional files to include when running 'make dist' @@ -264,4 +265,5 @@ EXTRA_DIST = \ 7100_01_characters_character_spell.sql \ 7107_01_mangos_string.sql \ 7113_01_characters_character_achievement_progress.sql \ + 7117_01_mangos_skill_discovery_template.sql \ README diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index cf4c90549..08c9f8be6 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -675,7 +675,7 @@ enum SpellEffects SPELL_EFFECT_154 = 154, SPELL_EFFECT_TITAN_GRIP = 155, SPELL_EFFECT_ADD_SOCKET = 156, - SPELL_EFFECT_157 = 157, + SPELL_EFFECT_CREATE_ITEM_2 = 157, SPELL_EFFECT_MILLING = 158, SPELL_EFFECT_ALLOW_RENAME_PET = 159, TOTAL_SPELL_EFFECTS = 160 diff --git a/src/game/SkillDiscovery.cpp b/src/game/SkillDiscovery.cpp index 7a2281428..eb7b687bf 100644 --- a/src/game/SkillDiscovery.cpp +++ b/src/game/SkillDiscovery.cpp @@ -29,14 +29,15 @@ struct SkillDiscoveryEntry { - uint32 spellId; - float chance; + uint32 spellId; // discavered spell + uint32 reqClass; // class limitation + float chance; // chance SkillDiscoveryEntry() - : spellId(0), chance(0) {} + : spellId(0), reqClass(0), chance(0) {} - SkillDiscoveryEntry(uint16 _spellId, float _chance) - : spellId(_spellId), chance(_chance) {} + SkillDiscoveryEntry(uint16 _spellId, uint32 req_class, float _chance) + : spellId(_spellId), reqClass(req_class), chance(_chance) {} }; typedef std::list SkillDiscoveryList; @@ -51,8 +52,8 @@ void LoadSkillDiscoveryTable() uint32 count = 0; - // 0 1 2 - QueryResult *result = WorldDatabase.Query("SELECT spellId, reqSpell, chance FROM skill_discovery_template"); + // 0 1 2 3 + QueryResult *result = WorldDatabase.Query("SELECT spellId, reqSpell, reqClass, chance FROM skill_discovery_template"); if (result) { @@ -67,11 +68,18 @@ void LoadSkillDiscoveryTable() uint32 spellId = fields[0].GetUInt32(); int32 reqSkillOrSpell = fields[1].GetInt32(); - float chance = fields[2].GetFloat(); + uint32 reqClass = fields[2].GetInt32(); + float chance = fields[3].GetFloat(); if( chance <= 0 ) // chance { - ssNonDiscoverableEntries << "spellId = " << spellId << " reqSkillOrSpell = " << reqSkillOrSpell << " chance = " << chance << "\n"; + ssNonDiscoverableEntries << "spellId = " << spellId << " reqSkillOrSpell = " << reqSkillOrSpell << " reqClass = " << reqClass << " chance = " << chance << "(chance problem)\n"; + continue; + } + + if(reqClass && (reqClass >= MAX_CLASSES || ((1 << (reqClass-1)) & CLASSMASK_ALL_PLAYABLE)==0)) + { + ssNonDiscoverableEntries << "spellId = " << spellId << " reqSkillOrSpell = " << reqSkillOrSpell << " reqClass = " << reqClass << " chance = " << chance << "(class problem)\n"; continue; } @@ -84,13 +92,16 @@ void LoadSkillDiscoveryTable() continue; } - if( spellEntry->Mechanic != MECHANIC_DISCOVERY ) + // mechanic discovery + if (spellEntry->Mechanic != MECHANIC_DISCOVERY && + // explicit discovery ability + !IsExplicitDiscoverySpell(spellEntry)) { - sLog.outErrorDb("Spell (ID: %u) not have have MECHANIC_DISCOVERY (28) value in Mechanic field in spell.dbc but listed in `skill_discovery_template` table",spellId); + sLog.outErrorDb("Spell (ID: %u) not have have MECHANIC_DISCOVERY (28) value in Mechanic field in spell.dbc and not 100% chance random discovery ability but listed in `skill_discovery_template` table",spellId); continue; } - SkillDiscoveryStore[reqSkillOrSpell].push_back( SkillDiscoveryEntry(spellId, chance) ); + SkillDiscoveryStore[reqSkillOrSpell].push_back( SkillDiscoveryEntry(spellId, reqClass, chance) ); } else if( reqSkillOrSpell == 0 ) // skill case { @@ -105,7 +116,7 @@ void LoadSkillDiscoveryTable() for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx) { - SkillDiscoveryStore[-int32(_spell_idx->second->skillId)].push_back( SkillDiscoveryEntry(spellId, chance) ); + SkillDiscoveryStore[-int32(_spell_idx->second->skillId)].push_back( SkillDiscoveryEntry(spellId, reqClass, chance) ); } } else @@ -113,6 +124,7 @@ void LoadSkillDiscoveryTable() sLog.outErrorDb("Spell (ID: %u) have negative value in `reqSpell` field in `skill_discovery_template` table",spellId); continue; } + ++count; } while (result->NextRow()); @@ -137,8 +149,45 @@ uint32 GetSkillDiscoverySpell(uint32 skillId, uint32 spellId, Player* player) if(tab != SkillDiscoveryStore.end()) { + SpellEntry const* spellInfo = sSpellStore.LookupEntry (spellId); + if(!spellInfo) + return 0; + + // explicit discovery spell chances (alwasy success if case exist) + if(IsExplicitDiscoverySpell(spellInfo)) + { + float full_chance = 0; + for(SkillDiscoveryList::iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter) + if(!item_iter->reqClass || player->getClass ()==item_iter->reqClass) + if(!player->HasSpell(item_iter->spellId)) + full_chance += item_iter->chance; + + float rate = full_chance / 100.0f; + float roll = rand_chance() * rate; // roll now in range 0..full_chance + + for(SkillDiscoveryList::iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter) + { + if(item_iter->reqClass && player->getClass ()!= item_iter->reqClass) + continue; + + if(player->HasSpell(item_iter->spellId)) + continue; + + if(item_iter->chance > roll) + return item_iter->spellId; + + roll -= item_iter->chance; + } + + return 0; + } + + for(SkillDiscoveryList::iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter) { + if(item_iter->reqClass && player->getClass ()!= item_iter->reqClass) + continue; + if( roll_chance_f(item_iter->chance * sWorld.getRate(RATE_SKILL_DISCOVERY)) && !player->HasSpell(item_iter->spellId) ) return item_iter->spellId; @@ -147,12 +196,18 @@ uint32 GetSkillDiscoverySpell(uint32 skillId, uint32 spellId, Player* player) return 0; } + if(!skillId) + return 0; + // check skill line case tab = SkillDiscoveryStore.find(-(int32)skillId); if(tab != SkillDiscoveryStore.end()) { for(SkillDiscoveryList::iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter) { + if(item_iter->reqClass && player->getClass ()!= item_iter->reqClass) + continue; + if( roll_chance_f(item_iter->chance * sWorld.getRate(RATE_SKILL_DISCOVERY)) && !player->HasSpell(item_iter->spellId) ) return item_iter->spellId; diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 53a23275d..b59412bfa 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -3078,7 +3078,7 @@ void Spell::SendLogExecute() data << uint8(0); break; case SPELL_EFFECT_CREATE_ITEM: - case SPELL_EFFECT_157: + case SPELL_EFFECT_CREATE_ITEM_2: data << uint32(m_spellInfo->EffectItemType[0]); break; case SPELL_EFFECT_SUMMON: diff --git a/src/game/Spell.h b/src/game/Spell.h index 5befc6789..bbe50f5c0 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -358,7 +358,6 @@ class Spell void setState(uint32 state) { m_spellState = state; } void DoCreateItem(uint32 i, uint32 itemtype); - void WriteSpellGoTargets( WorldPacket * data ); void WriteAmmoToPacket( WorldPacket * data ); void FillTargetMap(); diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 5e5412496..c95963817 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -54,6 +54,7 @@ #include "Util.h" #include "TemporarySummon.h" #include "ScriptCalls.h" +#include "SkillDiscovery.h" pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= { @@ -214,7 +215,7 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= &Spell::EffectNULL, //154 unused &Spell::EffectTitanGrip, //155 SPELL_EFFECT_TITAN_GRIP Allows you to equip two-handed axes, maces and swords in one hand, but you attack $49152s1% slower than normal. &Spell::EffectNULL, //156 Add Socket - &Spell::EffectNULL, //157 create/learn random item/spell for profession + &Spell::EffectCreateItem, //157 SPELL_EFFECT_CREATE_ITEM_2 create/learn item/spell for profession &Spell::EffectMilling, //158 milling &Spell::EffectNULL //159 allow rename pet once again }; @@ -4599,12 +4600,6 @@ void Spell::EffectScriptEffect(uint32 effIndex) { // TODO: we must implement hunter pet summon at login there (spell 6962) - // by spell id - switch(m_spellInfo->Id) - { - - } - switch(m_spellInfo->SpellFamilyName) { case SPELLFAMILY_GENERIC: @@ -4833,6 +4828,7 @@ void Spell::EffectScriptEffect(uint32 effIndex) break; } + // Emblazon Runeblade case 51770: { if(!unitTarget) @@ -4850,7 +4846,35 @@ void Spell::EffectScriptEffect(uint32 effIndex) unitTarget->CastSpell(unitTarget, damage, false); break; } + // random spell learn instead placeholder + case 60893: // Northrend Alchemy Research + case 61177: // Northrend Inscription Research + case 61288: // Minor Inscription Research + case 61756: // Northrend Inscription Research (FAST QA VERSION) + { + if(!IsExplicitDiscoverySpell(m_spellInfo)) + { + sLog.outError("Wrong explicit discowry spell %u structure, or outdated...",m_spellInfo->Id); + return; + } + if(m_caster->GetTypeId()!=TYPEID_PLAYER) + return; + Player* player = (Player*)m_caster; + + // need replace effect 0 item by loot + uint32 reagent_id = m_spellInfo->EffectItemType[0]; + if(!player->HasItemCount(reagent_id,1)) + return; + + // remove reagent + uint32 count = 1; + player->DestroyItemCount (reagent_id,count,true); + + if(uint32 discoveredSpell = GetSkillDiscoverySpell(0, m_spellInfo->Id, player)) + player->learnSpell(discoveredSpell); + return; + } } break; } diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index 1ae82e7c1..7f2b8803b 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -312,6 +312,11 @@ inline bool IsElementalShield(SpellEntry const *spellInfo) return (spellInfo->SpellFamilyFlags & 0x42000000400LL) || spellInfo->Id == 23552; } +inline bool IsExplicitDiscoverySpell(SpellEntry const *spellInfo) +{ + return spellInfo->Effect[0]==SPELL_EFFECT_CREATE_ITEM_2 && spellInfo->Effect[1]==SPELL_EFFECT_SCRIPT_EFFECT; +} + int32 CompareAuraRanks(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2); bool IsSingleFromSpellSpecificPerCaster(uint32 spellSpec1,uint32 spellSpec2); bool IsPassiveSpell(uint32 spellId); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index b6df063fc..baa9e020a 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7116" + #define REVISION_NR "7117" #endif // __REVISION_NR_H__ From dab1f96f667049843cf73e375f0dd294bb5f9fc7 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Mon, 19 Jan 2009 23:51:07 +0300 Subject: [PATCH 67/84] [7118] resolve problems with partly appied [7117] --- sql/mangos.sql | 4 ++-- ...mplate.sql => 7118_01_mangos_skill_discovery_template.sql} | 2 +- sql/updates/Makefile.am | 4 ++-- src/game/SkillDiscovery.cpp | 2 +- src/shared/revision_nr.h | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) rename sql/updates/{7117_01_mangos_skill_discovery_template.sql => 7118_01_mangos_skill_discovery_template.sql} (82%) diff --git a/sql/mangos.sql b/sql/mangos.sql index b2e3c89e0..b2198d4f7 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -22,7 +22,7 @@ DROP TABLE IF EXISTS `db_version`; CREATE TABLE `db_version` ( `version` varchar(120) default NULL, - `required_7117_01_mangos_skill_discovery_template` bit(1) default NULL + `required_7118_01_mangos_skill_discovery_template` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -13001,7 +13001,7 @@ CREATE TABLE `skill_discovery_template` ( `reqSpell` mediumint(8) unsigned NOT NULL default '0' COMMENT 'spell requirement', `reqClass` tinyint(2) unsigned NOT NULL default '0' COMMENT 'class requirement', `chance` float NOT NULL default '0' COMMENT 'chance to discover', - PRIMARY KEY (`spellId`,`reqSpell`), + PRIMARY KEY (`spellId`,`reqSpell`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Skill Discovery System'; -- diff --git a/sql/updates/7117_01_mangos_skill_discovery_template.sql b/sql/updates/7118_01_mangos_skill_discovery_template.sql similarity index 82% rename from sql/updates/7117_01_mangos_skill_discovery_template.sql rename to sql/updates/7118_01_mangos_skill_discovery_template.sql index c9cb8ad7c..f854855e6 100644 --- a/sql/updates/7117_01_mangos_skill_discovery_template.sql +++ b/sql/updates/7118_01_mangos_skill_discovery_template.sql @@ -1,4 +1,4 @@ -ALTER TABLE db_version CHANGE COLUMN required_7107_01_mangos_string required_7117_01_mangos_skill_discovery_template bit; +ALTER TABLE db_version CHANGE COLUMN required_7107_01_mangos_string required_7118_01_mangos_skill_discovery_template bit; ALTER TABLE skill_discovery_template DROP PRIMARY KEY, diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 648949442..0632de798 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -142,7 +142,7 @@ pkgdata_DATA = \ 7100_01_characters_character_spell.sql \ 7107_01_mangos_string.sql \ 7113_01_characters_character_achievement_progress.sql \ - 7117_01_mangos_skill_discovery_template.sql \ + 7118_01_mangos_skill_discovery_template.sql \ README ## Additional files to include when running 'make dist' @@ -265,5 +265,5 @@ EXTRA_DIST = \ 7100_01_characters_character_spell.sql \ 7107_01_mangos_string.sql \ 7113_01_characters_character_achievement_progress.sql \ - 7117_01_mangos_skill_discovery_template.sql \ + 7118_01_mangos_skill_discovery_template.sql \ README diff --git a/src/game/SkillDiscovery.cpp b/src/game/SkillDiscovery.cpp index eb7b687bf..fb24eb1c0 100644 --- a/src/game/SkillDiscovery.cpp +++ b/src/game/SkillDiscovery.cpp @@ -93,7 +93,7 @@ void LoadSkillDiscoveryTable() } // mechanic discovery - if (spellEntry->Mechanic != MECHANIC_DISCOVERY && + if (spellEntry->Mechanic != MECHANIC_DISCOVERY && // explicit discovery ability !IsExplicitDiscoverySpell(spellEntry)) { diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index baa9e020a..01eb472e8 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7117" + #define REVISION_NR "7118" #endif // __REVISION_NR_H__ From a97d49bdc5e6d802f1c3821fba21616c324037c0 Mon Sep 17 00:00:00 2001 From: Wyk3d Date: Tue, 20 Jan 2009 00:46:56 +0200 Subject: [PATCH 68/84] [7119] Fixed some typos that caused a freeze --- src/game/SpellEffects.cpp | 2 +- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index c95963817..09697eb02 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -492,7 +492,7 @@ void Spell::EffectSchoolDMG(uint32 effect_idx) Aura *poison = 0; // Lookup for Deadly poison (only attacker applied) Unit::AuraList const& auras = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE); - for(Unit::AuraList::const_iterator itr = auras.begin(); itr!=auras.end() && combo;) + for(Unit::AuraList::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr) if( (*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_ROGUE && (*itr)->GetSpellProto()->SpellFamilyFlags & 0x10000 && (*itr)->GetCasterGUID()==m_caster->GetGUID() ) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 01eb472e8..3b1bfe2a6 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7118" + #define REVISION_NR "7119" #endif // __REVISION_NR_H__ From dffdb47fb9ede109f4837cdc1f075f90a9d7971d Mon Sep 17 00:00:00 2001 From: Wyk3d Date: Tue, 20 Jan 2009 01:29:39 +0200 Subject: [PATCH 69/84] [7120] Revert "Reduced number of cells (doubled max visibility distance)." --- src/game/GridDefines.h | 4 ++-- src/mangosd/mangosd.conf.dist.in | 12 ++++++------ src/shared/revision_nr.h | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/game/GridDefines.h b/src/game/GridDefines.h index 03e8cc100..54cdca7b6 100644 --- a/src/game/GridDefines.h +++ b/src/game/GridDefines.h @@ -41,10 +41,10 @@ class Player; #define MIN_GRID_DELAY MINUTE*1000 #define MIN_MAP_UPDATE_DELAY 50 -#define MAX_NUMBER_OF_CELLS 4 +#define MAX_NUMBER_OF_CELLS 8 #define SIZE_OF_GRID_CELL (SIZE_OF_GRIDS/MAX_NUMBER_OF_CELLS) -#define CENTER_GRID_CELL_ID 128 +#define CENTER_GRID_CELL_ID 256 #define CENTER_GRID_CELL_OFFSET (SIZE_OF_GRID_CELL/2) #define TOTAL_NUMBER_OF_CELLS_PER_MAP (MAX_NUMBER_OF_GRIDS*MAX_NUMBER_OF_CELLS) diff --git a/src/mangosd/mangosd.conf.dist.in b/src/mangosd/mangosd.conf.dist.in index 241258ced..700e1c3c8 100644 --- a/src/mangosd/mangosd.conf.dist.in +++ b/src/mangosd/mangosd.conf.dist.in @@ -899,9 +899,9 @@ GM.LowerSecurity = 0 # Visibility.Distance.Creature # Visibility.Distance.Player # Visibility distance for different in game object -# Max limited by active player zone: ~ 333 +# Max limited by active player zone: ~ 166 # Min limit dependent from objects -# Default: 132 (cell size) +# Default: 66 (cell size) # Min limit is max aggro radius (45) * Rate.Creature.Aggro # # Visibility.Distance.Object @@ -927,10 +927,10 @@ GM.LowerSecurity = 0 ################################################################################################################### Visibility.GroupMode = 0 -Visibility.Distance.Creature = 132 -Visibility.Distance.Player = 132 -Visibility.Distance.Object = 132 -Visibility.Distance.InFlight = 132 +Visibility.Distance.Creature = 66 +Visibility.Distance.Player = 66 +Visibility.Distance.Object = 66 +Visibility.Distance.InFlight = 66 Visibility.Distance.Grey.Unit = 1 Visibility.Distance.Grey.Object = 10 diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 3b1bfe2a6..1171817aa 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7119" + #define REVISION_NR "7120" #endif // __REVISION_NR_H__ From 6ef0e056b0fbd2abaf2b3368529417bf6e88d87e Mon Sep 17 00:00:00 2001 From: arrai Date: Tue, 20 Jan 2009 01:53:07 +0100 Subject: [PATCH 70/84] [7121] Fixed ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT --- src/game/AchievementMgr.cpp | 6 +++++- src/shared/revision_nr.h | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp index 6fb0497db..2ae665c16 100644 --- a/src/game/AchievementMgr.cpp +++ b/src/game/AchievementMgr.cpp @@ -404,6 +404,10 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if(GetPlayer()->HasSpell(achievementCriteria->learn_spell.spellID)) SetCriteriaProgress(achievementCriteria, 1); break; + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT: + if(m_completedAchievements.find(achievementCriteria->complete_achievement.linkedAchievement) != m_completedAchievements.end()) + SetCriteriaProgress(achievementCriteria, 1); + break; case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP: // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case if(!miscvalue1) @@ -646,7 +650,7 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE: return progress->counter >= achievementCriteria->kill_creature.creatureCount; case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT: - return m_completedAchievements.find(achievementCriteria->complete_achievement.linkedAchievement) != m_completedAchievements.end(); + return progress->counter >= 1; case ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL: return progress->counter >= achievementCriteria->reach_skill_level.skillLevel; case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT: diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 1171817aa..70862d168 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7120" + #define REVISION_NR "7121" #endif // __REVISION_NR_H__ From 8171c9c61a21a0cc3247af6af7902e731b82138e Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Tue, 20 Jan 2009 15:31:58 +0300 Subject: [PATCH 71/84] [7122] Initilize UnitActionBarEntry fields. --- src/game/Unit.h | 2 ++ src/shared/revision_nr.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/game/Unit.h b/src/game/Unit.h index 8a6226579..94b4bcf15 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -646,6 +646,8 @@ uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missC struct UnitActionBarEntry { + UnitActionBarEntry() : Raw(0) {} + union { struct diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 70862d168..e234026a8 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7121" + #define REVISION_NR "7122" #endif // __REVISION_NR_H__ From ce384c52788c61cbbb913abc8ca4d9120e4eeb0f Mon Sep 17 00:00:00 2001 From: Balrok Date: Tue, 20 Jan 2009 20:04:12 +0100 Subject: [PATCH 72/84] [7123] Cleanup in using STD's containers erase method. Signed-off-by: ApoC --- src/game/AuctionHouseObject.h | 12 ++---------- src/game/ObjectAccessor.cpp | 16 ---------------- src/game/ObjectAccessor.h | 22 +++++++++++++--------- src/game/Player.h | 12 ++---------- src/game/SocialMgr.cpp | 7 ------- src/game/SocialMgr.h | 3 ++- src/game/Transports.cpp | 5 +---- src/game/Unit.h | 13 ++----------- src/shared/revision_nr.h | 2 +- 9 files changed, 23 insertions(+), 69 deletions(-) diff --git a/src/game/AuctionHouseObject.h b/src/game/AuctionHouseObject.h index 077991e8c..927063eb6 100644 --- a/src/game/AuctionHouseObject.h +++ b/src/game/AuctionHouseObject.h @@ -82,20 +82,12 @@ class AuctionHouseObject AuctionEntry* GetAuction(uint32 id) const { AuctionEntryMap::const_iterator itr = AuctionsMap.find( id ); - if( itr != AuctionsMap.end() ) - return itr->second; - return NULL; + return itr != AuctionsMap.end() ? itr->second : NULL; } bool RemoveAuction(uint32 id) { - AuctionEntryMap::iterator i = AuctionsMap.find(id); - if (i == AuctionsMap.end()) - { - return false; - } - AuctionsMap.erase(i); - return true; + return AuctionsMap.erase(id) ? true : false; } private: diff --git a/src/game/ObjectAccessor.cpp b/src/game/ObjectAccessor.cpp index 53b6c245f..447ec2059 100644 --- a/src/game/ObjectAccessor.cpp +++ b/src/game/ObjectAccessor.cpp @@ -274,22 +274,6 @@ ObjectAccessor::UpdateObject(Object* obj, Player* exceptPlayer) } } -void -ObjectAccessor::AddUpdateObject(Object *obj) -{ - Guard guard(i_updateGuard); - i_objects.insert(obj); -} - -void -ObjectAccessor::RemoveUpdateObject(Object *obj) -{ - Guard guard(i_updateGuard); - std::set::iterator iter = i_objects.find(obj); - if( iter != i_objects.end() ) - i_objects.erase( iter ); -} - void ObjectAccessor::_buildUpdateObject(Object *obj, UpdateDataMapType &update_players) { diff --git a/src/game/ObjectAccessor.h b/src/game/ObjectAccessor.h index eb09f6385..102da6984 100644 --- a/src/game/ObjectAccessor.h +++ b/src/game/ObjectAccessor.h @@ -57,9 +57,7 @@ class HashMapHolder static void Remove(T* o) { Guard guard(i_lock); - typename MapType::iterator itr = m_objectMap.find(o->GetGUID()); - if (itr != m_objectMap.end()) - m_objectMap.erase(itr); + m_objectMap.erase(o->GetGUID()); } static T* Find(uint64 guid) @@ -174,16 +172,22 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton::Remove(pl); Guard guard(i_updateGuard); - - std::set::iterator iter2 = std::find(i_objects.begin(), i_objects.end(), (Object *)pl); - if( iter2 != i_objects.end() ) - i_objects.erase(iter2); + i_objects.erase((Object *)pl); } void SaveAllPlayers(); - void AddUpdateObject(Object *obj); - void RemoveUpdateObject(Object *obj); + void AddUpdateObject(Object *obj) + { + Guard guard(i_updateGuard); + i_objects.insert(obj); + } + + void RemoveUpdateObject(Object *obj) + { + Guard guard(i_updateGuard); + i_objects.erase( obj ); + } void Update(uint32 diff); void UpdatePlayers(uint32 diff); diff --git a/src/game/Player.h b/src/game/Player.h index 2e962a9f3..b5448c2c4 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1454,10 +1454,7 @@ class MANGOS_DLL_SPEC Player : public Unit Item* GetMItem(uint32 id) { ItemMap::const_iterator itr = mMitems.find(id); - if (itr != mMitems.end()) - return itr->second; - - return NULL; + return itr != mMitems.end() ? itr->second : NULL; } void AddMItem(Item* it) @@ -1469,12 +1466,7 @@ class MANGOS_DLL_SPEC Player : public Unit bool RemoveMItem(uint32 id) { - ItemMap::iterator i = mMitems.find(id); - if (i == mMitems.end()) - return false; - - mMitems.erase(i); - return true; + return mMitems.erase(id) ? true : false; } void PetSpellInitialize(); diff --git a/src/game/SocialMgr.cpp b/src/game/SocialMgr.cpp index b7dba46a9..e620e8881 100644 --- a/src/game/SocialMgr.cpp +++ b/src/game/SocialMgr.cpp @@ -180,13 +180,6 @@ SocialMgr::~SocialMgr() } -void SocialMgr::RemovePlayerSocial(uint32 guid) -{ - SocialMap::iterator itr = m_socialMap.find(guid); - if(itr != m_socialMap.end()) - m_socialMap.erase(itr); -} - void SocialMgr::GetFriendInfo(Player *player, uint32 friendGUID, FriendInfo &friendInfo) { if(!player) diff --git a/src/game/SocialMgr.h b/src/game/SocialMgr.h index a06cde39a..d76d44625 100644 --- a/src/game/SocialMgr.h +++ b/src/game/SocialMgr.h @@ -141,7 +141,8 @@ class SocialMgr SocialMgr(); ~SocialMgr(); // Misc - void RemovePlayerSocial(uint32 guid); + void RemovePlayerSocial(uint32 guid) { m_socialMap.erase(guid); } + void GetFriendInfo(Player *player, uint32 friendGUID, FriendInfo &friendInfo); // Packet management void MakeFriendStatusPacket(FriendsResult result, uint32 friend_guid, WorldPacket *data); diff --git a/src/game/Transports.cpp b/src/game/Transports.cpp index d0de6afd4..dfe12119a 100644 --- a/src/game/Transports.cpp +++ b/src/game/Transports.cpp @@ -473,11 +473,8 @@ bool Transport::AddPassenger(Player* passenger) bool Transport::RemovePassenger(Player* passenger) { - if (m_passengers.find(passenger) != m_passengers.end()) - { + if (m_passengers.erase(passenger)) sLog.outDetail("Player %s removed from transport %s.", passenger->GetName(), m_name.c_str()); - m_passengers.erase(passenger); - } return true; } diff --git a/src/game/Unit.h b/src/game/Unit.h index 94b4bcf15..a779ba874 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -803,9 +803,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject } void _removeAttacker(Unit *pAttacker) // must be called only from Unit::AttackStop() { - AttackerSet::iterator itr = m_attackers.find(pAttacker); - if(itr != m_attackers.end()) - m_attackers.erase(itr); + m_attackers.erase(pAttacker); } Unit * getAttackerForHelper() // If someone wants to help, who to give them { @@ -1240,14 +1238,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject void SetVisibleAura(uint8 slot, uint32 spellid) { if(spellid == 0) - { - VisibleAuraMap::iterator itr = m_visibleAuras.find(slot); - if(itr != m_visibleAuras.end()) - { - m_visibleAuras.erase(itr); - return; - } - } + m_visibleAuras.erase(slot); else m_visibleAuras[slot] = spellid; } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index e234026a8..5503b0fde 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7122" + #define REVISION_NR "7123" #endif // __REVISION_NR_H__ From 220aa56fed83b33326000b250147c43e9e63710a Mon Sep 17 00:00:00 2001 From: ApoC Date: Tue, 20 Jan 2009 20:51:08 +0100 Subject: [PATCH 73/84] [7124] Removed virtual keyworld from Map::CanUnload method. This method needn't to be virtual. Method moved all into header file to be inlined. Fixed problem when instance never unloaded in case low population servers where update time always fit into WORLD_SLEEP_CONST and unload time is multiple of this constant. Signed-off-by: ApoC --- src/game/Map.cpp | 8 -------- src/game/Map.h | 8 +++++++- src/shared/revision_nr.h | 2 +- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/game/Map.cpp b/src/game/Map.cpp index bba8e945a..2a74d5ef4 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -1448,14 +1448,6 @@ void Map::RemoveAllObjectsInRemoveList() //sLog.outDebug("Object remover 2 check."); } -bool Map::CanUnload(const uint32 &diff) -{ - if(!m_unloadTimer) return false; - if(m_unloadTimer < diff) return true; - m_unloadTimer -= diff; - return false; -} - uint32 Map::GetPlayersCountExceptGMs() const { uint32 count = 0; diff --git a/src/game/Map.h b/src/game/Map.h index 35e83969e..664dc542a 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -131,7 +131,13 @@ class MANGOS_DLL_SPEC Map : public GridRefManager, public MaNGOS::Obj virtual ~Map(); // currently unused for normal maps - virtual bool CanUnload(const uint32& diff); + bool CanUnload(uint32 diff) + { + if(!m_unloadTimer) return false; + if(m_unloadTimer <= diff) return true; + m_unloadTimer -= diff; + return false; + } virtual bool Add(Player *); virtual void Remove(Player *, bool); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 5503b0fde..2a3210a62 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7123" + #define REVISION_NR "7124" #endif // __REVISION_NR_H__ From b6e7f49887359b48eb649bce4fb8829908f9e0ea Mon Sep 17 00:00:00 2001 From: DiSlord Date: Tue, 20 Jan 2009 01:38:23 +0300 Subject: [PATCH 74/84] Use SPELL_AURA_MOD_MECHANIC_RESISTANCE for melee spells Signed-off-by: DiSlord --- src/game/Unit.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index abbe2729b..37e9c8541 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -2351,6 +2351,24 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit *pVictim, SpellEntry const *spell) if (roll < tmp) return SPELL_MISS_MISS; + // Chance resist mechanic (select max value from every mechanic spell effect) + int32 resist_mech = 0; + // Get effects mechanic and chance + for(int eff = 0; eff < 3; ++eff) + { + int32 effect_mech = GetEffectMechanic(spell, eff); + if (effect_mech) + { + int32 temp = pVictim->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_MECHANIC_RESISTANCE, effect_mech); + if (resist_mech < temp*100) + resist_mech = temp*100; + } + } + // Roll chance + tmp += resist_mech; + if (roll < tmp) + return SPELL_MISS_RESIST; + bool canDodge = true; bool canParry = true; From ca7ac74134c45d217e8141a8de496b112f94252c Mon Sep 17 00:00:00 2001 From: DiSlord Date: Wed, 21 Jan 2009 00:25:09 +0300 Subject: [PATCH 75/84] Allow trigger from 10 and ranks Mage spell (work some talents) Signed-off-by: DiSlord --- src/game/Spell.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index b59412bfa..ab5e1fc80 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -687,8 +687,8 @@ void Spell::prepareDataForTriggerSystem() { switch (m_spellInfo->SpellFamilyName) { - case SPELLFAMILY_MAGE: // Arcane Missles triggers need do it - if (m_spellInfo->SpellFamilyFlags & 0x0000000000200000LL) m_canTrigger = true; + case SPELLFAMILY_MAGE: // Arcane Missles / Blizzard triggers need do it + if (m_spellInfo->SpellFamilyFlags & 0x0000000000200080LL) m_canTrigger = true; break; case SPELLFAMILY_WARLOCK: // For Hellfire Effect / Rain of Fire / Seed of Corruption triggers need do it if (m_spellInfo->SpellFamilyFlags & 0x0000800000000060LL) m_canTrigger = true; From 921914f87e6db65282162617d3061497b7b9a310 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Wed, 21 Jan 2009 00:14:39 +0300 Subject: [PATCH 76/84] [7125] Work under pet talents Coorrect update Talent Points on levelup / leveldown Unlearn other ranks of learned talent Fix typo in Pet::HasSpell (wrong result for removed spell) Allow .reset talents reset pet talent Implement SPELL_AURA_MOD_PET_TALENT_POINTS aura (hunter talent) Only reset pet talent from trainer unlearn. Signed-off-by: DiSlord --- src/game/Level3.cpp | 34 +++++-- src/game/Pet.cpp | 193 ++++++++++++++++++++++++++++++++---- src/game/Pet.h | 7 +- src/game/PetHandler.cpp | 39 +------- src/game/SpellAuraDefines.h | 4 +- src/game/SpellAuras.cpp | 14 ++- src/game/SpellAuras.h | 1 + src/game/SpellEffects.cpp | 1 + src/game/Unit.cpp | 2 +- src/shared/revision_nr.h | 2 +- 10 files changed, 225 insertions(+), 72 deletions(-) diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 83f1ad0be..1b9f35566 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -4402,8 +4402,10 @@ bool ChatHandler::HandleResetLevelCommand(const char * args) // reset level to summoned pet Pet* pet = player->GetPet(); if(pet && pet->getPetType()==SUMMON_PET) + { pet->InitStatsForLevel(1); - + pet->InitTalentForLevel(); + } return true; } @@ -4515,13 +4517,6 @@ bool ChatHandler::HandleResetTalentsCommand(const char * args) else player = getSelectedPlayer(); - if(!player && !playerGUID) - { - SendSysMessage(LANG_NO_CHAR_SELECTED); - SetSentErrorMessage(true); - return false; - } - if(player) { player->resetTalents(true); @@ -4530,14 +4525,33 @@ bool ChatHandler::HandleResetTalentsCommand(const char * args) if(m_session->GetPlayer()!=player) PSendSysMessage(LANG_RESET_TALENTS_ONLINE,player->GetName()); + return true; } - else + else if (playerGUID) { CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE guid = '%u'",uint32(AT_LOGIN_RESET_TALENTS), GUID_LOPART(playerGUID) ); PSendSysMessage(LANG_RESET_TALENTS_OFFLINE,pName); + return true; + } + // Try reset talenents as Hunter Pet + Creature* creature = getSelectedCreature(); + if (creature && creature->isPet() && ((Pet *)creature)->getPetType() == HUNTER_PET) + { + ((Pet *)creature)->resetTalents(true); + Unit *owner = creature->GetOwner(); + if (owner && owner->GetTypeId() == TYPEID_PLAYER) + { + player = (Player *)owner; + ChatHandler(player).SendSysMessage(LANG_RESET_TALENTS); + if(m_session->GetPlayer()!=player) + PSendSysMessage(LANG_RESET_TALENTS_ONLINE,player->GetName()); + } + return true; } - return true; + SendSysMessage(LANG_NO_CHAR_SELECTED); + SetSentErrorMessage(true); + return false; } bool ChatHandler::HandleResetAllCommand(const char * args) diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index df8042603..8c92cd6ec 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -53,6 +53,7 @@ Pet::Pet(PetType type) : Creature() m_resetTalentsCost = 0; m_resetTalentsTime = 0; + m_usedTalentCount = 0; m_auraUpdateMask = 0; @@ -716,6 +717,7 @@ void Pet::GivePetLevel(uint32 level) return; InitStatsForLevel(level); + InitTalentForLevel(); } bool Pet::CreateBaseAtCreature(Creature* creature) @@ -1291,22 +1293,42 @@ bool Pet::addSpell(uint16 spell_id, uint16 active, PetSpellState state, PetSpell else newspell->active = active; - uint32 chainstart = spellmgr.GetFirstSpellInChain(spell_id); - - for (PetSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr) + // talent: unlearn all other talent ranks (high and low) + if(TalentSpellPos const* talentPos = GetTalentSpellPos(spell_id)) { - if(itr->second->state == PETSPELL_REMOVED) continue; - - if(spellmgr.GetFirstSpellInChain(itr->first) == chainstart) + if(TalentEntry const *talentInfo = sTalentStore.LookupEntry( talentPos->talent_id )) { - newspell->active = itr->second->active; + for(int i=0; i <5; ++i) + { + // skip learning spell and no rank spell case + uint32 rankSpellId = talentInfo->RankID[i]; + if(!rankSpellId || rankSpellId==spell_id) + continue; - if(newspell->active == ACT_ENABLED) - ToggleAutocast(itr->first, false); + // skip unknown ranks + if(!HasSpell(rankSpellId)) + continue; + removeSpell(rankSpellId); + } + } + } + else if(uint32 chainstart = spellmgr.GetFirstSpellInChain(spell_id)) + { + for (PetSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr) + { + if(itr->second->state == PETSPELL_REMOVED) continue; - oldspell_id = itr->first; - unlearnSpell(itr->first); - break; + if(spellmgr.GetFirstSpellInChain(itr->first) == chainstart) + { + newspell->active = itr->second->active; + + if(newspell->active == ACT_ENABLED) + ToggleAutocast(itr->first, false); + + oldspell_id = itr->first; + unlearnSpell(itr->first); + break; + } } } @@ -1320,6 +1342,15 @@ bool Pet::addSpell(uint16 spell_id, uint16 active, PetSpellState state, PetSpell if(newspell->active == ACT_ENABLED) ToggleAutocast(spell_id, true); + uint32 talentCost = GetTalentSpellCost(spell_id); + if (talentCost) + { + int32 free_points = GetMaxTalentPointsForLevel(getLevel()); + m_usedTalentCount+=talentCost; + // update free talent points + free_points-=m_usedTalentCount; + SetFreeTalentPoints(free_points > 0 ? free_points : 0); + } return true; } @@ -1329,19 +1360,17 @@ bool Pet::learnSpell(uint16 spell_id) if (!addSpell(spell_id)) return false; - if(GetOwner()->GetTypeId() == TYPEID_PLAYER) + Unit* owner = GetOwner(); + if(owner && owner->GetTypeId() == TYPEID_PLAYER) { if(!m_loading) { WorldPacket data(SMSG_PET_LEARNED_SPELL, 2); data << uint16(spell_id); - ((Player*)GetOwner())->GetSession()->SendPacket(&data); + ((Player*)owner)->GetSession()->SendPacket(&data); } - } - - Unit* owner = GetOwner(); - if(owner->GetTypeId() == TYPEID_PLAYER) ((Player*)owner)->PetSpellInitialize(); + } return true; } @@ -1399,6 +1428,18 @@ bool Pet::removeSpell(uint16 spell_id) RemoveAurasDueToSpell(spell_id); + uint32 talentCost = GetTalentSpellCost(spell_id); + if (talentCost > 0) + { + if (m_usedTalentCount > talentCost) + m_usedTalentCount-=talentCost; + else + m_usedTalentCount = 0; + // update free talent points + int32 free_points = GetMaxTalentPointsForLevel(getLevel()) - m_usedTalentCount; + SetFreeTalentPoints(free_points > 0 ? free_points : 0); + } + return true; } @@ -1478,6 +1519,110 @@ void Pet::CheckLearning(uint32 spellid) } } +bool Pet::resetTalents(bool no_cost) +{ + Unit *owner = GetOwner(); + if (!owner || owner->GetTypeId()!=TYPEID_PLAYER) + return false; + + CreatureInfo const * ci = GetCreatureInfo(); + if(!ci) + return false; + // Check pet talent type + CreatureFamilyEntry const *pet_family = sCreatureFamilyStore.LookupEntry(ci->family); + if(!pet_family || pet_family->petTalentType < 0) + return false; + + Player *player = (Player *)owner; + + uint32 level = getLevel(); + uint32 talentPointsForLevel = GetMaxTalentPointsForLevel(level); + + if (m_usedTalentCount == 0) + { + SetFreeTalentPoints(talentPointsForLevel); + return false; + } + + uint32 cost = 0; + + if(!no_cost) + { + cost = resetTalentsCost(); + + if (player->GetMoney() < cost) + { + player->SendBuyError( BUY_ERR_NOT_ENOUGHT_MONEY, 0, 0, 0); + return false; + } + } + + for (unsigned int i = 0; i < sTalentStore.GetNumRows(); i++) + { + TalentEntry const *talentInfo = sTalentStore.LookupEntry(i); + + if (!talentInfo) continue; + + TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab ); + + if(!talentTabInfo) + continue; + + // unlearn only talents for pets family talent type + if(!((1 << pet_family->petTalentType) & talentTabInfo->petTalentMask)) + continue; + + for (int j = 0; j < 5; j++) + { + for(PetSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end();) + { + if(itr->second->state == PETSPELL_REMOVED) + { + ++itr; + continue; + } + // remove learned spells (all ranks) + 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)) + { + removeSpell(itr->first); + itr = m_spells.begin(); + continue; + } + else + ++itr; + } + } + } + + SetFreeTalentPoints(talentPointsForLevel); + + if(!no_cost) + { + player->ModifyMoney(-(int32)cost); + + m_resetTalentsCost = cost; + m_resetTalentsTime = time(NULL); + } + player->PetSpellInitialize(); + return true; +} + +void Pet::InitTalentForLevel() +{ + uint32 level = getLevel(); + uint32 talentPointsForLevel = GetMaxTalentPointsForLevel(level); + // Reset talents in case low level (on level down) or wrong points for level (hunter can unlearn TP increase talent) + if(talentPointsForLevel == 0 || m_usedTalentCount > talentPointsForLevel) + { + // Remove all talent points + resetTalents(true); + } + SetFreeTalentPoints(talentPointsForLevel - m_usedTalentCount); +} + uint32 Pet::resetTalentsCost() const { uint32 days = (sWorld.GetGameTime() - m_resetTalentsTime)/DAY; @@ -1496,6 +1641,15 @@ uint32 Pet::resetTalentsCost() const return (m_resetTalentsCost + 1*GOLD > 10*GOLD ? 10*GOLD : m_resetTalentsCost + 1*GOLD); } +uint8 Pet::GetMaxTalentPointsForLevel(uint32 level) +{ + uint8 points = (level >= 20) ? ((level - 16) / 4) : 0; + // Mod points from owner SPELL_AURA_MOD_PET_TALENT_POINTS + if (Unit *owner = GetOwner()) + points+=owner->GetTotalAuraModifier(SPELL_AURA_MOD_PET_TALENT_POINTS); + return points; +} + void Pet::ToggleAutocast(uint32 spellid, bool apply) { if(IsPassiveSpell(spellid)) @@ -1555,7 +1709,8 @@ bool Pet::Create(uint32 guidlow, Map *map, uint32 Entry, uint32 pet_number) bool Pet::HasSpell(uint32 spell) const { - return (m_spells.find(spell) != m_spells.end()); + PetSpellMap::const_iterator itr = m_spells.find((uint16)spell); + return (itr != m_spells.end() && itr->second->state != PETSPELL_REMOVED ); } // Get all passive spells in our skill line diff --git a/src/game/Pet.h b/src/game/Pet.h index 383089280..88e12c4a9 100644 --- a/src/game/Pet.h +++ b/src/game/Pet.h @@ -201,13 +201,18 @@ class Pet : public Creature void InitPetCreateSpells(); void CheckLearning(uint32 spellid); + + bool resetTalents(bool no_cost = false); uint32 resetTalentsCost() const; - uint8 GetMaxTalentPointsForLevel(uint32 level) { return (level >= 20) ? ((level - 16) / 4) : 0; } + void InitTalentForLevel(); + + uint8 GetMaxTalentPointsForLevel(uint32 level); uint8 GetFreeTalentPoints() { return GetByteValue(UNIT_FIELD_BYTES_1, 1); } void SetFreeTalentPoints(uint8 points) { SetByteValue(UNIT_FIELD_BYTES_1, 1, points); } uint32 m_resetTalentsCost; time_t m_resetTalentsTime; + uint32 m_usedTalentCount; uint64 GetAuraUpdateMask() { return m_auraUpdateMask; } void SetAuraUpdateMask(uint8 slot) { m_auraUpdateMask |= (uint64(1) << slot); } diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp index a79b6f1d5..19a6eac92 100644 --- a/src/game/PetHandler.cpp +++ b/src/game/PetHandler.cpp @@ -487,11 +487,11 @@ void WorldSession::HandlePetUnlearnOpcode(WorldPacket& recvPacket) sLog.outDetail("CMSG_PET_UNLEARN"); uint64 guid; - recvPacket >> guid; + recvPacket >> guid; // Pet guid Pet* pet = _player->GetPet(); - if(!pet || pet->getPetType() != HUNTER_PET || pet->m_spells.size() <= 1) + if(!pet || pet->getPetType() != HUNTER_PET || pet->m_usedTalentCount == 0) return; if(guid != pet->GetGUID()) @@ -506,37 +506,7 @@ void WorldSession::HandlePetUnlearnOpcode(WorldPacket& recvPacket) sLog.outError("WorldSession::HandlePetUnlearnOpcode: object "I64FMTD" is considered pet-like but doesn't have a charminfo!", pet->GetGUID()); return; } - - uint32 cost = pet->resetTalentsCost(); - - if (GetPlayer()->GetMoney() < cost) - { - GetPlayer()->SendBuyError( BUY_ERR_NOT_ENOUGHT_MONEY, 0, 0, 0); - return; - } - - for(PetSpellMap::iterator itr = pet->m_spells.begin(); itr != pet->m_spells.end();) - { - uint32 spell_id = itr->first; // Pet::removeSpell can invalidate iterator at erase NEW spell - ++itr; - //pet->removeSpell(spell_id); - pet->unlearnSpell(spell_id); - } - - for(uint8 i = 0; i < 10; i++) - { - if(charmInfo->GetActionBarEntry(i)->SpellOrAction && charmInfo->GetActionBarEntry(i)->Type == ACT_ENABLED || charmInfo->GetActionBarEntry(i)->Type == ACT_DISABLED) - charmInfo->GetActionBarEntry(i)->SpellOrAction = 0; - } - - // relearn pet passives - pet->LearnPetPassives(); - - pet->m_resetTalentsTime = time(NULL); - pet->m_resetTalentsCost = cost; - GetPlayer()->ModifyMoney(-(int32)cost); - - GetPlayer()->PetSpellInitialize(); + pet->resetTalents(); } void WorldSession::HandlePetSpellAutocastOpcode( WorldPacket& recvPacket ) @@ -809,7 +779,4 @@ void WorldSession::HandlePetLearnTalent( WorldPacket & recv_data ) // learn! (other talent ranks will unlearned at learning) pet->learnSpell(spellid); sLog.outDetail("TalentID: %u Rank: %u Spell: %u\n", talent_id, requested_rank, spellid); - - // update free talent points - pet->SetFreeTalentPoints(CurTalentPoints - 1); } diff --git a/src/game/SpellAuraDefines.h b/src/game/SpellAuraDefines.h index 5d401b2f2..d9f0892fb 100644 --- a/src/game/SpellAuraDefines.h +++ b/src/game/SpellAuraDefines.h @@ -187,8 +187,8 @@ enum AuraType SPELL_AURA_MOD_BASE_RESISTANCE_PCT = 142, SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE = 143, SPELL_AURA_SAFE_FALL = 144, - SPELL_AURA_CHARISMA = 145, - SPELL_AURA_PERSUADED = 146, + SPELL_AURA_MOD_PET_TALENT_POINTS = 145, + SPELL_AURA_ALLOW_TAME_PET_TYPE = 146, SPELL_AURA_ADD_CREATURE_IMMUNITY = 147, SPELL_AURA_RETAIN_COMBO_POINTS = 148, SPELL_AURA_RESIST_PUSHBACK = 149, // Resist Pushback diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 08fef1f30..c9b283fdc 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -195,8 +195,8 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleAuraModBaseResistancePCT, //142 SPELL_AURA_MOD_BASE_RESISTANCE_PCT &Aura::HandleAuraModResistanceExclusive, //143 SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE &Aura::HandleNoImmediateEffect, //144 SPELL_AURA_SAFE_FALL implemented in WorldSession::HandleMovementOpcodes - &Aura::HandleUnused, //145 SPELL_AURA_CHARISMA obsolete? - &Aura::HandleUnused, //146 SPELL_AURA_PERSUADED obsolete? + &Aura::HandleAuraModPetTalentsPoints, //145 SPELL_AURA_MOD_PET_TALENT_POINTS + &Aura::HandleNoImmediateEffect, //146 SPELL_AURA_ALLOW_TAME_PET_TYPE &Aura::HandleNULL, //147 SPELL_AURA_ADD_CREATURE_IMMUNITY &Aura::HandleAuraRetainComboPoints, //148 SPELL_AURA_RETAIN_COMBO_POINTS &Aura::HandleNoImmediateEffect, //149 SPELL_AURA_RESIST_PUSHBACK @@ -3122,6 +3122,16 @@ void Aura::HandleModPossessPet(bool apply, bool Real) } } +void Aura::HandleAuraModPetTalentsPoints(bool Apply, bool Real) +{ + if(!Real) + return; + + // Recalculate pet tlaent points + if (Pet *pet=m_target->GetPet()) + pet->InitTalentForLevel(); +} + void Aura::HandleModCharm(bool apply, bool Real) { if(!Real) diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h index 66ca5bc77..b3718e3eb 100644 --- a/src/game/SpellAuras.h +++ b/src/game/SpellAuras.h @@ -112,6 +112,7 @@ class MANGOS_DLL_SPEC Aura void HandlePeriodicTriggerSpell(bool Apply, bool Real); void HandlePeriodicEnergize(bool Apply, bool Real); void HandleAuraModResistanceExclusive(bool Apply, bool Real); + void HandleAuraModPetTalentsPoints(bool Apply, bool Real); void HandleModStealth(bool Apply, bool Real); void HandleInvisibility(bool Apply, bool Real); void HandleInvisibilityDetect(bool Apply, bool Real); diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 09697eb02..2fd902357 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -4152,6 +4152,7 @@ void Spell::EffectSummonPet(uint32 i) NewSummon->InitStatsForLevel(petlevel); NewSummon->InitPetCreateSpells(); + NewSummon->InitTalentForLevel(); if(NewSummon->getPetType()==SUMMON_PET) { diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 37e9c8541..92575b6c2 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -11103,7 +11103,6 @@ Pet* Unit::CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id) pet->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); uint32 level = (creatureTarget->getLevel() < (getLevel() - 5)) ? (getLevel() - 5) : creatureTarget->getLevel(); - pet->SetFreeTalentPoints(pet->GetMaxTalentPointsForLevel(level)); if(!pet->InitStatsForLevel(level)) { @@ -11116,6 +11115,7 @@ Pet* Unit::CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id) // this enables pet details window (Shift+P) pet->AIM_Initialize(); pet->InitPetCreateSpells(); + pet->InitTalentForLevel(); pet->SetHealth(pet->GetMaxHealth()); return pet; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 2a3210a62..c9cdb24bc 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7124" + #define REVISION_NR "7125" #endif // __REVISION_NR_H__ From 1d0d9c6fa2f48265eb141fe5500561b681b89c24 Mon Sep 17 00:00:00 2001 From: pasdVn Date: Tue, 20 Jan 2009 22:37:59 +0100 Subject: [PATCH 77/84] [7126] Fixed typo in spell 53301 and ranks dummy tick. Fixed typo in spell 53290 and ranks dummy proc. Signed-off-by: ApoC --- src/game/SpellAuras.cpp | 2 +- src/game/Unit.cpp | 2 +- src/shared/revision_nr.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index c9b283fdc..8981c51b1 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -6553,7 +6553,7 @@ void Aura::PeriodicDummyTick() if (!caster) return; // Skip 0 tick - if (m_duration < m_modifier.periodictime) + if (m_duration > m_modifier.periodictime) return; int32 damage = caster->CalculateSpellDamage(spell, GetEffIndex(), GetBasePoints(), m_target); damage+=caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 8 / 100; diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 92575b6c2..209dcf91a 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -5277,7 +5277,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu { triggered_spell_id = 57669; target = this; - return true; + break; } // Lock and Load if ( dummySpell->SpellIconID == 3579 ) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index c9cdb24bc..efd16d347 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7125" + #define REVISION_NR "7126" #endif // __REVISION_NR_H__ From 9e1b9e56fd5d77b32ffd44ed80a9f12d58c77b89 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Wed, 21 Jan 2009 01:35:16 +0300 Subject: [PATCH 78/84] [7127] Implement 271 SPELL_AURA_MOD_DAMAGE_FROM_CASTER aura Allow this aura trigger and drop charges (only if caster hit target) Signed-off-by: DiSlord --- src/game/SpellAuraDefines.h | 2 +- src/game/SpellAuras.cpp | 2 +- src/game/Unit.cpp | 12 ++++++++++++ src/shared/revision_nr.h | 2 +- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/game/SpellAuraDefines.h b/src/game/SpellAuraDefines.h index d9f0892fb..31c331458 100644 --- a/src/game/SpellAuraDefines.h +++ b/src/game/SpellAuraDefines.h @@ -313,7 +313,7 @@ enum AuraType SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT = 268, SPELL_AURA_269 = 269, SPELL_AURA_270 = 270, - SPELL_AURA_271 = 271, + SPELL_AURA_MOD_DAMAGE_FROM_CASTER = 271, SPELL_AURA_272 = 272, SPELL_AURA_273 = 273, SPELL_AURA_274 = 274, diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 8981c51b1..42b008a63 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -321,7 +321,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleAuraModAttackPowerOfStatPercent, //268 SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT &Aura::HandleNULL, //269 ignore DR effects? &Aura::HandleNULL, //270 - &Aura::HandleNULL, //271 increase damage done? + &Aura::HandleNoImmediateEffect, //271 SPELL_AURA_MOD_DAMAGE_FROM_CASTER implemented in Unit::SpellDamageBonus &Aura::HandleNULL, //272 reduce spell cast time? &Aura::HandleNULL, //273 &Aura::HandleNULL, //274 proc free shot? diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 209dcf91a..16a4f1d23 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -7468,6 +7468,12 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 } } + // From caster spells + AuraList const& mOwnerTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_FROM_CASTER); + for(AuraList::const_iterator i = mOwnerTaken.begin(); i != mOwnerTaken.end(); ++i) + if( (*i)->GetCasterGUID() == GetGUID() && (*i)->isAffectedOnSpell(spellProto)) + TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f; + // Distribute Damage over multiple effects, reduce by AoE CastingTime = GetCastingTimeForBonus( spellProto, damagetype, CastingTime ); @@ -10223,6 +10229,7 @@ bool InitTriggerAuraData() isTriggerAura[SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE]=true; isTriggerAura[SPELL_AURA_PRAYER_OF_MENDING] = true; isTriggerAura[SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE] = true; + isTriggerAura[SPELL_AURA_MOD_DAMAGE_FROM_CASTER] = true; isNonTriggerAura[SPELL_AURA_MOD_POWER_REGEN]=true; isNonTriggerAura[SPELL_AURA_RESIST_PUSHBACK]=true; @@ -10477,6 +10484,11 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag if (procSpell==NULL || procSpell->Mechanic != auraModifier->m_miscvalue) continue; break; + case SPELL_AURA_MOD_DAMAGE_FROM_CASTER: + // Compare casters + if (triggeredByAura->GetCasterGUID() != pTarget->GetGUID()) + continue; + break; default: // nothing do, just charges counter break; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index efd16d347..c76c09b72 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7126" + #define REVISION_NR "7127" #endif // __REVISION_NR_H__ From 03b7d1006a9169a1bd7a598235f8da73530b237f Mon Sep 17 00:00:00 2001 From: ApoC Date: Wed, 21 Jan 2009 01:29:08 +0100 Subject: [PATCH 79/84] [7128] Cleanup in PetHandler.cpp and little PetAI.cpp Fixed: pet stop attacking when casts spell by command. Signed-off-by: ApoC --- src/game/PetAI.cpp | 4 +-- src/game/PetHandler.cpp | 73 +++++++++++++++++++++------------------- src/shared/revision_nr.h | 2 +- 3 files changed, 41 insertions(+), 38 deletions(-) diff --git a/src/game/PetAI.cpp b/src/game/PetAI.cpp index 80613ae2f..ffc843235 100644 --- a/src/game/PetAI.cpp +++ b/src/game/PetAI.cpp @@ -139,11 +139,11 @@ void PetAI::UpdateAI(const uint32 diff) else m_updateAlliesTimer -= diff; - if (inCombat && i_pet.getVictim() == NULL) + if (inCombat && !i_pet.getVictim()) _stopAttack(); // i_pet.getVictim() can't be used for check in case stop fighting, i_pet.getVictim() clear at Unit death etc. - if( i_pet.getVictim() != NULL ) + if( i_pet.getVictim() ) { if( _needToStop() ) { diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp index 19a6eac92..274955d64 100644 --- a/src/game/PetHandler.cpp +++ b/src/game/PetHandler.cpp @@ -91,9 +91,7 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data ) break; case COMMAND_ATTACK: //spellid=1792 //ATTACK { - // only place where pet can be player - pet->clearUnitState(UNIT_STAT_FOLLOW); - uint64 selguid = _player->GetSelection(); + const uint64& selguid = _player->GetSelection(); Unit *TargetUnit = ObjectAccessor::GetUnit(*_player, selguid); if(!TargetUnit) return; @@ -105,29 +103,33 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data ) if(!pet->IsWithinLOSInMap(TargetUnit)) return; - if(pet->getVictim()) - pet->AttackStop(); - - if(pet->GetTypeId() != TYPEID_PLAYER) + // This is true if pet has no target or has target but targets differs. + if(pet->getVictim() != TargetUnit) { - pet->GetMotionMaster()->Clear(); - if (((Creature*)pet)->AI()) - ((Creature*)pet)->AI()->AttackStart(TargetUnit); + if (pet->getVictim()) + pet->AttackStop(); - //10% chance to play special pet attack talk, else growl - if(((Creature*)pet)->isPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != TargetUnit && urand(0, 100) < 10) - pet->SendPetTalk((uint32)PET_TALK_ATTACK); - else + if(pet->GetTypeId() != TYPEID_PLAYER) { - // 90% chance for pet and 100% chance for charmed creature + pet->GetMotionMaster()->Clear(); + if (((Creature*)pet)->AI()) + ((Creature*)pet)->AI()->AttackStart(TargetUnit); + + //10% chance to play special pet attack talk, else growl + if(((Creature*)pet)->isPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != TargetUnit && urand(0, 100) < 10) + pet->SendPetTalk((uint32)PET_TALK_ATTACK); + else + { + // 90% chance for pet and 100% chance for charmed creature + pet->SendPetAIReaction(guid1); + } + } + else // charmed player + { + pet->Attack(TargetUnit,true); pet->SendPetAIReaction(guid1); } } - else // charmed player - { - pet->Attack(TargetUnit,true); - pet->SendPetAIReaction(guid1); - } break; } case COMMAND_ABANDON: // abandon (hunter pet) or dismiss (summoned pet) @@ -161,15 +163,13 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data ) case ACT_PASSIVE: // 0x0100 case ACT_ENABLED: // 0xC100 spell { - Unit* unit_target; - if(guid2) - unit_target = ObjectAccessor::GetUnit(*_player,guid2); - else - unit_target = NULL; - + Unit* unit_target = NULL; if (((Creature*)pet)->GetGlobalCooldown() > 0) return; + if(guid2) + unit_target = ObjectAccessor::GetUnit(*_player,guid2); + // do not cast unknown spells SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellid ); if(!spellInfo) @@ -194,7 +194,7 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data ) int16 result = spell->PetCanCast(unit_target); - //auto turn to target unless possessed + //auto turn to target unless possessed if(result == SPELL_FAILED_UNIT_NOT_INFRONT && !pet->HasAuraType(SPELL_AURA_MOD_POSSESS)) { pet->SetInFront(unit_target); @@ -225,12 +225,15 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data ) if( unit_target && !GetPlayer()->IsFriendlyTo(unit_target) && !pet->HasAuraType(SPELL_AURA_MOD_POSSESS)) { - pet->clearUnitState(UNIT_STAT_FOLLOW); - if(pet->getVictim()) - pet->AttackStop(); - pet->GetMotionMaster()->Clear(); - if (((Creature*)pet)->AI()) - ((Creature*)pet)->AI()->AttackStart(unit_target); + // This is true if pet has no target or has target but targets differs. + if (pet->getVictim() != unit_target) + { + if (pet->getVictim()) + pet->AttackStop(); + pet->GetMotionMaster()->Clear(); + if (((Creature*)pet)->AI()) + ((Creature*)pet)->AI()->AttackStart(unit_target); + } } spell->prepare(&(spell->m_targets)); @@ -575,10 +578,10 @@ void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket ) if(!_player->GetPet() && !_player->GetCharm()) return; - if(ObjectAccessor::FindPlayer(guid)) + if (GUID_HIPART(guid) == HIGHGUID_PLAYER) return; - Creature* pet=ObjectAccessor::GetCreatureOrPet(*_player,guid); + Creature* pet = ObjectAccessor::GetCreatureOrPet(*_player,guid); if(!pet || (pet != _player->GetPet() && pet!= _player->GetCharm())) { diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index c76c09b72..4a4b91b7e 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7127" + #define REVISION_NR "7128" #endif // __REVISION_NR_H__ From a92354afeda1ae89e20f1f0c8e813a69941aa7bd Mon Sep 17 00:00:00 2001 From: ApoC Date: Wed, 21 Jan 2009 02:08:23 +0100 Subject: [PATCH 80/84] [7129] Changed uint64 results to const uint64& on some methods. Signed-off-by: ApoC --- src/game/GroupHandler.cpp | 4 ++-- src/game/Pet.h | 2 +- src/game/Player.h | 6 +++--- src/shared/revision_nr.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/game/GroupHandler.cpp b/src/game/GroupHandler.cpp index 51fc8cb7c..9ec47103e 100644 --- a/src/game/GroupHandler.cpp +++ b/src/game/GroupHandler.cpp @@ -707,7 +707,7 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke if (mask & GROUP_UPDATE_FLAG_AURAS) { - uint64 auramask = player->GetAuraUpdateMask(); + const uint64& auramask = player->GetAuraUpdateMask(); *data << uint64(auramask); for(uint32 i = 0; i < MAX_AURAS; ++i) { @@ -788,7 +788,7 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke { if(pet) { - uint64 auramask = pet->GetAuraUpdateMask(); + const uint64& auramask = pet->GetAuraUpdateMask(); *data << uint64(auramask); for(uint32 i = 0; i < MAX_AURAS; ++i) { diff --git a/src/game/Pet.h b/src/game/Pet.h index 88e12c4a9..f309bc518 100644 --- a/src/game/Pet.h +++ b/src/game/Pet.h @@ -214,7 +214,7 @@ class Pet : public Creature time_t m_resetTalentsTime; uint32 m_usedTalentCount; - uint64 GetAuraUpdateMask() { return m_auraUpdateMask; } + const uint64& GetAuraUpdateMask() const { return m_auraUpdateMask; } void SetAuraUpdateMask(uint8 slot) { m_auraUpdateMask |= (uint64(1) << slot); } void ResetAuraUpdateMask() { m_auraUpdateMask = 0; } diff --git a/src/game/Player.h b/src/game/Player.h index b5448c2c4..e8ddedb78 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1418,7 +1418,7 @@ class MANGOS_DLL_SPEC Player : public Unit void SetSelection(const uint64 &guid) { m_curSelection = guid; SetUInt64Value(UNIT_FIELD_TARGET, guid); } uint8 GetComboPoints() { return m_comboPoints; } - uint64 GetComboTarget() { return m_comboTarget; } + const uint64& GetComboTarget() const { return m_comboTarget; } void AddComboPoints(Unit* target, int8 count); void ClearComboPoints(); @@ -2150,9 +2150,9 @@ class MANGOS_DLL_SPEC Player : public Unit GroupReference& GetGroupRef() { return m_group; } void SetGroup(Group *group, int8 subgroup = -1); uint8 GetSubGroup() const { return m_group.getSubGroup(); } - uint32 GetGroupUpdateFlag() { return m_groupUpdateMask; } + uint32 GetGroupUpdateFlag() const { return m_groupUpdateMask; } void SetGroupUpdateFlag(uint32 flag) { m_groupUpdateMask |= flag; } - uint64 GetAuraUpdateMask() { return m_auraUpdateMask; } + const uint64& GetAuraUpdateMask() const { return m_auraUpdateMask; } void SetAuraUpdateMask(uint8 slot) { m_auraUpdateMask |= (uint64(1) << slot); } Player* GetNextRandomRaidMember(float radius); PartyResult CanUninviteFromGroup() const; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 4a4b91b7e..128c6e1f9 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7128" + #define REVISION_NR "7129" #endif // __REVISION_NR_H__ From 1718653e638e10f963c80b262760f928c3ecbc1d Mon Sep 17 00:00:00 2001 From: ApoC Date: Wed, 21 Jan 2009 02:45:31 +0100 Subject: [PATCH 81/84] [7130] Changet all *::Update(time_t) to *::Update(uint32), there is no need to use time_t (mostly 64b) because time diffs are very small numbers and the base calculation of diff is done as uint32. Signed-off-by: ApoC --- src/game/BattleGround.cpp | 2 +- src/game/BattleGround.h | 2 +- src/game/BattleGroundAA.cpp | 2 +- src/game/BattleGroundAA.h | 2 +- src/game/BattleGroundAB.cpp | 2 +- src/game/BattleGroundAB.h | 2 +- src/game/BattleGroundAV.cpp | 2 +- src/game/BattleGroundAV.h | 2 +- src/game/BattleGroundBE.cpp | 2 +- src/game/BattleGroundBE.h | 2 +- src/game/BattleGroundDS.cpp | 2 +- src/game/BattleGroundDS.h | 2 +- src/game/BattleGroundEY.cpp | 2 +- src/game/BattleGroundEY.h | 2 +- src/game/BattleGroundMgr.cpp | 2 +- src/game/BattleGroundMgr.h | 2 +- src/game/BattleGroundNA.cpp | 2 +- src/game/BattleGroundNA.h | 2 +- src/game/BattleGroundRL.cpp | 2 +- src/game/BattleGroundRL.h | 2 +- src/game/BattleGroundRV.cpp | 2 +- src/game/BattleGroundRV.h | 2 +- src/game/BattleGroundSA.cpp | 2 +- src/game/BattleGroundSA.h | 2 +- src/game/BattleGroundWS.cpp | 2 +- src/game/BattleGroundWS.h | 2 +- src/game/MapManager.cpp | 2 +- src/game/MapManager.h | 2 +- src/game/Weather.cpp | 2 +- src/game/Weather.h | 2 +- src/game/World.cpp | 4 ++-- src/game/World.h | 4 ++-- src/shared/revision_nr.h | 2 +- 33 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp index 6962bd69c..1e2e42f4a 100644 --- a/src/game/BattleGround.cpp +++ b/src/game/BattleGround.cpp @@ -116,7 +116,7 @@ BattleGround::~BattleGround() this->RemoveFromBGFreeSlotQueue(); } -void BattleGround::Update(time_t diff) +void BattleGround::Update(uint32 diff) { if(!GetPlayersSize() && !GetRemovedPlayersSize() && !GetReviveQueueSize()) //BG is empty diff --git a/src/game/BattleGround.h b/src/game/BattleGround.h index 6727c1a97..1e03c12cb 100644 --- a/src/game/BattleGround.h +++ b/src/game/BattleGround.h @@ -254,7 +254,7 @@ class BattleGround BattleGround(); /*BattleGround(const BattleGround& bg);*/ virtual ~BattleGround(); - virtual void Update(time_t diff); // must be implemented in BG subclass of BG specific update code, but must in begginning call parent version + virtual void Update(uint32 diff); // must be implemented in BG subclass of BG specific update code, but must in begginning call parent version virtual bool SetupBattleGround() // must be implemented in BG subclass { return true; diff --git a/src/game/BattleGroundAA.cpp b/src/game/BattleGroundAA.cpp index cc2404614..fcf9bd4ce 100644 --- a/src/game/BattleGroundAA.cpp +++ b/src/game/BattleGroundAA.cpp @@ -30,7 +30,7 @@ BattleGroundAA::~BattleGroundAA() } -void BattleGroundAA::Update(time_t diff) +void BattleGroundAA::Update(uint32 diff) { BattleGround::Update(diff); } diff --git a/src/game/BattleGroundAA.h b/src/game/BattleGroundAA.h index 767e4eb55..b144acae3 100644 --- a/src/game/BattleGroundAA.h +++ b/src/game/BattleGroundAA.h @@ -35,7 +35,7 @@ class BattleGroundAA : public BattleGround public: BattleGroundAA(); ~BattleGroundAA(); - void Update(time_t diff); + void Update(uint32 diff); /* inherited from BattlegroundClass */ virtual void AddPlayer(Player *plr); diff --git a/src/game/BattleGroundAB.cpp b/src/game/BattleGroundAB.cpp index 0a5186937..45421f908 100644 --- a/src/game/BattleGroundAB.cpp +++ b/src/game/BattleGroundAB.cpp @@ -38,7 +38,7 @@ BattleGroundAB::~BattleGroundAB() { } -void BattleGroundAB::Update(time_t diff) +void BattleGroundAB::Update(uint32 diff) { BattleGround::Update(diff); diff --git a/src/game/BattleGroundAB.h b/src/game/BattleGroundAB.h index 97615dc1c..e76f35209 100644 --- a/src/game/BattleGroundAB.h +++ b/src/game/BattleGroundAB.h @@ -236,7 +236,7 @@ class BattleGroundAB : public BattleGround BattleGroundAB(); ~BattleGroundAB(); - void Update(time_t diff); + void Update(uint32 diff); void AddPlayer(Player *plr); void RemovePlayer(Player *plr,uint64 guid); void HandleAreaTrigger(Player *Source, uint32 Trigger); diff --git a/src/game/BattleGroundAV.cpp b/src/game/BattleGroundAV.cpp index 99866f3f8..c444bcbb2 100644 --- a/src/game/BattleGroundAV.cpp +++ b/src/game/BattleGroundAV.cpp @@ -34,7 +34,7 @@ BattleGroundAV::~BattleGroundAV() } -void BattleGroundAV::Update(time_t diff) +void BattleGroundAV::Update(uint32 diff) { BattleGround::Update(diff); } diff --git a/src/game/BattleGroundAV.h b/src/game/BattleGroundAV.h index c77a6af88..c2e12a872 100644 --- a/src/game/BattleGroundAV.h +++ b/src/game/BattleGroundAV.h @@ -42,7 +42,7 @@ class BattleGroundAV : public BattleGround public: BattleGroundAV(); ~BattleGroundAV(); - void Update(time_t diff); + void Update(uint32 diff); /* inherited from BattlegroundClass */ virtual void AddPlayer(Player *plr); diff --git a/src/game/BattleGroundBE.cpp b/src/game/BattleGroundBE.cpp index cb38b0b80..cae899421 100644 --- a/src/game/BattleGroundBE.cpp +++ b/src/game/BattleGroundBE.cpp @@ -35,7 +35,7 @@ BattleGroundBE::~BattleGroundBE() } -void BattleGroundBE::Update(time_t diff) +void BattleGroundBE::Update(uint32 diff) { BattleGround::Update(diff); diff --git a/src/game/BattleGroundBE.h b/src/game/BattleGroundBE.h index c66d1b1b9..4e5663d03 100644 --- a/src/game/BattleGroundBE.h +++ b/src/game/BattleGroundBE.h @@ -55,7 +55,7 @@ class BattleGroundBE : public BattleGround public: BattleGroundBE(); ~BattleGroundBE(); - void Update(time_t diff); + void Update(uint32 diff); /* inherited from BattlegroundClass */ virtual void AddPlayer(Player *plr); diff --git a/src/game/BattleGroundDS.cpp b/src/game/BattleGroundDS.cpp index 276c0c84c..825a52967 100644 --- a/src/game/BattleGroundDS.cpp +++ b/src/game/BattleGroundDS.cpp @@ -30,7 +30,7 @@ BattleGroundDS::~BattleGroundDS() } -void BattleGroundDS::Update(time_t diff) +void BattleGroundDS::Update(uint32 diff) { BattleGround::Update(diff); } diff --git a/src/game/BattleGroundDS.h b/src/game/BattleGroundDS.h index afcb8f092..7f9de8ca7 100644 --- a/src/game/BattleGroundDS.h +++ b/src/game/BattleGroundDS.h @@ -35,7 +35,7 @@ class BattleGroundDS : public BattleGround public: BattleGroundDS(); ~BattleGroundDS(); - void Update(time_t diff); + void Update(uint32 diff); /* inherited from BattlegroundClass */ virtual void AddPlayer(Player *plr); diff --git a/src/game/BattleGroundEY.cpp b/src/game/BattleGroundEY.cpp index 7adca00f4..dcfc38337 100644 --- a/src/game/BattleGroundEY.cpp +++ b/src/game/BattleGroundEY.cpp @@ -42,7 +42,7 @@ BattleGroundEY::~BattleGroundEY() { } -void BattleGroundEY::Update(time_t diff) +void BattleGroundEY::Update(uint32 diff) { BattleGround::Update(diff); // after bg start we get there (once) diff --git a/src/game/BattleGroundEY.h b/src/game/BattleGroundEY.h index 8e19472b2..38291313d 100644 --- a/src/game/BattleGroundEY.h +++ b/src/game/BattleGroundEY.h @@ -298,7 +298,7 @@ class BattleGroundEY : public BattleGround public: BattleGroundEY(); ~BattleGroundEY(); - void Update(time_t diff); + void Update(uint32 diff); /* inherited from BattlegroundClass */ virtual void AddPlayer(Player *plr); diff --git a/src/game/BattleGroundMgr.cpp b/src/game/BattleGroundMgr.cpp index c21af527c..66c03df3b 100644 --- a/src/game/BattleGroundMgr.cpp +++ b/src/game/BattleGroundMgr.cpp @@ -1095,7 +1095,7 @@ BattleGroundMgr::~BattleGroundMgr() } // used to update running battlegrounds, and delete finished ones -void BattleGroundMgr::Update(time_t diff) +void BattleGroundMgr::Update(uint32 diff) { BattleGroundSet::iterator itr, next; for(itr = m_BattleGrounds.begin(); itr != m_BattleGrounds.end(); itr = next) diff --git a/src/game/BattleGroundMgr.h b/src/game/BattleGroundMgr.h index f36c41ca8..5b5a017ef 100644 --- a/src/game/BattleGroundMgr.h +++ b/src/game/BattleGroundMgr.h @@ -173,7 +173,7 @@ class BattleGroundMgr /* Construction */ BattleGroundMgr(); ~BattleGroundMgr(); - void Update(time_t diff); + void Update(uint32 diff); /* Packet Building */ void BuildPlayerJoinedBattleGroundPacket(WorldPacket *data, Player *plr); diff --git a/src/game/BattleGroundNA.cpp b/src/game/BattleGroundNA.cpp index 63bfed9e8..4321dd657 100644 --- a/src/game/BattleGroundNA.cpp +++ b/src/game/BattleGroundNA.cpp @@ -35,7 +35,7 @@ BattleGroundNA::~BattleGroundNA() } -void BattleGroundNA::Update(time_t diff) +void BattleGroundNA::Update(uint32 diff) { BattleGround::Update(diff); diff --git a/src/game/BattleGroundNA.h b/src/game/BattleGroundNA.h index 64ccf0a5a..866dbca42 100644 --- a/src/game/BattleGroundNA.h +++ b/src/game/BattleGroundNA.h @@ -56,7 +56,7 @@ class BattleGroundNA : public BattleGround public: BattleGroundNA(); ~BattleGroundNA(); - void Update(time_t diff); + void Update(uint32 diff); /* inherited from BattlegroundClass */ virtual void AddPlayer(Player *plr); diff --git a/src/game/BattleGroundRL.cpp b/src/game/BattleGroundRL.cpp index ee9beb181..281cdd706 100644 --- a/src/game/BattleGroundRL.cpp +++ b/src/game/BattleGroundRL.cpp @@ -35,7 +35,7 @@ BattleGroundRL::~BattleGroundRL() } -void BattleGroundRL::Update(time_t diff) +void BattleGroundRL::Update(uint32 diff) { BattleGround::Update(diff); diff --git a/src/game/BattleGroundRL.h b/src/game/BattleGroundRL.h index 2c0a67778..427ed9402 100644 --- a/src/game/BattleGroundRL.h +++ b/src/game/BattleGroundRL.h @@ -52,7 +52,7 @@ class BattleGroundRL : public BattleGround public: BattleGroundRL(); ~BattleGroundRL(); - void Update(time_t diff); + void Update(uint32 diff); /* inherited from BattlegroundClass */ virtual void AddPlayer(Player *plr); diff --git a/src/game/BattleGroundRV.cpp b/src/game/BattleGroundRV.cpp index 20c7d11f8..a66f0ce30 100644 --- a/src/game/BattleGroundRV.cpp +++ b/src/game/BattleGroundRV.cpp @@ -30,7 +30,7 @@ BattleGroundRV::~BattleGroundRV() } -void BattleGroundRV::Update(time_t diff) +void BattleGroundRV::Update(uint32 diff) { BattleGround::Update(diff); } diff --git a/src/game/BattleGroundRV.h b/src/game/BattleGroundRV.h index 9f515e35b..2d2ad12c9 100644 --- a/src/game/BattleGroundRV.h +++ b/src/game/BattleGroundRV.h @@ -35,7 +35,7 @@ class BattleGroundRV : public BattleGround public: BattleGroundRV(); ~BattleGroundRV(); - void Update(time_t diff); + void Update(uint32 diff); /* inherited from BattlegroundClass */ virtual void AddPlayer(Player *plr); diff --git a/src/game/BattleGroundSA.cpp b/src/game/BattleGroundSA.cpp index d7bc422ca..20a692976 100644 --- a/src/game/BattleGroundSA.cpp +++ b/src/game/BattleGroundSA.cpp @@ -29,7 +29,7 @@ BattleGroundSA::~BattleGroundSA() } -void BattleGroundSA::Update(time_t diff) +void BattleGroundSA::Update(uint32 diff) { BattleGround::Update(diff); } diff --git a/src/game/BattleGroundSA.h b/src/game/BattleGroundSA.h index 6727c7a1f..331a41455 100644 --- a/src/game/BattleGroundSA.h +++ b/src/game/BattleGroundSA.h @@ -35,7 +35,7 @@ class BattleGroundSA : public BattleGround public: BattleGroundSA(); ~BattleGroundSA(); - void Update(time_t diff); + void Update(uint32 diff); /* inherited from BattlegroundClass */ virtual void AddPlayer(Player *plr); diff --git a/src/game/BattleGroundWS.cpp b/src/game/BattleGroundWS.cpp index 6e70739fa..6071688f6 100644 --- a/src/game/BattleGroundWS.cpp +++ b/src/game/BattleGroundWS.cpp @@ -36,7 +36,7 @@ BattleGroundWS::~BattleGroundWS() { } -void BattleGroundWS::Update(time_t diff) +void BattleGroundWS::Update(uint32 diff) { BattleGround::Update(diff); diff --git a/src/game/BattleGroundWS.h b/src/game/BattleGroundWS.h index 56a7b3061..d5756d42e 100644 --- a/src/game/BattleGroundWS.h +++ b/src/game/BattleGroundWS.h @@ -134,7 +134,7 @@ class BattleGroundWS : public BattleGround /* Construction */ BattleGroundWS(); ~BattleGroundWS(); - void Update(time_t diff); + void Update(uint32 diff); /* inherited from BattlegroundClass */ virtual void AddPlayer(Player *plr); diff --git a/src/game/MapManager.cpp b/src/game/MapManager.cpp index 9a7d1c20e..29e443507 100644 --- a/src/game/MapManager.cpp +++ b/src/game/MapManager.cpp @@ -239,7 +239,7 @@ void MapManager::RemoveBonesFromMap(uint32 mapid, uint64 guid, float x, float y) } void -MapManager::Update(time_t diff) +MapManager::Update(uint32 diff) { i_timer.Update(diff); if( !i_timer.Passed() ) diff --git a/src/game/MapManager.h b/src/game/MapManager.h index 554634d33..cb4c469a6 100644 --- a/src/game/MapManager.h +++ b/src/game/MapManager.h @@ -54,7 +54,7 @@ class MANGOS_DLL_DECL MapManager : public MaNGOS::Singleton=0) m_timer.Update(diff); diff --git a/src/game/Weather.h b/src/game/Weather.h index d7f10bebd..2cf86276a 100644 --- a/src/game/Weather.h +++ b/src/game/Weather.h @@ -60,7 +60,7 @@ class Weather void SetWeather(WeatherType type, float grade); /// For which zone is this weather? uint32 GetZone() { return m_zone; }; - bool Update(time_t diff); + bool Update(uint32 diff); private: WeatherState GetWeatherState() const; uint32 m_zone; diff --git a/src/game/World.cpp b/src/game/World.cpp index 6453715c6..072f6cac5 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -1412,7 +1412,7 @@ void World::DetectDBCLang() } /// Update the World ! -void World::Update(time_t diff) +void World::Update(uint32 diff) { ///- Update the different timers for(int i = 0; i < WUPDATE_COUNT; i++) @@ -2591,7 +2591,7 @@ void World::SendServerMessage(uint32 type, const char *text, Player* player) SendGlobalMessage( &data ); } -void World::UpdateSessions( time_t diff ) +void World::UpdateSessions( uint32 diff ) { ///- Add new sessions while(!addSessQueue.empty()) diff --git a/src/game/World.h b/src/game/World.h index f75118e8c..3f2640ffa 100644 --- a/src/game/World.h +++ b/src/game/World.h @@ -426,9 +426,9 @@ class World static void StopNow(uint8 exitcode) { m_stopEvent = true; m_ExitCode = exitcode; } static bool IsStopped() { return m_stopEvent; } - void Update(time_t diff); + void Update(uint32 diff); - void UpdateSessions( time_t diff ); + void UpdateSessions( uint32 diff ); /// Set a server rate (see #Rates) void setRate(Rates rate,float value) { rate_values[rate]=value; } /// Get a server rate (see #Rates) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 128c6e1f9..64afe316d 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7129" + #define REVISION_NR "7130" #endif // __REVISION_NR_H__ From 93662a1fb378ee03b010d8d237db3a4a770969eb Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Wed, 21 Jan 2009 05:34:57 +0300 Subject: [PATCH 82/84] [7131] Ignore loot rates for some internal loot tables and batter loot checking at load. --- src/game/LootMgr.cpp | 89 +++++++++++++++++++++++++--------------- src/game/LootMgr.h | 11 +++-- src/shared/revision_nr.h | 2 +- 3 files changed, 65 insertions(+), 37 deletions(-) diff --git a/src/game/LootMgr.cpp b/src/game/LootMgr.cpp index 030db9011..b3dbc8d97 100644 --- a/src/game/LootMgr.cpp +++ b/src/game/LootMgr.cpp @@ -34,17 +34,17 @@ static Rates const qualityToRate[MAX_ITEM_QUALITY] = { RATE_DROP_ITEM_ARTIFACT, // ITEM_QUALITY_ARTIFACT }; -LootStore LootTemplates_Creature( "creature_loot_template", "creature entry"); -LootStore LootTemplates_Disenchant( "disenchant_loot_template", "item disenchant id"); -LootStore LootTemplates_Fishing( "fishing_loot_template", "area id"); -LootStore LootTemplates_Gameobject( "gameobject_loot_template", "gameobject entry"); -LootStore LootTemplates_Item( "item_loot_template", "item entry"); -LootStore LootTemplates_Milling( "milling_loot_template", "item entry"); -LootStore LootTemplates_Pickpocketing("pickpocketing_loot_template","creature pickpocket lootid"); -LootStore LootTemplates_Prospecting( "prospecting_loot_template", "item entry"); -LootStore LootTemplates_QuestMail( "quest_mail_loot_template", "quest id"); -LootStore LootTemplates_Reference( "reference_loot_template", "reference id"); -LootStore LootTemplates_Skinning( "skinning_loot_template", "creature skinning id"); +LootStore LootTemplates_Creature( "creature_loot_template", "creature entry", true); +LootStore LootTemplates_Disenchant( "disenchant_loot_template", "item disenchant id", true); +LootStore LootTemplates_Fishing( "fishing_loot_template", "area id", true); +LootStore LootTemplates_Gameobject( "gameobject_loot_template", "gameobject entry", true); +LootStore LootTemplates_Item( "item_loot_template", "item entry", true); +LootStore LootTemplates_Milling( "milling_loot_template", "item entry (herb)", true); +LootStore LootTemplates_Pickpocketing("pickpocketing_loot_template","creature pickpocket lootid", true); +LootStore LootTemplates_Prospecting( "prospecting_loot_template", "item entry (ore)", true); +LootStore LootTemplates_QuestMail( "quest_mail_loot_template", "quest id (with mail template)",false); +LootStore LootTemplates_Reference( "reference_loot_template", "reference id", false); +LootStore LootTemplates_Skinning( "skinning_loot_template", "creature skinning id", true); class LootTemplate::LootGroup // A set of loot definitions for items (refs are not allowed) { @@ -53,7 +53,7 @@ class LootTemplate::LootGroup // A set of loot def bool HasQuestDrop() const; // True if group includes at least 1 quest drop entry bool HasQuestDropForPlayer(Player const * player) const; // The same for active quests of the player - void Process(Loot& loot) const; // Rolls an item from the group (if any) and adds the item to the loot + void Process(Loot& loot, bool rate) const; // Rolls an item from the group (if any) and adds the item to the loot float RawTotalChance() const; // Overall chance for the group (without equal chanced items) float TotalChance() const; // Overall chance for the group @@ -64,7 +64,7 @@ class LootTemplate::LootGroup // A set of loot def LootStoreItemList ExplicitlyChanced; // Entries with chances defined in DB LootStoreItemList EqualChanced; // Zero chances - every entry takes the same chance - LootStoreItem const * Roll() const; // Rolls an item from the group, returns NULL if all miss their chances + LootStoreItem const * Roll(bool rate) const; // Rolls an item from the group, returns NULL if all miss their chances }; //Remove all data and free all memory @@ -228,17 +228,17 @@ void LootStore::ReportNotExistedId(uint32 id) const // Checks if the entry (quest, non-quest, reference) takes it's chance (at loot generation) // RATE_DROP_ITEMS is no longer used for all types of entries -bool LootStoreItem::Roll() const +bool LootStoreItem::Roll(bool rate) const { if(chance>=100.f) return true; if(mincountOrRef < 0) // reference case - return roll_chance_f(chance*sWorld.getRate(RATE_DROP_ITEM_REFERENCED)); + return roll_chance_f(chance* (rate ? sWorld.getRate(RATE_DROP_ITEM_REFERENCED) : 1.0f)); ItemPrototype const *pProto = objmgr.GetItemPrototype(itemid); - float qualityModifier = pProto ? sWorld.getRate(qualityToRate[pProto->Quality]) : 1.0f; + float qualityModifier = pProto && rate ? sWorld.getRate(qualityToRate[pProto->Quality]) : 1.0f; return roll_chance_f(chance*qualityModifier); } @@ -377,7 +377,7 @@ void Loot::FillLoot(uint32 loot_id, LootStore const& store, Player* loot_owner) items.reserve(MAX_NR_LOOT_ITEMS); quest_items.reserve(MAX_NR_QUEST_ITEMS); - tab->Process(*this, store); // Processing is done there, callback via Loot::AddItem() + tab->Process(*this, store,store.IsRatesAllowed ()); // Processing is done there, callback via Loot::AddItem() // Setting access rights fow group-looting case if(!loot_owner) @@ -763,7 +763,7 @@ void LootTemplate::LootGroup::AddEntry(LootStoreItem& item) } // Rolls an item from the group, returns NULL if all miss their chances -LootStoreItem const * LootTemplate::LootGroup::Roll() const +LootStoreItem const * LootTemplate::LootGroup::Roll(bool rate) const { if (!ExplicitlyChanced.empty()) // First explicitly chanced entries are checked { @@ -775,7 +775,7 @@ LootStoreItem const * LootTemplate::LootGroup::Roll() const return &ExplicitlyChanced[i]; ItemPrototype const *pProto = objmgr.GetItemPrototype(ExplicitlyChanced[i].itemid); - float qualityMultiplier = pProto ? sWorld.getRate(qualityToRate[pProto->Quality]) : 1.0f; + float qualityMultiplier = pProto && rate ? sWorld.getRate(qualityToRate[pProto->Quality]) : 1.0f; Roll -= ExplicitlyChanced[i].chance * qualityMultiplier; if (Roll < 0) return &ExplicitlyChanced[i]; @@ -812,9 +812,9 @@ bool LootTemplate::LootGroup::HasQuestDropForPlayer(Player const * player) const } // Rolls an item from the group (if any takes its chance) and adds the item to the loot -void LootTemplate::LootGroup::Process(Loot& loot) const +void LootTemplate::LootGroup::Process(Loot& loot, bool rate) const { - LootStoreItem const * item = Roll(); + LootStoreItem const * item = Roll(rate); if (item != NULL) loot.AddItem(*item); } @@ -899,21 +899,21 @@ void LootTemplate::AddEntry(LootStoreItem& item) } // Rolls for every item in the template and adds the rolled items the the loot -void LootTemplate::Process(Loot& loot, LootStore const& store, uint8 groupId) const +void LootTemplate::Process(Loot& loot, LootStore const& store, bool rate, uint8 groupId) const { if (groupId) // Group reference uses own processing of the group { if (groupId > Groups.size()) return; // Error message already printed at loading stage - Groups[groupId-1].Process(loot); + Groups[groupId-1].Process(loot,rate); return; } // Rolling non-grouped items for (LootStoreItemList::const_iterator i = Entries.begin() ; i != Entries.end() ; ++i ) { - if ( !i->Roll() ) + if (!i->Roll(rate)) continue; // Bad luck for the entry if (i->mincountOrRef < 0) // References processing @@ -924,7 +924,7 @@ void LootTemplate::Process(Loot& loot, LootStore const& store, uint8 groupId) co continue; // Error message already printed at loading stage for (uint32 loop=0; loop < i->maxcount; ++loop )// Ref multiplicator - Referenced->Process(loot, store, i->group); // Ref processing + Referenced->Process(loot, store, rate, i->group); } else // Plain entries (not a reference, not grouped) loot.AddItem(*i); // Chance is already checked, just add @@ -932,7 +932,7 @@ void LootTemplate::Process(Loot& loot, LootStore const& store, uint8 groupId) co // Now processing groups for (LootGroups::const_iterator i = Groups.begin( ) ; i != Groups.end( ) ; ++i ) - i->Process(loot); + i->Process(loot,rate); } // True if template includes at least 1 quest drop entry @@ -1143,9 +1143,17 @@ void LoadLootTemplates_Milling() // remove real entries and check existence loot for(uint32 i = 1; i < sItemStorage.MaxEntry; ++i ) - if(ItemPrototype const* proto = sItemStorage.LookupEntry(i)) - if(ids_set.count(proto->ItemId)) - ids_set.erase(proto->ItemId); + { + ItemPrototype const* proto = sItemStorage.LookupEntry(i); + if(!proto) + continue; + + if((proto->BagFamily & BAG_FAMILY_MASK_HERBS)==0) + continue; + + if(ids_set.count(proto->ItemId)) + ids_set.erase(proto->ItemId); + } // output error for any still listed (not referenced from appropriate table) ids LootTemplates_Milling.ReportUnusedIds(ids_set); @@ -1184,9 +1192,17 @@ void LoadLootTemplates_Prospecting() // remove real entries and check existence loot for(uint32 i = 1; i < sItemStorage.MaxEntry; ++i ) - if(ItemPrototype const* proto = sItemStorage.LookupEntry(i)) - if(ids_set.count(proto->ItemId)) - ids_set.erase(proto->ItemId); + { + ItemPrototype const* proto = sItemStorage.LookupEntry(i); + if(!proto) + continue; + + if((proto->BagFamily & BAG_FAMILY_MASK_MINING_SUPP)==0) + continue; + + if(ids_set.count(proto->ItemId)) + ids_set.erase(proto->ItemId); + } // output error for any still listed (not referenced from appropriate table) ids LootTemplates_Prospecting.ReportUnusedIds(ids_set); @@ -1200,8 +1216,15 @@ void LoadLootTemplates_QuestMail() // remove real entries and check existence loot ObjectMgr::QuestMap const& questMap = objmgr.GetQuestTemplates(); for(ObjectMgr::QuestMap::const_iterator itr = questMap.begin(); itr != questMap.end(); ++itr ) - if(ids_set.count(itr->first)) + { + if(!itr->second->GetRewMailTemplateId()) + continue; + + if(!ids_set.count(itr->first)) + LootTemplates_QuestMail.ReportNotExistedId(itr->first); + else ids_set.erase(itr->first); + } // output error for any still listed (not referenced from appropriate table) ids LootTemplates_QuestMail.ReportUnusedIds(ids_set); diff --git a/src/game/LootMgr.h b/src/game/LootMgr.h index 6f8289d31..0605fb77a 100644 --- a/src/game/LootMgr.h +++ b/src/game/LootMgr.h @@ -75,7 +75,7 @@ struct LootStoreItem group(_group), maxcount(_maxcount), conditionId(_conditionId), needs_quest(_chanceOrQuestChance < 0) {} - bool Roll() const; // Checks if the entry takes it's chance (at loot generation) + bool Roll(bool rate) const; // Checks if the entry takes it's chance (at loot generation) bool IsValid(LootStore const& store, uint32 entry) const; // Checks correctness of values }; @@ -127,7 +127,8 @@ typedef std::set LootIdSet; class LootStore { public: - explicit LootStore(char const* name, char const* entryName) : m_name(name), m_entryName(entryName) {} + explicit LootStore(char const* name, char const* entryName, bool ratesAllowed) + : m_name(name), m_entryName(entryName), m_ratesAllowed(m_ratesAllowed) {} virtual ~LootStore() { Clear(); } void Verify() const; @@ -145,6 +146,7 @@ class LootStore char const* GetName() const { return m_name; } char const* GetEntryName() const { return m_entryName; } + bool IsRatesAllowed() const { return m_ratesAllowed; } protected: void LoadLootTable(); void Clear(); @@ -152,6 +154,7 @@ class LootStore LootTemplateMap m_LootTemplates; char const* m_name; char const* m_entryName; + bool m_ratesAllowed; }; class LootTemplate @@ -163,7 +166,7 @@ class LootTemplate // Adds an entry to the group (at loading stage) void AddEntry(LootStoreItem& item); // Rolls for every item in the template and adds the rolled items the the loot - void Process(Loot& loot, LootStore const& store, uint8 GroupId = 0) const; + void Process(Loot& loot, LootStore const& store, bool rate, uint8 GroupId = 0) const; // True if template includes at least 1 quest drop entry bool HasQuestDrop(LootTemplateMap const& store, uint8 GroupId = 0) const; @@ -312,6 +315,7 @@ void LoadLootTemplates_Skinning(); void LoadLootTemplates_Disenchant(); void LoadLootTemplates_Prospecting(); void LoadLootTemplates_QuestMail(); + void LoadLootTemplates_Reference(); inline void LoadLootTables() @@ -326,6 +330,7 @@ inline void LoadLootTables() LoadLootTemplates_Disenchant(); LoadLootTemplates_Prospecting(); LoadLootTemplates_QuestMail(); + LoadLootTemplates_Reference(); } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 64afe316d..8994f3273 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7130" + #define REVISION_NR "7131" #endif // __REVISION_NR_H__ From 205957df0a3a0ba2cc1327c00c6d65456810174d Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Wed, 21 Jan 2009 06:08:07 +0300 Subject: [PATCH 83/84] [7132] Disable quest mail loot check: some quest mails not have items. --- src/game/LootMgr.cpp | 8 +++++--- src/shared/revision_nr.h | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/game/LootMgr.cpp b/src/game/LootMgr.cpp index b3dbc8d97..2cd7f212e 100644 --- a/src/game/LootMgr.cpp +++ b/src/game/LootMgr.cpp @@ -1220,10 +1220,12 @@ void LoadLootTemplates_QuestMail() if(!itr->second->GetRewMailTemplateId()) continue; - if(!ids_set.count(itr->first)) - LootTemplates_QuestMail.ReportNotExistedId(itr->first); - else + if(ids_set.count(itr->first)) ids_set.erase(itr->first); + /* disabled reporting: some quest mails not include items + else + LootTemplates_QuestMail.ReportNotExistedId(itr->first); + */ } // output error for any still listed (not referenced from appropriate table) ids diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 8994f3273..fa6fa3152 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7131" + #define REVISION_NR "7132" #endif // __REVISION_NR_H__ From 2b91a790bc2cc0216da0264a0898da00bf801c23 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Wed, 21 Jan 2009 06:14:34 +0300 Subject: [PATCH 84/84] [7133] Re-implement explicit spell discovery code. * Replace reqClass by reqSkillVlaue field in `skill_discovery_template` and check expected skill points amount for specific reipe discovery. * Add new `spell_loot_template` loot table for store item selection data for spells. At this moment for expclicit recipes discovery spells. * Code cleanups. --- sql/mangos.sql | 31 ++++- ...133_01_mangos_skill_discovery_template.sql | 5 + .../7133_02_mangos_spell_loot_template.sql | 15 +++ sql/updates/Makefile.am | 4 + src/game/Chat.cpp | 1 + src/game/Chat.h | 1 + src/game/Level3.cpp | 9 ++ src/game/LootMgr.cpp | 28 +++++ src/game/LootMgr.h | 3 + src/game/Player.cpp | 20 ++++ src/game/Player.h | 2 + src/game/SkillDiscovery.cpp | 109 +++++++++--------- src/game/SkillDiscovery.h | 1 + src/game/SpellEffects.cpp | 65 +++++------ src/shared/revision_nr.h | 2 +- 15 files changed, 201 insertions(+), 95 deletions(-) create mode 100644 sql/updates/7133_01_mangos_skill_discovery_template.sql create mode 100644 sql/updates/7133_02_mangos_spell_loot_template.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index b2198d4f7..686c3a8fc 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -22,7 +22,7 @@ DROP TABLE IF EXISTS `db_version`; CREATE TABLE `db_version` ( `version` varchar(120) default NULL, - `required_7118_01_mangos_skill_discovery_template` bit(1) default NULL + `required_7133_02_mangos_spell_loot_template` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -12999,7 +12999,7 @@ DROP TABLE IF EXISTS `skill_discovery_template`; CREATE TABLE `skill_discovery_template` ( `spellId` mediumint(8) unsigned NOT NULL default '0' COMMENT 'SpellId of the discoverable spell', `reqSpell` mediumint(8) unsigned NOT NULL default '0' COMMENT 'spell requirement', - `reqClass` tinyint(2) unsigned NOT NULL default '0' COMMENT 'class requirement', + `reqSkillValue` smallint(5) unsigned NOT NULL default '0' COMMENT 'skill points requirement', `chance` float NOT NULL default '0' COMMENT 'chance to discover', PRIMARY KEY (`spellId`,`reqSpell`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Skill Discovery System'; @@ -16225,6 +16225,33 @@ INSERT INTO `spell_learn_spell` VALUES /*!40000 ALTER TABLE `spell_learn_spell` ENABLE KEYS */; UNLOCK TABLES; +-- +-- Table structure for table `spell_loot_template` +-- + +DROP TABLE IF EXISTS `spell_loot_template`; +CREATE TABLE `spell_loot_template` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `item` mediumint(8) unsigned NOT NULL default '0', + `ChanceOrQuestChance` float NOT NULL default '100', + `groupid` tinyint(3) unsigned NOT NULL default '0', + `mincountOrRef` mediumint(9) NOT NULL default '1', + `maxcount` tinyint(3) unsigned NOT NULL default '1', + `lootcondition` tinyint(3) unsigned NOT NULL default '0', + `condition_value1` mediumint(8) unsigned NOT NULL default '0', + `condition_value2` mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`,`item`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Loot System'; + +-- +-- Dumping data for table `spell_loot_template` +-- + +LOCK TABLES `spell_loot_template` WRITE; +/*!40000 ALTER TABLE `spell_loot_template` DISABLE KEYS */; +/*!40000 ALTER TABLE `spell_loot_template` ENABLE KEYS */; +UNLOCK TABLES; + -- -- Table structure for table `spell_pet_auras` -- diff --git a/sql/updates/7133_01_mangos_skill_discovery_template.sql b/sql/updates/7133_01_mangos_skill_discovery_template.sql new file mode 100644 index 000000000..85653618c --- /dev/null +++ b/sql/updates/7133_01_mangos_skill_discovery_template.sql @@ -0,0 +1,5 @@ +ALTER TABLE db_version CHANGE COLUMN required_7118_01_mangos_skill_discovery_template required_7133_01_mangos_skill_discovery_template bit; + +ALTER TABLE skill_discovery_template + DROP `reqClass`, + ADD COLUMN `reqSkillValue` smallint(5) unsigned NOT NULL default '0' COMMENT 'skill points requirement' AFTER reqSpell; diff --git a/sql/updates/7133_02_mangos_spell_loot_template.sql b/sql/updates/7133_02_mangos_spell_loot_template.sql new file mode 100644 index 000000000..29b1681fb --- /dev/null +++ b/sql/updates/7133_02_mangos_spell_loot_template.sql @@ -0,0 +1,15 @@ +ALTER TABLE db_version CHANGE COLUMN required_7133_01_mangos_skill_discovery_template required_7133_02_mangos_spell_loot_template bit; + +DROP TABLE IF EXISTS `spell_loot_template`; +CREATE TABLE `spell_loot_template` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `item` mediumint(8) unsigned NOT NULL default '0', + `ChanceOrQuestChance` float NOT NULL default '100', + `groupid` tinyint(3) unsigned NOT NULL default '0', + `mincountOrRef` mediumint(9) NOT NULL default '1', + `maxcount` tinyint(3) unsigned NOT NULL default '1', + `lootcondition` tinyint(3) unsigned NOT NULL default '0', + `condition_value1` mediumint(8) unsigned NOT NULL default '0', + `condition_value2` mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`,`item`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Loot System'; diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 0632de798..f44216ebb 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -143,6 +143,8 @@ pkgdata_DATA = \ 7107_01_mangos_string.sql \ 7113_01_characters_character_achievement_progress.sql \ 7118_01_mangos_skill_discovery_template.sql \ + 7133_01_mangos_skill_discovery_template.sql \ + 7133_02_mangos_spell_loot_template.sql \ README ## Additional files to include when running 'make dist' @@ -266,4 +268,6 @@ EXTRA_DIST = \ 7107_01_mangos_string.sql \ 7113_01_characters_character_achievement_progress.sql \ 7118_01_mangos_skill_discovery_template.sql \ + 7133_01_mangos_skill_discovery_template.sql \ + 7133_02_mangos_spell_loot_template.sql \ README diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index 449267f87..06e3937c1 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -284,6 +284,7 @@ ChatCommand * ChatHandler::getCommandTable() { "spell_chain", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellChainCommand, "", NULL }, { "spell_elixir", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellElixirCommand, "", NULL }, { "spell_learn_spell", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellLearnSpellCommand, "", NULL }, + { "spell_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesSpellCommand, "", NULL }, { "spell_pet_auras", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellPetAurasCommand, "", NULL }, { "spell_proc_event", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellProcEventCommand, "", NULL }, { "spell_script_target", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellScriptTargetCommand, "", NULL }, diff --git a/src/game/Chat.h b/src/game/Chat.h index 12352f88a..13d044892 100644 --- a/src/game/Chat.h +++ b/src/game/Chat.h @@ -233,6 +233,7 @@ class ChatHandler bool HandleReloadLootTemplatesReferenceCommand(const char* args); bool HandleReloadLootTemplatesQuestMailCommand(const char* args); bool HandleReloadLootTemplatesSkinningCommand(const char* args); + bool HandleReloadLootTemplatesSpellCommand(const char* args); bool HandleReloadMangosStringCommand(const char* args); bool HandleReloadNpcGossipCommand(const char* args); bool HandleReloadNpcOptionCommand(const char* args); diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 1b9f35566..cd011e16a 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -339,6 +339,15 @@ bool ChatHandler::HandleReloadLootTemplatesSkinningCommand(const char*) return true; } +bool ChatHandler::HandleReloadLootTemplatesSpellCommand(const char*) +{ + sLog.outString( "Re-Loading Loot Tables... (`spell_loot_template`)" ); + LoadLootTemplates_Spell(); + LootTemplates_Spell.CheckLootRefs(); + SendGlobalSysMessage("DB table `spell_loot_template` reloaded."); + return true; +} + bool ChatHandler::HandleReloadMangosStringCommand(const char*) { sLog.outString( "Re-Loading mangos_string Table!" ); diff --git a/src/game/LootMgr.cpp b/src/game/LootMgr.cpp index 2cd7f212e..e5ffbbaec 100644 --- a/src/game/LootMgr.cpp +++ b/src/game/LootMgr.cpp @@ -23,6 +23,7 @@ #include "World.h" #include "Util.h" #include "SharedDefines.h" +#include "SpellMgr.h" static Rates const qualityToRate[MAX_ITEM_QUALITY] = { RATE_DROP_ITEM_POOR, // ITEM_QUALITY_POOR @@ -45,6 +46,7 @@ LootStore LootTemplates_Prospecting( "prospecting_loot_template", "item entry LootStore LootTemplates_QuestMail( "quest_mail_loot_template", "quest id (with mail template)",false); LootStore LootTemplates_Reference( "reference_loot_template", "reference id", false); LootStore LootTemplates_Skinning( "skinning_loot_template", "creature skinning id", true); +LootStore LootTemplates_Spell( "spell_loot_template", "spell id (explicitly discovering ability)",false); class LootTemplate::LootGroup // A set of loot definitions for items (refs are not allowed) { @@ -1258,6 +1260,32 @@ void LoadLootTemplates_Skinning() LootTemplates_Skinning.ReportUnusedIds(ids_set); } +void LoadLootTemplates_Spell() +{ + LootIdSet ids_set; + LootTemplates_Spell.LoadAndCollectLootIds(ids_set); + + // remove real entries and check existence loot + for(uint32 spell_id = 1; spell_id < sSpellStore.GetNumRows(); ++spell_id) + { + SpellEntry const* spellInfo = sSpellStore.LookupEntry (spell_id); + if(!spellInfo) + continue; + + // possible cases + if(!IsExplicitDiscoverySpell (spellInfo)) + continue; + + if(!ids_set.count(spell_id)) + LootTemplates_Spell.ReportNotExistedId(spell_id); + else + ids_set.erase(spell_id); + } + + // output error for any still listed (not referenced from appropriate table) ids + LootTemplates_QuestMail.ReportUnusedIds(ids_set); +} + void LoadLootTemplates_Reference() { LootIdSet ids_set; diff --git a/src/game/LootMgr.h b/src/game/LootMgr.h index 0605fb77a..9a7d31e09 100644 --- a/src/game/LootMgr.h +++ b/src/game/LootMgr.h @@ -304,6 +304,7 @@ extern LootStore LootTemplates_Skinning; extern LootStore LootTemplates_Disenchant; extern LootStore LootTemplates_Prospecting; extern LootStore LootTemplates_QuestMail; +extern LootStore LootTemplates_Spell; void LoadLootTemplates_Creature(); void LoadLootTemplates_Fishing(); @@ -316,6 +317,7 @@ void LoadLootTemplates_Disenchant(); void LoadLootTemplates_Prospecting(); void LoadLootTemplates_QuestMail(); +void LoadLootTemplates_Spell(); void LoadLootTemplates_Reference(); inline void LoadLootTables() @@ -330,6 +332,7 @@ inline void LoadLootTables() LoadLootTemplates_Disenchant(); LoadLootTemplates_Prospecting(); LoadLootTemplates_QuestMail(); + LoadLootTemplates_Spell(); LoadLootTemplates_Reference(); } diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 0cec2fd42..85de9fe8a 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -19313,3 +19313,23 @@ void Player::InitRunes() for(uint32 i = 0; i < NUM_RUNE_TYPES; ++i) SetFloatValue(PLAYER_RUNE_REGEN_1 + i, 0.1f); } + +void Player::AutoStoreLootItem(uint8 bag, uint8 slot, uint32 loot_id, LootStore const& store) +{ + Loot loot; + loot.FillLoot (loot_id,store,this); + if(loot.items.empty ()) + return; + LootItem const* lootItem = &loot.items[0]; + + ItemPosCountVec dest; + uint8 msg = CanStoreNewItem (bag,slot,dest,lootItem->itemid,lootItem->count); + if(msg != EQUIP_ERR_OK && slot != NULL_SLOT) + msg = CanStoreNewItem( bag, NULL_SLOT,dest,lootItem->itemid,lootItem->count); + if( msg != EQUIP_ERR_OK && bag != NULL_BAG) + msg = CanStoreNewItem( NULL_BAG, NULL_SLOT,dest,lootItem->itemid,lootItem->count); + if(msg != EQUIP_ERR_OK) + return; + + StoreNewItem (dest,lootItem->itemid,true,lootItem->randomPropertyId); +} diff --git a/src/game/Player.h b/src/game/Player.h index e8ddedb78..acf2a1c1c 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1154,6 +1154,8 @@ class MANGOS_DLL_SPEC Player : public Unit Item* EquipItem( uint16 pos, Item *pItem, bool update ); void AutoUnequipOffhandIfNeed(); bool StoreNewItemInBestSlots(uint32 item_id, uint32 item_count); + void AutoStoreLootItem(uint8 bag, uint8 slot, uint32 loot_id, LootStore const& store); + void AutoStoreLootItem(uint32 loot_id, LootStore const& store) { AutoStoreLootItem(NULL_BAG,NULL_SLOT,loot_id,store); } uint8 _CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count = NULL) const; uint8 _CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 entry, uint32 count, Item *pItem = NULL, bool swap = false, uint32* no_space_count = NULL ) const; diff --git a/src/game/SkillDiscovery.cpp b/src/game/SkillDiscovery.cpp index fb24eb1c0..9e2ba8f6f 100644 --- a/src/game/SkillDiscovery.cpp +++ b/src/game/SkillDiscovery.cpp @@ -30,14 +30,14 @@ struct SkillDiscoveryEntry { uint32 spellId; // discavered spell - uint32 reqClass; // class limitation + uint32 reqSkillValue; // skill level limitation float chance; // chance SkillDiscoveryEntry() - : spellId(0), reqClass(0), chance(0) {} + : spellId(0), reqSkillValue(0), chance(0) {} - SkillDiscoveryEntry(uint16 _spellId, uint32 req_class, float _chance) - : spellId(_spellId), reqClass(req_class), chance(_chance) {} + SkillDiscoveryEntry(uint16 _spellId, uint32 req_skill_val, float _chance) + : spellId(_spellId), reqSkillValue(req_skill_val), chance(_chance) {} }; typedef std::list SkillDiscoveryList; @@ -52,8 +52,8 @@ void LoadSkillDiscoveryTable() uint32 count = 0; - // 0 1 2 3 - QueryResult *result = WorldDatabase.Query("SELECT spellId, reqSpell, reqClass, chance FROM skill_discovery_template"); + // 0 1 2 3 + QueryResult *result = WorldDatabase.Query("SELECT spellId, reqSpell, reqSkillValue, chance FROM skill_discovery_template"); if (result) { @@ -68,18 +68,13 @@ void LoadSkillDiscoveryTable() uint32 spellId = fields[0].GetUInt32(); int32 reqSkillOrSpell = fields[1].GetInt32(); - uint32 reqClass = fields[2].GetInt32(); + uint32 reqSkillValue = fields[2].GetInt32(); float chance = fields[3].GetFloat(); if( chance <= 0 ) // chance { - ssNonDiscoverableEntries << "spellId = " << spellId << " reqSkillOrSpell = " << reqSkillOrSpell << " reqClass = " << reqClass << " chance = " << chance << "(chance problem)\n"; - continue; - } - - if(reqClass && (reqClass >= MAX_CLASSES || ((1 << (reqClass-1)) & CLASSMASK_ALL_PLAYABLE)==0)) - { - ssNonDiscoverableEntries << "spellId = " << spellId << " reqSkillOrSpell = " << reqSkillOrSpell << " reqClass = " << reqClass << " chance = " << chance << "(class problem)\n"; + ssNonDiscoverableEntries << "spellId = " << spellId << " reqSkillOrSpell = " << reqSkillOrSpell + << " reqSkillValue = " << reqSkillValue << " chance = " << chance << "(chance problem)\n"; continue; } @@ -101,7 +96,7 @@ void LoadSkillDiscoveryTable() continue; } - SkillDiscoveryStore[reqSkillOrSpell].push_back( SkillDiscoveryEntry(spellId, reqClass, chance) ); + SkillDiscoveryStore[reqSkillOrSpell].push_back( SkillDiscoveryEntry(spellId, reqSkillValue, chance) ); } else if( reqSkillOrSpell == 0 ) // skill case { @@ -116,7 +111,7 @@ void LoadSkillDiscoveryTable() for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx) { - SkillDiscoveryStore[-int32(_spell_idx->second->skillId)].push_back( SkillDiscoveryEntry(spellId, reqClass, chance) ); + SkillDiscoveryStore[-int32(_spell_idx->second->skillId)].push_back( SkillDiscoveryEntry(spellId, reqSkillValue, chance) ); } } else @@ -142,53 +137,57 @@ void LoadSkillDiscoveryTable() } } +uint32 GetExplicitDiscoverySpell(uint32 spellId, Player* player) +{ + // explicit discovery spell chances (always success if case exist) + // in this case we have both skill and spell + SkillDiscoveryMap::iterator tab = SkillDiscoveryStore.find(spellId); + if(tab == SkillDiscoveryStore.end()) + return 0; + + SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(spellId); + SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(spellId); + uint32 skillvalue = lower != upper ? player->GetSkillValue(lower->second->skillId) : 0; + + float full_chance = 0; + for(SkillDiscoveryList::iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter) + if(item_iter->reqSkillValue <= skillvalue) + if(!player->HasSpell(item_iter->spellId)) + full_chance += item_iter->chance; + + float rate = full_chance / 100.0f; + float roll = rand_chance() * rate; // roll now in range 0..full_chance + + for(SkillDiscoveryList::iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter) + { + if(item_iter->reqSkillValue > skillvalue) + continue; + + if(player->HasSpell(item_iter->spellId)) + continue; + + if(item_iter->chance > roll) + return item_iter->spellId; + + roll -= item_iter->chance; + } + + return 0; +} + uint32 GetSkillDiscoverySpell(uint32 skillId, uint32 spellId, Player* player) { + uint32 skillvalue = skillId ? player->GetSkillValue(skillId) : 0; + // check spell case SkillDiscoveryMap::iterator tab = SkillDiscoveryStore.find(spellId); if(tab != SkillDiscoveryStore.end()) { - SpellEntry const* spellInfo = sSpellStore.LookupEntry (spellId); - if(!spellInfo) - return 0; - - // explicit discovery spell chances (alwasy success if case exist) - if(IsExplicitDiscoverySpell(spellInfo)) - { - float full_chance = 0; - for(SkillDiscoveryList::iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter) - if(!item_iter->reqClass || player->getClass ()==item_iter->reqClass) - if(!player->HasSpell(item_iter->spellId)) - full_chance += item_iter->chance; - - float rate = full_chance / 100.0f; - float roll = rand_chance() * rate; // roll now in range 0..full_chance - - for(SkillDiscoveryList::iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter) - { - if(item_iter->reqClass && player->getClass ()!= item_iter->reqClass) - continue; - - if(player->HasSpell(item_iter->spellId)) - continue; - - if(item_iter->chance > roll) - return item_iter->spellId; - - roll -= item_iter->chance; - } - - return 0; - } - - for(SkillDiscoveryList::iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter) { - if(item_iter->reqClass && player->getClass ()!= item_iter->reqClass) - continue; - if( roll_chance_f(item_iter->chance * sWorld.getRate(RATE_SKILL_DISCOVERY)) + && item_iter->reqSkillValue <= skillvalue && !player->HasSpell(item_iter->spellId) ) return item_iter->spellId; } @@ -205,10 +204,8 @@ uint32 GetSkillDiscoverySpell(uint32 skillId, uint32 spellId, Player* player) { for(SkillDiscoveryList::iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter) { - if(item_iter->reqClass && player->getClass ()!= item_iter->reqClass) - continue; - if( roll_chance_f(item_iter->chance * sWorld.getRate(RATE_SKILL_DISCOVERY)) + && item_iter->reqSkillValue <= skillvalue && !player->HasSpell(item_iter->spellId) ) return item_iter->spellId; } diff --git a/src/game/SkillDiscovery.h b/src/game/SkillDiscovery.h index 781712662..2d4f1bded 100644 --- a/src/game/SkillDiscovery.h +++ b/src/game/SkillDiscovery.h @@ -25,4 +25,5 @@ class Player; void LoadSkillDiscoveryTable(); uint32 GetSkillDiscoverySpell(uint32 skillId, uint32 spellId, Player* player); +uint32 GetExplicitDiscoverySpell(uint32 spellId, Player* player); #endif diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 2fd902357..d009e299a 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -4610,21 +4610,17 @@ void Spell::EffectScriptEffect(uint32 effIndex) // PX-238 Winter Wondervolt TRAP case 26275: { - if (unitTarget->HasAura(26272,0) || - unitTarget->HasAura(26157,0) || - unitTarget->HasAura(26273,0) || - unitTarget->HasAura(26274,0)) - return; + uint32 spells[4] = { 26272, 26157, 26273, 26274 }; - uint32 iTmpSpellId; - switch(urand(0,3)) - { - case 0: iTmpSpellId = 26272; break; - case 1: iTmpSpellId = 26157; break; - case 2: iTmpSpellId = 26273; break; - case 3: iTmpSpellId = 26274; break; - } + // check presence + for(int j = 0; j < 4; ++j) + if(unitTarget->HasAura(spells[j],0)) + return; + // select spell + uint32 iTmpSpellId = spells[urand(0,3)]; + + // cast unitTarget->CastSpell(unitTarget, iTmpSpellId, true); return; } @@ -4668,16 +4664,16 @@ void Spell::EffectScriptEffect(uint32 effIndex) uint32 spellid; switch(m_spellInfo->Id) { - case 25140: spellid = 32571; break; - case 25143: spellid = 32572; break; - case 25650: spellid = 30140; break; - case 25652: spellid = 30141; break; - case 29128: spellid = 32568; break; - case 29129: spellid = 32569; break; - case 35376: spellid = 25649; break; - case 35727: spellid = 35730; break; - default: - return; + case 25140: spellid = 32571; break; + case 25143: spellid = 32572; break; + case 25650: spellid = 30140; break; + case 25652: spellid = 30141; break; + case 29128: spellid = 32568; break; + case 29129: spellid = 32569; break; + case 35376: spellid = 25649; break; + case 35727: spellid = 35730; break; + default: + return; } unitTarget->CastSpell(unitTarget,spellid,false); @@ -4803,18 +4799,10 @@ void Spell::EffectScriptEffect(uint32 effIndex) uint32 spellId; switch(rand()%4) { - case 0: - spellId=46740; - break; - case 1: - spellId=46739; - break; - case 2: - spellId=46738; - break; - case 3: - spellId=46736; - break; + case 0: spellId = 46740; break; + case 1: spellId = 46739; break; + case 2: spellId = 46738; break; + case 3: spellId = 46736; break; } unitTarget->CastSpell(unitTarget, spellId, true); break; @@ -4865,6 +4853,7 @@ void Spell::EffectScriptEffect(uint32 effIndex) // need replace effect 0 item by loot uint32 reagent_id = m_spellInfo->EffectItemType[0]; + if(!player->HasItemCount(reagent_id,1)) return; @@ -4872,7 +4861,11 @@ void Spell::EffectScriptEffect(uint32 effIndex) uint32 count = 1; player->DestroyItemCount (reagent_id,count,true); - if(uint32 discoveredSpell = GetSkillDiscoverySpell(0, m_spellInfo->Id, player)) + // create some random items + player->AutoStoreLootItem(m_spellInfo->Id,LootTemplates_Spell); + + // learn random explicit discovery recipe (if any) + if(uint32 discoveredSpell = GetExplicitDiscoverySpell(m_spellInfo->Id, player)) player->learnSpell(discoveredSpell); return; } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index fa6fa3152..bd694f788 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7132" + #define REVISION_NR "7133" #endif // __REVISION_NR_H__