mirror of
https://github.com/mangosfour/server.git
synced 2025-12-15 01:37:00 +00:00
[7450] Fixes and improvements in TARGET_BEHIND_VICTIM, SPELL_EFFECT_JUMP2, SPELL_EFFECT_TELEPORT_UNITS work.
* Move near teleport code for player/creature in Unit::NearTeleportTo * Allow correctly seelct target and end point orientation for script casted spells with TARGET_BEHIND_VICTIM * Replace use BuildTeleportAckMsg by BuildHeartBeatMsg for creature teleports. BuildTeleportAckMsg set active mover for targeted player to affected creature and "freeze" player.
This commit is contained in:
parent
571c56ff07
commit
3a5d59c0c7
5 changed files with 93 additions and 70 deletions
|
|
@ -426,6 +426,21 @@ void Spell::FillTargetMap()
|
||||||
// but need it support in some know cases
|
// but need it support in some know cases
|
||||||
switch(m_spellInfo->EffectImplicitTargetA[i])
|
switch(m_spellInfo->EffectImplicitTargetA[i])
|
||||||
{
|
{
|
||||||
|
case TARGET_SELF:
|
||||||
|
switch(m_spellInfo->EffectImplicitTargetB[i])
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
SetTargetMap(i,m_spellInfo->EffectImplicitTargetA[i],tmpUnitMap);
|
||||||
|
break;
|
||||||
|
case TARGET_BEHIND_VICTIM: // use B case that not dependent from from A in fact
|
||||||
|
SetTargetMap(i,m_spellInfo->EffectImplicitTargetB[i],tmpUnitMap);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SetTargetMap(i,m_spellInfo->EffectImplicitTargetA[i],tmpUnitMap);
|
||||||
|
SetTargetMap(i,m_spellInfo->EffectImplicitTargetB[i],tmpUnitMap);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case TARGET_CASTER_COORDINATES:
|
case TARGET_CASTER_COORDINATES:
|
||||||
// Note: this hack with search required until GO casting not implemented
|
// Note: this hack with search required until GO casting not implemented
|
||||||
// environment damage spells already have around enemies targeting but this not help in case not existed GO casting support
|
// environment damage spells already have around enemies targeting but this not help in case not existed GO casting support
|
||||||
|
|
@ -2051,8 +2066,15 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
|
||||||
}break;
|
}break;
|
||||||
case TARGET_BEHIND_VICTIM:
|
case TARGET_BEHIND_VICTIM:
|
||||||
{
|
{
|
||||||
Unit *pTarget = m_caster->getVictim();
|
Unit *pTarget = NULL;
|
||||||
if(!pTarget && m_caster->GetTypeId() == TYPEID_PLAYER)
|
|
||||||
|
// explicit cast data from client or server-side cast
|
||||||
|
// some spell at client send caster
|
||||||
|
if(m_targets.getUnitTarget() && m_targets.getUnitTarget()!=m_caster)
|
||||||
|
pTarget = m_targets.getUnitTarget();
|
||||||
|
else if(m_caster->getVictim())
|
||||||
|
pTarget = m_caster->getVictim();
|
||||||
|
else if(m_caster->GetTypeId() == TYPEID_PLAYER)
|
||||||
pTarget = ObjectAccessor::GetUnit(*m_caster, ((Player*)m_caster)->GetSelection());
|
pTarget = ObjectAccessor::GetUnit(*m_caster, ((Player*)m_caster)->GetSelection());
|
||||||
|
|
||||||
if(pTarget)
|
if(pTarget)
|
||||||
|
|
@ -2060,9 +2082,13 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
|
||||||
float _target_x, _target_y, _target_z;
|
float _target_x, _target_y, _target_z;
|
||||||
pTarget->GetClosePoint(_target_x, _target_y, _target_z, m_caster->GetObjectSize(), CONTACT_DISTANCE, M_PI);
|
pTarget->GetClosePoint(_target_x, _target_y, _target_z, m_caster->GetObjectSize(), CONTACT_DISTANCE, M_PI);
|
||||||
if(pTarget->IsWithinLOS(_target_x,_target_y,_target_z))
|
if(pTarget->IsWithinLOS(_target_x,_target_y,_target_z))
|
||||||
|
{
|
||||||
|
TagUnitMap.push_back(m_caster);
|
||||||
m_targets.setDestination(_target_x, _target_y, _target_z);
|
m_targets.setDestination(_target_x, _target_y, _target_z);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}break;
|
break;
|
||||||
|
}
|
||||||
case TARGET_DYNAMIC_OBJECT_COORDINATES:
|
case TARGET_DYNAMIC_OBJECT_COORDINATES:
|
||||||
{
|
{
|
||||||
// if parent spell create dynamic object extract area from it
|
// if parent spell create dynamic object extract area from it
|
||||||
|
|
|
||||||
|
|
@ -2009,39 +2009,41 @@ void Spell::EffectJump(uint32 i)
|
||||||
x = m_targets.m_destX;
|
x = m_targets.m_destX;
|
||||||
y = m_targets.m_destY;
|
y = m_targets.m_destY;
|
||||||
z = m_targets.m_destZ;
|
z = m_targets.m_destZ;
|
||||||
o = m_caster->GetOrientation();
|
|
||||||
|
if(m_spellInfo->EffectImplicitTargetA[i] == TARGET_BEHIND_VICTIM)
|
||||||
|
{
|
||||||
|
// explicit cast data from client or server-side cast
|
||||||
|
// some spell at client send caster
|
||||||
|
Unit* pTarget = NULL;
|
||||||
|
if(m_targets.getUnitTarget() && m_targets.getUnitTarget()!=m_caster)
|
||||||
|
pTarget = m_targets.getUnitTarget();
|
||||||
|
else if(unitTarget->getVictim())
|
||||||
|
pTarget = m_caster->getVictim();
|
||||||
|
else if(m_caster->GetTypeId() == TYPEID_PLAYER)
|
||||||
|
pTarget = ObjectAccessor::GetUnit(*m_caster, ((Player*)m_caster)->GetSelection());
|
||||||
|
|
||||||
|
o = pTarget ? pTarget->GetOrientation() : m_caster->GetOrientation();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
o = m_caster->GetOrientation();
|
||||||
}
|
}
|
||||||
else if(unitTarget)
|
else if(unitTarget)
|
||||||
{
|
{
|
||||||
x = unitTarget->GetPositionX();
|
unitTarget->GetContactPoint(m_caster,x,y,z,CONTACT_DISTANCE);
|
||||||
y = unitTarget->GetPositionY();
|
o = m_caster->GetOrientation();
|
||||||
z = unitTarget->GetPositionZ();
|
|
||||||
o = m_spellInfo->EffectImplicitTargetA[i] == TARGET_BEHIND_VICTIM
|
|
||||||
? unitTarget->GetOrientation()
|
|
||||||
: m_caster->GetOrientation();
|
|
||||||
}
|
}
|
||||||
else if(gameObjTarget)
|
else if(gameObjTarget)
|
||||||
{
|
{
|
||||||
x = gameObjTarget->GetPositionX();
|
gameObjTarget->GetContactPoint(m_caster,x,y,z,CONTACT_DISTANCE);
|
||||||
y = gameObjTarget->GetPositionY();
|
|
||||||
z = gameObjTarget->GetPositionZ();
|
|
||||||
o = m_caster->GetOrientation();
|
o = m_caster->GetOrientation();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
|
||||||
// Teleport
|
|
||||||
if(m_caster->GetTypeId() == TYPEID_PLAYER)
|
|
||||||
((Player*)m_caster)->TeleportTo(m_caster->GetMapId(), x, y, z, o,
|
|
||||||
TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET | (unitTarget==m_caster ? TELE_TO_SPELL : 0));
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_caster->GetMap()->CreatureRelocation((Creature*)m_caster, x, y, z, o);
|
sLog.outError( "Spell::EffectJump - unsupported target mode for spell ID %u", m_spellInfo->Id );
|
||||||
WorldPacket data;
|
return;
|
||||||
m_caster->BuildTeleportAckMsg(&data, x, y, z, o);
|
|
||||||
m_caster->SendMessageToSet(&data, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_caster->NearTeleportTo(x,y,z,o,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Spell::EffectTeleportUnits(uint32 i)
|
void Spell::EffectTeleportUnits(uint32 i)
|
||||||
|
|
@ -2062,45 +2064,38 @@ void Spell::EffectTeleportUnits(uint32 i)
|
||||||
}
|
}
|
||||||
case TARGET_TABLE_X_Y_Z_COORDINATES:
|
case TARGET_TABLE_X_Y_Z_COORDINATES:
|
||||||
{
|
{
|
||||||
// TODO: Only players can teleport?
|
|
||||||
if (unitTarget->GetTypeId() != TYPEID_PLAYER)
|
|
||||||
return;
|
|
||||||
SpellTargetPosition const* st = spellmgr.GetSpellTargetPosition(m_spellInfo->Id);
|
SpellTargetPosition const* st = spellmgr.GetSpellTargetPosition(m_spellInfo->Id);
|
||||||
if(!st)
|
if(!st)
|
||||||
{
|
{
|
||||||
sLog.outError( "Spell::EffectTeleportUnits - unknown Teleport coordinates for spell ID %u", m_spellInfo->Id );
|
sLog.outError( "Spell::EffectTeleportUnits - unknown Teleport coordinates for spell ID %u", m_spellInfo->Id );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
((Player*)unitTarget)->TeleportTo(st->target_mapId,st->target_X,st->target_Y,st->target_Z,st->target_Orientation,unitTarget==m_caster ? TELE_TO_SPELL : 0);
|
|
||||||
|
if(st->target_mapId==unitTarget->GetMapId())
|
||||||
|
unitTarget->NearTeleportTo(st->target_X,st->target_Y,st->target_Z,st->target_Orientation,unitTarget==m_caster);
|
||||||
|
else if(unitTarget->GetTypeId()==TYPEID_PLAYER)
|
||||||
|
((Player*)unitTarget)->TeleportTo(st->target_mapId,st->target_X,st->target_Y,st->target_Z,st->target_Orientation,unitTarget==m_caster ? TELE_TO_SPELL : 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TARGET_BEHIND_VICTIM:
|
case TARGET_BEHIND_VICTIM:
|
||||||
{
|
{
|
||||||
// Get selected target for player (or victim for units)
|
|
||||||
Unit *pTarget = NULL;
|
Unit *pTarget = NULL;
|
||||||
if(m_caster->GetTypeId() == TYPEID_PLAYER)
|
|
||||||
pTarget = ObjectAccessor::GetUnit(*m_caster, ((Player*)m_caster)->GetSelection());
|
// explicit cast data from client or server-side cast
|
||||||
else
|
// some spell at client send caster
|
||||||
pTarget = m_caster->getVictim();
|
if(m_targets.getUnitTarget() && m_targets.getUnitTarget()!=unitTarget)
|
||||||
// No target present - return
|
pTarget = m_targets.getUnitTarget();
|
||||||
if (!pTarget)
|
else if(unitTarget->getVictim())
|
||||||
return;
|
pTarget = unitTarget->getVictim();
|
||||||
|
else if(unitTarget->GetTypeId() == TYPEID_PLAYER)
|
||||||
|
pTarget = ObjectAccessor::GetUnit(*unitTarget, ((Player*)unitTarget)->GetSelection());
|
||||||
|
|
||||||
// Init dest coordinates
|
// Init dest coordinates
|
||||||
uint32 mapid = m_caster->GetMapId();
|
|
||||||
float x = m_targets.m_destX;
|
float x = m_targets.m_destX;
|
||||||
float y = m_targets.m_destY;
|
float y = m_targets.m_destY;
|
||||||
float z = m_targets.m_destZ;
|
float z = m_targets.m_destZ;
|
||||||
float orientation = pTarget->GetOrientation();
|
float orientation = pTarget ? pTarget->GetOrientation() : unitTarget->GetOrientation();
|
||||||
// Teleport
|
unitTarget->NearTeleportTo(x,y,z,orientation,unitTarget==m_caster);
|
||||||
if(unitTarget->GetTypeId() == TYPEID_PLAYER)
|
|
||||||
((Player*)unitTarget)->TeleportTo(mapid, x, y, z, orientation, TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET | (unitTarget==m_caster ? TELE_TO_SPELL : 0));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_caster->GetMap()->CreatureRelocation((Creature*)unitTarget, x, y, z, orientation);
|
|
||||||
WorldPacket data;
|
|
||||||
unitTarget->BuildTeleportAckMsg(&data, x, y, z, orientation);
|
|
||||||
unitTarget->SendMessageToSet(&data, false);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
@ -2118,15 +2113,7 @@ void Spell::EffectTeleportUnits(uint32 i)
|
||||||
float z = m_targets.m_destZ;
|
float z = m_targets.m_destZ;
|
||||||
float orientation = unitTarget->GetOrientation();
|
float orientation = unitTarget->GetOrientation();
|
||||||
// Teleport
|
// Teleport
|
||||||
if(unitTarget->GetTypeId() == TYPEID_PLAYER)
|
unitTarget->NearTeleportTo(x,y,z,orientation,unitTarget==m_caster);
|
||||||
((Player*)unitTarget)->TeleportTo(mapid, x, y, z, orientation, TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET | (unitTarget==m_caster ? TELE_TO_SPELL : 0));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_caster->GetMap()->CreatureRelocation((Creature*)unitTarget, x, y, z, orientation);
|
|
||||||
WorldPacket data;
|
|
||||||
unitTarget->BuildTeleportAckMsg(&data, x, y, z, orientation);
|
|
||||||
unitTarget->SendMessageToSet(&data, false);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3787,16 +3774,12 @@ void Spell::EffectTeleUnitsFaceCaster(uint32 i)
|
||||||
if(unitTarget->isInFlight())
|
if(unitTarget->isInFlight())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint32 mapid = m_caster->GetMapId();
|
|
||||||
float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
|
float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
|
||||||
|
|
||||||
float fx,fy,fz;
|
float fx,fy,fz;
|
||||||
m_caster->GetClosePoint(fx,fy,fz,unitTarget->GetObjectSize(),dis);
|
m_caster->GetClosePoint(fx,fy,fz,unitTarget->GetObjectSize(),dis);
|
||||||
|
|
||||||
if(unitTarget->GetTypeId() == TYPEID_PLAYER)
|
unitTarget->NearTeleportTo(fx,fy,fz,-m_caster->GetOrientation(),unitTarget==m_caster);
|
||||||
((Player*)unitTarget)->TeleportTo(mapid, fx, fy, fz, -m_caster->GetOrientation(), TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET | (unitTarget==m_caster ? TELE_TO_SPELL : 0));
|
|
||||||
else
|
|
||||||
m_caster->GetMap()->CreatureRelocation((Creature*)m_caster, fx, fy, fz, -m_caster->GetOrientation());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Spell::EffectLearnSkill(uint32 i)
|
void Spell::EffectLearnSkill(uint32 i)
|
||||||
|
|
@ -5800,7 +5783,6 @@ void Spell::EffectMomentMove(uint32 i)
|
||||||
|
|
||||||
if( m_spellInfo->rangeIndex== 1) //self range
|
if( m_spellInfo->rangeIndex== 1) //self range
|
||||||
{
|
{
|
||||||
uint32 mapid = m_caster->GetMapId();
|
|
||||||
float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
|
float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
|
||||||
|
|
||||||
// before caster
|
// before caster
|
||||||
|
|
@ -5810,7 +5792,7 @@ void Spell::EffectMomentMove(uint32 i)
|
||||||
unitTarget->GetPosition(ox,oy,oz);
|
unitTarget->GetPosition(ox,oy,oz);
|
||||||
|
|
||||||
float fx2,fy2,fz2; // getObjectHitPos overwrite last args in any result case
|
float fx2,fy2,fz2; // getObjectHitPos overwrite last args in any result case
|
||||||
if(VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(mapid, ox,oy,oz+0.5, fx,fy,oz+0.5,fx2,fy2,fz2, -0.5))
|
if(VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(unitTarget->GetMapId(), ox,oy,oz+0.5, fx,fy,oz+0.5,fx2,fy2,fz2, -0.5))
|
||||||
{
|
{
|
||||||
fx = fx2;
|
fx = fx2;
|
||||||
fy = fy2;
|
fy = fy2;
|
||||||
|
|
@ -5818,10 +5800,7 @@ void Spell::EffectMomentMove(uint32 i)
|
||||||
unitTarget->UpdateGroundPositionZ(fx,fy,fz);
|
unitTarget->UpdateGroundPositionZ(fx,fy,fz);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(unitTarget->GetTypeId() == TYPEID_PLAYER)
|
unitTarget->NearTeleportTo(fx, fy, fz, unitTarget->GetOrientation(),unitTarget==m_caster);
|
||||||
((Player*)unitTarget)->TeleportTo(mapid, fx, fy, fz, unitTarget->GetOrientation(), TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET | (unitTarget==m_caster ? TELE_TO_SPELL : 0));
|
|
||||||
else
|
|
||||||
m_caster->GetMap()->CreatureRelocation((Creature*)unitTarget, fx, fy, fz, unitTarget->GetOrientation());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11373,3 +11373,19 @@ void Unit::SetPhaseMask(uint32 newPhaseMask, bool update)
|
||||||
if(Pet* pet = GetPet())
|
if(Pet* pet = GetPet())
|
||||||
pet->SetPhaseMask(newPhaseMask,true);
|
pet->SetPhaseMask(newPhaseMask,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Unit::NearTeleportTo( float x, float y, float z, float orientation, bool casting /*= false*/ )
|
||||||
|
{
|
||||||
|
if(GetTypeId() == TYPEID_PLAYER)
|
||||||
|
((Player*)this)->TeleportTo(GetMapId(), x, y, z, orientation, TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET | (casting ? TELE_TO_SPELL : 0));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GetMap()->CreatureRelocation((Creature*)this, x, y, z, orientation);
|
||||||
|
|
||||||
|
WorldPacket data;
|
||||||
|
// Work strange for many spells: triggered active mover set for targeted player to creature
|
||||||
|
//BuildTeleportAckMsg(&data, x, y, z, orientation);
|
||||||
|
BuildHeartBeatMsg(&data);
|
||||||
|
SendMessageToSet(&data, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1066,6 +1066,8 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
|
||||||
void SendSpellNonMeleeDamageLog(Unit *target,uint32 SpellID,uint32 Damage, SpellSchoolMask damageSchoolMask,uint32 AbsorbedDamage, uint32 Resist,bool PhysicalDamage, uint32 Blocked, bool CriticalHit = false);
|
void SendSpellNonMeleeDamageLog(Unit *target,uint32 SpellID,uint32 Damage, SpellSchoolMask damageSchoolMask,uint32 AbsorbedDamage, uint32 Resist,bool PhysicalDamage, uint32 Blocked, bool CriticalHit = false);
|
||||||
void SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo);
|
void SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo);
|
||||||
|
|
||||||
|
void NearTeleportTo(float x, float y, float z, float orientation, bool casting = false);
|
||||||
|
|
||||||
void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, uint32 MovementFlags, uint32 Time, Player* player = NULL);
|
void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, uint32 MovementFlags, uint32 Time, Player* player = NULL);
|
||||||
void SendMonsterMoveByPath(Path const& path, uint32 start, uint32 end, uint32 MovementFlags);
|
void SendMonsterMoveByPath(Path const& path, uint32 start, uint32 end, uint32 MovementFlags);
|
||||||
void SendMonsterMoveWithSpeed(float x, float y, float z, uint32 transitTime = 0, Player* player = NULL);
|
void SendMonsterMoveWithSpeed(float x, float y, float z, uint32 transitTime = 0, Player* player = NULL);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "7449"
|
#define REVISION_NR "7450"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue