*Update melee range calculation. By QAston.
--HG-- branch : trunk
This commit is contained in:
@@ -126,7 +126,7 @@ AggressorAI::UpdateAI(const uint32 /*diff*/)
|
||||
|
||||
if( i_creature.isAttackReady() )
|
||||
{
|
||||
if( i_creature.IsWithinCombatDist(i_creature.getVictim(), ATTACK_DISTANCE))
|
||||
if( i_creature.IsWithinMeleeRange(i_creature.getVictim()))
|
||||
{
|
||||
i_creature.AttackerStateUpdate(i_creature.getVictim());
|
||||
i_creature.resetAttackTimer();
|
||||
|
||||
@@ -117,7 +117,7 @@ void GuardAI::UpdateAI(const uint32 /*diff*/)
|
||||
|
||||
if( i_creature.isAttackReady() )
|
||||
{
|
||||
if( i_creature.IsWithinCombatDist(i_creature.getVictim(), ATTACK_DISTANCE))
|
||||
if( i_creature.IsWithinMeleeRange(i_creature.getVictim()))
|
||||
{
|
||||
i_creature.AttackerStateUpdate(i_creature.getVictim());
|
||||
i_creature.resetAttackTimer();
|
||||
|
||||
+3
-1
@@ -39,7 +39,9 @@
|
||||
|
||||
#define DEFAULT_WORLD_OBJECT_SIZE 0.388999998569489f // player size, also currently used (correctly?) for any non Unit world objects
|
||||
#define DEFAULT_COMBAT_REACH 1.5f
|
||||
#define ATTACK_DISTANCE (5.0f - DEFAULT_COMBAT_REACH * 2) // melee range: center to center for players
|
||||
#define MIN_MELEE_REACH 2.0f
|
||||
#define NOMINAL_MELEE_RANGE 5.0f
|
||||
#define MELEE_RANGE (NOMINAL_MELEE_RANGE - MIN_MELEE_REACH * 2) //center to center for players
|
||||
|
||||
enum TypeMask
|
||||
{
|
||||
|
||||
+3
-3
@@ -156,7 +156,7 @@ void PetAI::UpdateAI(const uint32 diff)
|
||||
_stopAttack();
|
||||
return;
|
||||
}
|
||||
else if( i_pet.IsStopped() || i_pet.IsWithinDistInMap(i_pet.getVictim(), ATTACK_DISTANCE))
|
||||
else if( i_pet.IsStopped() || i_pet.IsWithinMeleeRange(i_pet.getVictim()))
|
||||
{
|
||||
// required to be stopped cases
|
||||
if ( i_pet.IsStopped() && i_pet.IsNonMeleeSpellCasted(false) )
|
||||
@@ -167,7 +167,7 @@ void PetAI::UpdateAI(const uint32 diff)
|
||||
return;
|
||||
}
|
||||
// not required to be stopped case
|
||||
else if( i_pet.isAttackReady() && i_pet.IsWithinCombatDist(i_pet.getVictim(), ATTACK_DISTANCE) )
|
||||
else if( i_pet.isAttackReady() && i_pet.IsWithinMeleeRange(i_pet.getVictim()) )
|
||||
{
|
||||
i_pet.AttackerStateUpdate(i_pet.getVictim());
|
||||
|
||||
@@ -341,6 +341,6 @@ void PetAI::AttackedBy(Unit *attacker)
|
||||
{
|
||||
//when attacked, fight back in case 1)no victim already AND 2)not set to passive AND 3)not set to stay, unless can it can reach attacker with melee attack anyway
|
||||
if(!i_pet.getVictim() && i_pet.GetCharmInfo() && !i_pet.GetCharmInfo()->HasReactState(REACT_PASSIVE) &&
|
||||
(!i_pet.GetCharmInfo()->HasCommandState(COMMAND_STAY) || i_pet.canReachWithAttack(attacker)))
|
||||
(!i_pet.GetCharmInfo()->HasCommandState(COMMAND_STAY) || i_pet.IsWithinMeleeRange(attacker)))
|
||||
AttackStart(attacker);
|
||||
}
|
||||
|
||||
+2
-4
@@ -1106,11 +1106,9 @@ void Player::Update( uint32 p_time )
|
||||
// default combat reach 10
|
||||
// TODO add weapon,skill check
|
||||
|
||||
float pldistance = ATTACK_DISTANCE;
|
||||
|
||||
if (isAttackReady(BASE_ATTACK))
|
||||
{
|
||||
if(!IsWithinCombatDist(pVictim, pldistance))
|
||||
if(!IsWithinMeleeRange(pVictim))
|
||||
{
|
||||
setAttackTimer(BASE_ATTACK,100);
|
||||
if(m_swingErrorMsg != 1) // send single time (client auto repeat)
|
||||
@@ -1147,7 +1145,7 @@ void Player::Update( uint32 p_time )
|
||||
|
||||
if ( haveOffhandWeapon() && isAttackReady(OFF_ATTACK))
|
||||
{
|
||||
if(!IsWithinCombatDist(pVictim, pldistance))
|
||||
if(!IsWithinMeleeRange(pVictim))
|
||||
{
|
||||
setAttackTimer(OFF_ATTACK,100);
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ void PossessedAI::UpdateAI(const uint32 diff)
|
||||
_stopAttack(); // i_victimGuid == 0 && i_pet.getVictim() == NULL now
|
||||
return;
|
||||
}
|
||||
else if(i_pet.IsWithinCombatDist(i_pet.getVictim(), ATTACK_DISTANCE) && i_pet.isAttackReady() && !i_pet.GetCharmer()->HasAuraType(SPELL_AURA_MOD_PACIFY))
|
||||
else if(i_pet.IsWithinMeleeRange(i_pet.getVictim()) && i_pet.isAttackReady() && !i_pet.GetCharmer()->HasAuraType(SPELL_AURA_MOD_PACIFY))
|
||||
{
|
||||
i_pet.AttackerStateUpdate(i_pet.getVictim());
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ ReactorAI::UpdateAI(const uint32 /*time_diff*/)
|
||||
|
||||
if( i_creature.isAttackReady() )
|
||||
{
|
||||
if( i_creature.IsWithinCombatDist(i_creature.getVictim(), ATTACK_DISTANCE))
|
||||
if( i_creature.IsWithinMeleeRange(i_creature.getVictim()))
|
||||
{
|
||||
i_creature.AttackerStateUpdate(i_creature.getVictim());
|
||||
i_creature.resetAttackTimer();
|
||||
|
||||
+15
-20
@@ -4682,23 +4682,9 @@ uint8 Spell::CheckRange(bool strict)
|
||||
range_mod = 6.25;*/
|
||||
|
||||
SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex);
|
||||
float max_range, min_range;
|
||||
float range_type = GetSpellRangeType(srange);
|
||||
if(range_type == SPELL_RANGE_DEFAULT)
|
||||
{
|
||||
max_range = GetSpellMaxRange(srange);// + range_mod;
|
||||
min_range = GetSpellMinRange(srange);
|
||||
}
|
||||
else if(range_type == SPELL_RANGE_MELEE)
|
||||
{
|
||||
max_range = ATTACK_DISTANCE;
|
||||
min_range = GetSpellMinRange(srange);
|
||||
}
|
||||
else
|
||||
{
|
||||
max_range = GetSpellMaxRange(srange);// + range_mod;
|
||||
min_range = ATTACK_DISTANCE;
|
||||
}
|
||||
float max_range = GetSpellMaxRange(srange); // + range_mod;
|
||||
float min_range = GetSpellMinRange(srange);
|
||||
uint32 range_type = GetSpellRangeType(srange);
|
||||
|
||||
if(Player* modOwner = m_caster->GetSpellModOwner())
|
||||
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, max_range, this);
|
||||
@@ -4707,11 +4693,20 @@ uint8 Spell::CheckRange(bool strict)
|
||||
|
||||
if(target && target != m_caster)
|
||||
{
|
||||
// distance from target center in checks
|
||||
if(!m_caster->IsWithinCombatDist(target, max_range))
|
||||
if(range_type == SPELL_RANGE_MELEE)
|
||||
{
|
||||
if(!m_caster->IsWithinMeleeRange(target))
|
||||
return SPELL_FAILED_OUT_OF_RANGE;
|
||||
}
|
||||
else if(!m_caster->IsWithinCombatRange(target, max_range))
|
||||
return SPELL_FAILED_OUT_OF_RANGE; //0x5A;
|
||||
|
||||
if(min_range && m_caster->IsWithinCombatDist(target, min_range)) // skip this check if min_range = 0
|
||||
if(range_type == SPELL_RANGE_RANGED)
|
||||
{
|
||||
if(m_caster->IsWithinMeleeRange(target))
|
||||
return SPELL_FAILED_TOO_CLOSE;
|
||||
}
|
||||
else if(min_range && m_caster->IsWithinCombatRange(target, min_range)) // skip this check if min_range = 0
|
||||
return SPELL_FAILED_TOO_CLOSE;
|
||||
|
||||
if( m_caster->GetTypeId() == TYPEID_PLAYER &&
|
||||
|
||||
@@ -60,7 +60,7 @@ TargetedMovementGenerator<T>::_setTargetLocation(T &owner)
|
||||
if(!i_offset)
|
||||
{
|
||||
// to nearest random contact position
|
||||
i_target->GetRandomContactPoint( &owner, x, y, z, 0.5f, ATTACK_DISTANCE - 0.5f );
|
||||
i_target->GetRandomContactPoint( &owner, x, y, z, 0, MELEE_RANGE - 0.5f );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -185,7 +185,7 @@ TargetedMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
|
||||
owner.SetInFront(i_target.getTarget());
|
||||
|
||||
owner.StopMoving();
|
||||
if(owner.IsWithinCombatDist(i_target.getTarget(), ATTACK_DISTANCE) && !owner.hasUnitState(UNIT_STAT_FOLLOW))
|
||||
if(owner.IsWithinMeleeRange(i_target.getTarget()) && !owner.hasUnitState(UNIT_STAT_FOLLOW))
|
||||
owner.Attack(i_target.getTarget(),true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,7 +302,7 @@ HostilReference* ThreatContainer::selectNextVictim(Creature* pAttacker, HostilRe
|
||||
}
|
||||
|
||||
if( currentRef->getThreat() > 1.3f * pCurrentVictim->getThreat() ||
|
||||
currentRef->getThreat() > 1.1f * pCurrentVictim->getThreat() && pAttacker->IsWithinDistInMap(target, ATTACK_DISTANCE) )
|
||||
currentRef->getThreat() > 1.1f * pCurrentVictim->getThreat() && pAttacker->IsWithinMeleeRange(target) )
|
||||
{ //implement 110% threat rule for targets in melee range
|
||||
found = true; //and 130% rule for targets in ranged distances
|
||||
break; //for selecting alive targets
|
||||
|
||||
+17
-8
@@ -420,13 +420,7 @@ void Unit::resetAttackTimer(WeaponAttackType type)
|
||||
m_attackTimer[type] = uint32(GetAttackTime(type) * m_modAttackSpeedPct[type]);
|
||||
}
|
||||
|
||||
bool Unit::canReachWithAttack(Unit *pVictim) const
|
||||
{
|
||||
assert(pVictim);
|
||||
return IsWithinDistInMap(pVictim, GetCombatReach());
|
||||
}
|
||||
|
||||
bool Unit::IsWithinCombatDist(Unit *obj, float dist2compare) const
|
||||
bool Unit::IsWithinCombatRange(Unit *obj, float dist2compare) const
|
||||
{
|
||||
if (!obj || !IsInMap(obj)) return false;
|
||||
|
||||
@@ -434,13 +428,28 @@ bool Unit::IsWithinCombatDist(Unit *obj, float dist2compare) const
|
||||
float dy = GetPositionY() - obj->GetPositionY();
|
||||
float dz = GetPositionZ() - obj->GetPositionZ();
|
||||
float distsq = dx*dx + dy*dy + dz*dz;
|
||||
//not sure here, or combatreach + combatreach?
|
||||
|
||||
float sizefactor = GetCombatReach() + obj->GetCombatReach();
|
||||
float maxdist = dist2compare + sizefactor;
|
||||
|
||||
return distsq < maxdist * maxdist;
|
||||
}
|
||||
|
||||
bool Unit::IsWithinMeleeRange(Unit *obj) const
|
||||
{
|
||||
if (!obj || !IsInMap(obj)) return false;
|
||||
|
||||
float dx = GetPositionX() - obj->GetPositionX();
|
||||
float dy = GetPositionY() - obj->GetPositionY();
|
||||
float dz = GetPositionZ() - obj->GetPositionZ();
|
||||
float distsq = dx*dx + dy*dy + dz*dz;
|
||||
|
||||
float sizefactor = GetMeleeReach() + obj->GetMeleeReach();
|
||||
float maxdist = MELEE_RANGE + sizefactor;
|
||||
|
||||
return distsq < maxdist * maxdist;
|
||||
}
|
||||
|
||||
void Unit::GetRandomContactPoint( const Unit* obj, float &x, float &y, float &z, float distance2dMin, float distance2dMax ) const
|
||||
{
|
||||
float combat_reach = GetCombatReach();
|
||||
|
||||
+4
-4
@@ -771,10 +771,10 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
|
||||
bool haveOffhandWeapon() const;
|
||||
bool CanDualWield() const { return m_canDualWield; }
|
||||
void SetCanDualWield(bool value) { m_canDualWield = value; }
|
||||
bool canReachWithAttack(Unit *pVictim) const;
|
||||
float GetCombatReach() const { return m_floatValues[UNIT_FIELD_COMBATREACH]; }
|
||||
bool IsWithinCombatDist(Unit *obj, float dist2compare) const;
|
||||
bool IsWithinMeleeRange(Unit *obj) const { return IsWithinCombatDist(obj, ATTACK_DISTANCE); }
|
||||
float GetMeleeReach() const { float reach = m_floatValues[UNIT_FIELD_COMBATREACH]; return reach > MIN_MELEE_REACH ? reach : MIN_MELEE_REACH; }
|
||||
bool IsWithinCombatRange(Unit *obj, float dist2compare) const;
|
||||
bool IsWithinMeleeRange(Unit *obj) const;
|
||||
void GetRandomContactPoint( const Unit* target, float &x, float &y, float &z, float distance2dMin, float distance2dMax ) const;
|
||||
uint32 m_extraAttacks;
|
||||
bool m_canDualWield;
|
||||
@@ -810,7 +810,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
|
||||
Unit* getVictim() const { return m_attacking; }
|
||||
void CombatStop(bool cast = false);
|
||||
void CombatStopWithPets(bool cast = false);
|
||||
Unit* SelectNearbyTarget(float dist = ATTACK_DISTANCE) const;
|
||||
Unit* SelectNearbyTarget(float dist = NOMINAL_MELEE_RANGE) const;
|
||||
|
||||
void addUnitState(uint32 f) { m_state |= f; }
|
||||
bool hasUnitState(const uint32 f) const { return (m_state & f); }
|
||||
|
||||
+3
-3
@@ -477,11 +477,11 @@ void World::LoadConfigSettings(bool reload)
|
||||
sLog.outError("TargetPosRecalculateRange (%f) must be >= %f. Using %f instead.",rate_values[RATE_TARGET_POS_RECALCULATION_RANGE],CONTACT_DISTANCE,CONTACT_DISTANCE);
|
||||
rate_values[RATE_TARGET_POS_RECALCULATION_RANGE] = CONTACT_DISTANCE;
|
||||
}
|
||||
else if(rate_values[RATE_TARGET_POS_RECALCULATION_RANGE] > ATTACK_DISTANCE)
|
||||
else if(rate_values[RATE_TARGET_POS_RECALCULATION_RANGE] > NOMINAL_MELEE_RANGE)
|
||||
{
|
||||
sLog.outError("TargetPosRecalculateRange (%f) must be <= %f. Using %f instead.",
|
||||
rate_values[RATE_TARGET_POS_RECALCULATION_RANGE],ATTACK_DISTANCE,ATTACK_DISTANCE);
|
||||
rate_values[RATE_TARGET_POS_RECALCULATION_RANGE] = ATTACK_DISTANCE;
|
||||
rate_values[RATE_TARGET_POS_RECALCULATION_RANGE],NOMINAL_MELEE_RANGE,NOMINAL_MELEE_RANGE);
|
||||
rate_values[RATE_TARGET_POS_RECALCULATION_RANGE] = NOMINAL_MELEE_RANGE;
|
||||
}
|
||||
|
||||
rate_values[RATE_DURABILITY_LOSS_DAMAGE] = sConfig.GetFloatDefault("DurabilityLossChance.Damage",0.5f);
|
||||
|
||||
Reference in New Issue
Block a user