@@ -8316,7 +8316,7 @@ void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32
|
||||
}
|
||||
}
|
||||
|
||||
void Player::CastItemUseSpell(Item* item, SpellCastTargets const& targets, uint8 cast_count, uint32 glyphIndex)
|
||||
void Player::CastItemUseSpell(Item* item, SpellCastTargets const& targets, uint8 castCount, uint32 misc)
|
||||
{
|
||||
ItemTemplate const* proto = item->GetTemplate();
|
||||
// special learning case
|
||||
@@ -8337,7 +8337,7 @@ void Player::CastItemUseSpell(Item* item, SpellCastTargets const& targets, uint8
|
||||
|
||||
Spell* spell = new Spell(this, spellInfo, TRIGGERED_NONE);
|
||||
spell->m_CastItem = item;
|
||||
spell->m_cast_count = cast_count; //set count of casts
|
||||
spell->m_cast_count = castCount; //set count of casts
|
||||
spell->SetSpellValue(SPELLVALUE_BASE_POINT0, learning_spell_id);
|
||||
spell->prepare(&targets);
|
||||
return;
|
||||
@@ -8365,8 +8365,8 @@ void Player::CastItemUseSpell(Item* item, SpellCastTargets const& targets, uint8
|
||||
|
||||
Spell* spell = new Spell(this, spellInfo, (count > 0) ? TRIGGERED_FULL_MASK : TRIGGERED_NONE);
|
||||
spell->m_CastItem = item;
|
||||
spell->m_cast_count = cast_count; // set count of casts
|
||||
spell->m_misc.Data = glyphIndex; // glyph index
|
||||
spell->m_cast_count = castCount; // set count of casts
|
||||
spell->m_misc.Data = misc;
|
||||
spell->prepare(&targets);
|
||||
|
||||
++count;
|
||||
@@ -8393,8 +8393,8 @@ void Player::CastItemUseSpell(Item* item, SpellCastTargets const& targets, uint8
|
||||
|
||||
Spell* spell = new Spell(this, spellInfo, (count > 0) ? TRIGGERED_FULL_MASK : TRIGGERED_NONE);
|
||||
spell->m_CastItem = item;
|
||||
spell->m_cast_count = cast_count; // set count of casts
|
||||
spell->m_misc.Data = glyphIndex; // glyph index
|
||||
spell->m_cast_count = castCount; // set count of casts
|
||||
spell->m_misc.Data = misc; // glyph index
|
||||
spell->prepare(&targets);
|
||||
|
||||
++count;
|
||||
|
||||
@@ -2313,7 +2313,7 @@ class Player : public Unit, public GridObject<Player>
|
||||
void ApplyEquipSpell(SpellInfo const* spellInfo, Item* item, bool apply, bool form_change = false);
|
||||
void UpdateEquipSpellsAtFormChange();
|
||||
void CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32 procVictim, uint32 procEx);
|
||||
void CastItemUseSpell(Item* item, SpellCastTargets const& targets, uint8 cast_count, uint32 glyphIndex);
|
||||
void CastItemUseSpell(Item* item, SpellCastTargets const& targets, uint8 castCount, uint32 misc);
|
||||
void CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32 procVictim, uint32 procEx, Item* item, ItemTemplate const* proto);
|
||||
|
||||
void SendEquipmentSetList();
|
||||
|
||||
@@ -1578,12 +1578,12 @@ void WorldSession::HandleUpdateMissileTrajectory(WorldPacket& recvPacket)
|
||||
|
||||
ObjectGuid guid;
|
||||
uint32 spellId;
|
||||
float elevation, speed;
|
||||
float pitch, speed;
|
||||
float curX, curY, curZ;
|
||||
float targetX, targetY, targetZ;
|
||||
uint8 moveStop;
|
||||
|
||||
recvPacket >> guid >> spellId >> elevation >> speed;
|
||||
recvPacket >> guid >> spellId >> pitch >> speed;
|
||||
recvPacket >> curX >> curY >> curZ;
|
||||
recvPacket >> targetX >> targetY >> targetZ;
|
||||
recvPacket >> moveStop;
|
||||
@@ -1604,7 +1604,7 @@ void WorldSession::HandleUpdateMissileTrajectory(WorldPacket& recvPacket)
|
||||
pos.Relocate(targetX, targetY, targetZ);
|
||||
spell->m_targets.ModDst(pos);
|
||||
|
||||
spell->m_targets.SetElevation(elevation);
|
||||
spell->m_targets.SetPitch(pitch);
|
||||
spell->m_targets.SetSpeed(speed);
|
||||
|
||||
if (moveStop)
|
||||
|
||||
@@ -38,121 +38,63 @@
|
||||
#include "SpellPackets.h"
|
||||
#include "GameObjectPackets.h"
|
||||
|
||||
void WorldSession::HandleClientCastFlags(WorldPacket& recvPacket, uint8 castFlags, SpellCastTargets& targets)
|
||||
void WorldSession::HandleUseItemOpcode(WorldPackets::Spells::UseItem& packet)
|
||||
{
|
||||
// some spell cast packet including more data (for projectiles?)
|
||||
if (castFlags & 0x02)
|
||||
{
|
||||
// not sure about these two
|
||||
float elevation, speed;
|
||||
recvPacket >> elevation;
|
||||
recvPacket >> speed;
|
||||
|
||||
targets.SetElevation(elevation);
|
||||
targets.SetSpeed(speed);
|
||||
|
||||
uint8 hasMovementData;
|
||||
recvPacket >> hasMovementData;
|
||||
//if (hasMovementData)
|
||||
// HandleMovementOpcodes(recvPacket);
|
||||
}
|
||||
else if (castFlags & 0x8) // Archaeology
|
||||
{
|
||||
uint32 count, entry, usedCount;
|
||||
uint8 type;
|
||||
recvPacket >> count;
|
||||
for (uint32 i = 0; i < count; ++i)
|
||||
{
|
||||
recvPacket >> type;
|
||||
switch (type)
|
||||
{
|
||||
case 2: // Keystones
|
||||
recvPacket >> entry; // Item id
|
||||
recvPacket >> usedCount; // Item count
|
||||
break;
|
||||
case 1: // Fragments
|
||||
recvPacket >> entry; // Currency id
|
||||
recvPacket >> usedCount; // Currency count
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
|
||||
{
|
||||
/// @todo add targets.read() check
|
||||
Player* pUser = _player;
|
||||
Player* user = _player;
|
||||
|
||||
// ignore for remote control state
|
||||
if (pUser->m_mover != pUser)
|
||||
if (user->m_mover != user)
|
||||
return;
|
||||
|
||||
uint8 bagIndex, slot, castFlags;
|
||||
uint8 castCount; // next cast if exists (single or not)
|
||||
ObjectGuid itemGUID;
|
||||
uint32 glyphIndex; // something to do with glyphs?
|
||||
uint32 spellId; // cast spell id
|
||||
|
||||
recvPacket >> bagIndex >> slot >> castCount >> spellId >> itemGUID >> glyphIndex >> castFlags;
|
||||
|
||||
if (glyphIndex >= MAX_GLYPH_SLOT_INDEX)
|
||||
Item* item = user->GetUseableItemByPos(packet.PackSlot, packet.Slot);
|
||||
if (!item)
|
||||
{
|
||||
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL);
|
||||
user->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
Item* pItem = pUser->GetUseableItemByPos(bagIndex, slot);
|
||||
if (!pItem)
|
||||
if (item->GetGUID() != packet.CastItem)
|
||||
{
|
||||
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL);
|
||||
user->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pItem->GetGUID() != itemGUID)
|
||||
{
|
||||
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
TC_LOG_DEBUG("network", "WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, castCount: %u, spellId: %u, Item: %u, glyphIndex: %u, data length = %i", bagIndex, slot, castCount, spellId, pItem->GetEntry(), glyphIndex, (uint32)recvPacket.size());
|
||||
|
||||
ItemTemplate const* proto = pItem->GetTemplate();
|
||||
ItemTemplate const* proto = item->GetTemplate();
|
||||
if (!proto)
|
||||
{
|
||||
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, NULL);
|
||||
user->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, item, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
// some item classes can be used only in equipped state
|
||||
if (proto->GetInventoryType() != INVTYPE_NON_EQUIP && !pItem->IsEquipped())
|
||||
if (proto->GetInventoryType() != INVTYPE_NON_EQUIP && !item->IsEquipped())
|
||||
{
|
||||
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, NULL);
|
||||
user->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, item, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
InventoryResult msg = pUser->CanUseItem(pItem);
|
||||
InventoryResult msg = user->CanUseItem(item);
|
||||
if (msg != EQUIP_ERR_OK)
|
||||
{
|
||||
pUser->SendEquipError(msg, pItem, NULL);
|
||||
user->SendEquipError(msg, item, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
// only allow conjured consumable, bandage, poisons (all should have the 2^21 item flag set in DB)
|
||||
if (proto->GetClass() == ITEM_CLASS_CONSUMABLE && !(proto->GetFlags() & ITEM_PROTO_FLAG_USEABLE_IN_ARENA) && pUser->InArena())
|
||||
if (proto->GetClass() == ITEM_CLASS_CONSUMABLE && !(proto->GetFlags() & ITEM_PROTO_FLAG_USEABLE_IN_ARENA) && user->InArena())
|
||||
{
|
||||
pUser->SendEquipError(EQUIP_ERR_NOT_DURING_ARENA_MATCH, pItem, NULL);
|
||||
user->SendEquipError(EQUIP_ERR_NOT_DURING_ARENA_MATCH, item, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
// don't allow items banned in arena
|
||||
if (proto->GetFlags() & ITEM_PROTO_FLAG_NOT_USEABLE_IN_ARENA && pUser->InArena())
|
||||
if (proto->GetFlags() & ITEM_PROTO_FLAG_NOT_USEABLE_IN_ARENA && user->InArena())
|
||||
{
|
||||
pUser->SendEquipError(EQUIP_ERR_NOT_DURING_ARENA_MATCH, pItem, NULL);
|
||||
user->SendEquipError(EQUIP_ERR_NOT_DURING_ARENA_MATCH, item, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pUser->IsInCombat())
|
||||
if (user->IsInCombat())
|
||||
{
|
||||
for (uint32 i = 0; i < proto->Effects.size(); ++i)
|
||||
{
|
||||
@@ -160,7 +102,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
|
||||
{
|
||||
if (!spellInfo->CanBeUsedInCombat())
|
||||
{
|
||||
pUser->SendEquipError(EQUIP_ERR_NOT_IN_COMBAT, pItem, NULL);
|
||||
user->SendEquipError(EQUIP_ERR_NOT_IN_COMBAT, item, NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -168,24 +110,22 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
|
||||
}
|
||||
|
||||
// check also BIND_WHEN_PICKED_UP and BIND_QUEST_ITEM for .additem or .additemset case by GM (not binded at adding to inventory)
|
||||
if (pItem->GetTemplate()->GetBonding() == BIND_WHEN_USE || pItem->GetTemplate()->GetBonding() == BIND_WHEN_PICKED_UP || pItem->GetTemplate()->GetBonding() == BIND_QUEST_ITEM)
|
||||
if (item->GetTemplate()->GetBonding() == BIND_WHEN_USE || item->GetTemplate()->GetBonding() == BIND_WHEN_PICKED_UP || item->GetTemplate()->GetBonding() == BIND_QUEST_ITEM)
|
||||
{
|
||||
if (!pItem->IsSoulBound())
|
||||
if (!item->IsSoulBound())
|
||||
{
|
||||
pItem->SetState(ITEM_CHANGED, pUser);
|
||||
pItem->SetBinding(true);
|
||||
item->SetState(ITEM_CHANGED, user);
|
||||
item->SetBinding(true);
|
||||
}
|
||||
}
|
||||
|
||||
SpellCastTargets targets;
|
||||
targets.Read(recvPacket, pUser);
|
||||
HandleClientCastFlags(recvPacket, castFlags, targets);
|
||||
SpellCastTargets targets(user, packet.Cast);
|
||||
|
||||
// Note: If script stop casting it must send appropriate data to client to prevent stuck item in gray state.
|
||||
if (!sScriptMgr->OnItemUse(pUser, pItem, targets))
|
||||
if (!sScriptMgr->OnItemUse(user, item, targets))
|
||||
{
|
||||
// no script or script not process request by self
|
||||
pUser->CastItemUseSpell(pItem, targets, castCount, glyphIndex);
|
||||
user->CastItemUseSpell(item, targets, packet.Cast.CastID, packet.Cast.Misc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -366,7 +306,7 @@ void WorldSession::HandleCastSpellOpcode(WorldPackets::Spells::CastSpell& cast)
|
||||
return;
|
||||
|
||||
// client provided targets
|
||||
SpellCastTargets targets(caster, cast.Cast.Target);
|
||||
SpellCastTargets targets(caster, cast.Cast);
|
||||
|
||||
// auto-selection buff level base at target level (in spellInfo)
|
||||
if (targets.GetUnitTarget())
|
||||
|
||||
@@ -223,6 +223,15 @@ void WorldPackets::Spells::PetCastSpell::Read()
|
||||
_worldPacket >> Cast;
|
||||
}
|
||||
|
||||
|
||||
void WorldPackets::Spells::UseItem::Read()
|
||||
{
|
||||
_worldPacket >> PackSlot;
|
||||
_worldPacket >> Slot;
|
||||
_worldPacket >> CastItem;
|
||||
_worldPacket >> Cast;
|
||||
}
|
||||
|
||||
ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::TargetLocation const& targetLocation)
|
||||
{
|
||||
data << targetLocation.Transport;
|
||||
|
||||
@@ -188,8 +188,8 @@ namespace WorldPackets
|
||||
struct SpellCastRequest
|
||||
{
|
||||
uint8 CastID = 0;
|
||||
uint32 SpellID = 0;
|
||||
uint32 Misc = 0;
|
||||
int32 SpellID = 0;
|
||||
int32 Misc = 0;
|
||||
uint8 SendCastFlags = 0;
|
||||
SpellTargetData Target;
|
||||
MissileTrajectoryRequest MissileTrajectory;
|
||||
@@ -201,7 +201,6 @@ namespace WorldPackets
|
||||
class CastSpell final : public ClientPacket
|
||||
{
|
||||
public:
|
||||
|
||||
CastSpell(WorldPacket&& packet) : ClientPacket(CMSG_CAST_SPELL, std::move(packet)) { }
|
||||
|
||||
void Read() override;
|
||||
@@ -212,7 +211,6 @@ namespace WorldPackets
|
||||
class PetCastSpell final : public ClientPacket
|
||||
{
|
||||
public:
|
||||
|
||||
PetCastSpell(WorldPacket&& packet) : ClientPacket(CMSG_PET_CAST_SPELL, std::move(packet)) { }
|
||||
|
||||
void Read() override;
|
||||
@@ -221,6 +219,19 @@ namespace WorldPackets
|
||||
SpellCastRequest Cast;
|
||||
};
|
||||
|
||||
class UseItem final : public ClientPacket
|
||||
{
|
||||
public:
|
||||
UseItem(WorldPacket&& packet) : ClientPacket(CMSG_USE_ITEM, std::move(packet)) { }
|
||||
|
||||
void Read() override;
|
||||
|
||||
uint8 PackSlot;
|
||||
uint8 Slot;
|
||||
ObjectGuid CastItem;
|
||||
SpellCastRequest Cast;
|
||||
};
|
||||
|
||||
struct SpellMissStatus
|
||||
{
|
||||
uint8 Reason = 0;
|
||||
|
||||
@@ -886,7 +886,7 @@ void OpcodeTable::Initialize()
|
||||
DEFINE_OPCODE_HANDLER_OLD(CMSG_USED_FOLLOW, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
|
||||
DEFINE_OPCODE_HANDLER_OLD(CMSG_USE_CRITTER_ITEM, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
|
||||
DEFINE_OPCODE_HANDLER_OLD(CMSG_USE_EQUIPMENT_SET, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleEquipmentSetUse );
|
||||
DEFINE_OPCODE_HANDLER_OLD(CMSG_USE_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleUseItemOpcode );
|
||||
DEFINE_HANDLER(CMSG_USE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Spells::UseItem, &WorldSession::HandleUseItemOpcode);
|
||||
DEFINE_OPCODE_HANDLER_OLD(CMSG_USE_TOY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
|
||||
DEFINE_HANDLER(CMSG_VIOLENCE_LEVEL, STATUS_AUTHED, PROCESS_INPLACE, WorldPackets::Misc::ViolenceLevel, &WorldSession::HandleViolenceLevel);
|
||||
DEFINE_OPCODE_HANDLER_OLD(CMSG_VOICE_ADD_IGNORE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
|
||||
|
||||
@@ -281,6 +281,7 @@ namespace WorldPackets
|
||||
class CancelAura;
|
||||
class CastSpell;
|
||||
class PetCastSpell;
|
||||
class UseItem;
|
||||
class SetActionButton;
|
||||
}
|
||||
|
||||
@@ -997,7 +998,7 @@ class WorldSession
|
||||
void HandleAttackStopOpcode(WorldPackets::Combat::AttackStop& packet);
|
||||
void HandleSetSheathedOpcode(WorldPacket& recvPacket);
|
||||
|
||||
void HandleUseItemOpcode(WorldPacket& recvPacket);
|
||||
void HandleUseItemOpcode(WorldPackets::Spells::UseItem& packet);
|
||||
void HandleOpenItemOpcode(WorldPacket& recvPacket);
|
||||
void HandleCastSpellOpcode(WorldPackets::Spells::CastSpell& castRequest);
|
||||
void HandleCancelCastOpcode(WorldPacket& recvPacket);
|
||||
|
||||
@@ -110,43 +110,46 @@ void SpellDestination::RelocateOffset(Position const& offset)
|
||||
}
|
||||
|
||||
SpellCastTargets::SpellCastTargets() : m_targetMask(0), m_objectTarget(nullptr), m_itemTarget(nullptr),
|
||||
m_itemTargetEntry(0), m_elevation(0.0f), m_speed(0.0f)
|
||||
m_itemTargetEntry(0), m_pitch(0.0f), m_speed(0.0f)
|
||||
{
|
||||
}
|
||||
|
||||
SpellCastTargets::SpellCastTargets(Unit* caster, WorldPackets::Spells::SpellTargetData const& spellTargetData) :
|
||||
m_targetMask(spellTargetData.Flags), m_objectTarget(nullptr), m_itemTarget(nullptr),
|
||||
m_objectTargetGUID(spellTargetData.Unit), m_itemTargetGUID(spellTargetData.Item),
|
||||
m_itemTargetEntry(0), m_elevation(0.0f), m_speed(0.0f), m_strTarget(spellTargetData.Name)
|
||||
SpellCastTargets::SpellCastTargets(Unit* caster, WorldPackets::Spells::SpellCastRequest const& spellCastRequest) :
|
||||
m_targetMask(spellCastRequest.Target.Flags), m_objectTarget(nullptr), m_itemTarget(nullptr),
|
||||
m_objectTargetGUID(spellCastRequest.Target.Unit), m_itemTargetGUID(spellCastRequest.Target.Item),
|
||||
m_itemTargetEntry(0), m_pitch(0.0f), m_speed(0.0f), m_strTarget(spellCastRequest.Target.Name)
|
||||
{
|
||||
if (spellTargetData.SrcLocation.HasValue)
|
||||
if (spellCastRequest.Target.SrcLocation.HasValue)
|
||||
{
|
||||
m_src._transportGUID = spellTargetData.SrcLocation.Value.Transport;
|
||||
m_src._transportGUID = spellCastRequest.Target.SrcLocation.Value.Transport;
|
||||
Position* pos;
|
||||
if (!m_src._transportGUID.IsEmpty())
|
||||
pos = &m_src._transportOffset;
|
||||
else
|
||||
pos = &m_src._position;
|
||||
|
||||
pos->Relocate(spellTargetData.SrcLocation.Value.Location);
|
||||
if (spellTargetData.Orientation.HasValue)
|
||||
pos->SetOrientation(spellTargetData.Orientation.Value);
|
||||
pos->Relocate(spellCastRequest.Target.SrcLocation.Value.Location);
|
||||
if (spellCastRequest.Target.Orientation.HasValue)
|
||||
pos->SetOrientation(spellCastRequest.Target.Orientation.Value);
|
||||
}
|
||||
|
||||
if (spellTargetData.DstLocation.HasValue)
|
||||
if (spellCastRequest.Target.DstLocation.HasValue)
|
||||
{
|
||||
m_dst._transportGUID = spellTargetData.DstLocation.Value.Transport;
|
||||
m_dst._transportGUID = spellCastRequest.Target.DstLocation.Value.Transport;
|
||||
Position* pos;
|
||||
if (!m_dst._transportGUID.IsEmpty())
|
||||
pos = &m_dst._transportOffset;
|
||||
else
|
||||
pos = &m_dst._position;
|
||||
|
||||
pos->Relocate(spellTargetData.DstLocation.Value.Location);
|
||||
if (spellTargetData.Orientation.HasValue)
|
||||
pos->SetOrientation(spellTargetData.Orientation.Value);
|
||||
pos->Relocate(spellCastRequest.Target.DstLocation.Value.Location);
|
||||
if (spellCastRequest.Target.Orientation.HasValue)
|
||||
pos->SetOrientation(spellCastRequest.Target.Orientation.Value);
|
||||
}
|
||||
|
||||
SetPitch(spellCastRequest.MissileTrajectory.Pitch);
|
||||
SetSpeed(spellCastRequest.MissileTrajectory.Speed);
|
||||
|
||||
Update(caster);
|
||||
}
|
||||
|
||||
@@ -535,7 +538,7 @@ void SpellCastTargets::OutDebug() const
|
||||
if (m_targetMask & TARGET_FLAG_STRING)
|
||||
TC_LOG_INFO("spells", "String: %s", m_strTarget.c_str());
|
||||
TC_LOG_INFO("spells", "speed: %f", m_speed);
|
||||
TC_LOG_INFO("spells", "elevation: %f", m_elevation);
|
||||
TC_LOG_INFO("spells", "pitch: %f", m_pitch);
|
||||
}
|
||||
|
||||
SpellValue::SpellValue(Difficulty diff, SpellInfo const* proto)
|
||||
@@ -1582,7 +1585,7 @@ void Spell::SelectImplicitTrajTargets(SpellEffIndex effIndex)
|
||||
|
||||
targets.sort(Trinity::ObjectDistanceOrderPred(m_caster));
|
||||
|
||||
float b = tangent(m_targets.GetElevation());
|
||||
float b = tangent(m_targets.GetPitch());
|
||||
float a = (srcToDestDelta - dist2d * b) / (dist2d * dist2d);
|
||||
if (a > -0.0001f)
|
||||
a = 0;
|
||||
@@ -4117,7 +4120,7 @@ void Spell::SendSpellGo()
|
||||
if (castFlags & CAST_FLAG_ADJUST_MISSILE)
|
||||
{
|
||||
castData.MissileTrajectory.TravelTime = m_delayMoment;
|
||||
castData.MissileTrajectory.Pitch = m_targets.GetElevation();
|
||||
castData.MissileTrajectory.Pitch = m_targets.GetPitch();
|
||||
}
|
||||
/*WorldPacket data(SMSG_SPELL_GO, 50); // guess size
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace WorldPackets
|
||||
{
|
||||
namespace Spells
|
||||
{
|
||||
struct SpellCastRequest;
|
||||
struct SpellTargetData;
|
||||
}
|
||||
}
|
||||
@@ -107,7 +108,7 @@ class SpellCastTargets
|
||||
{
|
||||
public:
|
||||
SpellCastTargets();
|
||||
SpellCastTargets(Unit* caster, WorldPackets::Spells::SpellTargetData const& spellTargetData);
|
||||
SpellCastTargets(Unit* caster, WorldPackets::Spells::SpellCastRequest const& spellCastRequest);
|
||||
~SpellCastTargets();
|
||||
|
||||
void Read(ByteBuffer& data, Unit* caster);
|
||||
@@ -166,14 +167,14 @@ class SpellCastTargets
|
||||
bool HasDst() const { return (GetTargetMask() & TARGET_FLAG_DEST_LOCATION) != 0; }
|
||||
bool HasTraj() const { return m_speed != 0; }
|
||||
|
||||
float GetElevation() const { return m_elevation; }
|
||||
void SetElevation(float elevation) { m_elevation = elevation; }
|
||||
float GetPitch() const { return m_pitch; }
|
||||
void SetPitch(float pitch) { m_pitch = pitch; }
|
||||
float GetSpeed() const { return m_speed; }
|
||||
void SetSpeed(float speed) { m_speed = speed; }
|
||||
|
||||
float GetDist2d() const { return m_src._position.GetExactDist2d(&m_dst._position); }
|
||||
float GetSpeedXY() const { return m_speed * std::cos(m_elevation); }
|
||||
float GetSpeedZ() const { return m_speed * std::sin(m_elevation); }
|
||||
float GetSpeedXY() const { return m_speed * std::cos(m_pitch); }
|
||||
float GetSpeedZ() const { return m_speed * std::sin(m_pitch); }
|
||||
|
||||
void Update(Unit* caster);
|
||||
void OutDebug() const;
|
||||
@@ -195,7 +196,7 @@ class SpellCastTargets
|
||||
SpellDestination m_src;
|
||||
SpellDestination m_dst;
|
||||
|
||||
float m_elevation, m_speed;
|
||||
float m_pitch, m_speed;
|
||||
std::string m_strTarget;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user