double F::DISTANCE::GetLineSegmentPointDistanceSq(const CLineSegment &_ls, const CVector &_p ) { CLine ln(_ls); double dist = GetLinePointDistance(ln,_p); if(F::INTERSECTION::PointProjectionOnLineSegment(_p, _ls)) return dist*dist; return F::MISC::Min(GetDistanceSq(_ls.a,_p), GetDistanceSq(_ls.b,_p)); }
SpellEntry const *Creature::reachWithSpellAttack(Unit *pVictim) { if(!pVictim) return NULL; for(uint32 i=0; i < CREATURE_MAX_SPELLS; i++) { if(!m_spells[i]) continue; SpellEntry const *spellInfo = sSpellStore.LookupEntry(m_spells[i] ); if(!spellInfo) { sLog.outError("WORLD: unknown spell id %i\n", m_spells[i]); continue; } bool bcontinue = true; for(uint32 j=0;j<3;j++) { if( (spellInfo->Effect[j] == SPELL_EFFECT_SCHOOL_DAMAGE ) || (spellInfo->Effect[j] == SPELL_EFFECT_INSTAKILL) || (spellInfo->Effect[j] == SPELL_EFFECT_ENVIRONMENTAL_DAMAGE) || (spellInfo->Effect[j] == SPELL_EFFECT_HEALTH_LEECH ) ) { bcontinue = false; break; } } if(bcontinue) continue; if(spellInfo->manaCost > GetPower(POWER_MANA)) continue; SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(spellInfo->rangeIndex); float range = GetMaxRange(srange); float minrange = GetMinRange(srange); float dist = GetDistanceSq(pVictim); //if(!isInFront( pVictim, range ) && spellInfo->AttributesEx ) // continue; if( dist > range * range || dist < minrange * minrange ) continue; if(m_silenced) continue; return spellInfo; } return NULL; }
void DynamicObject::DealWithSpellDamage(Unit &caster) { Modifier mod; mod.m_auraname = 3; mod.m_amount = m_PeriodicDamage; UnitList.clear(); MapManager::Instance().GetMap(m_mapId)->GetUnitList(GetPositionX(), GetPositionY(),UnitList); for(std::list<Unit*>::iterator iter=UnitList.begin();iter!=UnitList.end();iter++) { if((*iter)) { if((*iter)->isAlive()&& !(*iter)->isInFlight() ) { if(m_caster->IsFriendlyTo(*iter)) continue; if(GetDistanceSq(*iter) < m_PeriodicDamageRadius * m_PeriodicDamageRadius ) caster.PeriodicAuraLog((*iter),m_spell,&mod); } } } }
void DynamicObject::UpdateTargets() { if(m_aliveDuration == 0) return; if(m_aliveDuration >= 100) { FactionRangeList::iterator itr = m_inRangeOppFactions.begin(); FactionRangeList::iterator iend = m_inRangeOppFactions.end(); Unit * target; Aura * pAura; float radius = powf(m_floatValues[DYNAMICOBJECT_RADIUS], 2); while(itr != iend) { target = *itr; ++itr; // skip units already hit, their range will be tested later if(targets.find(target) != targets.end()) continue; if(GetDistanceSq(target) <= radius) { pAura = new Aura(m_spellProto, m_aliveDuration, u_caster, target); for(uint32 i = 0; i < 3; ++i) { if(m_spellProto->Effect[i] == 27) { pAura->AddMod(m_spellProto->EffectApplyAuraName[i], m_spellProto->EffectBasePoints[i]+1, m_spellProto->EffectMiscValue[i], i); } } target->AddAura(pAura); if(p_caster) p_caster->HandleProc(PROC_ON_CAST_SPECIFIC_SPELL | PROC_ON_CAST_SPELL,target, m_spellProto); // add to target list targets.insert(target); } } // loop the targets, check the range of all of them DynamicObjectList::iterator jtr = targets.begin(); DynamicObjectList::iterator jtr2; DynamicObjectList::iterator jend = targets.end(); while(jtr != jend) { target = *jtr; jtr2 = jtr; ++jtr; if(GetDistanceSq(target) > radius) { targets.erase(jtr2); target->RemoveAura(m_spellProto->Id); } } m_aliveDuration -= 100; } else { m_aliveDuration = 0; } if(m_aliveDuration == 0) { DynamicObjectList::iterator jtr = targets.begin(); DynamicObjectList::iterator jend = targets.end(); Unit * target; while(jtr != jend) { target = *jtr; ++jtr; target->RemoveAura(m_spellProto->Id); } Remove(); } }
void DynamicObject::UpdateTargets() { if(m_aliveDuration == 0) return; if(m_aliveDuration >= 100) { Unit* target; Aura* pAura; float radius = m_floatValues[ DYNAMICOBJECT_RADIUS ] * m_floatValues[ DYNAMICOBJECT_RADIUS ]; // Looking for targets in the Object set for(std::set< Object* >::iterator itr = m_objectsInRange.begin(); itr != m_objectsInRange.end(); ++itr) { Object* o = *itr; if(!o->IsUnit() || !TO< Unit* >(o)->isAlive()) continue; target = TO< Unit* >(o); if(!isAttackable(u_caster, target, !(m_spellProto->c_is_flags & SPELL_FLAG_IS_TARGETINGSTEALTHED))) continue; // skip units already hit, their range will be tested later if(targets.find(target->GetGUID()) != targets.end()) continue; if(GetDistanceSq(target) <= radius) { pAura = sSpellFactoryMgr.NewAura(m_spellProto, m_aliveDuration, u_caster, target, true); for(uint32 i = 0; i < 3; ++i) { if(m_spellProto->Effect[i] == SPELL_EFFECT_PERSISTENT_AREA_AURA) { pAura->AddMod(m_spellProto->EffectApplyAuraName[i], m_spellProto->EffectBasePoints[i] + 1, m_spellProto->EffectMiscValue[i], i); } } target->AddAura(pAura); if(p_caster) { p_caster->HandleProc(PROC_ON_CAST_SPECIFIC_SPELL | PROC_ON_CAST_SPELL, target, m_spellProto); p_caster->m_procCounter = 0; } // add to target list targets.insert(target->GetGUID()); } } // loop the targets, check the range of all of them DynamicObjectList::iterator jtr = targets.begin(); DynamicObjectList::iterator jtr2; DynamicObjectList::iterator jend = targets.end(); while(jtr != jend) { target = GetMapMgr() ? GetMapMgr()->GetUnit(*jtr) : NULL; jtr2 = jtr; ++jtr; if((target != NULL) && (GetDistanceSq(target) > radius)) { target->RemoveAura(m_spellProto->Id); targets.erase(jtr2); } } m_aliveDuration -= 100; } else { m_aliveDuration = 0; } if(m_aliveDuration == 0) { Remove(); } }
void DynamicObject::UpdateTargets() { if(m_aliveDuration == 0) return; if(m_aliveDuration >= 100) { std::set<Object*>::iterator itr = GetInRangeSetBegin(),itr2; std::set<Object*>::iterator iend = GetInRangeSetEnd(); Unit * target; Aura * pAura; float radius = m_floatValues[DYNAMICOBJECT_RADIUS]*m_floatValues[DYNAMICOBJECT_RADIUS]; this->AquireInrangeLock(); //make sure to release lock before exit function ! while(itr != iend) { // target = *itr; // ++itr; itr2 = itr; ++itr; if( !( (*itr2)->IsUnit() ) || ! static_cast< Unit* >( *itr2 )->isAlive() || ( static_cast< Creature* >( *itr2 )->IsTotem() && !static_cast< Unit* >( *itr2 )->IsPlayer() ) ) continue; target = static_cast< Unit* >( *itr2 ); if( !isAttackable( p_caster, target, !(m_spellProto->c_is_flags & SPELL_FLAG_IS_TARGETINGSTEALTHED) ) ) continue; // skip units already hit, their range will be tested later if(targets.find(target->GetGUID()) != targets.end()) continue; if(GetDistanceSq(target) <= radius) { pAura = AuraPool.PooledNew(); pAura->Init(m_spellProto, m_aliveDuration, u_caster, target, true); for(uint32 i = 0; i < 3; ++i) { if(m_spellProto->Effect[i] == SPELL_EFFECT_PERSISTENT_AREA_AURA) { pAura->AddMod(m_spellProto->EffectApplyAuraName[i], m_spellProto->EffectBasePoints[i]+1, m_spellProto->EffectMiscValue[i], i); } } target->AddAura(pAura, m_spellScript); if(p_caster) { p_caster->HandleProc(PROC_ON_CAST_SPECIFIC_SPELL | PROC_ON_CAST_SPELL,target, m_spellProto); p_caster->m_procCounter = 0; } // add to target list targets.insert(target->GetGUID()); } } this->ReleaseInrangeLock(); // loop the targets, check the range of all of them DynamicObjectList::iterator jtr = targets.begin(); DynamicObjectList::iterator jtr2; DynamicObjectList::iterator jend = targets.end(); while(jtr != jend) { target = GetMapMgr() ? GetMapMgr()->GetUnit(*jtr) : NULL; jtr2 = jtr; ++jtr; if(GetDistanceSq(target) > radius) { target->RemoveAura(m_spellProto->Id); targets.erase(jtr2); } } m_aliveDuration -= 100; } else { m_aliveDuration = 0; } if(m_aliveDuration == 0) { Remove(); } }
void DynamicObject::UpdateTargets() { if(m_aliveDuration == 0) return; if(m_aliveDuration >= 200) { Unit* target; float radius = m_floatValues[DYNAMICOBJECT_RADIUS]*m_floatValues[DYNAMICOBJECT_RADIUS]; Object::InRangeSet::iterator itr,itr2; for( itr = GetInRangeSetBegin(); itr != GetInRangeSetEnd(); itr++) { itr2 = itr; if( !( (*itr2)->IsUnit() ) || ! TO_UNIT( *itr2 )->isAlive() || ((*itr2)->GetTypeId()==TYPEID_UNIT && TO_CREATURE(*itr2)->IsTotem() ) ) continue; target = TO_UNIT( *itr2 ); if( !isAttackable( m_caster, target, !(m_spellProto->c_is_flags & SPELL_FLAG_IS_TARGETINGSTEALTHED) ) ) continue; // skip units already hit, their range will be tested later if(targets.find(target) != targets.end()) continue; if(GetDistanceSq(target) <= radius) { Aura* pAura(new Aura(m_spellProto, m_aliveDuration, m_caster, target)); for(uint32 i = 0; i < 3; ++i) { if(m_spellProto->Effect[i] == 27) { pAura->AddMod(m_spellProto->EffectApplyAuraName[i], m_spellProto->EffectBasePoints[i]+1, m_spellProto->EffectMiscValue[i], i); } } target->AddAura(pAura); if( m_caster->IsPlayer() ) { p_caster->HandleProc(PROC_ON_CAST_SPECIFIC_SPELL | PROC_ON_CAST_SPELL,target, m_spellProto); p_caster->m_procCounter = 0; } // add to target list targets.insert(target); } } // loop the targets, check the range of all of them DynamicObjectList::iterator jtr = targets.begin(); DynamicObjectList::iterator jtr2; DynamicObjectList::iterator jend = targets.end(); while(jtr != jend) { target = *jtr; jtr2 = jtr; ++jtr; if(GetDistanceSq(target) > radius) { targets.erase(jtr2); target->RemoveAura(m_spellProto->Id); } } m_aliveDuration -= 200; } else { m_aliveDuration = 0; } if(m_aliveDuration == 0) { DynamicObjectList::iterator jtr = targets.begin(); DynamicObjectList::iterator jend = targets.end(); Unit* target; while(jtr != jend) { target = *jtr; ++jtr; target->RemoveAura(m_spellProto->Id); } Remove(); } }
void GameObject::Update(uint32 p_time) { if(m_event_Instanceid != m_instanceId) { event_Relocate(); return; } if(!IsInWorld()) return; if(m_deleted) return; if(spell && (GetUInt32Value(GAMEOBJECT_STATE) == 1)) { if(checkrate > 1) { if(counter++%checkrate) return; } ObjectSet::iterator itr = GetInRangeSetBegin(); ObjectSet::iterator it2 = itr; ObjectSet::iterator iend = GetInRangeSetEnd(); Unit * pUnit; float dist; for(; it2 != iend;) { itr = it2; ++it2; dist = GetDistanceSq((*itr)); if( (*itr) != m_summoner && (*itr)->IsUnit() && dist <= range) { pUnit = static_cast<Unit*>(*itr); if(m_summonedGo) { if(!m_summoner) { ExpireAndDelete(); return; } if(!isAttackable(m_summoner,pUnit))continue; } Spell * sp=new Spell((Object*)this,spell,true,NULL); SpellCastTargets tgt((*itr)->GetGUID()); tgt.m_destX = GetPositionX(); tgt.m_destY = GetPositionY(); tgt.m_destZ = GetPositionZ(); sp->prepare(&tgt); if(m_summonedGo) { ExpireAndDelete(); return; } if(spell->EffectImplicitTargetA[0] == 16 || spell->EffectImplicitTargetB[0] == 16) return; // on area dont continue. } } } }
void GameObject::Update(uint32 p_time) { if(m_event_Instanceid != m_instanceId) { event_Relocate(); return; } if(!IsInWorld()) return; if(m_deleted) return; if(spell && (GetUInt32Value(GAMEOBJECT_STATE) == 1)) { if(checkrate > 1) { if(counter++%checkrate) return; } ObjectSet::iterator itr = GetInRangeSetBegin(); ObjectSet::iterator it2 = itr; ObjectSet::iterator iend = GetInRangeSetEnd(); Unit * pUnit; float dist; this->AquireInrangeLock(); //make sure to release lock before exit function ! for(; it2 != iend;) { itr = it2; ++it2; dist = GetDistanceSq((*itr)); if( (*itr) != m_summoner && (*itr)->IsUnit() && dist <= range) { pUnit = static_cast<Unit*>(*itr); if(m_summonedGo) { if(!m_summoner) { ExpireAndDelete(); return; } if(!isAttackable(m_summoner,pUnit))continue; } Spell * sp=SpellPool.PooledNew(); sp->Init((Object*)this,spell,true,NULL); SpellCastTargets tgt((*itr)->GetGUID()); tgt.m_destX = GetPositionX(); tgt.m_destY = GetPositionY(); tgt.m_destZ = GetPositionZ(); sp->prepare(&tgt); // proc on trap trigger if( pInfo->Type == GAMEOBJECT_TYPE_TRAP ) { if( m_summoner != NULL ) m_summoner->HandleProc( PROC_ON_TRAP_TRIGGER, pUnit, spell ); } if(m_summonedGo) { ExpireAndDelete(); this->ReleaseInrangeLock(); return; } if(spell->EffectImplicitTargetA[0] == 16 || spell->EffectImplicitTargetB[0] == 16) { this->ReleaseInrangeLock(); return; // on area dont continue. } } } this->ReleaseInrangeLock(); } }
bool F::DISTANCE::DistBetweenVecsBiggerThan(const CVector &_a,const CVector &_b, double _dist) { return GetDistanceSq(_a, _b) >= _dist*_dist; }
void GameObject::Update(uint32 p_time) { if(m_event_Instanceid != m_instanceId) { event_Relocate(); return; } if(!IsInWorld()) return; if(m_deleted) return; if(spell && (GetByte(GAMEOBJECT_BYTES_1, GAMEOBJECT_BYTES_STATE) == 1)) { if(checkrate > 1) { if(counter++%checkrate) return; } Object::InRangeSet::iterator itr,it2; Unit* pUnit; float dist; for( it2 = GetInRangeSetBegin(); it2 != GetInRangeSetEnd(); ++it2) { itr = it2; dist = GetDistanceSq((*itr)); if( (*itr) != m_summoner && (*itr)->IsUnit() && dist <= range) { pUnit = TO_UNIT(*itr); if(m_summonedGo) { if(!m_summoner) { ExpireAndDelete(); return; } if(!isAttackable(m_summoner,pUnit))continue; } Spell* sp= (new Spell(TO_OBJECT(this),spell,true,NULL)); SpellCastTargets tgt((*itr)->GetGUID()); tgt.m_destX = GetPositionX(); tgt.m_destY = GetPositionY(); tgt.m_destZ = GetPositionZ(); sp->prepare(&tgt); if(pInfo->Type == 6) { if(m_summoner != NULL) m_summoner->HandleProc(PROC_ON_TRAP_TRIGGER, pUnit, spell); } if(m_summonedGo) { ExpireAndDelete(); return; } if(spell->EffectImplicitTargetA[0] == 16 || spell->EffectImplicitTargetB[0] == 16) return; // on area dont continue. } } } }
void DynamicObject::UpdateTargets(uint32 p_time) { Unit* u_caster = NULL; if(GUID_HIPART(casterGuid) == HIGHGUID_TYPE_GAMEOBJECT) { GameObject* goCaster = GetMapMgr()->GetGameObject(casterGuid); if(goCaster == NULL || !goCaster->IsInWorld()) m_aliveDuration = 0; // Set alive duration to 0 else if(goCaster->m_summoner) u_caster = goCaster->m_summoner; } else { u_caster = GetMapMgr()->GetUnit(casterGuid); if(u_caster == NULL || !u_caster->IsInWorld()) m_aliveDuration = 0; // Set alive duration to 0 } // If we're a channelled spell, we are required to be the caster channel target if(m_spellProto->IsChannelSpell() && u_caster) { if(u_caster->GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT) != GetGUID()) m_aliveDuration = 0; } if(m_aliveDuration > 0) { if(m_aliveDuration < p_time) m_aliveDuration = 0; else m_aliveDuration -= p_time; } if(m_aliveDuration && u_caster) { Aura* pAura; Unit* target; float radius = m_floatValues[DYNAMICOBJECT_RADIUS] * m_floatValues[DYNAMICOBJECT_RADIUS]; // Looking for targets in the Object set for(std::unordered_set< Unit* >::iterator itr = m_unitsInRange.begin(); itr != m_unitsInRange.end(); ++itr) { target = *itr; if(!target->isAlive()) continue; if(!sFactionSystem.isAttackable(u_caster, target, !(m_spellProto->c_is_flags & SPELL_FLAG_IS_TARGETINGSTEALTHED))) continue; // skip units already hit, their range will be tested later if(targets.find(target->GetGUID()) != targets.end()) continue; if(GetDistanceSq(target) <= radius) { pAura = new Aura(m_spellProto, m_aliveDuration, u_caster, target); for(uint32 i = 0; i < 3; ++i) { if(m_spellProto->Effect[i] == SPELL_EFFECT_PERSISTENT_AREA_AURA) { pAura->AddMod(m_spellProto->EffectApplyAuraName[i], m_spellProto->EffectBasePoints[i]+1, m_spellProto->EffectMiscValue[i], i); } } target->AddAura(pAura); u_caster->HandleProc(PROC_ON_CAST_SPECIFIC_SPELL | PROC_ON_CAST_SPELL, NULL, target, m_spellProto); // add to target list targets.insert(target->GetGUID()); } } // loop the targets, check the range of all of them DynamicObjectList::iterator jtr = targets.begin(), jtr2, jend = targets.end(); while(jtr != jend) { jtr2 = jtr; ++jtr; target = GetMapMgr() ? GetMapMgr()->GetUnit(*jtr2) : NULL; if(target == NULL || GetDistanceSq(target) > radius) { if(target) target->RemoveAura(m_spellProto->Id); targets.erase(jtr2); } } } else { // call remove here Remove(); } }