From 803a815fa45d568f353d040907354f7833f1adcd Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Wed, 13 May 2009 15:47:14 +0400 Subject: [PATCH 01/23] [7815] Apply mangos code style: Replace tabs by spaces in recent added code. --- src/game/World.h | 4 ++-- src/shared/Database/Database.cpp | 2 +- src/shared/Database/DatabaseMysql.cpp | 2 +- src/shared/revision_nr.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/game/World.h b/src/game/World.h index d126b32ef..0fd19e9b8 100644 --- a/src/game/World.h +++ b/src/game/World.h @@ -557,7 +557,7 @@ class World static float m_VisibleObjectGreyDistance; // CLI command holder to be thread safe - ACE_Based::LockedQueue cliCmdQueue; + ACE_Based::LockedQueue cliCmdQueue; SqlResultQueue *m_resultQueue; // next daily quests reset time @@ -568,7 +568,7 @@ class World //sessions that are added async void AddSession_(WorldSession* s); - ACE_Based::LockedQueue addSessQueue; + ACE_Based::LockedQueue addSessQueue; //used versions std::string m_DBVersion; diff --git a/src/shared/Database/Database.cpp b/src/shared/Database/Database.cpp index c8a4b20b1..84ef210db 100644 --- a/src/shared/Database/Database.cpp +++ b/src/shared/Database/Database.cpp @@ -108,7 +108,7 @@ bool Database::PExecuteLog(const char * format,...) void Database::SetResultQueue(SqlResultQueue * queue) { - m_queryQueues[ACE_Based::Thread::current()] = queue; + m_queryQueues[ACE_Based::Thread::current()] = queue; } diff --git a/src/shared/Database/DatabaseMysql.cpp b/src/shared/Database/DatabaseMysql.cpp index bb58c66b2..74efbf71b 100644 --- a/src/shared/Database/DatabaseMysql.cpp +++ b/src/shared/Database/DatabaseMysql.cpp @@ -335,7 +335,7 @@ bool DatabaseMysql::CommitTransaction() // don't use queued execution if it has not been initialized if (!m_threadBody) { - if (tranThread != ACE_Based::Thread::current()) + if (tranThread != ACE_Based::Thread::current()) return false; bool _res = _TransactionCmd("COMMIT"); tranThread = NULL; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index d40415776..c238d1de3 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 "7814" + #define REVISION_NR "7815" #endif // __REVISION_NR_H__ From ae52a1b782fecba19a863918e2c4d42193a95004 Mon Sep 17 00:00:00 2001 From: Ambal Date: Wed, 13 May 2009 16:18:33 +0400 Subject: [PATCH 02/23] [7816] ACE thread priority values verification. Signed-off-by: AlexDereka --- src/shared/Threading.cpp | 63 +++++++++++++++++++++------------------- src/shared/revision_nr.h | 2 +- 2 files changed, 34 insertions(+), 31 deletions(-) diff --git a/src/shared/Threading.cpp b/src/shared/Threading.cpp index b2c88a2c2..496e86353 100644 --- a/src/shared/Threading.cpp +++ b/src/shared/Threading.cpp @@ -44,40 +44,43 @@ ThreadPriority::ThreadPriority() ASSERT (!_tmp.empty()); - const size_t max_pos = _tmp.size(); - size_t min_pos = 1; - size_t norm_pos = 0; - for (size_t i = 0; i < max_pos; ++i) + if(_tmp.size() >= MAXPRIORITYNUM) { - if(_tmp[i] == ACE_THR_PRI_OTHER_DEF) + const size_t max_pos = _tmp.size(); + size_t min_pos = 1; + size_t norm_pos = 0; + for (size_t i = 0; i < max_pos; ++i) { - norm_pos = i + 1; - break; + if(_tmp[i] == ACE_THR_PRI_OTHER_DEF) + { + norm_pos = i + 1; + break; + } } + + //since we have only 7(seven) values in enum Priority + //and 3 we know already (Idle, Normal, Realtime) so + //we need to split each list [Idle...Normal] and [Normal...Realtime] + //into ¹ piesces + const size_t _divider = 4; + size_t _div = (norm_pos - min_pos) / _divider; + if(_div == 0) + _div = 1; + + min_pos = (norm_pos - 1); + + m_priority[Low] = _tmp[min_pos -= _div]; + m_priority[Lowest] = _tmp[min_pos -= _div ]; + + _div = (max_pos - norm_pos) / _divider; + if(_div == 0) + _div = 1; + + min_pos = norm_pos - 1; + + m_priority[High] = _tmp[min_pos += _div]; + m_priority[Highest] = _tmp[min_pos += _div]; } - - //since we have only 7(seven) values in enum Priority - //and 3 we know already (Idle, Normal, Realtime) so - //we need to split each list [Idle...Normal] and [Normal...Realtime] - //into ¹ piesces - const size_t _divider = 4; - size_t _div = (norm_pos - min_pos) / _divider; - if(_div == 0) - _div = 1; - - min_pos = (norm_pos - 1); - - m_priority[Low] = _tmp[min_pos -= _div]; - m_priority[Lowest] = _tmp[min_pos -= _div ]; - - _div = (max_pos - norm_pos) / _divider; - if(_div == 0) - _div = 1; - - min_pos = norm_pos - 1; - - m_priority[High] = _tmp[min_pos += _div]; - m_priority[Highest] = _tmp[min_pos += _div]; } int ThreadPriority::getPriority(Priority p) const diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index c238d1de3..b99ce9005 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 "7815" + #define REVISION_NR "7816" #endif // __REVISION_NR_H__ From dcec7c88c418a29c359d551997efd3837a66dde6 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Wed, 13 May 2009 16:38:24 +0400 Subject: [PATCH 03/23] Record in NEWS recent changes in dep. libs. --- NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS b/NEWS index 32e10c556..ddba38e79 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,8 @@ http://mangos.lighthouseapp.com/ Version 0.13 * Under discussion. + * OpenSSL lib upgrade to OpenSSL 0.9.8k + * ZThread replaced by similar ACE framework functionality. ZThread use dropped. * Upgrade to client version 3.0.9 (build 9551). Version 0.12 From f81cc0bf6a58716a0160d9f8af82e62c5aeb4066 Mon Sep 17 00:00:00 2001 From: Brueggus Date: Sun, 10 May 2009 17:27:09 +0200 Subject: [PATCH 04/23] [7817] Add missing sql-updates to mangos.sql (7776, 7777, 7782) (cherry picked from commit dd26ba3edf339277a94301aa10caf26d33aab576) Signed-off-by: VladimirMangos --- sql/mangos.sql | 28 +++++++++++++++++++++++++--- src/shared/revision_nr.h | 2 +- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/sql/mangos.sql b/sql/mangos.sql index 5381bda91..5ab7a5373 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -3159,6 +3159,27 @@ LOCK TABLES `npc_option` WRITE; /*!40000 ALTER TABLE `npc_option` ENABLE KEYS */; UNLOCK TABLES; +-- +-- Table structure for table `npc_spellclick_spells` +-- + +DROP TABLE IF EXISTS `npc_spellclick_spells`; +CREATE TABLE `npc_spellclick_spells` ( + `npc_entry` INT UNSIGNED NOT NULL COMMENT 'reference to creature_template', + `spell_id` INT UNSIGNED NOT NULL COMMENT 'spell which should be casted ', + `quest_id` INT UNSIGNED NOT NULL COMMENT 'reference to quest_template', + `cast_flags` TINYINT UNSIGNED NOT NULL COMMENT 'first bit defines caster: 1=player, 0=creature; second bit defines target, same mapping as caster bit' +) ENGINE = MYISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `npc_spellclick_spells` +-- + +LOCK TABLES `npc_spellclick_spells` WRITE; +/*!40000 ALTER TABLE `npc_spellclick_spells` DISABLE KEYS */; +/*!40000 ALTER TABLE `npc_spellclick_spells` ENABLE KEYS */; +UNLOCK TABLES; + -- -- Table structure for table `npc_text` -- @@ -17013,9 +17034,9 @@ INSERT INTO `spell_proc_event` VALUES (30293, 0x00000000, 5, 0x00000381, 0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (30295, 0x00000000, 5, 0x00000381, 0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (30296, 0x00000000, 5, 0x00000381, 0x000000C0, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(30299, 0x00000024, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(30301, 0x00000024, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), -(30302, 0x00000024, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(30299, 0x0000007E, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(30301, 0x0000007E, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(30302, 0x0000007E, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (30675, 0x00000000, 11, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (30678, 0x00000000, 11, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (30679, 0x00000000, 11, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), @@ -17101,6 +17122,7 @@ INSERT INTO `spell_proc_event` VALUES (33882, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (33883, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (33953, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 45), +(34074, 0x00000000, 9, 0x0007FA43, 0x00881081, 0x00000201, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (34080, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008, 0.000000, 0.000000, 0), (34138, 0x00000000, 11, 0x00000080, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (34139, 0x00000000, 10, 0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index b99ce9005..e9dbeedee 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 "7816" + #define REVISION_NR "7817" #endif // __REVISION_NR_H__ From fd71c2bd6f7038c6f3eebc1a184cbb02e4f618be Mon Sep 17 00:00:00 2001 From: DonTomika Date: Wed, 13 May 2009 23:24:55 +0400 Subject: [PATCH 05/23] [7818] Implement SPELL_AURA_MOD_FACTION_REPUTATION_GAIN. Signed-off-by: VladimirMangos --- src/game/Player.cpp | 19 +++++++++++-------- src/game/Player.h | 2 +- src/game/SpellAuras.cpp | 2 +- src/shared/revision_nr.h | 2 +- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 526773dad..a222307c9 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -5669,23 +5669,26 @@ ReputationRank Player::GetReputationRank(uint32 faction) const } //Calculate total reputation percent player gain with quest/creature level -int32 Player::CalculateReputationGain(uint32 creatureOrQuestLevel, int32 rep, bool for_quest) +int32 Player::CalculateReputationGain(uint32 creatureOrQuestLevel, int32 rep, int32 faction, bool for_quest) { float percent = 100.0f; float rate = for_quest ? sWorld.getRate(RATE_REPUTATION_LOWLEVEL_QUEST) : sWorld.getRate(RATE_REPUTATION_LOWLEVEL_KILL); - if(rate != 1.0f && creatureOrQuestLevel <= MaNGOS::XP::GetGrayLevel(getLevel())) + if (rate != 1.0f && creatureOrQuestLevel <= MaNGOS::XP::GetGrayLevel(getLevel())) percent *= rate; - int32 repMod = GetTotalAuraModifier(SPELL_AURA_MOD_REPUTATION_GAIN); + float repMod = GetTotalAuraModifier(SPELL_AURA_MOD_REPUTATION_GAIN); + + if (!for_quest) + repMod += GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_FACTION_REPUTATION_GAIN, faction); percent += rep > 0 ? repMod : -repMod; - if(percent <= 0.0f) + if (percent <= 0.0f) return 0; - return int32(sWorld.getRate(RATE_REPUTATION_GAIN)*rep*percent/100); + return int32(sWorld.getRate(RATE_REPUTATION_GAIN)*rep*percent/100.0f); } //Calculates how many reputation points player gains in victim's enemy factions @@ -5701,7 +5704,7 @@ void Player::RewardReputation(Unit *pVictim, float rate) if(Rep->repfaction1 && (!Rep->team_dependent || GetTeam()==ALLIANCE)) { - int32 donerep1 = CalculateReputationGain(pVictim->getLevel(),Rep->repvalue1,false); + int32 donerep1 = CalculateReputationGain(pVictim->getLevel(), Rep->repvalue1, Rep->repfaction1, false); donerep1 = int32(donerep1*rate); FactionEntry const *factionEntry1 = sFactionStore.LookupEntry(Rep->repfaction1); uint32 current_reputation_rank1 = GetReputationMgr().GetRank(factionEntry1); @@ -5719,7 +5722,7 @@ void Player::RewardReputation(Unit *pVictim, float rate) if(Rep->repfaction2 && (!Rep->team_dependent || GetTeam()==HORDE)) { - int32 donerep2 = CalculateReputationGain(pVictim->getLevel(),Rep->repvalue2,false); + int32 donerep2 = CalculateReputationGain(pVictim->getLevel(), Rep->repvalue2, Rep->repfaction2, false); donerep2 = int32(donerep2*rate); FactionEntry const *factionEntry2 = sFactionStore.LookupEntry(Rep->repfaction2); uint32 current_reputation_rank2 = GetReputationMgr().GetRank(factionEntry2); @@ -5744,7 +5747,7 @@ void Player::RewardReputation(Quest const *pQuest) { if(pQuest->RewRepFaction[i] && pQuest->RewRepValue[i] ) { - int32 rep = CalculateReputationGain(GetQuestLevel(pQuest),pQuest->RewRepValue[i],true); + int32 rep = CalculateReputationGain(GetQuestLevel(pQuest), pQuest->RewRepValue[i], pQuest->RewRepFaction[i], true); FactionEntry const* factionEntry = sFactionStore.LookupEntry(pQuest->RewRepFaction[i]); if(factionEntry) GetReputationMgr().ModifyReputation(factionEntry, rep); diff --git a/src/game/Player.h b/src/game/Player.h index 4e3487c2f..eadb0e028 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -2283,7 +2283,7 @@ class MANGOS_DLL_SPEC Player : public Unit Item* _StoreItem( uint16 pos, Item *pItem, uint32 count, bool clone, bool update ); void UpdateKnownCurrencies(uint32 itemId, bool apply); - int32 CalculateReputationGain(uint32 creatureOrQuestLevel, int32 rep, bool for_quest); + int32 CalculateReputationGain(uint32 creatureOrQuestLevel, int32 rep, int32 faction, bool for_quest); void AdjustQuestReqItemCount( Quest const* pQuest, QuestStatusData& questStatusData ); GridReference m_gridRef; diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index f84dd6a46..2a50fdc54 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -240,7 +240,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleNoImmediateEffect, //187 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE implemented in Unit::GetUnitCriticalChance &Aura::HandleNoImmediateEffect, //188 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_CHANCE implemented in Unit::GetUnitCriticalChance &Aura::HandleModRating, //189 SPELL_AURA_MOD_RATING - &Aura::HandleNULL, //190 SPELL_AURA_MOD_FACTION_REPUTATION_GAIN + &Aura::HandleNoImmediateEffect, //190 SPELL_AURA_MOD_FACTION_REPUTATION_GAIN implemented in Player::CalculateReputationGain &Aura::HandleAuraModUseNormalSpeed, //191 SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED &Aura::HandleModMeleeRangedSpeedPct, //192 SPELL_AURA_HASTE_MELEE &Aura::HandleModCombatSpeedPct, //193 SPELL_AURA_MELEE_SLOW (in fact combat (any type attack) speed pct) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index e9dbeedee..473146166 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 "7817" + #define REVISION_NR "7818" #endif // __REVISION_NR_H__ From bfe2e187a6921426be09d4c78ed34bd45ac2217f Mon Sep 17 00:00:00 2001 From: DiSlord Date: Thu, 14 May 2009 00:10:14 +0400 Subject: [PATCH 06/23] [7819] Correct use item ScalingStatValues data (ScalingStatValues.dbc): - ScalingStatDistribution stats multiplier - Armor bonus from ssv - Damage from ssv - Feral AP from ssv - Feral AP from ssv dps bonus Use item->StatsCount in apply mods Not allow equip item if level > ScalingStatDistribution->maxlevel field TODO find more info about ScalingStatValuesEntry->spellBonus Signed-off-by: DiSlord --- src/game/DBCStructure.h | 55 +++++++++++++++++++++++++++-- src/game/ItemPrototype.h | 44 ++--------------------- src/game/Player.cpp | 75 ++++++++++++++++++++++++++-------------- src/shared/revision_nr.h | 2 +- 4 files changed, 106 insertions(+), 70 deletions(-) diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h index 1df277492..2948f8621 100644 --- a/src/game/DBCStructure.h +++ b/src/game/DBCStructure.h @@ -1136,7 +1136,7 @@ struct RandomPropertiesPointsEntry struct ScalingStatDistributionEntry { uint32 Id; - uint32 StatMod[10]; + int32 StatMod[10]; uint32 Modifier[10]; uint32 MaxLevel; }; @@ -1145,7 +1145,58 @@ struct ScalingStatValuesEntry { uint32 Id; uint32 Level; - uint32 Multiplier[17]; + uint32 ssdMultiplier[5]; // Multiplier for ScalingStatDistribution + uint32 armorMod[4]; // Armor for level + uint32 dpsMod[6]; // DPS mod for level + uint32 spellBonus; // not sure.. TODO: need more info about + uint32 feralBonus; // Feral AP bonus + + uint32 getssdMultiplier(uint32 mask) const + { + if (mask&0x001F) + { + if(mask & 0x00000001) return ssdMultiplier[0]; + if(mask & 0x00000002) return ssdMultiplier[1]; + if(mask & 0x00000004) return ssdMultiplier[2]; + if(mask & 0x00000008) return ssdMultiplier[3]; + if(mask & 0x00000010) return ssdMultiplier[4]; + } + return 0; + } + uint32 getArmorMod(uint32 mask) const + { + if (mask&0x01E0) + { + if(mask & 0x00000020) return armorMod[0]; + if(mask & 0x00000040) return armorMod[1]; + if(mask & 0x00000080) return armorMod[2]; + if(mask & 0x00000100) return armorMod[3]; + } + return 0; + } + uint32 getDPSMod(uint32 mask) const + { + if (mask&0x7E00) + { + if(mask & 0x00000200) return dpsMod[0]; + if(mask & 0x00000400) return dpsMod[1]; + if(mask & 0x00000800) return dpsMod[2]; + if(mask & 0x00001000) return dpsMod[3]; + if(mask & 0x00002000) return dpsMod[4]; + if(mask & 0x00004000) return dpsMod[5]; + } + return 0; + } + uint32 getSpellBonus(uint32 mask) const + { + if (mask & 0x00008000) return spellBonus; + return 0; + } + uint32 getFeralBonus(uint32 mask) const + { + if (mask & 0x00010000) return feralBonus; + return 0; + } }; //struct SkillLineCategoryEntry{ diff --git a/src/game/ItemPrototype.h b/src/game/ItemPrototype.h index c5f0f4d8a..ba578c7d7 100644 --- a/src/game/ItemPrototype.h +++ b/src/game/ItemPrototype.h @@ -593,46 +593,6 @@ struct ItemPrototype return false; } - uint32 GetScalingStatValuesColumn() const - { - if(ScalingStatValue & 0x00000001) // stat mod - return 0; - if(ScalingStatValue & 0x00000002) // stat mod - return 1; - if(ScalingStatValue & 0x00000004) // stat mod - return 2; - if(ScalingStatValue & 0x00000008) // stat mod - return 3; - if(ScalingStatValue & 0x00000010) // stat mod - return 4; - if(ScalingStatValue & 0x00000020) // armor mod - return 5; - if(ScalingStatValue & 0x00000040) // armor mod - return 6; - if(ScalingStatValue & 0x00000080) // armor mod - return 7; - if(ScalingStatValue & 0x00000100) // armor mod - return 8; - if(ScalingStatValue & 0x00000200) // damage mod - return 9; - if(ScalingStatValue & 0x00000400) // damage mod - return 10; - if(ScalingStatValue & 0x00000800) // damage mod - return 11; - if(ScalingStatValue & 0x00001000) // damage mod - return 12; - if(ScalingStatValue & 0x00002000) // damage mod - return 13; - if(ScalingStatValue & 0x00004000) // damage mod - return 14; - if(ScalingStatValue & 0x00008000) // spell power - return 15; - if(ScalingStatValue & 0x00020000) // feral AP - return 16; - - return 0; - } - uint32 GetMaxStackSize() const { return Stackable > 0 ? uint32(Stackable) : uint32(0x7FFFFFFF-1); } float getDPS() const @@ -645,12 +605,12 @@ struct ItemPrototype return temp*500/Delay; } - int32 getFeralBonus() const + int32 getFeralBonus(int32 extraDPS = 0) const { // 0x02A5F3 - is mask for Melee weapon from ItemSubClassMask.dbc if (Class == ITEM_CLASS_WEAPON && (1<= INVENTORY_SLOT_BAG_END || !proto) return; + ScalingStatDistributionEntry const *ssd = proto->ScalingStatDistribution ? sScalingStatDistributionStore.LookupEntry(proto->ScalingStatDistribution) : 0; + ScalingStatValuesEntry const *ssv = proto->ScalingStatValue ? sScalingStatValuesStore.LookupEntry(getLevel()) : 0; + for (int i = 0; i < MAX_ITEM_PROTO_STATS; ++i) { uint32 statType = 0; - int32 val = 0; - - if(proto->ScalingStatDistribution) + int32 val = 0; + // If set ScalingStatDistribution need get stats and values from it + if (ssd && ssv) { - if(ScalingStatDistributionEntry const *ssd = sScalingStatDistributionStore.LookupEntry(proto->ScalingStatDistribution)) - { - statType = ssd->StatMod[i]; - - if(uint32 modifier = ssd->Modifier[i]) - { - uint32 level = ((getLevel() > ssd->MaxLevel) ? ssd->MaxLevel : getLevel()); - if(ScalingStatValuesEntry const *ssv = sScalingStatValuesStore.LookupEntry(level)) - { - uint32 multiplier = ssv->Multiplier[proto->GetScalingStatValuesColumn()]; - val = (multiplier * modifier) / 10000; - } - } - } + if (ssd->StatMod[i] < 0) + continue; + statType = ssd->StatMod[i]; + val = (ssv->getssdMultiplier(proto->ScalingStatValue) * ssd->Modifier[i]) / 10000; } else { + if (proto->StatsCount >= i) + continue; statType = proto->ItemStat[i].ItemStatType; val = proto->ItemStat[i].ItemStatValue; } @@ -6516,8 +6511,15 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl } } - if (proto->Armor) - HandleStatModifier(UNIT_MOD_ARMOR, BASE_VALUE, float(proto->Armor), apply); + // If set ScalingStatValue armor get it or use item armor + uint32 armor = proto->Armor; + if (ssv) + { + if (uint32 ssvarmor = ssv->getArmorMod(proto->ScalingStatValue)) + armor = ssvarmor; + } + if (armor) + HandleStatModifier(UNIT_MOD_ARMOR, BASE_VALUE, float(armor), apply); if (proto->Block) HandleBaseModValue(SHIELD_BLOCK_VALUE, FLAT_MOD, float(proto->Block), apply); @@ -6554,23 +6556,42 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl attType = OFF_ATTACK; } - if (proto->Damage[0].DamageMin > 0 ) + float minDamage = proto->Damage[0].DamageMin; + float maxDamage = proto->Damage[0].DamageMax; + int32 extraDPS = 0; + // If set dpsMod in ScalingStatValue use it for min (70% from avernge), max (130% from averange) damage + if (ssv) { - damage = apply ? proto->Damage[0].DamageMin : BASE_MINDAMAGE; + if (extraDPS = ssv->getDPSMod(proto->ScalingStatValue)) + { + float averange = extraDPS * proto->Delay / 1000.0f; + minDamage = 0.7f * averange; + maxDamage = 1.3f * averange; + } + } + if (minDamage > 0 ) + { + damage = apply ? minDamage : BASE_MINDAMAGE; SetBaseWeaponDamage(attType, MINDAMAGE, damage); //sLog.outError("applying mindam: assigning %f to weapon mindamage, now is: %f", damage, GetWeaponDamageRange(attType, MINDAMAGE)); } - if (proto->Damage[0].DamageMax > 0 ) + if (maxDamage > 0 ) { - damage = apply ? proto->Damage[0].DamageMax : BASE_MAXDAMAGE; + damage = apply ? maxDamage : BASE_MAXDAMAGE; SetBaseWeaponDamage(attType, MAXDAMAGE, damage); } - // Druids get feral AP bonus from weapon dps + // Apply feral bonus from ScalingStatValue if set + if (ssv) + { + if (int32 feral_bonus = ssv->getFeralBonus(proto->ScalingStatValue)) + ApplyFeralAPBonus(feral_bonus, apply); + } + // Druids get feral AP bonus from weapon dps (lso use DPS from ScalingStatValue) if(getClass() == CLASS_DRUID) { - int32 feral_bonus = proto->getFeralBonus(); + int32 feral_bonus = proto->getFeralBonus(extraDPS); if (feral_bonus > 0) ApplyFeralAPBonus(feral_bonus, apply); } @@ -9566,6 +9587,10 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo return EQUIP_ERR_CANT_DO_RIGHT_NOW; } + ScalingStatDistributionEntry const *ssd = pProto->ScalingStatDistribution ? sScalingStatDistributionStore.LookupEntry(pProto->ScalingStatDistribution) : 0; + if (ssd && ssd->MaxLevel < getLevel()) + return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED; + uint8 eslot = FindEquipSlot( pProto, slot, swap ); if( eslot == NULL_SLOT ) return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 473146166..1a12c009b 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 "7818" + #define REVISION_NR "7819" #endif // __REVISION_NR_H__ From 167e8c86f6182617550c4227a14eccc956116e39 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Thu, 14 May 2009 10:37:23 +0400 Subject: [PATCH 07/23] Code style and cleanups in item equip checks. --- src/game/Player.cpp | 86 ++++++++++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 40 deletions(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 07453e54b..1b5620286 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -9592,17 +9592,17 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED; uint8 eslot = FindEquipSlot( pProto, slot, swap ); - if( eslot == NULL_SLOT ) + if (eslot == NULL_SLOT) return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED; - uint8 msg = CanUseItem( pItem , not_loading ); - if( msg != EQUIP_ERR_OK ) + uint8 msg = CanUseItem(pItem , not_loading); + if (msg != EQUIP_ERR_OK) return msg; - if( !swap && GetItemByPos( INVENTORY_SLOT_BAG_0, eslot ) ) + if (!swap && GetItemByPos(INVENTORY_SLOT_BAG_0, eslot)) return EQUIP_ERR_NO_EQUIPMENT_SLOT_AVAILABLE; // if swap ignore item (equipped also) - if(uint8 res2 = CanEquipUniqueItem(pItem, swap ? eslot : NULL_SLOT)) + if (uint8 res2 = CanEquipUniqueItem(pItem, swap ? eslot : NULL_SLOT)) return res2; // check unique-equipped special item classes @@ -9610,19 +9610,16 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo { for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i) { - if( Item* pBag = GetItemByPos( INVENTORY_SLOT_BAG_0, i ) ) + if (Item* pBag = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) { - if( pBag != pItem ) + if (pBag != pItem) { - if( ItemPrototype const* pBagProto = pBag->GetProto() ) + if (ItemPrototype const* pBagProto = pBag->GetProto()) { - if( pBagProto->Class==pProto->Class && (!swap || pBag->GetSlot() != eslot ) ) - { - if(pBagProto->SubClass == ITEM_SUBCLASS_AMMO_POUCH) - return EQUIP_ERR_CAN_EQUIP_ONLY1_AMMOPOUCH; - else - return EQUIP_ERR_CAN_EQUIP_ONLY1_QUIVER; - } + if (pBagProto->Class==pProto->Class && (!swap || pBag->GetSlot() != eslot)) + return (pBagProto->SubClass == ITEM_SUBCLASS_AMMO_POUCH) + ? EQUIP_ERR_CAN_EQUIP_ONLY1_AMMOPOUCH + : EQUIP_ERR_CAN_EQUIP_ONLY1_QUIVER; } } } @@ -9631,25 +9628,25 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo uint32 type = pProto->InventoryType; - if(eslot == EQUIPMENT_SLOT_OFFHAND) + if (eslot == EQUIPMENT_SLOT_OFFHAND) { if (type == INVTYPE_WEAPON || type == INVTYPE_WEAPONOFFHAND) { - if(!CanDualWield()) + if (!CanDualWield()) return EQUIP_ERR_CANT_DUAL_WIELD; } else if (type == INVTYPE_2HWEAPON) { - if(!CanDualWield() || !CanTitanGrip()) + if (!CanDualWield() || !CanTitanGrip()) return EQUIP_ERR_CANT_DUAL_WIELD; } - if(IsTwoHandUsed()) + if (IsTwoHandUsed()) return EQUIP_ERR_CANT_EQUIP_WITH_TWOHANDED; } // equip two-hand weapon case (with possible unequip 2 items) - if( type == INVTYPE_2HWEAPON ) + if (type == INVTYPE_2HWEAPON) { if (eslot == EQUIPMENT_SLOT_OFFHAND) { @@ -9664,9 +9661,9 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo // offhand item must can be stored in inventory for offhand item and it also must be unequipped Item *offItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND ); ItemPosCountVec off_dest; - if( offItem && (!not_loading || + if (offItem && (!not_loading || CanUnequipItem(uint16(INVENTORY_SLOT_BAG_0) << 8 | EQUIPMENT_SLOT_OFFHAND,false) != EQUIP_ERR_OK || - CanStoreItem( NULL_BAG, NULL_SLOT, off_dest, offItem, false ) != EQUIP_ERR_OK ) ) + CanStoreItem( NULL_BAG, NULL_SLOT, off_dest, offItem, false ) != EQUIP_ERR_OK )) return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED : EQUIP_ERR_INVENTORY_FULL; } } @@ -9674,10 +9671,8 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo return EQUIP_ERR_OK; } } - if( !swap ) - return EQUIP_ERR_ITEM_NOT_FOUND; - else - return EQUIP_ERR_ITEMS_CANT_BE_SWAPPED; + + return !swap ? EQUIP_ERR_ITEM_NOT_FOUND : EQUIP_ERR_ITEMS_CANT_BE_SWAPPED; } uint8 Player::CanUnequipItem( uint16 pos, bool swap ) const @@ -9896,38 +9891,49 @@ uint8 Player::CanBankItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *p uint8 Player::CanUseItem( Item *pItem, bool not_loading ) const { - if( pItem ) + if (pItem) { sLog.outDebug( "STORAGE: CanUseItem item = %u", pItem->GetEntry()); - if( !isAlive() && not_loading ) + + if (!isAlive() && not_loading) return EQUIP_ERR_YOU_ARE_DEAD; - //if( isStunned() ) + + //if (isStunned()) // return EQUIP_ERR_YOU_ARE_STUNNED; + ItemPrototype const *pProto = pItem->GetProto(); - if( pProto ) + if (pProto) { - if( pItem->IsBindedNotWith(GetGUID()) ) + if (pItem->IsBindedNotWith(GetGUID())) return EQUIP_ERR_DONT_OWN_THAT_ITEM; - if( (pProto->AllowableClass & getClassMask()) == 0 || (pProto->AllowableRace & getRaceMask()) == 0 ) + + if ((pProto->AllowableClass & getClassMask()) == 0 || (pProto->AllowableRace & getRaceMask()) == 0) return EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM; - if( pItem->GetSkill() != 0 ) + + if (pItem->GetSkill() != 0) { - if( GetSkillValue( pItem->GetSkill() ) == 0 ) + if (GetSkillValue( pItem->GetSkill() ) == 0) return EQUIP_ERR_NO_REQUIRED_PROFICIENCY; } - if( pProto->RequiredSkill != 0 ) + + if (pProto->RequiredSkill != 0) { - if( GetSkillValue( pProto->RequiredSkill ) == 0 ) + if (GetSkillValue( pProto->RequiredSkill ) == 0) return EQUIP_ERR_NO_REQUIRED_PROFICIENCY; - else if( GetSkillValue( pProto->RequiredSkill ) < pProto->RequiredSkillRank ) + + if (GetSkillValue( pProto->RequiredSkill ) < pProto->RequiredSkillRank) return EQUIP_ERR_ERR_CANT_EQUIP_SKILL; } - if( pProto->RequiredSpell != 0 && !HasSpell( pProto->RequiredSpell ) ) + + if (pProto->RequiredSpell != 0 && !HasSpell(pProto->RequiredSpell)) return EQUIP_ERR_NO_REQUIRED_PROFICIENCY; - if( pProto->RequiredReputationFaction && uint32(GetReputationRank(pProto->RequiredReputationFaction)) < pProto->RequiredReputationRank ) + + if (pProto->RequiredReputationFaction && uint32(GetReputationRank(pProto->RequiredReputationFaction)) < pProto->RequiredReputationRank) return EQUIP_ERR_CANT_EQUIP_REPUTATION; - if( getLevel() < pProto->RequiredLevel ) + + if (getLevel() < pProto->RequiredLevel) return EQUIP_ERR_CANT_EQUIP_LEVEL_I; + return EQUIP_ERR_OK; } } From 4edbdb02f60e8c96ec49e959fbe6b98be91169d5 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Thu, 14 May 2009 10:39:14 +0400 Subject: [PATCH 08/23] [7820] Fixed typo in [7819] that not allow correct work non-scalling item stats. --- src/game/Player.cpp | 2 +- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 1b5620286..7856a287d 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -6355,7 +6355,7 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl } else { - if (proto->StatsCount >= i) + if (i >= proto->StatsCount) continue; statType = proto->ItemStat[i].ItemStatType; val = proto->ItemStat[i].ItemStatValue; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 1a12c009b..835d52759 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 "7819" + #define REVISION_NR "7820" #endif // __REVISION_NR_H__ From 28c7c95b876dbf14f1ec8c1026fd3c7aee157a44 Mon Sep 17 00:00:00 2001 From: KAPATEJIb Date: Thu, 14 May 2009 10:44:49 +0400 Subject: [PATCH 09/23] [7821] Fixed typo in comment and var. name. Signed-off-by: VladimirMangos --- src/game/Player.cpp | 8 ++++---- src/shared/revision_nr.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 7856a287d..6be643e3c 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -6559,14 +6559,14 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl float minDamage = proto->Damage[0].DamageMin; float maxDamage = proto->Damage[0].DamageMax; int32 extraDPS = 0; - // If set dpsMod in ScalingStatValue use it for min (70% from avernge), max (130% from averange) damage + // If set dpsMod in ScalingStatValue use it for min (70% from average), max (130% from average) damage if (ssv) { if (extraDPS = ssv->getDPSMod(proto->ScalingStatValue)) { - float averange = extraDPS * proto->Delay / 1000.0f; - minDamage = 0.7f * averange; - maxDamage = 1.3f * averange; + float average = extraDPS * proto->Delay / 1000.0f; + minDamage = 0.7f * average; + maxDamage = 1.3f * average; } } if (minDamage > 0 ) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 835d52759..369a5b4bd 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 "7820" + #define REVISION_NR "7821" #endif // __REVISION_NR_H__ From dbf1f4323bff205fcb1eaf07cb318abdd9f00952 Mon Sep 17 00:00:00 2001 From: Foks Date: Thu, 14 May 2009 11:17:38 +0400 Subject: [PATCH 10/23] [7822] Avoid declined names form show in case disabled config option with russian client at non-russian realm. Signed-off-by: VladimirMangos --- src/game/CharacterHandler.cpp | 2 +- src/game/Player.cpp | 7 ++++++- src/shared/revision_nr.h | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index 1554d0b60..fabdc906c 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -169,7 +169,7 @@ void WorldSession::HandleCharEnumOpcode( WorldPacket & /*recv_data*/ ) // 0 1 2 3 4 5 6 7 8 "SELECT characters.guid, characters.data, characters.name, characters.position_x, characters.position_y, characters.position_z, characters.map, characters.totaltime, characters.leveltime, " // 9 10 11 12 13 14 - "characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, guild_member.guildid, genitive " + "characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, guild_member.guildid, character_declinedname.genitive " "FROM characters LEFT JOIN character_pet ON characters.guid = character_pet.owner AND character_pet.slot='%u' " "LEFT JOIN character_declinedname ON characters.guid = character_declinedname.guid " "LEFT JOIN guild_member ON characters.guid = guild_member.guid " diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 6be643e3c..f6ef64c24 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -1445,7 +1445,12 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) char_flags |= CHARACTER_FLAG_GHOST; if(HasAtLoginFlag(AT_LOGIN_RENAME)) char_flags |= CHARACTER_FLAG_RENAME; - if(sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) && (fields[14].GetCppString() != "")) + if(sWorld.getConfig(CONFIG_DECLINED_NAMES_USED)) + { + if(!fields[14].GetCppString().empty()) + char_flags |= CHARACTER_FLAG_DECLINED; + } + else char_flags |= CHARACTER_FLAG_DECLINED; *p_data << uint32(char_flags); // character flags diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 369a5b4bd..871d29d7a 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 "7821" + #define REVISION_NR "7822" #endif // __REVISION_NR_H__ From 640d46ce1f2a597e81a6fd6e6e0a9548e75b198d Mon Sep 17 00:00:00 2001 From: DiSlord Date: Thu, 14 May 2009 11:47:48 +0400 Subject: [PATCH 11/23] [7823] Fix ScalingStatValue field size in item_template table. Signed-off-by: DiSlord --- sql/mangos.sql | 4 ++-- sql/updates/7823_01_mangos_item_template.sql | 4 ++++ sql/updates/Makefile.am | 2 ++ src/shared/revision_nr.h | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 sql/updates/7823_01_mangos_item_template.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index 5ab7a5373..3b26ee8bc 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -23,7 +23,7 @@ DROP TABLE IF EXISTS `db_version`; CREATE TABLE `db_version` ( `version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL, - `required_7796_02_mangos_mangos_string` bit(1) default NULL + `required_7823_01_mangos_item_template` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -1712,7 +1712,7 @@ CREATE TABLE `item_template` ( `stat_type10` tinyint(3) unsigned NOT NULL default '0', `stat_value10` smallint(6) NOT NULL default '0', `ScalingStatDistribution` smallint(6) NOT NULL default '0', - `ScalingStatValue` smallint(6) NOT NULL default '0', + `ScalingStatValue` int(6) unsigned NOT NULL default '0', `dmg_min1` float NOT NULL default '0', `dmg_max1` float NOT NULL default '0', `dmg_type1` tinyint(3) unsigned NOT NULL default '0', diff --git a/sql/updates/7823_01_mangos_item_template.sql b/sql/updates/7823_01_mangos_item_template.sql new file mode 100644 index 000000000..2b3a0b314 --- /dev/null +++ b/sql/updates/7823_01_mangos_item_template.sql @@ -0,0 +1,4 @@ +ALTER TABLE db_version CHANGE COLUMN required_7796_02_mangos_mangos_string required_7823_01_mangos_item_template bit; + +ALTER TABLE item_template +CHANGE COLUMN ScalingStatValue ScalingStatValue int(6) unsigned NOT NULL default '0'; \ No newline at end of file diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 499016c4b..8a7cedfd4 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -184,6 +184,7 @@ pkgdata_DATA = \ 7796_02_mangos_mangos_string.sql \ 7802_01_characters_character_achievement.sql \ 7802_02_characters_character_achievement_progress.sql \ + 7823_01_mangos_item_template.sql \ README ## Additional files to include when running 'make dist' @@ -348,4 +349,5 @@ EXTRA_DIST = \ 7796_02_mangos_mangos_string.sql \ 7802_01_characters_character_achievement.sql \ 7802_02_characters_character_achievement_progress.sql \ + 7823_01_mangos_item_template.sql \ README diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 871d29d7a..f4620f971 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 "7822" + #define REVISION_NR "7823" #endif // __REVISION_NR_H__ From 1f3210b0ca2358a4a2877f0297527782aa33ecbe Mon Sep 17 00:00:00 2001 From: DiSlord Date: Thu, 14 May 2009 12:06:09 +0400 Subject: [PATCH 12/23] [7824] Implement use ArmorDamageModifier bonus for armor Signed-off-by: DiSlord --- src/game/Player.cpp | 3 +++ src/shared/revision_nr.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index f6ef64c24..fd19a2412 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -6523,6 +6523,9 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl if (uint32 ssvarmor = ssv->getArmorMod(proto->ScalingStatValue)) armor = ssvarmor; } + // Add armor bonus from ArmorDamageModifier if > 0 + if (proto->ArmorDamageModifier > 0) + armor+=proto->ArmorDamageModifier; if (armor) HandleStatModifier(UNIT_MOD_ARMOR, BASE_VALUE, float(armor), apply); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index f4620f971..fdff48589 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 "7823" + #define REVISION_NR "7824" #endif // __REVISION_NR_H__ From ff80f14d2d04d763fdc2c57fee36f64ed3241eeb Mon Sep 17 00:00:00 2001 From: BombermaG Date: Thu, 14 May 2009 12:33:36 +0400 Subject: [PATCH 13/23] [7825] Fixed typo in comment and var. name. Signed-off-by: DiSlord --- src/game/DBCEnums.h | 2 +- src/game/SpellEffects.cpp | 4 ++-- src/shared/revision_nr.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/game/DBCEnums.h b/src/game/DBCEnums.h index 68f4bb1be..20b28c1d4 100644 --- a/src/game/DBCEnums.h +++ b/src/game/DBCEnums.h @@ -48,7 +48,7 @@ enum AchievementFlags ACHIEVEMENT_FLAG_SUMM = 0x00000008, // Use summ criteria value from all reqirements (and calculate max value) ACHIEVEMENT_FLAG_MAX_USED = 0x00000010, // Show max criteria (and calculate max value ??) ACHIEVEMENT_FLAG_REQ_COUNT = 0x00000020, // Use not zero req count (and calculate max value) - ACHIEVEMENT_FLAG_AVERANGE = 0x00000040, // Show as averange value (value / time_in_days) depend from other flag (by def use last criteria value) + ACHIEVEMENT_FLAG_AVERAGE = 0x00000040, // Show as average value (value / time_in_days) depend from other flag (by def use last criteria value) ACHIEVEMENT_FLAG_BAR = 0x00000080, // Show as progress bar (value / max vale) depend from other flag (by def use last criteria value) ACHIEVEMENT_FLAG_REALM_FIRST_REACH = 0x00000100, // ACHIEVEMENT_FLAG_REALM_FIRST_KILL = 0x00000200, // diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index f208f5042..ce4528ec0 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -589,9 +589,9 @@ void Spell::EffectSchoolDMG(uint32 effect_idx) else if(m_spellInfo->SpellFamilyFlags&0x0004000000000000LL) { // Add main hand dps * effect[2] amount - float averange = (m_caster->GetFloatValue(UNIT_FIELD_MINDAMAGE) + m_caster->GetFloatValue(UNIT_FIELD_MAXDAMAGE)) / 2; + float average = (m_caster->GetFloatValue(UNIT_FIELD_MINDAMAGE) + m_caster->GetFloatValue(UNIT_FIELD_MAXDAMAGE)) / 2; int32 count = m_caster->CalculateSpellDamage(m_spellInfo, 2, m_spellInfo->EffectBasePoints[2], unitTarget); - damage += count * int32(averange * IN_MILISECONDS) / m_caster->GetAttackTime(BASE_ATTACK); + damage += count * int32(average * IN_MILISECONDS) / m_caster->GetAttackTime(BASE_ATTACK); } // Shield of Righteousness else if(m_spellInfo->SpellFamilyFlags&0x0010000000000000LL) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index fdff48589..45b5a3244 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 "7824" + #define REVISION_NR "7825" #endif // __REVISION_NR_H__ From 788cdf9b3a4c9218b3af0c1bc26c245283a9b1fb Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Thu, 14 May 2009 18:16:03 +0400 Subject: [PATCH 14/23] [7826] Avoid use GetDistance* that used slow sqrt call where possible, other related speedups. --- src/bindings/universal/ScriptMgr.h | 2 +- src/game/AggressorAI.cpp | 2 +- src/game/Creature.cpp | 4 +- src/game/CreatureEventAI.cpp | 13 ++--- src/game/GridNotifiers.cpp | 12 ++-- src/game/GridNotifiers.h | 2 +- src/game/Group.cpp | 14 ++--- src/game/GuardAI.cpp | 2 +- src/game/LootHandler.cpp | 2 +- src/game/MiscHandler.cpp | 4 +- src/game/Object.cpp | 83 +++++++++++++++++++++++----- src/game/Object.h | 21 +++++-- src/game/PetAI.cpp | 3 +- src/game/Player.cpp | 2 +- src/game/RandomMovementGenerator.cpp | 2 +- src/game/Spell.cpp | 19 +++---- src/game/Spell.h | 16 ++++-- src/game/TradeHandler.cpp | 28 +++++----- src/game/Unit.cpp | 14 ++--- src/game/Unit.h | 4 +- src/shared/revision_nr.h | 2 +- 21 files changed, 158 insertions(+), 93 deletions(-) diff --git a/src/bindings/universal/ScriptMgr.h b/src/bindings/universal/ScriptMgr.h index 5cfb164db..daf4b02a2 100644 --- a/src/bindings/universal/ScriptMgr.h +++ b/src/bindings/universal/ScriptMgr.h @@ -89,7 +89,7 @@ struct MANGOS_DLL_DECL ScriptedAI : public CreatureAI // Is unit visible for MoveInLineOfSight bool IsVisible(Unit* who) const { - return !who->HasStealthAura() && m_creature->GetDistance(who) <= VISIBLE_RANGE; + return !who->HasStealthAura() && m_creature->IsWithinDist(who,VISIBLE_RANGE); } // Called at World update tick diff --git a/src/game/AggressorAI.cpp b/src/game/AggressorAI.cpp index 50878ee59..c1a544d5d 100644 --- a/src/game/AggressorAI.cpp +++ b/src/game/AggressorAI.cpp @@ -140,7 +140,7 @@ AggressorAI::UpdateAI(const uint32 /*diff*/) bool AggressorAI::IsVisible(Unit *pl) const { - return m_creature->GetDistance(pl) < sWorld.getConfig(CONFIG_SIGHT_MONSTER) + return m_creature->IsWithinDist(pl,sWorld.getConfig(CONFIG_SIGHT_MONSTER)) && pl->isVisibleForOrDetect(m_creature,true); } diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 250af557c..5210ba9a5 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -1778,12 +1778,12 @@ bool Creature::IsOutOfThreatArea(Unit* pVictim) const if(sMapStore.LookupEntry(GetMapId())->IsDungeon()) return false; - float length = pVictim->GetDistance(CombatStartX,CombatStartY,CombatStartZ); float AttackDist = GetAttackDistance(pVictim); uint32 ThreatRadius = sWorld.getConfig(CONFIG_THREAT_RADIUS); //Use AttackDistance in distance check if threat radius is lower. This prevents creature bounce in and out of combat every update tick. - return ( length > (ThreatRadius > AttackDist ? ThreatRadius : AttackDist)); + return !pVictim->IsWithinDist(CombatStartX,CombatStartY,CombatStartZ, + ThreatRadius > AttackDist ? ThreatRadius : AttackDist); } CreatureDataAddon const* Creature::GetCreatureAddon() const diff --git a/src/game/CreatureEventAI.cpp b/src/game/CreatureEventAI.cpp index 49d5634d4..10addd297 100644 --- a/src/game/CreatureEventAI.cpp +++ b/src/game/CreatureEventAI.cpp @@ -1277,13 +1277,10 @@ void CreatureEventAI::UpdateAI(const uint32 diff) break; case EVENT_T_RANGE: if (Combat) - { - if (m_creature->IsWithinDistInMap(m_creature->getVictim(),(float)(*i).Event.event_param2)) - { - if (m_creature->GetDistance(m_creature->getVictim()) >= (float)(*i).Event.event_param1) + if (m_creature->IsInMap(m_creature->getVictim())) + if (m_creature->IsInRange(m_creature->getVictim(), + (float)(*i).Event.event_param1,(float)(*i).Event.event_param2)) ProcessEvent(*i); - } - } break; } } @@ -1305,7 +1302,7 @@ void CreatureEventAI::UpdateAI(const uint32 diff) bool CreatureEventAI::IsVisible(Unit *pl) const { - return m_creature->GetDistance(pl) < sWorld.getConfig(CONFIG_SIGHT_MONSTER) + return m_creature->IsWithinDist(pl,sWorld.getConfig(CONFIG_SIGHT_MONSTER)) && pl->isVisibleForOrDetect(m_creature,true); } @@ -1584,7 +1581,7 @@ bool CreatureEventAI::CanCast(Unit* Target, SpellEntry const *Spell, bool Trigge return false; //Unit is out of range of this spell - if (m_creature->GetDistance(Target) > TempRange->maxRange || m_creature->GetDistance(Target) < TempRange->minRange) + if (!m_creature->IsInRange(Target,TempRange->minRange,TempRange->minRange)) return false; return true; diff --git a/src/game/GridNotifiers.cpp b/src/game/GridNotifiers.cpp index b1acc2b61..1aefbcb4a 100644 --- a/src/game/GridNotifiers.cpp +++ b/src/game/GridNotifiers.cpp @@ -176,14 +176,14 @@ MessageDistDeliverer::Visit(PlayerMapType &m) { for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter) { - if( (i_toSelf || iter->getSource() != &i_player ) && + if ((i_toSelf || iter->getSource() != &i_player ) && (!i_ownTeamOnly || iter->getSource()->GetTeam() == i_player.GetTeam() ) && - (!i_dist || iter->getSource()->GetDistance(&i_player) <= i_dist) ) + (!i_dist || iter->getSource()->IsWithinDist(&i_player,i_dist))) { if (!i_player.InSamePhase(iter->getSource())) continue; - if(WorldSession* session = iter->getSource()->GetSession()) + if (WorldSession* session = iter->getSource()->GetSession()) session->SendPacket(i_message); } } @@ -194,12 +194,12 @@ ObjectMessageDistDeliverer::Visit(PlayerMapType &m) { for(PlayerMapType::iterator iter=m.begin(); iter != m.end(); ++iter) { - if( !i_dist || iter->getSource()->GetDistance(&i_object) <= i_dist ) + if (!i_dist || iter->getSource()->IsWithinDist(&i_object,i_dist)) { - if( !i_object.InSamePhase(iter->getSource())) + if (!i_object.InSamePhase(iter->getSource())) continue; - if(WorldSession* session = iter->getSource()->GetSession()) + if (WorldSession* session = iter->getSource()->GetSession()) session->SendPacket(i_message); } } diff --git a/src/game/GridNotifiers.h b/src/game/GridNotifiers.h index daf393eff..d8798d58b 100644 --- a/src/game/GridNotifiers.h +++ b/src/game/GridNotifiers.h @@ -494,7 +494,7 @@ namespace MaNGOS void Visit(PlayerMapType &m) { for(PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - if(itr->getSource()->InSamePhase(i_searcher) && itr->getSource()->GetDistance(i_searcher) <= i_dist) + if (itr->getSource()->InSamePhase(i_searcher) && itr->getSource()->IsWithinDist(i_searcher,i_dist)) i_do(itr->getSource()); } diff --git a/src/game/Group.cpp b/src/game/Group.cpp index b2b495cb8..484e5fde7 100644 --- a/src/game/Group.cpp +++ b/src/game/Group.cpp @@ -567,7 +567,7 @@ void Group::GroupLoot(const uint64& playerGUID, Loot *loot, Creature *creature) continue; if ( i->AllowedForPlayer(member) ) { - if (member->GetDistance2d(creature) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) + if (member->IsWithinDist(creature,sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE),false)) { r->playerVote[member->GetGUID()] = NOT_EMITED_YET; ++r->totalPlayersRolling; @@ -617,7 +617,7 @@ void Group::NeedBeforeGreed(const uint64& playerGUID, Loot *loot, Creature *crea if (playerToRoll->CanUseItem(item) && i->AllowedForPlayer(playerToRoll) ) { - if (playerToRoll->GetDistance2d(creature) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) + if (playerToRoll->IsWithinDist(creature,sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE),false)) { r->playerVote[playerToRoll->GetGUID()] = NOT_EMITED_YET; ++r->totalPlayersRolling; @@ -665,7 +665,7 @@ void Group::MasterLoot(const uint64& playerGUID, Loot* /*loot*/, Creature *creat if (!looter->IsInWorld()) continue; - if (looter->GetDistance2d(creature) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) + if (looter->IsWithinDist(creature,sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE),false)) { data << looter->GetGUID(); ++real_count; @@ -677,7 +677,7 @@ void Group::MasterLoot(const uint64& playerGUID, Loot* /*loot*/, Creature *creat for(GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next()) { Player *looter = itr->getSource(); - if (looter->GetDistance2d(creature) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) + if (looter->IsWithinDist(creature,sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE),false)) looter->GetSession()->SendPacket(&data); } } @@ -1334,7 +1334,7 @@ void Group::UpdateLooterGuid( Creature* creature, bool ifneed ) { // not update if only update if need and ok Player* looter = ObjectAccessor::FindPlayer(guid_itr->guid); - if(looter && looter->GetDistance2d(creature) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) + if(looter && looter->IsWithinDist(creature,sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE),false)) return; } ++guid_itr; @@ -1347,7 +1347,7 @@ void Group::UpdateLooterGuid( Creature* creature, bool ifneed ) { if(Player* pl = ObjectAccessor::FindPlayer(itr->guid)) { - if (pl->GetDistance2d(creature) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) + if (pl->IsWithinDist(creature,sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE),false)) { bool refresh = pl->GetLootGUID()==creature->GetGUID(); @@ -1368,7 +1368,7 @@ void Group::UpdateLooterGuid( Creature* creature, bool ifneed ) { if(Player* pl = ObjectAccessor::FindPlayer(itr->guid)) { - if (pl->GetDistance2d(creature) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) + if (pl->IsWithinDist(creature,sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE),false)) { bool refresh = pl->GetLootGUID()==creature->GetGUID(); diff --git a/src/game/GuardAI.cpp b/src/game/GuardAI.cpp index 8e0e5ba18..5dcbb5a23 100644 --- a/src/game/GuardAI.cpp +++ b/src/game/GuardAI.cpp @@ -125,7 +125,7 @@ void GuardAI::UpdateAI(const uint32 /*diff*/) bool GuardAI::IsVisible(Unit *pl) const { - return m_creature->GetDistance(pl) < sWorld.getConfig(CONFIG_SIGHT_GUARDER) + return m_creature->IsWithinDist(pl,sWorld.getConfig(CONFIG_SIGHT_GUARDER)) && pl->isVisibleForOrDetect(m_creature,true); } diff --git a/src/game/LootHandler.cpp b/src/game/LootHandler.cpp index 0dc2b5598..cfba29ad3 100644 --- a/src/game/LootHandler.cpp +++ b/src/game/LootHandler.cpp @@ -212,7 +212,7 @@ void WorldSession::HandleLootMoneyOpcode( WorldPacket & /*recv_data*/ ) Player* playerGroup = itr->getSource(); if(!playerGroup) continue; - if (player->GetDistance2d(playerGroup) < sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE)) + if (player->IsWithinDist(playerGroup,sWorld.getConfig(CONFIG_GROUP_XP_DISTANCE),false)) playersNear.push_back(playerGroup); } diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp index 6d2d15d91..2cc1dbde8 100644 --- a/src/game/MiscHandler.cpp +++ b/src/game/MiscHandler.cpp @@ -674,9 +674,7 @@ void WorldSession::HandleCorpseReclaimOpcode(WorldPacket &recv_data) if(corpse->GetGhostTime() + GetPlayer()->GetCorpseReclaimDelay(corpse->GetType()==CORPSE_RESURRECTABLE_PVP) > time(NULL)) return; - float dist = corpse->GetDistance2d(GetPlayer()); - sLog.outDebug("Corpse 2D Distance: \t%f",dist); - if (dist > CORPSE_RECLAIM_RADIUS) + if (!corpse->IsWithinDist(GetPlayer(),CORPSE_RECLAIM_RADIUS,false)) return; uint64 guid; diff --git a/src/game/Object.cpp b/src/game/Object.cpp index 15963e84f..10b2ed8a5 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -1087,7 +1087,7 @@ float WorldObject::GetDistance2d(float x, float y) const return ( dist > 0 ? dist : 0); } -float WorldObject::GetDistance(const float x, const float y, const float z) const +float WorldObject::GetDistance(float x, float y, float z) const { float dx = GetPositionX() - x; float dy = GetPositionY() - y; @@ -1114,10 +1114,24 @@ float WorldObject::GetDistanceZ(const WorldObject* obj) const return ( dist > 0 ? dist : 0); } -bool WorldObject::IsWithinDistInMap(const WorldObject* obj, const float dist2compare, const bool is3D) const +bool WorldObject::IsWithinDist(float x, float y, float z, float dist2compare, bool is3D) const { - if (!obj || !IsInMap(obj)) return false; + float dx = GetPositionX() - x; + float dy = GetPositionY() - y; + float distsq = dx*dx + dy*dy; + if(is3D) + { + float dz = GetPositionZ() - z; + distsq += dz*dz; + } + float sizefactor = GetObjectSize(); + float maxdist = dist2compare + sizefactor; + return distsq < maxdist * maxdist; +} + +bool WorldObject::_IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D) const +{ float dx = GetPositionX() - obj->GetPositionX(); float dy = GetPositionY() - obj->GetPositionY(); float distsq = dx*dx + dy*dy; @@ -1140,7 +1154,7 @@ bool WorldObject::IsWithinLOSInMap(const WorldObject* obj) const return(IsWithinLOS(ox, oy, oz )); } -bool WorldObject::IsWithinLOS(const float ox, const float oy, const float oz ) const +bool WorldObject::IsWithinLOS(float ox, float oy, float oz) const { float x,y,z; GetPosition(x,y,z); @@ -1148,6 +1162,54 @@ bool WorldObject::IsWithinLOS(const float ox, const float oy, const float oz ) c return vMapManager->isInLineOfSight(GetMapId(), x, y, z+2.0f, ox, oy, oz+2.0f); } +bool WorldObject::GetDistanceOrder(WorldObject const* obj1, WorldObject const* obj2) const +{ + float dx1 = GetPositionX() - obj1->GetPositionX(); + float dy1 = GetPositionY() - obj1->GetPositionY(); + float dz1 = GetPositionZ() - obj1->GetPositionZ(); + float distsq1 = dx1*dx1 + dy1*dy1 + dz1*dz1; + + float dx2 = GetPositionX() - obj2->GetPositionX(); + float dy2 = GetPositionY() - obj2->GetPositionY(); + float dz2 = GetPositionZ() - obj2->GetPositionZ(); + float distsq2 = dx2*dx2 + dy2*dy2 + dz2*dz2; + + return distsq1 < distsq2; +} + +bool WorldObject::IsInRange(WorldObject const* obj, float minRange, float maxRange) const +{ + float dx = GetPositionX() - obj->GetPositionX(); + float dy = GetPositionY() - obj->GetPositionY(); + float dz = GetPositionZ() - obj->GetPositionZ(); + float distsq = dx*dx + dy*dy + dz*dz; + + float sizefactor = GetObjectSize() + obj->GetObjectSize(); + + float mindist = minRange + sizefactor; + if(distsq < mindist * mindist) + return false; + + float maxdist = maxRange + sizefactor; + return distsq < maxdist * maxdist; +} + +bool WorldObject::IsInRange2d(float x, float y, float minRange, float maxRange) const +{ + float dx = GetPositionX() - x; + float dy = GetPositionY() - y; + float distsq = dx*dx + dy*dy; + + float sizefactor = GetObjectSize(); + + float mindist = minRange + sizefactor; + if(distsq < mindist * mindist) + return false; + + float maxdist = maxRange + sizefactor; + return distsq < maxdist * maxdist; +} + float WorldObject::GetAngle(const WorldObject* obj) const { if(!obj) return 0; @@ -1543,15 +1605,8 @@ namespace MaNGOS // we must add used pos that can fill places around center void add(WorldObject* u, float x, float y) const { - // dist include size of u - float dist2d = i_object.GetDistance2d(x,y); - - // u is too nearest to i_object - if(dist2d + i_object.GetObjectSize() + u->GetObjectSize() < i_selector.m_dist - i_selector.m_size) - return; - - // u is too far away from i_object - if(dist2d + i_object.GetObjectSize() - u->GetObjectSize() > i_selector.m_dist + i_selector.m_size) + // u is too nearest/far away to i_object + if(!i_object.IsInRange2d(x,y,i_selector.m_dist - i_selector.m_size,i_selector.m_dist + i_selector.m_size)) return; float angle = i_object.GetAngle(u)-i_angle; @@ -1562,6 +1617,8 @@ namespace MaNGOS while(angle < -M_PI) angle += 2.0f * M_PI; + // dist include size of u + float dist2d = i_object.GetDistance2d(x,y); i_selector.AddUsedPos(u->GetObjectSize(),angle,dist2d + i_object.GetObjectSize()); } private: diff --git a/src/game/Object.h b/src/game/Object.h index fc01e3a42..42ffdee2d 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -424,18 +424,31 @@ class MANGOS_DLL_SPEC WorldObject : public Object virtual const char* GetNameForLocaleIdx(int32 /*locale_idx*/) const { return GetName(); } float GetDistance( const WorldObject* obj ) const; - float GetDistance(const float x, const float y, const float z) const; + float GetDistance(float x, float y, float z) const; float GetDistance2d(const WorldObject* obj) const; - float GetDistance2d(const float x, const float y) const; + float GetDistance2d(float x, float y) const; float GetDistanceZ(const WorldObject* obj) const; bool IsInMap(const WorldObject* obj) const { return IsInWorld() && obj->IsInWorld() && GetMapId()==obj->GetMapId() && GetInstanceId()==obj->GetInstanceId() && InSamePhase(obj); } - bool IsWithinDistInMap(const WorldObject* obj, const float dist2compare, const bool is3D = true) const; - bool IsWithinLOS(const float x, const float y, const float z ) const; + bool IsWithinDist(float x, float y, float z, float dist2compare, bool is3D = true) const; + bool _IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D) const; + bool IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D = true) const + // use only if you will sure about placing both object at same map + { + return obj && _IsWithinDist(obj,dist2compare,is3D); + } + bool IsWithinDistInMap(WorldObject const* obj, float dist2compare, bool is3D = true) const + { + return obj && IsInMap(obj) && _IsWithinDist(obj,dist2compare,is3D); + } + bool IsWithinLOS(float x, float y, float z) const; bool IsWithinLOSInMap(const WorldObject* obj) const; + bool GetDistanceOrder(WorldObject const* obj1, WorldObject const* obj2) const; + bool IsInRange(WorldObject const* obj, float minRange, float maxRange) const; + bool IsInRange2d(float x, float y, float minRange, float maxRange) const; float GetAngle( const WorldObject* obj ) const; float GetAngle( const float x, const float y ) const; diff --git a/src/game/PetAI.cpp b/src/game/PetAI.cpp index 3fc412c6f..8de2644f3 100644 --- a/src/game/PetAI.cpp +++ b/src/game/PetAI.cpp @@ -288,8 +288,7 @@ void PetAI::UpdateAI(const uint32 diff) bool PetAI::_isVisible(Unit *u) const { - //return false; //( ((Creature*)&i_pet)->GetDistanceSq(u) * 1.0<= sWorld.getConfig(CONFIG_SIGHT_GUARDER) && !u->m_stealth && u->isAlive()); - return m_creature->GetDistance(u) < sWorld.getConfig(CONFIG_SIGHT_GUARDER) + return m_creature->IsWithinDist(u,sWorld.getConfig(CONFIG_SIGHT_GUARDER)) && u->isVisibleForOrDetect(m_creature,true); } diff --git a/src/game/Player.cpp b/src/game/Player.cpp index fd19a2412..35b2cb0e5 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -1616,7 +1616,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati if (!(options & TELE_TO_NOT_UNSUMMON_PET)) { //same map, only remove pet if out of range for new position - if(pet && pet->GetDistance(x,y,z) >= OWNER_MAX_DISTANCE) + if(pet && !pet->IsWithinDist(x,y,z, OWNER_MAX_DISTANCE)) UnsummonPetTemporaryIfAny(); } diff --git a/src/game/RandomMovementGenerator.cpp b/src/game/RandomMovementGenerator.cpp index d1d77eea2..de9d76fe8 100644 --- a/src/game/RandomMovementGenerator.cpp +++ b/src/game/RandomMovementGenerator.cpp @@ -153,7 +153,7 @@ RandomMovementGenerator::Update(Creature &creature, const uint32 &diff creature.SetUnitMovementFlags(irand(0,RUNNING_CHANCE_RANDOMMV) > 0 ? MOVEMENTFLAG_WALK_MODE : MOVEMENTFLAG_NONE); _setRandomLocation(creature); } - else if(creature.isPet() && creature.GetOwner() && creature.GetDistance(creature.GetOwner()) > PET_FOLLOW_DIST+2.5f) + else if(creature.isPet() && creature.GetOwner() && !creature.IsWithinDist(creature.GetOwner(),PET_FOLLOW_DIST+2.5f)) { creature.SetUnitMovementFlags(MOVEMENTFLAG_NONE); _setRandomLocation(creature); diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 02ec11a91..82147467c 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -1334,7 +1334,7 @@ struct TargetDistanceOrder : public std::binary_function" bool operator()(const Unit* _Left, const Unit* _Right) const { - return (MainTarget->GetDistance(_Left) < MainTarget->GetDistance(_Right)); + return MainTarget->GetDistanceOrder(_Left,_Right); } }; @@ -1427,7 +1427,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap) //Now to get us a random target that's in the initial range of the spell uint32 t = 0; std::list::iterator itr = tempUnitMap.begin(); - while(itr!= tempUnitMap.end() && (*itr)->GetDistance(m_caster) < radius) + while(itr!= tempUnitMap.end() && (*itr)->IsWithinDist(m_caster,radius)) ++t, ++itr; if(!t) @@ -1448,7 +1448,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap) while(t && next != tempUnitMap.end() ) { - if(prev->GetDistance(*next) > CHAIN_SPELL_JUMP_RADIUS) + if(!prev->IsWithinDist(*next,CHAIN_SPELL_JUMP_RADIUS)) break; if(!prev->IsWithinLOSInMap(*next)) @@ -1496,7 +1496,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap) //Now to get us a random target that's in the initial range of the spell uint32 t = 0; std::list::iterator itr = tempUnitMap.begin(); - while(itr!= tempUnitMap.end() && (*itr)->GetDistance(m_caster) < radius) + while(itr!= tempUnitMap.end() && (*itr)->IsWithinDist(m_caster,radius)) ++t, ++itr; if(!t) @@ -1517,7 +1517,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap) while(t && next != tempUnitMap.end() ) { - if(prev->GetDistance(*next) > CHAIN_SPELL_JUMP_RADIUS) + if(!prev->IsWithinDist(*next,CHAIN_SPELL_JUMP_RADIUS)) break; if(!prev->IsWithinLOSInMap(*next)) @@ -1602,7 +1602,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap) while(t && next != tempUnitMap.end() ) { - if(prev->GetDistance(*next) > CHAIN_SPELL_JUMP_RADIUS) + if(!prev->IsWithinDist(*next,CHAIN_SPELL_JUMP_RADIUS)) break; if(!prev->IsWithinLOSInMap(*next)) @@ -2029,7 +2029,7 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,UnitList& TagUnitMap) while(t && next != tempUnitMap.end() ) { - if(prev->GetDistance(*next) > CHAIN_SPELL_JUMP_RADIUS) + if(!prev->IsWithinDist(*next,CHAIN_SPELL_JUMP_RADIUS)) break; if(!prev->IsWithinLOSInMap(*next)) @@ -4689,10 +4689,9 @@ SpellCastResult Spell::CheckRange(bool strict) if(m_targets.m_targetMask == TARGET_FLAG_DEST_LOCATION && m_targets.m_destX != 0 && m_targets.m_destY != 0 && m_targets.m_destZ != 0) { - float dist = m_caster->GetDistance(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ); - if(dist > max_range) + if(!m_caster->IsWithinDist(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ,max_range)) return SPELL_FAILED_OUT_OF_RANGE; - if(dist < min_range) + if(m_caster->IsWithinDist(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ,min_range)) return SPELL_FAILED_TOO_CLOSE; } diff --git a/src/game/Spell.h b/src/game/Spell.h index ac2544b59..402c3c2ff 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -621,7 +621,7 @@ namespace MaNGOS if( i_originalCaster->IsFriendlyTo(pPlayer) ) continue; - if( pPlayer->GetDistance(i_spell.m_targets.m_destX, i_spell.m_targets.m_destY, i_spell.m_targets.m_destZ) < i_radius ) + if( pPlayer->IsWithinDist(i_spell.m_targets.m_destX, i_spell.m_targets.m_destY, i_spell.m_targets.m_destZ,i_radius)) i_data.push_back(pPlayer); } } @@ -656,6 +656,10 @@ namespace MaNGOS if( !itr->getSource()->isAlive() || (itr->getSource()->GetTypeId() == TYPEID_PLAYER && ((Player*)itr->getSource())->isInFlight())) continue; + // mostly phase check + if(!itr->getSource()->IsInMap(i_originalCaster)) + continue; + switch (i_TargetType) { case SPELL_TARGETS_HOSTILE: @@ -701,23 +705,23 @@ namespace MaNGOS switch(i_push_type) { case PUSH_IN_FRONT: - if(i_spell.GetCaster()->isInFront((Unit*)(itr->getSource()), i_radius, 2*M_PI/3 )) + if(i_spell.GetCaster()->isInFrontInMap((Unit*)(itr->getSource()), i_radius, 2*M_PI/3 )) i_data->push_back(itr->getSource()); break; case PUSH_IN_BACK: - if(i_spell.GetCaster()->isInBack((Unit*)(itr->getSource()), i_radius, 2*M_PI/3 )) + if(i_spell.GetCaster()->isInBackInMap((Unit*)(itr->getSource()), i_radius, 2*M_PI/3 )) i_data->push_back(itr->getSource()); break; case PUSH_SELF_CENTER: - if(i_spell.GetCaster()->IsWithinDistInMap((Unit*)(itr->getSource()), i_radius)) + if(i_spell.GetCaster()->IsWithinDist((Unit*)(itr->getSource()), i_radius)) i_data->push_back(itr->getSource()); break; case PUSH_DEST_CENTER: - if((itr->getSource()->GetDistance(i_spell.m_targets.m_destX, i_spell.m_targets.m_destY, i_spell.m_targets.m_destZ) < i_radius )) + if(itr->getSource()->IsWithinDist(i_spell.m_targets.m_destX, i_spell.m_targets.m_destY, i_spell.m_targets.m_destZ,i_radius)) i_data->push_back(itr->getSource()); break; case PUSH_TARGET_CENTER: - if(i_spell.m_targets.getUnitTarget()->IsWithinDistInMap((Unit*)(itr->getSource()), i_radius)) + if(i_spell.m_targets.getUnitTarget()->IsWithinDist((Unit*)(itr->getSource()), i_radius)) i_data->push_back(itr->getSource()); break; } diff --git a/src/game/TradeHandler.cpp b/src/game/TradeHandler.cpp index aa323c974..64408c6b5 100644 --- a/src/game/TradeHandler.cpp +++ b/src/game/TradeHandler.cpp @@ -459,30 +459,30 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket) { CHECK_PACKET_SIZE(recvPacket,8); - if( GetPlayer()->pTrader ) + if (GetPlayer()->pTrader) return; uint64 ID; - if( !GetPlayer()->isAlive() ) + if (!GetPlayer()->isAlive()) { SendTradeStatus(TRADE_STATUS_YOU_DEAD); return; } - if( GetPlayer()->hasUnitState(UNIT_STAT_STUNNED) ) + if (GetPlayer()->hasUnitState(UNIT_STAT_STUNNED)) { SendTradeStatus(TRADE_STATUS_YOU_STUNNED); return; } - if( isLogingOut() ) + if (isLogingOut()) { SendTradeStatus(TRADE_STATUS_YOU_LOGOUT); return; } - if( GetPlayer()->isInFlight() ) + if (GetPlayer()->isInFlight()) { SendTradeStatus(TRADE_STATUS_TARGET_TO_FAR); return; @@ -492,55 +492,55 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket) Player* pOther = ObjectAccessor::FindPlayer( ID ); - if( !pOther ) + if (!pOther) { SendTradeStatus(TRADE_STATUS_NO_TARGET); return; } - if( pOther == GetPlayer() || pOther->pTrader ) + if (pOther == GetPlayer() || pOther->pTrader) { SendTradeStatus(TRADE_STATUS_BUSY); return; } - if( !pOther->isAlive() ) + if (!pOther->isAlive()) { SendTradeStatus(TRADE_STATUS_TARGET_DEAD); return; } - if( pOther->isInFlight() ) + if (pOther->isInFlight()) { SendTradeStatus(TRADE_STATUS_TARGET_TO_FAR); return; } - if( pOther->hasUnitState(UNIT_STAT_STUNNED) ) + if (pOther->hasUnitState(UNIT_STAT_STUNNED)) { SendTradeStatus(TRADE_STATUS_TARGET_STUNNED); return; } - if( pOther->GetSession()->isLogingOut() ) + if (pOther->GetSession()->isLogingOut()) { SendTradeStatus(TRADE_STATUS_TARGET_LOGOUT); return; } - if( pOther->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow()) ) + if (pOther->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) { SendTradeStatus(TRADE_STATUS_IGNORE_YOU); return; } - if(pOther->GetTeam() !=_player->GetTeam() ) + if (pOther->GetTeam() !=_player->GetTeam() ) { SendTradeStatus(TRADE_STATUS_WRONG_FACTION); return; } - if( pOther->GetDistance2d( _player ) > 10.0f ) + if (!pOther->IsWithinDistInMap(_player,10.0f,false)) { SendTradeStatus(TRADE_STATUS_TARGET_TO_FAR); return; diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 5ea368169..474b6009e 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -3200,7 +3200,7 @@ Spell* Unit::FindCurrentSpellBySpellId(uint32 spell_id) const return NULL; } -bool Unit::isInFront(Unit const* target, float distance, float arc) const +bool Unit::isInFrontInMap(Unit const* target, float distance, float arc) const { return IsWithinDistInMap(target, distance) && HasInArc( arc, target ); } @@ -3210,7 +3210,7 @@ void Unit::SetInFront(Unit const* target) SetOrientation(GetAngle(target)); } -bool Unit::isInBack(Unit const* target, float distance, float arc) const +bool Unit::isInBackInMap(Unit const* target, float distance, float arc) const { return IsWithinDistInMap(target, distance) && !HasInArc( 2 * M_PI - arc, target ); } @@ -9070,9 +9070,7 @@ bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList, return true; // If there is collision rogue is seen regardless of level difference - // TODO: check sizes in DB - float distance = GetDistance(u); - if (distance < 0.24f) + if (IsWithinDist(u,0.24f)) return true; //If a mob or player is stunned he will not be able to detect stealth @@ -9083,14 +9081,14 @@ bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList, if(u->GetTypeId() != TYPEID_PLAYER) { //Always invisible from back and out of aggro range - bool isInFront = u->isInFront(this,((Creature const*)u)->GetAttackDistance(this)); + bool isInFront = u->isInFrontInMap(this,((Creature const*)u)->GetAttackDistance(this)); if(!isInFront) return false; } else { //Always invisible from back - bool isInFront = u->isInFront(this,(GetTypeId()==TYPEID_PLAYER || GetCharmerOrOwnerGUID()) ? World::GetMaxVisibleDistanceForPlayer() : World::GetMaxVisibleDistanceForCreature()); + bool isInFront = u->isInFrontInMap(this,(GetTypeId()==TYPEID_PLAYER || GetCharmerOrOwnerGUID()) ? World::GetMaxVisibleDistanceForPlayer() : World::GetMaxVisibleDistanceForCreature()); if(!isInFront) return false; } @@ -9116,7 +9114,7 @@ bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList, //based on wowwiki every 5 mod we have 1 more level diff in calculation visibleDistance += (int32(u->GetTotalAuraModifier(SPELL_AURA_MOD_DETECT)) - stealthMod)/5.0f; - if(distance > visibleDistance) + if(!IsWithinDist(u,visibleDistance)) return false; } diff --git a/src/game/Unit.h b/src/game/Unit.h index 9ea6ca3e6..35ceb2fed 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1240,9 +1240,9 @@ class MANGOS_DLL_SPEC Unit : public WorldObject float GetWeaponDamageRange(WeaponAttackType attType ,WeaponDamageRange type) const; void SetBaseWeaponDamage(WeaponAttackType attType ,WeaponDamageRange damageRange, float value) { m_weaponDamage[attType][damageRange] = value; } - bool isInFront(Unit const* target,float distance, float arc = M_PI) const; + bool isInFrontInMap(Unit const* target,float distance, float arc = M_PI) const; void SetInFront(Unit const* target); - bool isInBack(Unit const* target, float distance, float arc = M_PI) const; + bool isInBackInMap(Unit const* target, float distance, float arc = M_PI) const; // Visibility system UnitVisibility GetVisibility() const { return m_Visibility; } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 45b5a3244..e6f9a434b 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 "7825" + #define REVISION_NR "7826" #endif // __REVISION_NR_H__ From 592db69c0ccd38c1c339c9ce2390743a0dbeb08d Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Thu, 14 May 2009 20:09:30 +0400 Subject: [PATCH 15/23] [7827] dd support 2d version for WorldObject::GetDistanceOrder. --- src/game/Object.cpp | 18 +++++++++++++----- src/game/Object.h | 2 +- src/shared/revision_nr.h | 2 +- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/game/Object.cpp b/src/game/Object.cpp index 10b2ed8a5..1478ff971 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -1162,17 +1162,25 @@ bool WorldObject::IsWithinLOS(float ox, float oy, float oz) const return vMapManager->isInLineOfSight(GetMapId(), x, y, z+2.0f, ox, oy, oz+2.0f); } -bool WorldObject::GetDistanceOrder(WorldObject const* obj1, WorldObject const* obj2) const +bool WorldObject::GetDistanceOrder(WorldObject const* obj1, WorldObject const* obj2, bool is3D /* = true */) const { float dx1 = GetPositionX() - obj1->GetPositionX(); float dy1 = GetPositionY() - obj1->GetPositionY(); - float dz1 = GetPositionZ() - obj1->GetPositionZ(); - float distsq1 = dx1*dx1 + dy1*dy1 + dz1*dz1; + float distsq1 = dx1*dx1 + dy1*dy1; + if(is3D) + { + float dz1 = GetPositionZ() - obj1->GetPositionZ(); + distsq1 += dz1*dz1; + } float dx2 = GetPositionX() - obj2->GetPositionX(); float dy2 = GetPositionY() - obj2->GetPositionY(); - float dz2 = GetPositionZ() - obj2->GetPositionZ(); - float distsq2 = dx2*dx2 + dy2*dy2 + dz2*dz2; + float distsq2 = dx2*dx2 + dy2*dy2; + if(is3D) + { + float dz2 = GetPositionZ() - obj2->GetPositionZ(); + distsq2 += dz2*dz2; + } return distsq1 < distsq2; } diff --git a/src/game/Object.h b/src/game/Object.h index 42ffdee2d..e9953d797 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -446,7 +446,7 @@ class MANGOS_DLL_SPEC WorldObject : public Object } bool IsWithinLOS(float x, float y, float z) const; bool IsWithinLOSInMap(const WorldObject* obj) const; - bool GetDistanceOrder(WorldObject const* obj1, WorldObject const* obj2) const; + bool GetDistanceOrder(WorldObject const* obj1, WorldObject const* obj2, bool is3D = true) const; bool IsInRange(WorldObject const* obj, float minRange, float maxRange) const; bool IsInRange2d(float x, float y, float minRange, float maxRange) const; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index e6f9a434b..c2ab7f32e 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 "7826" + #define REVISION_NR "7827" #endif // __REVISION_NR_H__ From 42d74d811fc0da437ec7324ef79327194f5013d9 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Thu, 14 May 2009 20:37:02 +0400 Subject: [PATCH 16/23] [7828] Add 2d/3d versions for WorldObject::IsInRange(x,y,... and WorldObject::IsWithinDist(x,y,... --- src/game/Object.cpp | 48 ++++++++++++++++++++++++++++++++-------- src/game/Object.h | 6 +++-- src/shared/revision_nr.h | 2 +- 3 files changed, 44 insertions(+), 12 deletions(-) diff --git a/src/game/Object.cpp b/src/game/Object.cpp index 1478ff971..20601091f 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -1114,16 +1114,25 @@ float WorldObject::GetDistanceZ(const WorldObject* obj) const return ( dist > 0 ? dist : 0); } -bool WorldObject::IsWithinDist(float x, float y, float z, float dist2compare, bool is3D) const +bool WorldObject::IsWithinDist(float x, float y, float z, float dist2compare) const +{ + float dx = GetPositionX() - x; + float dy = GetPositionY() - y; + float dz = GetPositionZ() - z; + float distsq = dx*dx + dy*dy + dz*dz; + + float sizefactor = GetObjectSize(); + float maxdist = dist2compare + sizefactor; + + return distsq < maxdist * maxdist; +} + +bool WorldObject::IsWithinDist2d(float x, float y, float dist2compare) const { float dx = GetPositionX() - x; float dy = GetPositionY() - y; float distsq = dx*dx + dy*dy; - if(is3D) - { - float dz = GetPositionZ() - z; - distsq += dz*dz; - } + float sizefactor = GetObjectSize(); float maxdist = dist2compare + sizefactor; @@ -1185,12 +1194,16 @@ bool WorldObject::GetDistanceOrder(WorldObject const* obj1, WorldObject const* o return distsq1 < distsq2; } -bool WorldObject::IsInRange(WorldObject const* obj, float minRange, float maxRange) const +bool WorldObject::IsInRange(WorldObject const* obj, float minRange, float maxRange, bool is3D /* = true */) const { float dx = GetPositionX() - obj->GetPositionX(); float dy = GetPositionY() - obj->GetPositionY(); - float dz = GetPositionZ() - obj->GetPositionZ(); - float distsq = dx*dx + dy*dy + dz*dz; + float distsq = dx*dx + dy*dy; + if(is3D) + { + float dz = GetPositionZ() - obj->GetPositionZ(); + distsq += dz*dz; + } float sizefactor = GetObjectSize() + obj->GetObjectSize(); @@ -1218,6 +1231,23 @@ bool WorldObject::IsInRange2d(float x, float y, float minRange, float maxRange) return distsq < maxdist * maxdist; } +bool WorldObject::IsInRange(float x, float y, float z, float minRange, float maxRange) const +{ + float dx = GetPositionX() - x; + float dy = GetPositionY() - y; + float dz = GetPositionZ() - z; + float distsq = dx*dx + dy*dy + dz*dz; + + float sizefactor = GetObjectSize(); + + float mindist = minRange + sizefactor; + if(distsq < mindist * mindist) + return false; + + float maxdist = maxRange + sizefactor; + return distsq < maxdist * maxdist; +} + float WorldObject::GetAngle(const WorldObject* obj) const { if(!obj) return 0; diff --git a/src/game/Object.h b/src/game/Object.h index e9953d797..f77ceeead 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -433,7 +433,8 @@ class MANGOS_DLL_SPEC WorldObject : public Object return IsInWorld() && obj->IsInWorld() && GetMapId()==obj->GetMapId() && GetInstanceId()==obj->GetInstanceId() && InSamePhase(obj); } - bool IsWithinDist(float x, float y, float z, float dist2compare, bool is3D = true) const; + bool IsWithinDist(float x, float y, float z, float dist2compare) const; + bool IsWithinDist2d(float x, float y, float dist2compare) const; bool _IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D) const; bool IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D = true) const // use only if you will sure about placing both object at same map @@ -447,8 +448,9 @@ class MANGOS_DLL_SPEC WorldObject : public Object bool IsWithinLOS(float x, float y, float z) const; bool IsWithinLOSInMap(const WorldObject* obj) const; bool GetDistanceOrder(WorldObject const* obj1, WorldObject const* obj2, bool is3D = true) const; - bool IsInRange(WorldObject const* obj, float minRange, float maxRange) const; + bool IsInRange(WorldObject const* obj, float minRange, float maxRange, bool is3D = true) const; bool IsInRange2d(float x, float y, float minRange, float maxRange) const; + bool IsInRange(float x, float y, float z, float minRange, float maxRange) const; float GetAngle( const WorldObject* obj ) const; float GetAngle( const float x, const float y ) const; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index c2ab7f32e..709a95ae9 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 "7827" + #define REVISION_NR "7828" #endif // __REVISION_NR_H__ From 8858aacfb02a4486865efc284f92f577071c34c5 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Thu, 14 May 2009 21:40:39 +0400 Subject: [PATCH 17/23] [7829] Rename 3d (x,y,.. versions of IsWithinDist/IsWithinDist functions with adding 3d explict posfix to name for avoid wrong use. --- src/game/Creature.cpp | 2 +- src/game/Object.cpp | 4 ++-- src/game/Object.h | 4 ++-- src/game/Pet.h | 2 +- src/game/Player.cpp | 2 +- src/game/Spell.cpp | 4 ++-- src/game/Spell.h | 4 ++-- src/shared/revision_nr.h | 2 +- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 5210ba9a5..0680a14e8 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -1782,7 +1782,7 @@ bool Creature::IsOutOfThreatArea(Unit* pVictim) const uint32 ThreatRadius = sWorld.getConfig(CONFIG_THREAT_RADIUS); //Use AttackDistance in distance check if threat radius is lower. This prevents creature bounce in and out of combat every update tick. - return !pVictim->IsWithinDist(CombatStartX,CombatStartY,CombatStartZ, + return !pVictim->IsWithinDist3d(CombatStartX,CombatStartY,CombatStartZ, ThreatRadius > AttackDist ? ThreatRadius : AttackDist); } diff --git a/src/game/Object.cpp b/src/game/Object.cpp index 20601091f..81ff11d97 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -1114,7 +1114,7 @@ float WorldObject::GetDistanceZ(const WorldObject* obj) const return ( dist > 0 ? dist : 0); } -bool WorldObject::IsWithinDist(float x, float y, float z, float dist2compare) const +bool WorldObject::IsWithinDist3d(float x, float y, float z, float dist2compare) const { float dx = GetPositionX() - x; float dy = GetPositionY() - y; @@ -1231,7 +1231,7 @@ bool WorldObject::IsInRange2d(float x, float y, float minRange, float maxRange) return distsq < maxdist * maxdist; } -bool WorldObject::IsInRange(float x, float y, float z, float minRange, float maxRange) const +bool WorldObject::IsInRange3d(float x, float y, float z, float minRange, float maxRange) const { float dx = GetPositionX() - x; float dy = GetPositionY() - y; diff --git a/src/game/Object.h b/src/game/Object.h index f77ceeead..b42acbd04 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -433,7 +433,7 @@ class MANGOS_DLL_SPEC WorldObject : public Object return IsInWorld() && obj->IsInWorld() && GetMapId()==obj->GetMapId() && GetInstanceId()==obj->GetInstanceId() && InSamePhase(obj); } - bool IsWithinDist(float x, float y, float z, float dist2compare) const; + bool IsWithinDist3d(float x, float y, float z, float dist2compare) const; bool IsWithinDist2d(float x, float y, float dist2compare) const; bool _IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D) const; bool IsWithinDist(WorldObject const* obj, float dist2compare, bool is3D = true) const @@ -450,7 +450,7 @@ class MANGOS_DLL_SPEC WorldObject : public Object bool GetDistanceOrder(WorldObject const* obj1, WorldObject const* obj2, bool is3D = true) const; bool IsInRange(WorldObject const* obj, float minRange, float maxRange, bool is3D = true) const; bool IsInRange2d(float x, float y, float minRange, float maxRange) const; - bool IsInRange(float x, float y, float z, float minRange, float maxRange) const; + bool IsInRange3d(float x, float y, float z, float minRange, float maxRange) const; float GetAngle( const WorldObject* obj ) const; float GetAngle( const float x, const float y ) const; diff --git a/src/game/Pet.h b/src/game/Pet.h index e88576438..08c72e31c 100644 --- a/src/game/Pet.h +++ b/src/game/Pet.h @@ -114,7 +114,7 @@ typedef std::vector AutoSpellList; #define ACTIVE_SPELLS_MAX 4 -#define OWNER_MAX_DISTANCE 100 +#define OWNER_MAX_DISTANCE 100.0f #define PET_FOLLOW_DIST 1 #define PET_FOLLOW_ANGLE (M_PI/2) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 35b2cb0e5..131b0310a 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -1616,7 +1616,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati if (!(options & TELE_TO_NOT_UNSUMMON_PET)) { //same map, only remove pet if out of range for new position - if(pet && !pet->IsWithinDist(x,y,z, OWNER_MAX_DISTANCE)) + if(pet && !pet->IsWithinDist3d(x,y,z, OWNER_MAX_DISTANCE)) UnsummonPetTemporaryIfAny(); } diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 82147467c..3c874ee56 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -4689,9 +4689,9 @@ SpellCastResult Spell::CheckRange(bool strict) if(m_targets.m_targetMask == TARGET_FLAG_DEST_LOCATION && m_targets.m_destX != 0 && m_targets.m_destY != 0 && m_targets.m_destZ != 0) { - if(!m_caster->IsWithinDist(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ,max_range)) + if(!m_caster->IsWithinDist3d(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ,max_range)) return SPELL_FAILED_OUT_OF_RANGE; - if(m_caster->IsWithinDist(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ,min_range)) + if(m_caster->IsWithinDist3d(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ,min_range)) return SPELL_FAILED_TOO_CLOSE; } diff --git a/src/game/Spell.h b/src/game/Spell.h index 402c3c2ff..3ffa368eb 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -621,7 +621,7 @@ namespace MaNGOS if( i_originalCaster->IsFriendlyTo(pPlayer) ) continue; - if( pPlayer->IsWithinDist(i_spell.m_targets.m_destX, i_spell.m_targets.m_destY, i_spell.m_targets.m_destZ,i_radius)) + if( pPlayer->IsWithinDist3d(i_spell.m_targets.m_destX, i_spell.m_targets.m_destY, i_spell.m_targets.m_destZ,i_radius)) i_data.push_back(pPlayer); } } @@ -717,7 +717,7 @@ namespace MaNGOS i_data->push_back(itr->getSource()); break; case PUSH_DEST_CENTER: - if(itr->getSource()->IsWithinDist(i_spell.m_targets.m_destX, i_spell.m_targets.m_destY, i_spell.m_targets.m_destZ,i_radius)) + if(itr->getSource()->IsWithinDist3d(i_spell.m_targets.m_destX, i_spell.m_targets.m_destY, i_spell.m_targets.m_destZ,i_radius)) i_data->push_back(itr->getSource()); break; case PUSH_TARGET_CENTER: diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 709a95ae9..e701b8f17 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 "7828" + #define REVISION_NR "7829" #endif // __REVISION_NR_H__ From ac67ac8c285acdb9c130629367d794b145e9c87f Mon Sep 17 00:00:00 2001 From: byeolpyo Date: Thu, 14 May 2009 23:39:41 +0400 Subject: [PATCH 18/23] [7830] Spell chain data for 54424 and ranks. Signed-off-by: VladimirMangos --- sql/mangos.sql | 14 ++++++++++---- sql/updates/7830_01_mangos_spell_chain.sql | 10 ++++++++++ sql/updates/Makefile.am | 2 ++ src/shared/revision_nr.h | 2 +- 4 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 sql/updates/7830_01_mangos_spell_chain.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index 3b26ee8bc..6451c9815 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -23,7 +23,7 @@ DROP TABLE IF EXISTS `db_version`; CREATE TABLE `db_version` ( `version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL, - `required_7823_01_mangos_item_template` bit(1) default NULL + `required_7830_01_mangos_spell_chain` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -14497,7 +14497,7 @@ INSERT INTO spell_chain VALUES /*------------------ --(189)Pet-Felhunter ------------------*/ -/*DevourMagic*/ +/*Devour Magic*/ (19505,0,19505,1,0), (19731,19505,19505,2,0), (19734,19731,19505,3,0), @@ -14505,13 +14505,19 @@ INSERT INTO spell_chain VALUES (27276,19736,19505,5,0), (27277,27276,19505,6,0), (48011,27277,19505,7,0), -/*ShadowBite*/ +/*Fel Intelligence*/ +(54424,0,54424,1,0), +(57564,54424,54424,2,0), +(57565,57564,54424,3,0), +(57566,57565,54424,4,0), +(57567,57566,54424,5,0), +/*Shadow Bite*/ (54049,0,54049,1,0), (54050,54049,54049,2,0), (54051,54050,54049,3,0), (54052,54051,54049,4,0), (54053,54052,54049,5,0), -/*SpellLock*/ +/*Spell Lock*/ (19244,0,19244,1,0), (19647,19244,19244,2,0), /*------------------ diff --git a/sql/updates/7830_01_mangos_spell_chain.sql b/sql/updates/7830_01_mangos_spell_chain.sql new file mode 100644 index 000000000..32815cbb5 --- /dev/null +++ b/sql/updates/7830_01_mangos_spell_chain.sql @@ -0,0 +1,10 @@ +ALTER TABLE db_version CHANGE COLUMN required_7823_01_mangos_item_template required_7830_01_mangos_spell_chain bit; + +DELETE FROM spell_chain WHERE spell_id in (54424,57564,57565,57566,57567); + +INSERT INTO `spell_chain` VALUES + (54424,0, 54424,1,0), + (57564,54424,54424,2,0), + (57565,57564,54424,3,0), + (57566,57565,54424,4,0), + (57567,57566,54424,5,0); diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 8a7cedfd4..d20edfdf0 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -185,6 +185,7 @@ pkgdata_DATA = \ 7802_01_characters_character_achievement.sql \ 7802_02_characters_character_achievement_progress.sql \ 7823_01_mangos_item_template.sql \ + 7830_01_mangos_spell_chain.sql \ README ## Additional files to include when running 'make dist' @@ -350,4 +351,5 @@ EXTRA_DIST = \ 7802_01_characters_character_achievement.sql \ 7802_02_characters_character_achievement_progress.sql \ 7823_01_mangos_item_template.sql \ + 7830_01_mangos_spell_chain.sql \ README diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index e701b8f17..90577a58e 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 "7829" + #define REVISION_NR "7830" #endif // __REVISION_NR_H__ From e134b5383b926294b6de64311178a03a3ca567b0 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Fri, 15 May 2009 04:56:56 +0400 Subject: [PATCH 19/23] [7831] Prevent have hunter pet with level greater player levels at level changes. Propertly set hunter pet xp values at level update. --- src/game/Level2.cpp | 5 +++++ src/game/Pet.cpp | 31 +++++++++++++++++++++++++++++-- src/game/Pet.h | 1 + src/game/Player.cpp | 12 +++++++----- src/game/Player.h | 1 + src/shared/revision_nr.h | 2 +- 6 files changed, 44 insertions(+), 8 deletions(-) diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index 654e9d964..31211c5ac 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -1283,6 +1283,11 @@ bool ChatHandler::HandleNpcChangeLevelCommand(const char* args) if(pCreature->isPet()) { + if(((Pet*)pCreature)->getPetType()==HUNTER_PET) + { + pCreature->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, objmgr.GetXPForLevel(lvl)/4); + pCreature->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0); + } ((Pet*)pCreature)->GivePetLevel(lvl); } else diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index 7771b165b..607c848c4 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -345,6 +345,8 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool } m_loading = false; + + SynchronizeLevelWithOwner(); return true; } @@ -732,12 +734,11 @@ void Pet::GivePetXP(uint32 xp) { newXP -= nextLvlXP; - SetLevel( level + 1 ); + GivePetLevel(level+1); SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, objmgr.GetXPForLevel(level+1)/4); level = getLevel(); nextLvlXP = GetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP); - GivePetLevel(level); } SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, newXP); @@ -1847,3 +1848,29 @@ void Pet::learnSpellHighRank(uint32 spellid) for(SpellChainMapNext::const_iterator itr = nextMap.lower_bound(spellid); itr != nextMap.upper_bound(spellid); ++itr) learnSpellHighRank(itr->second); } + +void Pet::SynchronizeLevelWithOwner() +{ + Unit* owner = GetOwner(); + if (!owner || owner->GetTypeId() != TYPEID_PLAYER) + return; + + switch(getPetType()) + { + // always same level + case SUMMON_PET: + GivePetLevel(owner->getLevel()); + break; + // can't be greater owner level + case HUNTER_PET: + if(getLevel() > owner->getLevel()) + { + GivePetLevel(owner->getLevel()); + SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, objmgr.GetXPForLevel(owner->getLevel())/4); + SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, GetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP)-1); + } + break; + default: + break; + } +} diff --git a/src/game/Pet.h b/src/game/Pet.h index 08c72e31c..791851cd8 100644 --- a/src/game/Pet.h +++ b/src/game/Pet.h @@ -161,6 +161,7 @@ class Pet : public Creature HappinessState GetHappinessState(); void GivePetXP(uint32 xp); void GivePetLevel(uint32 level); + void SynchronizeLevelWithOwner(); bool InitStatsForLevel(uint32 level); bool HaveInDiet(ItemPrototype const* item) const; uint32 GetCurrentFoodBenefitLevel(uint32 itemlevel); diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 131b0310a..b35de7b29 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -2302,10 +2302,9 @@ void Player::GiveLevel(uint32 level) SetPower(POWER_FOCUS, 0); SetPower(POWER_HAPPINESS, 0); - // give level to summoned pet - Pet* pet = GetPet(); - if(pet && pet->getPetType()==SUMMON_PET) - pet->GivePetLevel(level); + // update level to hunter/summon pet + if (Pet* pet = GetPet()) + pet->SynchronizeLevelWithOwner(); GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL); } @@ -2491,6 +2490,10 @@ void Player::InitStatsForLevel(bool reapplyMods) SetPower(POWER_FOCUS, 0); SetPower(POWER_HAPPINESS, 0); SetPower(POWER_RUNIC_POWER, 0); + + // update level to hunter/summon pet + if (Pet* pet = GetPet()) + pet->SynchronizeLevelWithOwner(); } void Player::SendInitialSpells() @@ -20016,4 +20019,3 @@ bool Player::canSeeSpellClickOn(Creature const *c) const } return false; } - diff --git a/src/game/Player.h b/src/game/Player.h index eadb0e028..20a917b2f 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -906,6 +906,7 @@ class MANGOS_DLL_SPEC Player : public Unit void GiveXP(uint32 xp, Unit* victim); void GiveLevel(uint32 level); + void InitStatsForLevel(bool reapplyMods = false); // Played Time Stuff diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 90577a58e..dbcc5bcf1 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 "7830" + #define REVISION_NR "7831" #endif // __REVISION_NR_H__ From b722e75d906663c3a11b00ea1a84c0b78b2f095e Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Fri, 15 May 2009 06:17:29 +0400 Subject: [PATCH 20/23] [7832] Better check at `petcreateinfo_spell` loading for errors and redundend data. --- src/game/ObjectMgr.cpp | 39 ++++++++++++++++++++++++++++++++++++--- src/game/Player.cpp | 1 + src/shared/revision_nr.h | 2 +- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 763532169..e70902299 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -3589,20 +3589,53 @@ void ObjectMgr::LoadPetCreateSpells() uint32 creature_id = fields[0].GetUInt32(); - if(!creature_id || !sCreatureStorage.LookupEntry(creature_id)) + if(!creature_id) + { + sLog.outErrorDb("Creature id %u listed in `petcreateinfo_spell` not exist.",creature_id); continue; + } + + CreatureInfo const* cInfo = sCreatureStorage.LookupEntry(creature_id); + if(!cInfo) + { + sLog.outErrorDb("Creature id %u listed in `petcreateinfo_spell` not exist.",creature_id); + continue; + } PetCreateSpellEntry PetCreateSpell; + + bool have_spell = false; + bool have_spell_db = false; for(int i = 0; i < 4; i++) { PetCreateSpell.spellid[i] = fields[i + 1].GetUInt32(); - if(PetCreateSpell.spellid[i] && !sSpellStore.LookupEntry(PetCreateSpell.spellid[i])) + if(!PetCreateSpell.spellid[i]) + continue; + + have_spell_db = true; + + SpellEntry const* i_spell = sSpellStore.LookupEntry(PetCreateSpell.spellid[i]); + if(!i_spell) + { sLog.outErrorDb("Spell %u listed in `petcreateinfo_spell` does not exist",PetCreateSpell.spellid[i]); + PetCreateSpell.spellid[i] = 0; + continue; + } + + have_spell = true; } - mPetCreateSpell[creature_id] = PetCreateSpell; + if(!have_spell_db) + { + sLog.outErrorDb("Creature %u listed in `petcreateinfo_spell` have only 0 spell data, why it listed?",creature_id); + continue; + } + if(!have_spell) + continue; + + mPetCreateSpell[creature_id] = PetCreateSpell; ++count; } while (result->NextRow()); diff --git a/src/game/Player.cpp b/src/game/Player.cpp index b35de7b29..fd9b6d491 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -2305,6 +2305,7 @@ void Player::GiveLevel(uint32 level) // update level to hunter/summon pet if (Pet* pet = GetPet()) pet->SynchronizeLevelWithOwner(); + GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL); } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index dbcc5bcf1..95d2a494d 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 "7831" + #define REVISION_NR "7832" #endif // __REVISION_NR_H__ From a1f4549862e98366596b5cda4b67fe6798b94a57 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Fri, 15 May 2009 06:22:24 +0400 Subject: [PATCH 21/23] [7833] Implement levelup spells for non-hunter pets. * Use less hacky way to prepare data in SpellMgr::LoadPetLevelupSpellMap. * Fill data for all pet families including not hunter pets. * Fixed bug with lost/unexpected learned spells for some hunter pet families. Use less hackky way for --- src/game/Pet.cpp | 4 +- src/game/SharedDefines.h | 2 + src/game/SpellMgr.cpp | 225 ++++++++++++--------------------------- src/game/SpellMgr.h | 2 +- src/shared/revision_nr.h | 2 +- 5 files changed, 78 insertions(+), 157 deletions(-) diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index 607c848c4..4579193a7 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -941,7 +941,6 @@ bool Pet::InitStatsForLevel(uint32 petlevel) case HUNTER_PET: { 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 SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4)) ); @@ -999,6 +998,9 @@ bool Pet::InitStatsForLevel(uint32 petlevel) for (int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) SetModifierValue(UnitMods(UNIT_MOD_RESISTANCE_START + i), BASE_VALUE, float(createResistance[i])); + if(cinfo->family) + learnLevelupSpells(); + UpdateAllStats(); SetHealth(GetMaxHealth()); diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index 54ff80ae5..874df027a 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -1814,6 +1814,8 @@ enum CreatureFamily CREATURE_FAMILY_SPIRIT_BEAST = 46 }; +#define MAX_CREATURE_FAMILY 47 + enum CreatureTypeFlags { CREATURE_TYPEFLAGS_TAMEABLE = 0x0001, diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 7c72d2ec2..5b7ba0848 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -2126,184 +2126,101 @@ void SpellMgr::LoadSpellPetAuras() sLog.outString( ">> Loaded %u spell pet auras", count ); } +static uint32 family2skillline[MAX_CREATURE_FAMILY][2] = { + /* ----------------------------- = 0 */ {0, 0 }, + /*CREATURE_FAMILY_WOLF = 1 */ {208, 270}, + /*CREATURE_FAMILY_CAT = 2 */ {209, 270}, + /*CREATURE_FAMILY_SPIDER = 3 */ {203, 270}, + /*CREATURE_FAMILY_BEAR = 4 */ {210, 270}, + /*CREATURE_FAMILY_BOAR = 5 */ {211, 270}, + /*CREATURE_FAMILY_CROCOLISK = 6 */ {212, 270}, + /*CREATURE_FAMILY_CARRION_BIRD = 7 */ {213, 270}, + /*CREATURE_FAMILY_CRAB = 8 */ {214, 270}, + /*CREATURE_FAMILY_GORILLA = 9 */ {215, 270}, + /*CREATURE_FAMILY_HORSE_CUSTOM = 10*/ {0, 0 }, + /*CREATURE_FAMILY_RAPTOR = 11*/ {217, 270}, + /*CREATURE_FAMILY_TALLSTRIDER = 12*/ {218, 270}, + /* ----------------------------- = 13*/ {0, 0 }, + /* ----------------------------- = 14*/ {0, 0 }, + /*CREATURE_FAMILY_FELHUNTER = 15*/ {189, 0 }, + /*CREATURE_FAMILY_VOIDWALKER = 16*/ {204, 0 }, + /*CREATURE_FAMILY_SUCCUBUS = 17*/ {205, 0 }, + /* ----------------------------- = 18*/ {0, 0 }, + /*CREATURE_FAMILY_DOOMGUARD = 19*/ {207, 0 }, + /*CREATURE_FAMILY_SCORPID = 20*/ {236, 270}, + /*CREATURE_FAMILY_TURTLE = 21*/ {251, 270}, + /* ----------------------------- = 22*/ {0, 0 }, + /*CREATURE_FAMILY_IMP = 23*/ {188, 0 }, + /*CREATURE_FAMILY_BAT = 24*/ {653, 270}, + /*CREATURE_FAMILY_HYENA = 25*/ {654, 270}, + /*CREATURE_FAMILY_BIRD_OF_PREY = 26*/ {655, 270}, + /*CREATURE_FAMILY_WIND_SERPENT = 27*/ {656, 270}, + /*CREATURE_FAMILY_REMOTE_CONTROL = 28*/ {758, 0 }, + /*CREATURE_FAMILY_FELGUARD = 29*/ {761, 0 }, + /*CREATURE_FAMILY_DRAGONHAWK = 30*/ {763, 270}, + /*CREATURE_FAMILY_RAVAGER = 31*/ {767, 270}, + /*CREATURE_FAMILY_WARP_STALKER = 32*/ {766, 270}, + /*CREATURE_FAMILY_SPOREBAT = 33*/ {765, 270}, + /*CREATURE_FAMILY_NETHER_RAY = 34*/ {764, 270}, + /*CREATURE_FAMILY_SERPENT = 35*/ {768, 270}, + /* ----------------------------- = 36*/ {0, 0 }, + /*CREATURE_FAMILY_MOTH = 37*/ {775, 270}, + /*CREATURE_FAMILY_CHIMAERA = 38*/ {780, 270}, + /*CREATURE_FAMILY_DEVILSAUR = 39*/ {781, 270}, + /*CREATURE_FAMILY_GHOUL = 40*/ {782, 0 }, + /*CREATURE_FAMILY_SILITHID = 41*/ {783, 270}, + /*CREATURE_FAMILY_WORM = 42*/ {784, 270}, + /*CREATURE_FAMILY_RHINO = 43*/ {786, 270}, + /*CREATURE_FAMILY_WASP = 44*/ {785, 270}, + /*CREATURE_FAMILY_CORE_HOUND = 45*/ {787, 270}, + /*CREATURE_FAMILY_SPIRIT_BEAST = 46*/ {788, 270} +}; + void SpellMgr::LoadPetLevelupSpellMap() { - CreatureFamilyEntry const *creatureFamily; - SpellEntry const *spell; uint32 count = 0; + uint32 family_count = 0; for (uint32 i = 0; i < sCreatureFamilyStore.GetNumRows(); ++i) { - creatureFamily = sCreatureFamilyStore.LookupEntry(i); - + CreatureFamilyEntry const *creatureFamily = sCreatureFamilyStore.LookupEntry(i); if(!creatureFamily) // not exist continue; - if(creatureFamily->petTalentType < 0) // not hunter pet family + if(i >= MAX_CREATURE_FAMILY) continue; - for(uint32 j = 0; j < sSpellStore.GetNumRows(); ++j) + if(!family2skillline[i][0]) + continue; + + for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j) { - spell = sSpellStore.LookupEntry(j); - - // not exist - if(!spell) + SkillLineAbilityEntry const *skillLine = sSkillLineAbilityStore.LookupEntry(j); + if( !skillLine ) continue; - // not hunter spell - if(spell->SpellFamilyName != SPELLFAMILY_HUNTER) + if (skillLine->skillId!=family2skillline[i][0] && + (!family2skillline[i][1] || skillLine->skillId!=family2skillline[i][1])) continue; - // not pet spell - if(!(spell->SpellFamilyFlags & 0x1000000000000000LL)) + if(skillLine->learnOnGetSkill != ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL) continue; - // not Growl or Cower (generics) - if(spell->SpellIconID != 201 && spell->SpellIconID != 958) - { - switch(creatureFamily->ID) - { - case CREATURE_FAMILY_BAT: // Bite and Sonic Blast - if(spell->SpellIconID != 1680 && spell->SpellIconID != 1577) - continue; - break; - case CREATURE_FAMILY_BEAR: // Claw and Swipe - if(spell->SpellIconID != 262 && spell->SpellIconID != 1562) - continue; - break; - case CREATURE_FAMILY_BIRD_OF_PREY: // Claw and Snatch - if(spell->SpellIconID != 262 && spell->SpellIconID != 168) - continue; - break; - case CREATURE_FAMILY_BOAR: // Bite and Gore - if(spell->SpellIconID != 1680 && spell->SpellIconID != 1578) - continue; - break; - case CREATURE_FAMILY_CARRION_BIRD: // Bite and Demoralizing Screech - if(spell->SpellIconID != 1680 && spell->SpellIconID != 1579) - continue; - break; - case CREATURE_FAMILY_CAT: // Claw and Prowl and Rake - if(spell->SpellIconID != 262 && spell->SpellIconID != 495 && spell->SpellIconID != 494) - continue; - break; - case CREATURE_FAMILY_CHIMAERA: // Bite and Froststorm Breath - if(spell->SpellIconID != 1680 && spell->SpellIconID != 62) - continue; - break; - case CREATURE_FAMILY_CORE_HOUND: // Bite and Lava Breath - if(spell->SpellIconID != 1680 && spell->SpellIconID != 1197) - continue; - break; - case CREATURE_FAMILY_CRAB: // Claw and Pin - if(spell->SpellIconID != 262 && spell->SpellIconID != 2679) - continue; - break; - case CREATURE_FAMILY_CROCOLISK: // Bite and Bad Attitude - if(spell->SpellIconID != 1680 && spell->SpellIconID != 1581) - continue; - break; - case CREATURE_FAMILY_DEVILSAUR: // Bite and Monstrous Bite - if(spell->SpellIconID != 1680 && spell->SpellIconID != 599) - continue; - break; - case CREATURE_FAMILY_DRAGONHAWK: // Bite and Fire Breath - if(spell->SpellIconID != 1680 && spell->SpellIconID != 2128) - continue; - break; - case CREATURE_FAMILY_GORILLA: // Smack and Thunderstomp - if(spell->SpellIconID != 473 && spell->SpellIconID != 148) - continue; - break; - case CREATURE_FAMILY_HYENA: // Bite and Tendon Rip - if(spell->SpellIconID != 1680 && spell->SpellIconID != 138) - continue; - break; - case CREATURE_FAMILY_MOTH: // Serenity Dust and Smack - if(spell->SpellIconID != 1714 && spell->SpellIconID != 473) - continue; - break; - case CREATURE_FAMILY_NETHER_RAY: // Bite and Nether Shock - if(spell->SpellIconID != 1680 && spell->SpellIconID != 2027) - continue; - break; - case CREATURE_FAMILY_RAPTOR: // Claw and Savage Rend - if(spell->SpellIconID != 262 && spell->SpellIconID != 245) - continue; - break; - case CREATURE_FAMILY_RAVAGER: // Bite and Ravage - if(spell->SpellIconID != 1680 && spell->SpellIconID != 2253) - continue; - break; - case CREATURE_FAMILY_RHINO: // Smack and Stampede - if(spell->SpellIconID != 473 && spell->SpellIconID != 3066) - continue; - break; - case CREATURE_FAMILY_SCORPID: // Claw and Scorpid Poison - if(spell->SpellIconID != 262 && spell->SpellIconID != 163) - continue; - break; - case CREATURE_FAMILY_SERPENT: // Bite and Poison Spit - if(spell->SpellIconID != 1680 && spell->SpellIconID != 68) - continue; - break; - case CREATURE_FAMILY_SILITHID: // Claw and Venom Web Spray - if(spell->SpellIconID != 262 && (spell->SpellIconID != 272 && spell->SpellVisual[0] != 12013)) - continue; - break; - case CREATURE_FAMILY_SPIDER: // Bite and Web - if(spell->SpellIconID != 1680 && (spell->SpellIconID != 272 && spell->SpellVisual[0] != 684)) - continue; - break; - case CREATURE_FAMILY_SPIRIT_BEAST: // Claw and Prowl and Spirit Strike - if(spell->SpellIconID != 262 && spell->SpellIconID != 495 && spell->SpellIconID != 255) - continue; - break; - case CREATURE_FAMILY_SPOREBAT: // Smack and Spore Cloud - if(spell->SpellIconID != 473 && spell->SpellIconID != 2681) - continue; - break; - case CREATURE_FAMILY_TALLSTRIDER: // Claw and Dust Cloud - if(spell->SpellIconID != 262 && (spell->SpellIconID != 157 && !(spell->Attributes & 0x4000000))) - continue; - break; - case CREATURE_FAMILY_TURTLE: // Bite and Shell Shield - if(spell->SpellIconID != 1680 && spell->SpellIconID != 1588) - continue; - break; - case CREATURE_FAMILY_WARP_STALKER: // Bite and Warp - if(spell->SpellIconID != 1680 && spell->SpellIconID != 1952) - continue; - break; - case CREATURE_FAMILY_WASP: // Smack and Sting - if(spell->SpellIconID != 473 && spell->SpellIconID != 110) - continue; - break; - case CREATURE_FAMILY_WIND_SERPENT: // Bite and Lightning Breath - if(spell->SpellIconID != 1680 && spell->SpellIconID != 62) - continue; - break; - case CREATURE_FAMILY_WOLF: // Bite and Furious Howl - if(spell->SpellIconID != 1680 && spell->SpellIconID != 1573) - continue; - break; - case CREATURE_FAMILY_WORM: // Acid Spit and Bite - if(spell->SpellIconID != 636 && spell->SpellIconID != 1680) - continue; - break; - default: - sLog.outError("LoadPetLevelupSpellMap: Unhandled creature family %u", creatureFamily->ID); - continue; - } - } + SpellEntry const *spell = sSpellStore.LookupEntry(skillLine->spellId); + if(!spell) // not exist + continue; - mPetLevelupSpellMap[creatureFamily->ID][spell->spellLevel] = spell->Id; + PetLevelupSpellSet& spellSet = mPetLevelupSpellMap[creatureFamily->ID]; + if(spellSet.empty()) + ++family_count; + + spellSet.insert(PetLevelupSpellSet::value_type(spell->spellLevel,spell->Id)); count++; } } sLog.outString(); - sLog.outString( ">> Loaded %u pet levelup spells", count ); + sLog.outString( ">> Loaded %u pet levelup and default spells for %u families", count, family_count ); } /// Some checks for spells, to prevent adding deprecated/broken spells for trainers, spell book, etc diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index 8061dbee3..48ef3f744 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -559,7 +559,7 @@ typedef std::multimap SpellLearnSpellMap; typedef std::multimap SkillLineAbilityMap; -typedef std::map PetLevelupSpellSet; +typedef std::multimap PetLevelupSpellSet; typedef std::map PetLevelupSpellMap; inline bool IsPrimaryProfessionSkill(uint32 skill) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 95d2a494d..821e79162 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 "7832" + #define REVISION_NR "7833" #endif // __REVISION_NR_H__ From 6aacc45acebbea968aed25dc17e5192f45d91cc6 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Fri, 15 May 2009 16:49:35 +0400 Subject: [PATCH 22/23] [7834] Mangos string loading code cleanups. * Better integration creature event ai strings. * Not inclide in checks as expected max mangos strings range value to range --- src/game/CreatureEventAI.h | 1 - src/game/CreatureEventAIMgr.cpp | 12 ++++--- src/game/ObjectMgr.cpp | 61 +++++++++++++++++++++++---------- src/game/ObjectMgr.h | 12 ++++--- src/shared/revision_nr.h | 2 +- 5 files changed, 57 insertions(+), 31 deletions(-) diff --git a/src/game/CreatureEventAI.h b/src/game/CreatureEventAI.h index 56bccc947..771d582ef 100644 --- a/src/game/CreatureEventAI.h +++ b/src/game/CreatureEventAI.h @@ -30,7 +30,6 @@ class WorldObject; #define EVENT_UPDATE_TIME 500 #define SPELL_RUN_AWAY 8225 #define MAX_ACTIONS 3 -#define TEXT_SOURCE_RANGE -1000000 //the amount of entries each text source has available enum EventAI_Type { diff --git a/src/game/CreatureEventAIMgr.cpp b/src/game/CreatureEventAIMgr.cpp index 5961e0995..bd3631a75 100644 --- a/src/game/CreatureEventAIMgr.cpp +++ b/src/game/CreatureEventAIMgr.cpp @@ -36,7 +36,7 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Texts() m_CreatureEventAI_TextMap.clear(); // Load EventAI Text - LoadMangosStrings(WorldDatabase,"creature_ai_texts",-1,1+(TEXT_SOURCE_RANGE)); + objmgr.LoadMangosStrings(WorldDatabase,"creature_ai_texts",MIN_CREATURE_AI_TEXT_STRING_ID,MAX_CREATURE_AI_TEXT_STRING_ID); // Gather Additional data from EventAI Texts QueryResult *result = WorldDatabase.PQuery("SELECT entry, sound, type, language, emote FROM creature_ai_texts"); @@ -59,15 +59,17 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Texts() temp.Language = fields[3].GetInt32(); temp.Emote = fields[4].GetInt32(); - if (i >= 0) + // range negative + if (i > MIN_CREATURE_AI_TEXT_STRING_ID || i <= MAX_CREATURE_AI_TEXT_STRING_ID) { - sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` is not a negative value.",i); + sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` is not in valid range(%d-%d)",i,MIN_CREATURE_AI_TEXT_STRING_ID,MAX_CREATURE_AI_TEXT_STRING_ID); continue; } - if (i <= TEXT_SOURCE_RANGE) + // range negative (don't must be happen, loaded from same table) + if (!objmgr.GetMangosStringLocale(i)) { - sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` is out of accepted entry range for table.",i); + sLog.outErrorDb("CreatureEventAI: Entry %i in table `creature_ai_texts` not found",i); continue; } diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index e70902299..5cb337b3e 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -6524,10 +6524,35 @@ void ObjectMgr::LoadGameObjectForQuests() bool ObjectMgr::LoadMangosStrings(DatabaseType& db, char const* table, int32 min_value, int32 max_value) { + int32 start_value = min_value; + int32 end_value = max_value; + // some string can have negative indexes range + if (start_value < 0) + { + if (end_value >= start_value) + { + sLog.outErrorDb("Table '%s' attempt loaded with invalid range (%d - %d), strings not loaded.",table,min_value,max_value); + return false; + } + + // real range (max+1,min+1) exaple: (-10,-1000) -> -999...-10+1 + std::swap(start_value,end_value); + ++start_value; + ++end_value; + } + else + { + if (start_value >= end_value) + { + sLog.outErrorDb("Table '%s' attempt loaded with invalid range (%d - %d), strings not loaded.",table,min_value,max_value); + return false; + } + } + // cleanup affected map part for reloading case for(MangosStringLocaleMap::iterator itr = mMangosStringLocaleMap.begin(); itr != mMangosStringLocaleMap.end();) { - if(itr->first >= min_value && itr->first <= max_value) + if (itr->first >= start_value && itr->first < end_value) { MangosStringLocaleMap::iterator itr2 = itr; ++itr; @@ -6539,14 +6564,14 @@ bool ObjectMgr::LoadMangosStrings(DatabaseType& db, char const* table, int32 min QueryResult *result = db.PQuery("SELECT entry,content_default,content_loc1,content_loc2,content_loc3,content_loc4,content_loc5,content_loc6,content_loc7,content_loc8 FROM %s",table); - if(!result) + if (!result) { barGoLink bar(1); bar.step(); sLog.outString(); - if(min_value == MIN_MANGOS_STRING_ID) // error only in case internal strings + if (min_value == MIN_MANGOS_STRING_ID) // error only in case internal strings sLog.outErrorDb(">> Loaded 0 mangos strings. DB table `%s` is empty. Cannot continue.",table); else sLog.outString(">> Loaded 0 string templates. DB table `%s` is empty.",table); @@ -6564,22 +6589,20 @@ bool ObjectMgr::LoadMangosStrings(DatabaseType& db, char const* table, int32 min int32 entry = fields[0].GetInt32(); - if(entry==0) + if (entry==0) { sLog.outErrorDb("Table `%s` contain reserved entry 0, ignored.",table); continue; } - else if(entry < min_value || entry > max_value) + else if (entry < start_value || entry >= end_value) { - int32 start = min_value > 0 ? min_value : max_value; - int32 end = min_value > 0 ? max_value : min_value; - sLog.outErrorDb("Table `%s` contain entry %i out of allowed range (%d - %d), ignored.",table,entry,start,end); + sLog.outErrorDb("Table `%s` contain entry %i out of allowed range (%d - %d), ignored.",table,entry,min_value,max_value); continue; } MangosStringLocale& data = mMangosStringLocaleMap[entry]; - if(data.Content.size() > 0) + if (data.Content.size() > 0) { sLog.outErrorDb("Table `%s` contain data for already loaded entry %i (from another table?), ignored.",table,entry); continue; @@ -6594,13 +6617,13 @@ bool ObjectMgr::LoadMangosStrings(DatabaseType& db, char const* table, int32 min for(int i = 1; i < MAX_LOCALE; ++i) { std::string str = fields[i+1].GetCppString(); - if(!str.empty()) + if (!str.empty()) { int idx = GetOrNewIndexForLocale(LocaleConstant(i)); - if(idx >= 0) + if (idx >= 0) { // 0 -> default, idx in to idx+1 - if(data.Content.size() <= idx+1) + if (data.Content.size() <= idx+1) data.Content.resize(idx+2); data.Content[idx+1] = str; @@ -6612,7 +6635,7 @@ bool ObjectMgr::LoadMangosStrings(DatabaseType& db, char const* table, int32 min delete result; sLog.outString(); - if(min_value == MIN_MANGOS_STRING_ID) // error only in case internal strings + if (min_value == MIN_MANGOS_STRING_ID) sLog.outString( ">> Loaded %u MaNGOS strings from table %s", count,table); else sLog.outString( ">> Loaded %u string templates from %s", count,table); @@ -7550,15 +7573,15 @@ uint32 GetAreaTriggerScriptId(uint32 trigger_id) bool LoadMangosStrings(DatabaseType& db, char const* table,int32 start_value, int32 end_value) { - if(start_value >= 0 || start_value <= end_value) // start/end reversed for negative values + // MAX_DB_SCRIPT_STRING_ID is max allowed negative value for scripts (scrpts can use only more deep negative values + // start/end reversed for negative values + if (start_value > MAX_DB_SCRIPT_STRING_ID || end_value >= start_value) { - sLog.outErrorDb("Table '%s' attempt loaded with invalid range (%d - %d), use (%d - %d) instead.",table,start_value,end_value,-1,std::numeric_limits::min()); - start_value = -1; - end_value = std::numeric_limits::min(); + sLog.outErrorDb("Table '%s' attempt loaded with reserved by mangos range (%d - %d), strings not loaded.",table,start_value,end_value+1); + return false; } - // for scripting localized strings allowed use _only_ negative entries - return objmgr.LoadMangosStrings(db,table,end_value,start_value); + return objmgr.LoadMangosStrings(db,table,start_value,end_value); } uint32 MANGOS_DLL_SPEC GetScriptId(const char *name) diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index 037148be6..d2cb1a766 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -136,10 +136,12 @@ typedef UNORDERED_MAP RespawnTimes; // mangos string ranges -#define MIN_MANGOS_STRING_ID 1 -#define MAX_MANGOS_STRING_ID 2000000000 -#define MIN_DB_SCRIPT_STRING_ID MAX_MANGOS_STRING_ID -#define MAX_DB_SCRIPT_STRING_ID 2000010000 +#define MIN_MANGOS_STRING_ID 1 // 'mangos_string' +#define MAX_MANGOS_STRING_ID 2000000000 +#define MIN_DB_SCRIPT_STRING_ID MAX_MANGOS_STRING_ID // 'db_script_string' +#define MAX_DB_SCRIPT_STRING_ID 2000010000 +#define MIN_CREATURE_AI_TEXT_STRING_ID (-1) // 'creature_ai_texts' +#define MAX_CREATURE_AI_TEXT_STRING_ID (-1000000) struct MangosStringLocale { @@ -885,7 +887,7 @@ class ObjectMgr #define objmgr MaNGOS::Singleton::Instance() // scripting access functions -MANGOS_DLL_SPEC bool LoadMangosStrings(DatabaseType& db, char const* table,int32 start_value = -1, int32 end_value = std::numeric_limits::min()); +MANGOS_DLL_SPEC bool LoadMangosStrings(DatabaseType& db, char const* table,int32 start_value = MAX_CREATURE_AI_TEXT_STRING_ID, int32 end_value = std::numeric_limits::min()); MANGOS_DLL_SPEC uint32 GetAreaTriggerScriptId(uint32 trigger_id); MANGOS_DLL_SPEC uint32 GetScriptId(const char *name); MANGOS_DLL_SPEC ObjectMgr::ScriptNameMap& GetScriptNames(); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 821e79162..b7c7183d5 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 "7833" + #define REVISION_NR "7834" #endif // __REVISION_NR_H__ From 7a7ee86f97d6b853ed1913d3a7d2160e2776a813 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Fri, 15 May 2009 17:19:46 +0400 Subject: [PATCH 23/23] [7835] Store structures (with size = uint32) insteed pointer to structure in PetSpellMap. --- src/game/Pet.cpp | 112 ++++++++++++++++++--------------------- src/game/Pet.h | 7 ++- src/game/Player.cpp | 4 +- src/shared/revision_nr.h | 2 +- 4 files changed, 57 insertions(+), 68 deletions(-) diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index 4579193a7..e8b5bb04e 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -58,11 +58,7 @@ m_declinedname(NULL) Pet::~Pet() { if(m_uint32Values) // only for fully created Object - { - for (PetSpellMap::const_iterator i = m_spells.begin(); i != m_spells.end(); ++i) - delete i->second; ObjectAccessor::Instance().RemoveObject(this); - } delete m_declinedname; } @@ -1132,19 +1128,32 @@ void Pet::_LoadSpells() void Pet::_SaveSpells() { - for (PetSpellMap::const_iterator itr = m_spells.begin(), next = m_spells.begin(); itr != m_spells.end(); itr = next) + for (PetSpellMap::iterator itr = m_spells.begin(), next = m_spells.begin(); itr != m_spells.end(); itr = next) { ++next; - if (itr->second->type == PETSPELL_FAMILY) continue; // prevent saving family passives to DB - if (itr->second->state == PETSPELL_REMOVED || itr->second->state == PETSPELL_CHANGED) - CharacterDatabase.PExecute("DELETE FROM pet_spell WHERE guid = '%u' and spell = '%u'", m_charmInfo->GetPetNumber(), itr->first); - if (itr->second->state == PETSPELL_NEW || itr->second->state == PETSPELL_CHANGED) - CharacterDatabase.PExecute("INSERT INTO pet_spell (guid,spell,active) VALUES ('%u', '%u', '%u')", m_charmInfo->GetPetNumber(), itr->first, itr->second->active); - if (itr->second->state == PETSPELL_REMOVED) - _removeSpell(itr->first); - else - itr->second->state = PETSPELL_UNCHANGED; + // prevent saving family passives to DB + if (itr->second.type == PETSPELL_FAMILY) + continue; + + switch(itr->second.state) + { + case PETSPELL_REMOVED: + CharacterDatabase.PExecute("DELETE FROM pet_spell WHERE guid = '%u' and spell = '%u'", m_charmInfo->GetPetNumber(), itr->first); + m_spells.erase(itr); + continue; + case PETSPELL_CHANGED: + CharacterDatabase.PExecute("DELETE FROM pet_spell WHERE guid = '%u' and spell = '%u'", m_charmInfo->GetPetNumber(), itr->first); + CharacterDatabase.PExecute("INSERT INTO pet_spell (guid,spell,active) VALUES ('%u', '%u', '%u')", m_charmInfo->GetPetNumber(), itr->first, itr->second.active); + break; + case PETSPELL_NEW: + CharacterDatabase.PExecute("INSERT INTO pet_spell (guid,spell,active) VALUES ('%u', '%u', '%u')", m_charmInfo->GetPetNumber(), itr->first, itr->second.active); + break; + case PETSPELL_UNCHANGED: + continue; + } + + itr->second.state = PETSPELL_UNCHANGED; } } @@ -1275,7 +1284,7 @@ void Pet::_SaveAuras() } } -bool Pet::addSpell(uint32 spell_id, uint16 active, PetSpellState state, PetSpellType type) +bool Pet::addSpell(uint32 spell_id,uint16 active /*= ACT_DECIDE*/, PetSpellState state /*= PETSPELL_NEW*/, PetSpellType type /*= PETSPELL_NORMAL*/) { SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id); if (!spellInfo) @@ -1295,16 +1304,15 @@ bool Pet::addSpell(uint32 spell_id, uint16 active, PetSpellState state, PetSpell PetSpellMap::iterator itr = m_spells.find(spell_id); if (itr != m_spells.end()) { - if (itr->second->state == PETSPELL_REMOVED) + if (itr->second.state == PETSPELL_REMOVED) { - delete itr->second; m_spells.erase(itr); state = PETSPELL_CHANGED; } - else if (state == PETSPELL_UNCHANGED && itr->second->state != PETSPELL_UNCHANGED) + else if (state == PETSPELL_UNCHANGED && itr->second.state != PETSPELL_UNCHANGED) { // can be in case spell loading but learned at some previous spell loading - itr->second->state = PETSPELL_UNCHANGED; + itr->second.state = PETSPELL_UNCHANGED; if(active == ACT_ENABLED) ToggleAutocast(spell_id, true); @@ -1319,19 +1327,19 @@ bool Pet::addSpell(uint32 spell_id, uint16 active, PetSpellState state, PetSpell uint32 oldspell_id = 0; - PetSpell *newspell = new PetSpell; - newspell->state = state; - newspell->type = type; + PetSpell newspell; + newspell.state = state; + newspell.type = type; if(active == ACT_DECIDE) //active was not used before, so we save it's autocast/passive state here { if(IsPassiveSpell(spell_id)) - newspell->active = ACT_PASSIVE; + newspell.active = ACT_PASSIVE; else - newspell->active = ACT_DISABLED; + newspell.active = ACT_DISABLED; } else - newspell->active = active; + newspell.active = active; // talent: unlearn all other talent ranks (high and low) if(TalentSpellPos const* talentPos = GetTalentSpellPos(spell_id)) @@ -1356,13 +1364,13 @@ bool Pet::addSpell(uint32 spell_id, uint16 active, PetSpellState state, PetSpell { for (PetSpellMap::const_iterator itr2 = m_spells.begin(); itr2 != m_spells.end(); ++itr2) { - if(itr2->second->state == PETSPELL_REMOVED) continue; + if(itr2->second.state == PETSPELL_REMOVED) continue; if(spellmgr.GetFirstSpellInChain(itr2->first) == chainstart) { - newspell->active = itr2->second->active; + newspell.active = itr2->second.active; - if(newspell->active == ACT_ENABLED) + if(newspell.active == ACT_ENABLED) ToggleAutocast(itr2->first, false); oldspell_id = itr2->first; @@ -1379,7 +1387,7 @@ bool Pet::addSpell(uint32 spell_id, uint16 active, PetSpellState state, PetSpell else if(state == PETSPELL_NEW) m_charmInfo->AddSpellToAB(oldspell_id, spell_id); - if(newspell->active == ACT_ENABLED) + if(newspell.active == ACT_ENABLED) ToggleAutocast(spell_id, true); uint32 talentCost = GetTalentSpellCost(spell_id); @@ -1455,16 +1463,13 @@ bool Pet::removeSpell(uint32 spell_id) if (itr == m_spells.end()) return false; - if(itr->second->state == PETSPELL_REMOVED) + if(itr->second.state == PETSPELL_REMOVED) return false; - if(itr->second->state == PETSPELL_NEW) - { - delete itr->second; + if(itr->second.state == PETSPELL_NEW) m_spells.erase(itr); - } else - itr->second->state = PETSPELL_REMOVED; + itr->second.state = PETSPELL_REMOVED; RemoveAurasDueToSpell(spell_id); @@ -1483,24 +1488,9 @@ bool Pet::removeSpell(uint32 spell_id) return true; } -bool Pet::_removeSpell(uint32 spell_id) -{ - PetSpellMap::iterator itr = m_spells.find(spell_id); - if (itr != m_spells.end()) - { - delete itr->second; - m_spells.erase(itr); - return true; - } - return false; -} - void Pet::InitPetCreateSpells() { m_charmInfo->InitPetActionBar(); - - for (PetSpellMap::const_iterator i = m_spells.begin(); i != m_spells.end(); ++i) - delete i->second; m_spells.clear(); uint32 petspellid; @@ -1619,7 +1609,7 @@ bool Pet::resetTalents(bool no_cost) { for(PetSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end();) { - if(itr->second->state == PETSPELL_REMOVED) + if(itr->second.state == PETSPELL_REMOVED) { ++itr; continue; @@ -1698,7 +1688,7 @@ void Pet::ToggleAutocast(uint32 spellid, bool apply) if(IsPassiveSpell(spellid)) return; - PetSpellMap::const_iterator itr = m_spells.find(spellid); + PetSpellMap::iterator itr = m_spells.find(spellid); int i; @@ -1711,11 +1701,11 @@ void Pet::ToggleAutocast(uint32 spellid, bool apply) { m_autospells.push_back(spellid); - if(itr->second->active != ACT_ENABLED) + if(itr->second.active != ACT_ENABLED) { - itr->second->active = ACT_ENABLED; - if(itr->second->state != PETSPELL_NEW) - itr->second->state = PETSPELL_CHANGED; + itr->second.active = ACT_ENABLED; + if(itr->second.state != PETSPELL_NEW) + itr->second.state = PETSPELL_CHANGED; } } } @@ -1728,11 +1718,11 @@ void Pet::ToggleAutocast(uint32 spellid, bool apply) if (i < m_autospells.size()) { m_autospells.erase(itr2); - if(itr->second->active != ACT_DISABLED) + if(itr->second.active != ACT_DISABLED) { - itr->second->active = ACT_DISABLED; - if(itr->second->state != PETSPELL_NEW) - itr->second->state = PETSPELL_CHANGED; + itr->second.active = ACT_DISABLED; + if(itr->second.state != PETSPELL_NEW) + itr->second.state = PETSPELL_CHANGED; } } } @@ -1784,7 +1774,7 @@ bool Pet::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint3 bool Pet::HasSpell(uint32 spell) const { PetSpellMap::const_iterator itr = m_spells.find(spell); - return (itr != m_spells.end() && itr->second->state != PETSPELL_REMOVED ); + 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 791851cd8..07e1036ce 100644 --- a/src/game/Pet.h +++ b/src/game/Pet.h @@ -71,8 +71,8 @@ struct PetSpell { uint16 active; - PetSpellState state : 16; - PetSpellType type : 16; + PetSpellState state : 8; + PetSpellType type : 8; }; enum ActionFeedback @@ -106,7 +106,7 @@ enum PetNameInvalidReason PET_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME = 16 }; -typedef UNORDERED_MAP PetSpellMap; +typedef UNORDERED_MAP PetSpellMap; typedef std::map TeachSpellMap; typedef std::vector AutoSpellList; @@ -202,7 +202,6 @@ class Pet : public Creature void learnLevelupSpells(); bool unlearnSpell(uint32 spell_id); bool removeSpell(uint32 spell_id); - bool _removeSpell(uint32 spell_id); PetSpellMap m_spells; TeachSpellMap m_teachspells; diff --git a/src/game/Player.cpp b/src/game/Player.cpp index fd9b6d491..aba7012ab 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -16397,11 +16397,11 @@ void Player::PetSpellInitialize() // spells loop for (PetSpellMap::const_iterator itr = pet->m_spells.begin(); itr != pet->m_spells.end(); ++itr) { - if(itr->second->state == PETSPELL_REMOVED) + if(itr->second.state == PETSPELL_REMOVED) continue; data << uint16(itr->first); - data << uint16(itr->second->active); // pet spell active state isn't boolean + data << uint16(itr->second.active); // pet spell active state isn't boolean ++addlist; } } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index b7c7183d5..13bd699da 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 "7834" + #define REVISION_NR "7835" #endif // __REVISION_NR_H__