mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 13:37:05 +00:00
Merge commit 'origin/master' into 310
Conflicts: src/game/Player.cpp
This commit is contained in:
commit
6734694a90
47 changed files with 740 additions and 524 deletions
2
NEWS
2
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
|
||||
|
|
|
|||
|
|
@ -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_7830_01_mangos_spell_chain` 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',
|
||||
|
|
@ -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`
|
||||
--
|
||||
|
|
@ -14476,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),
|
||||
|
|
@ -14484,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),
|
||||
/*------------------
|
||||
|
|
@ -17013,9 +17040,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 +17128,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),
|
||||
|
|
|
|||
4
sql/updates/7823_01_mangos_item_template.sql
Normal file
4
sql/updates/7823_01_mangos_item_template.sql
Normal file
|
|
@ -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';
|
||||
10
sql/updates/7830_01_mangos_spell_chain.sql
Normal file
10
sql/updates/7830_01_mangos_spell_chain.sql
Normal file
|
|
@ -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);
|
||||
|
|
@ -184,6 +184,8 @@ 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 \
|
||||
7830_01_mangos_spell_chain.sql \
|
||||
README
|
||||
|
||||
## Additional files to include when running 'make dist'
|
||||
|
|
@ -348,4 +350,6 @@ 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 \
|
||||
7830_01_mangos_spell_chain.sql \
|
||||
README
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 "
|
||||
|
|
|
|||
|
|
@ -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->IsWithinDist3d(CombatStartX,CombatStartY,CombatStartZ,
|
||||
ThreatRadius > AttackDist ? ThreatRadius : AttackDist);
|
||||
}
|
||||
|
||||
CreatureDataAddon const* Creature::GetCreatureAddon() const
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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, //
|
||||
|
|
|
|||
|
|
@ -1139,7 +1139,7 @@ struct RandomPropertiesPointsEntry
|
|||
struct ScalingStatDistributionEntry
|
||||
{
|
||||
uint32 Id;
|
||||
uint32 StatMod[10];
|
||||
int32 StatMod[10];
|
||||
uint32 Modifier[10];
|
||||
uint32 MaxLevel;
|
||||
};
|
||||
|
|
@ -1148,7 +1148,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{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -594,46 +594,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
|
||||
|
|
@ -646,12 +606,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<<SubClass)&0x02A5F3)
|
||||
{
|
||||
int32 bonus = int32(getDPS()*14.0f) - 767;
|
||||
int32 bonus = int32((extraDPS + getDPS())*14.0f) - 767;
|
||||
if (bonus < 0)
|
||||
return 0;
|
||||
return bonus;
|
||||
|
|
|
|||
|
|
@ -1277,6 +1277,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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -675,9 +675,7 @@ void WorldSession::HandleReclaimCorpseOpcode(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;
|
||||
|
|
|
|||
|
|
@ -1107,7 +1107,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;
|
||||
|
|
@ -1134,10 +1134,33 @@ 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::IsWithinDist3d(float x, float y, float z, float dist2compare) const
|
||||
{
|
||||
if (!obj || !IsInMap(obj)) return false;
|
||||
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;
|
||||
|
||||
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;
|
||||
|
|
@ -1160,7 +1183,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);
|
||||
|
|
@ -1168,6 +1191,83 @@ 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, bool is3D /* = true */) const
|
||||
{
|
||||
float dx1 = GetPositionX() - obj1->GetPositionX();
|
||||
float dy1 = GetPositionY() - obj1->GetPositionY();
|
||||
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 distsq2 = dx2*dx2 + dy2*dy2;
|
||||
if(is3D)
|
||||
{
|
||||
float dz2 = GetPositionZ() - obj2->GetPositionZ();
|
||||
distsq2 += dz2*dz2;
|
||||
}
|
||||
|
||||
return distsq1 < distsq2;
|
||||
}
|
||||
|
||||
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 distsq = dx*dx + dy*dy;
|
||||
if(is3D)
|
||||
{
|
||||
float dz = GetPositionZ() - obj->GetPositionZ();
|
||||
distsq += 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;
|
||||
}
|
||||
|
||||
bool WorldObject::IsInRange3d(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;
|
||||
|
|
@ -1563,15 +1663,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;
|
||||
|
|
@ -1582,6 +1675,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:
|
||||
|
|
|
|||
|
|
@ -421,18 +421,33 @@ 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 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
|
||||
// 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, 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 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;
|
||||
|
|
|
|||
|
|
@ -3590,20 +3590,53 @@ void ObjectMgr::LoadPetCreateSpells()
|
|||
|
||||
uint32 creature_id = fields[0].GetUInt32();
|
||||
|
||||
if(!creature_id || !sCreatureStorage.LookupEntry<CreatureInfo>(creature_id))
|
||||
if(!creature_id)
|
||||
{
|
||||
sLog.outErrorDb("Creature id %u listed in `petcreateinfo_spell` not exist.",creature_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(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());
|
||||
|
|
@ -6509,10 +6542,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;
|
||||
|
|
@ -6524,14 +6582,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);
|
||||
|
|
@ -6549,22 +6607,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;
|
||||
|
|
@ -6579,13 +6635,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;
|
||||
|
|
@ -6597,7 +6653,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);
|
||||
|
|
@ -7535,15 +7591,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<int32>::min());
|
||||
start_value = -1;
|
||||
end_value = std::numeric_limits<int32>::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)
|
||||
|
|
|
|||
|
|
@ -136,10 +136,12 @@ typedef UNORDERED_MAP<uint64/*(instance,guid) pair*/,time_t> 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
|
||||
{
|
||||
|
|
@ -887,7 +889,7 @@ class ObjectMgr
|
|||
#define objmgr MaNGOS::Singleton<ObjectMgr>::Instance()
|
||||
|
||||
// scripting access functions
|
||||
MANGOS_DLL_SPEC bool LoadMangosStrings(DatabaseType& db, char const* table,int32 start_value = -1, int32 end_value = std::numeric_limits<int32>::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<int32>::min());
|
||||
MANGOS_DLL_SPEC uint32 GetAreaTriggerScriptId(uint32 trigger_id);
|
||||
MANGOS_DLL_SPEC uint32 GetScriptId(const char *name);
|
||||
MANGOS_DLL_SPEC ObjectMgr::ScriptNameMap& GetScriptNames();
|
||||
|
|
|
|||
147
src/game/Pet.cpp
147
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;
|
||||
}
|
||||
|
|
@ -345,6 +341,8 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
|||
}
|
||||
|
||||
m_loading = false;
|
||||
|
||||
SynchronizeLevelWithOwner();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -732,12 +730,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);
|
||||
|
|
@ -940,7 +937,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)) );
|
||||
|
|
@ -998,6 +994,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());
|
||||
|
|
@ -1129,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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1272,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)
|
||||
|
|
@ -1292,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);
|
||||
|
|
@ -1316,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))
|
||||
|
|
@ -1353,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;
|
||||
|
|
@ -1376,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);
|
||||
|
|
@ -1452,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);
|
||||
|
||||
|
|
@ -1480,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;
|
||||
|
|
@ -1616,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;
|
||||
|
|
@ -1701,7 +1694,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;
|
||||
|
||||
|
|
@ -1714,11 +1707,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1731,11 +1724,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1787,7 +1780,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
|
||||
|
|
@ -1853,3 +1846,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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<uint32, PetSpell*> PetSpellMap;
|
||||
typedef UNORDERED_MAP<uint32, PetSpell> PetSpellMap;
|
||||
typedef std::map<uint32,uint32> TeachSpellMap;
|
||||
typedef std::vector<uint32> AutoSpellList;
|
||||
|
||||
|
|
@ -114,7 +114,7 @@ typedef std::vector<uint32> 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)
|
||||
|
|
@ -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);
|
||||
|
|
@ -201,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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1442,7 +1442,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
|
||||
|
|
@ -1608,7 +1613,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->IsWithinDist3d(x,y,z, OWNER_MAX_DISTANCE))
|
||||
UnsummonPetTemporaryIfAny();
|
||||
}
|
||||
|
||||
|
|
@ -2294,10 +2299,10 @@ 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);
|
||||
}
|
||||
|
||||
|
|
@ -2485,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()
|
||||
|
|
@ -5659,23 +5668,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
|
||||
|
|
@ -5691,7 +5703,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);
|
||||
|
|
@ -5709,7 +5721,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);
|
||||
|
|
@ -5734,7 +5746,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);
|
||||
|
|
@ -6325,30 +6337,25 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl
|
|||
if(slot >= 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 (i >= proto->StatsCount)
|
||||
continue;
|
||||
statType = proto->ItemStat[i].ItemStatType;
|
||||
val = proto->ItemStat[i].ItemStatValue;
|
||||
}
|
||||
|
|
@ -6503,8 +6510,18 @@ 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;
|
||||
}
|
||||
// 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);
|
||||
|
||||
if (proto->Block)
|
||||
HandleBaseModValue(SHIELD_BLOCK_VALUE, FLAT_MOD, float(proto->Block), apply);
|
||||
|
|
@ -6541,23 +6558,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 average), max (130% from average) damage
|
||||
if (ssv)
|
||||
{
|
||||
damage = apply ? proto->Damage[0].DamageMin : BASE_MINDAMAGE;
|
||||
if (extraDPS = ssv->getDPSMod(proto->ScalingStatValue))
|
||||
{
|
||||
float average = extraDPS * proto->Delay / 1000.0f;
|
||||
minDamage = 0.7f * average;
|
||||
maxDamage = 1.3f * average;
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
|
@ -9545,18 +9581,22 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo
|
|||
return EQUIP_ERR_CANT_DO_RIGHT_NOW;
|
||||
}
|
||||
|
||||
uint8 eslot = FindEquipSlot( pProto, slot, swap );
|
||||
if( eslot == NULL_SLOT )
|
||||
ScalingStatDistributionEntry const *ssd = pProto->ScalingStatDistribution ? sScalingStatDistributionStore.LookupEntry(pProto->ScalingStatDistribution) : 0;
|
||||
if (ssd && ssd->MaxLevel < getLevel())
|
||||
return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED;
|
||||
|
||||
uint8 msg = CanUseItem( pItem , not_loading );
|
||||
if( msg != EQUIP_ERR_OK )
|
||||
uint8 eslot = FindEquipSlot( pProto, slot, swap );
|
||||
if (eslot == NULL_SLOT)
|
||||
return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED;
|
||||
|
||||
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
|
||||
|
|
@ -9564,19 +9604,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9585,25 +9622,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)
|
||||
{
|
||||
|
|
@ -9618,9 +9655,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;
|
||||
}
|
||||
}
|
||||
|
|
@ -9628,10 +9665,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
|
||||
|
|
@ -9850,38 +9885,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;
|
||||
}
|
||||
}
|
||||
|
|
@ -16295,11 +16341,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;
|
||||
}
|
||||
}
|
||||
|
|
@ -20210,4 +20256,4 @@ void Player::DeleteEquipmentSet(uint64 setGuid)
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -949,6 +949,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
|
||||
|
|
@ -2315,7 +2316,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<Player> m_gridRef;
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ RandomMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff
|
|||
creature.SetUnitMovementFlags(irand(0,RUNNING_CHANCE_RANDOMMV) > 0 ? MONSTER_MOVE_WALK : MONSTER_MOVE_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(MONSTER_MOVE_WALK);
|
||||
_setRandomLocation(creature);
|
||||
|
|
|
|||
|
|
@ -1817,6 +1817,8 @@ enum CreatureFamily
|
|||
CREATURE_FAMILY_SPIRIT_BEAST = 46
|
||||
};
|
||||
|
||||
#define MAX_CREATURE_FAMILY 47
|
||||
|
||||
enum CreatureTypeFlags
|
||||
{
|
||||
CREATURE_TYPEFLAGS_TAMEABLE = 0x0001,
|
||||
|
|
|
|||
|
|
@ -1334,7 +1334,7 @@ struct TargetDistanceOrder : public std::binary_function<const Unit, const Unit,
|
|||
// functor for operator ">"
|
||||
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<Unit *>::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<Unit *>::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))
|
||||
|
|
@ -4688,10 +4688,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->IsWithinDist3d(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->IsWithinDist3d(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ,min_range))
|
||||
return SPELL_FAILED_TOO_CLOSE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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->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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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()->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:
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -592,9 +592,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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -559,7 +559,7 @@ typedef std::multimap<uint32, SpellLearnSpellNode> SpellLearnSpellMap;
|
|||
|
||||
typedef std::multimap<uint32, SkillLineAbilityEntry const*> SkillLineAbilityMap;
|
||||
|
||||
typedef std::map<uint32, uint32> PetLevelupSpellSet;
|
||||
typedef std::multimap<uint32, uint32> PetLevelupSpellSet;
|
||||
typedef std::map<uint32, PetLevelupSpellSet> PetLevelupSpellMap;
|
||||
|
||||
inline bool IsPrimaryProfessionSkill(uint32 skill)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -3207,7 +3207,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 );
|
||||
}
|
||||
|
|
@ -3217,7 +3217,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 );
|
||||
}
|
||||
|
|
@ -9077,9 +9077,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
|
||||
|
|
@ -9090,14 +9088,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;
|
||||
}
|
||||
|
|
@ -9123,7 +9121,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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1276,9 +1276,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; }
|
||||
|
|
|
|||
|
|
@ -557,7 +557,7 @@ class World
|
|||
static float m_VisibleObjectGreyDistance;
|
||||
|
||||
// CLI command holder to be thread safe
|
||||
ACE_Based::LockedQueue<CliCommandHolder*,ACE_Thread_Mutex> cliCmdQueue;
|
||||
ACE_Based::LockedQueue<CliCommandHolder*,ACE_Thread_Mutex> 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<WorldSession*, ACE_Thread_Mutex> addSessQueue;
|
||||
ACE_Based::LockedQueue<WorldSession*, ACE_Thread_Mutex> addSessQueue;
|
||||
|
||||
//used versions
|
||||
std::string m_DBVersion;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "7814"
|
||||
#define REVISION_NR "7835"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue