Merge commit 'origin/master' into 310

Conflicts:
	src/game/Player.cpp
This commit is contained in:
tomrus88 2009-05-16 00:47:37 +04:00
commit 6734694a90
47 changed files with 740 additions and 524 deletions

View file

@ -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

View file

@ -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);
}

View file

@ -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 "

View file

@ -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

View file

@ -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;

View file

@ -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
{

View file

@ -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;
}

View file

@ -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, //

View file

@ -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{

View file

@ -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);
}
}

View file

@ -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());
}

View file

@ -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();

View file

@ -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);
}

View file

@ -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;

View file

@ -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

View file

@ -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);
}

View file

@ -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;

View file

@ -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:

View file

@ -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;

View file

@ -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)

View file

@ -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();

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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);
}

View file

@ -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;
}
}
}
}

View file

@ -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;

View file

@ -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);

View file

@ -1817,6 +1817,8 @@ enum CreatureFamily
CREATURE_FAMILY_SPIRIT_BEAST = 46
};
#define MAX_CREATURE_FAMILY 47
enum CreatureTypeFlags
{
CREATURE_TYPEFLAGS_TAMEABLE = 0x0001,

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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)

View file

@ -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;

View file

@ -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;
}

View file

@ -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; }

View file

@ -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;

View file

@ -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;
}

View file

@ -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;

View file

@ -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

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "7814"
#define REVISION_NR "7835"
#endif // __REVISION_NR_H__