diff options
author | QAston <none@none> | 2010-08-08 20:32:14 +0200 |
---|---|---|
committer | QAston <none@none> | 2010-08-08 20:32:14 +0200 |
commit | 617a56ba29badd00c7a82805bdbc3b94c5b12a6c (patch) | |
tree | da7f70e56178a4df0709682c8c060ea292bbae09 /src | |
parent | 48c4d4551c5c61da2a4f7c9c6f2b27f7c129302b (diff) |
*Implement spell casting on transports (no more out of range error, etc)
*Add MO transports to ObjectAccessor storage
*Add functions Position::RelocateOffset and Position::GetPositionOffsetTo to help offset manipulations - BIG thanks to azazelkon for creating formulas!
*Add function to output debug info for MovementInfo and SpellCastTargets
*Throw ByteBufferException on incorrect packGUID read
*Add rfinish function to finish bytebuffer read.
--HG--
branch : trunk
Diffstat (limited to 'src')
19 files changed, 433 insertions, 234 deletions
diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp index d1cfb2866b2..d4f257cf588 100644 --- a/src/server/game/AI/CoreAI/PetAI.cpp +++ b/src/server/game/AI/CoreAI/PetAI.cpp @@ -212,10 +212,10 @@ void PetAI::UpdateAI(const uint32 diff) { me->SetInFront(target); if (target && target->GetTypeId() == TYPEID_PLAYER) - me->SendUpdateToPlayer(target->ToPlayer()); + me->SendUpdateToPlayer(target->ToPlayer()); if (owner && owner->GetTypeId() == TYPEID_PLAYER) - me->SendUpdateToPlayer(owner->ToPlayer()); + me->SendUpdateToPlayer(owner->ToPlayer()); } me->AddCreatureSpellCooldown(spell->m_spellInfo->Id); diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 5901ad7caa1..f17e48a76b9 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -1144,6 +1144,13 @@ bool Position::HasInLine(const Unit * const target, float distance, float width) return abs(sin(angle)) * GetExactDist2d(target->GetPositionX(), target->GetPositionY()) < width; } +std::string Position::ToString() const +{ + std::stringstream sstr; + sstr << "X: " << m_positionX << " Y: " << m_positionY << " Z: " << m_positionZ << " O: " << m_orientation; + return sstr.str(); +} + ByteBuffer &operator>>(ByteBuffer& buf, Position::PositionXYZOStreamer const & streamer) { float x, y, z, o; @@ -1175,6 +1182,39 @@ ByteBuffer & operator<<(ByteBuffer& buf, Position::PositionXYZOStreamer const & return buf; } +void MovementInfo::OutDebug() +{ + sLog.outString("MOVEMENT INFO"); + sLog.outString("guid " UI64FMTD, guid); + sLog.outString("flags %u", flags); + sLog.outString("flags2 %u", flags2); + sLog.outString("time %u current time %u", flags2, ::time(NULL)); + sLog.outString("position: `%s`", pos.ToString().c_str()); + if (flags & MOVEMENTFLAG_ONTRANSPORT) + { + sLog.outString("TRANSPORT:"); + sLog.outString("guid: " UI64FMTD, t_guid); + sLog.outString("position: `%s`", t_pos.ToString().c_str()); + sLog.outString("seat: %i", t_seat); + sLog.outString("time: %u", t_time); + if (flags2 & MOVEMENTFLAG2_INTERPOLATED_MOVEMENT) + sLog.outString("time2: %u", t_time2); + } + if ((flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || (flags2 & MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING)) + { + sLog.outString("pitch: %f", pitch); + } + sLog.outString("fallTime: %u", fallTime); + if (flags & MOVEMENTFLAG_JUMPING) + { + sLog.outString("j_zspeed: %f j_sinAngle: %f j_cosAngle: %f j_xyspeed: %f", j_zspeed, j_sinAngle, j_cosAngle, j_xyspeed); + } + if (flags & MOVEMENTFLAG_SPLINE_ELEVATION) + { + sLog.outString("splineElevation: %f", splineElevation); + } +} + WorldObject::WorldObject() : WorldLocation(), m_InstanceId(0), m_phaseMask(PHASEMASK_NORMAL), m_currMap(NULL) , m_zoneScript(NULL) @@ -1400,6 +1440,25 @@ bool WorldObject::IsInRange3d(float x, float y, float z, float minRange, float m return distsq < maxdist * maxdist; } +void Position::RelocateOffset(const Position & offset) +{ + m_positionX = GetPositionX() + (offset.GetPositionX() * cos(GetOrientation()) + offset.GetPositionY() * sin(GetOrientation() + M_PI)); + m_positionY = GetPositionY() + (offset.GetPositionY() * cos(GetOrientation()) + offset.GetPositionX() * sin(GetOrientation())); + m_positionZ = GetPositionZ() + offset.GetPositionZ(); + m_orientation = GetOrientation() + offset.GetOrientation(); +} + +void Position::GetPositionOffsetTo(const Position & endPos, Position & retOffset) const +{ + float dx = endPos.GetPositionX() - GetPositionX(); + float dy = endPos.GetPositionY() - GetPositionY(); + + retOffset.m_positionX = dx * cos(GetOrientation()) + dy * sin(GetOrientation()); + retOffset.m_positionY = dy * cos(GetOrientation()) - dx * sin(GetOrientation()); + retOffset.m_positionZ = endPos.GetPositionZ() - GetPositionZ(); + retOffset.m_orientation = endPos.GetOrientation() - GetOrientation(); +} + float Position::GetAngle(const Position *obj) const { if (!obj) return 0; @@ -2473,3 +2532,10 @@ void WorldObject::BuildUpdate(UpdateDataMapType& data_map) ClearUpdateMask(false); } + +uint64 WorldObject::GetTransGUID() const +{ + if (GetTransport()) + return GetTransport()->GetGUID(); + return 0; +}
\ No newline at end of file diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index bd417ea9c09..3c9a3606cfb 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -31,6 +31,7 @@ #include <set> #include <string> +#include <sstream> #define CONTACT_DISTANCE 0.5f #define INTERACTION_DISTANCE 5.0f @@ -396,6 +397,7 @@ struct Position { m_positionX = pos.m_positionX; m_positionY = pos.m_positionY; m_positionZ = pos.m_positionZ; m_orientation = pos.m_orientation; } void Relocate(const Position *pos) { m_positionX = pos->m_positionX; m_positionY = pos->m_positionY; m_positionZ = pos->m_positionZ; m_orientation = pos->m_orientation; } + void RelocateOffset(const Position &offset); void SetOrientation(float orientation) { m_orientation = orientation; } @@ -444,6 +446,8 @@ struct Position float GetExactDist(const Position *pos) const { return sqrt(GetExactDistSq(pos)); } + void GetPositionOffsetTo(const Position & endPos, Position & retOffset) const; + float GetAngle(const Position *pos) const; float GetAngle(float x, float y) const; float GetRelativeAngle(const Position *pos) const @@ -461,6 +465,7 @@ struct Position { return GetExactDistSq(pos) < dist * dist; } bool HasInArc(float arcangle, const Position *pos) const; bool HasInLine(const Unit *target, float distance, float width) const; + std::string ToString() const; }; ByteBuffer &operator>>(ByteBuffer& buf, Position::PositionXYZOStreamer const & streamer); ByteBuffer & operator<<(ByteBuffer& buf, Position::PositionXYZStreamer const & streamer); @@ -507,6 +512,7 @@ struct MovementInfo uint32 GetMovementFlags() { return flags; } void AddMovementFlag(uint32 flag) { flags |= flag; } bool HasMovementFlag(uint32 flag) const { return flags & flag; } + void OutDebug(); }; #define MAPID_INVALID 0xFFFFFFFF @@ -536,6 +542,8 @@ class GridObject class WorldObject : public Object, public WorldLocation { + protected: + explicit WorldObject(); public: virtual ~WorldObject(); @@ -767,11 +775,17 @@ class WorldObject : public Object, public WorldLocation // Transports Transport *GetTransport() const { return m_transport; } + virtual float GetTransOffsetX() const { return 0; } + virtual float GetTransOffsetY() const { return 0; } + virtual float GetTransOffsetZ() const { return 0; } + virtual float GetTransOffsetO() const { return 0; } + virtual uint32 GetTransTime() const { return 0; } + virtual int8 GetTransSeat() const { return -1; } + virtual uint64 GetTransGUID() const; void SetTransport(Transport *t) { m_transport = t; } MovementInfo m_movementInfo; protected: - explicit WorldObject(); std::string m_name; bool m_isActive; ZoneScript *m_zoneScript; diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index 1ee002780b9..4871ed978cf 100644 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -105,6 +105,7 @@ void MapManager::LoadTransports() //If we someday decide to use the grid to track transports, here: t->SetMap(sMapMgr.CreateMap(mapid, t, 0)); + t->AddToWorld(); for (TransportNPCSet::const_iterator i = m_TransportNPCMap[entry].begin(); i != m_TransportNPCMap[entry].end(); ++i) { @@ -506,10 +507,12 @@ void Transport::TeleportTransport(uint32 newMapid, float x, float y, float z) } m_NPCPassengerSet.clear(); + RemoveFromWorld(); ResetMap(); Map * newMap = sMapMgr.CreateMap(newMapid, this, 0); SetMap(newMap); ASSERT (GetMap()); + AddToWorld(); if (oldMap != newMap) { diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index b56f5300635..eea51b53ab6 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -15642,6 +15642,16 @@ Creature *Unit::GetVehicleCreatureBase() const return NULL; } +uint64 Unit::GetTransGUID() const +{ + if (GetVehicle()) + return GetVehicle()->GetBase()->GetGUID(); + if (GetTransport()) + return GetTransport()->GetGUID(); + + return 0; +} + bool Unit::IsInPartyWith(Unit const *unit) const { if (this == unit) diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 8aee8a6bb04..36b8ab9e9be 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1534,7 +1534,7 @@ class Unit : public WorldObject CharmInfo* GetCharmInfo() { return m_charmInfo; } CharmInfo* InitCharmInfo(); - void DeleteCharmInfo(); + void DeleteCharmInfo(); void UpdateCharmAI(); //Player * GetMoverSource() const; Player * m_movedPlayer; @@ -1955,6 +1955,7 @@ class Unit : public WorldObject float GetTransOffsetO() const { return m_movementInfo.t_pos.GetOrientation(); } uint32 GetTransTime() const { return m_movementInfo.t_time; } int8 GetTransSeat() const { return m_movementInfo.t_seat; } + uint64 GetTransGUID() const; bool m_ControlledByPlayer; diff --git a/src/server/game/Globals/ObjectAccessor.cpp b/src/server/game/Globals/ObjectAccessor.cpp index 5f6806aa74e..fdb13637263 100644 --- a/src/server/game/Globals/ObjectAccessor.cpp +++ b/src/server/game/Globals/ObjectAccessor.cpp @@ -59,14 +59,14 @@ WorldObject* ObjectAccessor::GetWorldObject(WorldObject const& p, uint64 guid) switch (GUID_HIPART(guid)) { case HIGHGUID_PLAYER: return GetPlayer(p, guid); + case HIGHGUID_TRANSPORT: + case HIGHGUID_MO_TRANSPORT: case HIGHGUID_GAMEOBJECT: return GetGameObject(p, guid); case HIGHGUID_VEHICLE: case HIGHGUID_UNIT: return GetCreature(p, guid); case HIGHGUID_PET: return GetPet(p, guid); case HIGHGUID_DYNAMICOBJECT: return GetDynamicObject(p, guid); - case HIGHGUID_TRANSPORT: return NULL; case HIGHGUID_CORPSE: return GetCorpse(p,guid); - case HIGHGUID_MO_TRANSPORT: return NULL; default: return NULL; } } @@ -83,6 +83,8 @@ Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const& p, uint64 guid, u if (typemask & TYPEMASK_PLAYER) return GetPlayer(p, guid); break; + case HIGHGUID_TRANSPORT: + case HIGHGUID_MO_TRANSPORT: case HIGHGUID_GAMEOBJECT: if (typemask & TYPEMASK_GAMEOBJECT) return GetGameObject(p, guid); @@ -100,9 +102,7 @@ Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const& p, uint64 guid, u if (typemask & TYPEMASK_DYNAMICOBJECT) return GetDynamicObject(p, guid); break; - case HIGHGUID_TRANSPORT: case HIGHGUID_CORPSE: - case HIGHGUID_MO_TRANSPORT: break; } diff --git a/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp b/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp index 634c0cd1136..f25dd5824dc 100644 --- a/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp @@ -1257,8 +1257,7 @@ void WorldSession::HandleEquipmentSetSave(WorldPacket &recv_data) sLog.outDebug("CMSG_EQUIPMENT_SET_SAVE"); uint64 setGuid; - if (!recv_data.readPackGUID(setGuid)) - return; + recv_data.readPackGUID(setGuid); uint32 index; recv_data >> index; @@ -1281,8 +1280,7 @@ void WorldSession::HandleEquipmentSetSave(WorldPacket &recv_data) for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i) { uint64 itemGuid; - if (!recv_data.readPackGUID(itemGuid)) - return; + recv_data.readPackGUID(itemGuid); Item *item = _player->GetItemByPos(INVENTORY_SLOT_BAG_0, i); @@ -1303,8 +1301,7 @@ void WorldSession::HandleEquipmentSetDelete(WorldPacket &recv_data) sLog.outDebug("CMSG_EQUIPMENT_SET_DELETE"); uint64 setGuid; - if (!recv_data.readPackGUID(setGuid)) - return; + recv_data.readPackGUID(setGuid); _player->DeleteEquipmentSet(setGuid); } @@ -1317,8 +1314,7 @@ void WorldSession::HandleEquipmentSetUse(WorldPacket &recv_data) for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i) { uint64 itemGuid; - if (!recv_data.readPackGUID(itemGuid)) - return; + recv_data.readPackGUID(itemGuid); uint8 srcbag, srcslot; recv_data >> srcbag >> srcslot; diff --git a/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp b/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp index b5f37c96e6d..f076a14febb 100644 --- a/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp @@ -1090,11 +1090,7 @@ void WorldSession::HandleMoveTimeSkippedOpcode(WorldPacket & recv_data) DEBUG_LOG("WORLD: Time Lag/Synchronization Resent/Update"); uint64 guid; - if (!recv_data.readPackGUID(guid)) - { - recv_data.rpos(recv_data.wpos()); - return; - } + recv_data.readPackGUID(guid); recv_data.read_skip<uint32>(); /* uint64 guid; @@ -1651,8 +1647,8 @@ void WorldSession::HandleMoveSetCanFlyAckOpcode(WorldPacket & recv_data) //recv_data.hexlike(); uint64 guid; // guid - unused - if (!recv_data.readPackGUID(guid)) - return; + recv_data.readPackGUID(guid); + recv_data.read_skip<uint32>(); // unk @@ -1684,8 +1680,7 @@ void WorldSession::HandleSetTaxiBenchmarkOpcode(WorldPacket & recv_data) void WorldSession::HandleQueryInspectAchievements(WorldPacket & recv_data) { uint64 guid; - if (!recv_data.readPackGUID(guid)) - return; + recv_data.readPackGUID(guid); Player *player = sObjectMgr.GetPlayer(guid); if (!player) diff --git a/src/server/game/Server/Protocol/Handlers/MovementHandler.cpp b/src/server/game/Server/Protocol/Handlers/MovementHandler.cpp index e7bab3eed1f..0a0e11922cc 100644 --- a/src/server/game/Server/Protocol/Handlers/MovementHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/MovementHandler.cpp @@ -195,8 +195,7 @@ void WorldSession::HandleMoveTeleportAck(WorldPacket& recv_data) sLog.outDebug("MSG_MOVE_TELEPORT_ACK"); uint64 guid; - if (!recv_data.readPackGUID(guid)) - return; + recv_data.readPackGUID(guid); uint32 flags, time; recv_data >> flags >> time; @@ -264,8 +263,7 @@ void WorldSession::HandleMovementOpcodes(WorldPacket & recv_data) /* extract packet */ uint64 guid; - if (!recv_data.readPackGUID(guid)) - return; + recv_data.readPackGUID(guid); MovementInfo movementInfo; movementInfo.guid = guid; @@ -424,8 +422,7 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data) uint32 unk1; float newspeed; - if (!recv_data.readPackGUID(guid)) - return; + recv_data.readPackGUID(guid); // now can skip not our packet if (_player->GetGUID() != guid) @@ -525,8 +522,7 @@ void WorldSession::HandleMoveNotActiveMover(WorldPacket &recv_data) sLog.outDebug("WORLD: Recvd CMSG_MOVE_NOT_ACTIVE_MOVER"); uint64 old_mover_guid; - if (!recv_data.readPackGUID(old_mover_guid)) - return; + recv_data.readPackGUID(old_mover_guid); /*if (_player->m_mover->GetGUID() == old_mover_guid) { @@ -558,8 +554,7 @@ void WorldSession::HandleDismissControlledVehicle(WorldPacket &recv_data) uint64 guid; - if (!recv_data.readPackGUID(guid)) - return; + recv_data.readPackGUID(guid); MovementInfo mi; mi.guid = guid; @@ -592,14 +587,12 @@ void WorldSession::HandleChangeSeatsOnControlledVehicle(WorldPacket &recv_data) case CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE: { uint64 guid; // current vehicle guid - if (!recv_data.readPackGUID(guid)) - return; + recv_data.readPackGUID(guid); ReadMovementInfo(recv_data, &vehicle_base->m_movementInfo); uint64 accessory; // accessory guid - if (!recv_data.readPackGUID(accessory)) - return; + recv_data.readPackGUID(accessory); int8 seatId; recv_data >> seatId; @@ -620,8 +613,7 @@ void WorldSession::HandleChangeSeatsOnControlledVehicle(WorldPacket &recv_data) case CMSG_REQUEST_VEHICLE_SWITCH_SEAT: { uint64 guid; // current vehicle guid - if (!recv_data.readPackGUID(guid)) - return; + recv_data.readPackGUID(guid); int8 seatId; recv_data >> seatId; @@ -693,8 +685,7 @@ void WorldSession::HandleMoveKnockBackAck(WorldPacket & recv_data) sLog.outDebug("CMSG_MOVE_KNOCK_BACK_ACK"); uint64 guid; // guid - unused - if (!recv_data.readPackGUID(guid)) - return; + recv_data.readPackGUID(guid); recv_data.read_skip<uint32>(); // unk @@ -707,8 +698,7 @@ void WorldSession::HandleMoveHoverAck(WorldPacket& recv_data) sLog.outDebug("CMSG_MOVE_HOVER_ACK"); uint64 guid; // guid - unused - if (!recv_data.readPackGUID(guid)) - return; + recv_data.readPackGUID(guid); recv_data.read_skip<uint32>(); // unk @@ -723,8 +713,7 @@ void WorldSession::HandleMoveWaterWalkAck(WorldPacket& recv_data) sLog.outDebug("CMSG_MOVE_WATER_WALK_ACK"); uint64 guid; // guid - unused - if (!recv_data.readPackGUID(guid)) - return; + recv_data.readPackGUID(guid); recv_data.read_skip<uint32>(); // unk diff --git a/src/server/game/Server/Protocol/Handlers/PetHandler.cpp b/src/server/game/Server/Protocol/Handlers/PetHandler.cpp index 24413abaebd..71454ce428f 100644 --- a/src/server/game/Server/Protocol/Handlers/PetHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/PetHandler.cpp @@ -692,12 +692,13 @@ void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket) sLog.outDetail("WORLD: CMSG_PET_CAST_SPELL"); uint64 guid; - uint32 spellid; - uint8 cast_count; + uint8 castCount; + uint32 spellId; + uint8 castFlags; - recvPacket >> guid >> cast_count >> spellid; + recvPacket >> guid >> castCount >> spellId >> castFlags; - sLog.outDebug("WORLD: CMSG_PET_CAST_SPELL, cast_count: %u, spellid %u", cast_count, spellid); + sLog.outDebug("WORLD: CMSG_PET_CAST_SPELL, guid: " UI64FMTD ", castCount: %u, spellId %u, castFlags %u", guid, castCount, spellId, castFlags); // This opcode is also sent from charmed and possessed units (players and creatures) if (!_player->GetGuardianPet() && !_player->GetCharm()) @@ -711,32 +712,32 @@ void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket) return; } - SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellid); + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); if (!spellInfo) { - sLog.outError("WORLD: unknown PET spell id %i", spellid); + sLog.outError("WORLD: unknown PET spell id %i", spellId); return; } - if (spellInfo->StartRecoveryCategory > 0) //Check if spell is affected by GCD + if (spellInfo->StartRecoveryCategory > 0) // Check if spell is affected by GCD if (caster->GetTypeId() == TYPEID_UNIT && caster->ToCreature()->GetGlobalCooldown() > 0) { - caster->SendPetCastFail(spellid, SPELL_FAILED_NOT_READY); + caster->SendPetCastFail(spellId, SPELL_FAILED_NOT_READY); return; } // do not cast not learned spells - if (!caster->HasSpell(spellid) || IsPassiveSpell(spellid)) + if (!caster->HasSpell(spellId) || IsPassiveSpell(spellId)) return; SpellCastTargets targets; - if (!targets.read(&recvPacket,caster)) - return; + targets.read(recvPacket, caster); + HandleClientCastFlags(recvPacket, castFlags, targets); caster->clearUnitState(UNIT_STAT_FOLLOW); - Spell *spell = new Spell(caster, spellInfo, spellid == 33395); // water elemental can cast freeze as triggered - spell->m_cast_count = spellid == 33395 ? 0 : cast_count; // probably pending spell cast + Spell *spell = new Spell(caster, spellInfo, spellId == 33395); // water elemental can cast freeze as triggered + spell->m_cast_count = spellId == 33395 ? 0 : castCount; // probably pending spell cast spell->m_targets = targets; // TODO: need to check victim? @@ -750,7 +751,7 @@ void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket) if (caster->GetTypeId() == TYPEID_UNIT) { Creature* pet = caster->ToCreature(); - pet->AddCreatureSpellCooldown(spellid); + pet->AddCreatureSpellCooldown(spellId); if (pet->isPet()) { Pet* p = (Pet*)pet; @@ -767,16 +768,16 @@ void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket) } else { - caster->SendPetCastFail(spellid, result); + caster->SendPetCastFail(spellId, result); if (caster->GetTypeId() == TYPEID_PLAYER) { - if (!caster->ToPlayer()->HasSpellCooldown(spellid)) - GetPlayer()->SendClearCooldown(spellid, caster); + if (!caster->ToPlayer()->HasSpellCooldown(spellId)) + GetPlayer()->SendClearCooldown(spellId, caster); } else { - if (!caster->ToCreature()->HasSpellCooldown(spellid)) - GetPlayer()->SendClearCooldown(spellid, caster); + if (!caster->ToCreature()->HasSpellCooldown(spellId)) + GetPlayer()->SendClearCooldown(spellId, caster); } spell->finish(false); diff --git a/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp b/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp index 8c0e7c0735d..178828c9880 100644 --- a/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp @@ -33,6 +33,31 @@ #include "CreatureAI.h" #include "ScriptMgr.h" +void WorldSession::HandleClientCastFlags(WorldPacket& recvPacket, uint8 castFlags, SpellCastTargets & targets) +{ + // some spell cast packet including more data (for projectiles?) + if (castFlags & 0x02) + { + // not sure about these two + recvPacket >> targets.m_elevation; + recvPacket >> targets.m_speed; + uint8 hasMovementData; + recvPacket >> hasMovementData; + if (hasMovementData) + { + recvPacket.rfinish(); + // movement packet for caster of the spell + /*recvPacket.read_skip<uint32>(); // MSG_MOVE_STOP - hardcoded in client + uint64 guid; + recvPacket.readPackGUID(guid); + + MovementInfo movementInfo; + movementInfo.guid = guid; + ReadMovementInfo(recvPacket, &movementInfo);*/ + } + } +} + void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) { // TODO: add targets.read() check @@ -42,13 +67,13 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) if (pUser->m_mover != pUser) return; - uint8 bagIndex, slot; - uint8 cast_count; // next cast if exists (single or not) - uint64 item_guid; + uint8 bagIndex, slot, castFlags; + uint8 castCount; // next cast if exists (single or not) + uint64 itemGUID; uint32 glyphIndex; // something to do with glyphs? - uint32 spellid; // casted spell id + uint32 spellId; // casted spell id - recvPacket >> bagIndex >> slot >> cast_count >> spellid >> item_guid >> glyphIndex; + recvPacket >> bagIndex >> slot >> castCount >> spellId >> itemGUID >> glyphIndex >> castFlags; if (glyphIndex >= MAX_GLYPH_SLOT_INDEX) { @@ -63,13 +88,13 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) return; } - if (pItem->GetGUID() != item_guid) + if (pItem->GetGUID() != itemGUID) { pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL); return; } - sLog.outDetail("WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, cast_count: %u, spellid: %u, Item: %u, glyphIndex: %u, data length = %i", bagIndex, slot, cast_count, spellid, pItem->GetEntry(), glyphIndex, (uint32)recvPacket.size()); + sLog.outDetail("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()); ItemPrototype const *proto = pItem->GetProto(); if (!proto) @@ -132,10 +157,8 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) } SpellCastTargets targets; - if (!targets.read(&recvPacket, pUser)) - return; - - targets.Update(pUser); + targets.read(recvPacket, pUser); + HandleClientCastFlags(recvPacket, castFlags, targets); if (!pItem->IsTargetValidForItemUse(targets.getUnitTarget())) { @@ -143,23 +166,23 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) pUser->SendEquipError(EQUIP_ERR_NONE, pItem, NULL); // send spell error - if (SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid)) + if (SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellId)) { // for implicit area/coord target spells if (!targets.getUnitTarget()) - Spell::SendCastResult(_player,spellInfo,cast_count,SPELL_FAILED_NO_VALID_TARGETS); + Spell::SendCastResult(_player,spellInfo,castCount,SPELL_FAILED_NO_VALID_TARGETS); // for explicit target spells else - Spell::SendCastResult(_player,spellInfo,cast_count,SPELL_FAILED_BAD_TARGETS); + Spell::SendCastResult(_player,spellInfo,castCount,SPELL_FAILED_BAD_TARGETS); } return; } - //Note: If script stop casting it must send appropriate data to client to prevent stuck item in gray state. + // 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)) { // no script or script not process request by self - pUser->CastItemUseSpell(pItem,targets,cast_count,glyphIndex); + pUser->CastItemUseSpell(pItem,targets,castCount,glyphIndex); } } @@ -293,26 +316,25 @@ void WorldSession::HandleGameobjectReportUse(WorldPacket& recvPacket) void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) { uint32 spellId; - uint8 cast_count; - recvPacket >> cast_count; - recvPacket >> spellId; + uint8 castCount, castFlags; + recvPacket >> castCount >> spellId >> castFlags; + + sLog.outDebug("WORLD: got cast spell packet, castCount: %u, spellId: %u, castFlags: %u, data length = %u", castCount, spellId, castFlags, (uint32)recvPacket.size()); // ignore for remote control state (for player case) Unit* mover = _player->m_mover; if (mover != _player && mover->GetTypeId() == TYPEID_PLAYER) { - recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet + recvPacket.rfinish(); // prevent spam at ignore packet return; } - sLog.outDebug("WORLD: got cast spell packet, spellId - %u, cast_count: %u, data length = %i", spellId, cast_count, (uint32)recvPacket.size()); - SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); if (!spellInfo) { sLog.outError("WORLD: unknown spell id %u", spellId); - recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet + recvPacket.rfinish(); // prevent spam at ignore packet return; } @@ -322,7 +344,7 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) if (!mover->ToPlayer()->HasActiveSpell (spellId) || IsPassiveSpell(spellId)) { //cheater? kick? ban? - recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet + recvPacket.rfinish(); // prevent spam at ignore packet return; } } @@ -332,7 +354,7 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) if ((mover->GetTypeId() == TYPEID_UNIT && !mover->ToCreature()->HasSpell(spellId)) || IsPassiveSpell(spellId)) { //cheater? kick? ban? - recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet + recvPacket.rfinish(); // prevent spam at ignore packet return; } } @@ -345,15 +367,15 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) // can't use our own spells when we're in possession of another unit, if (_player->isPossessing()) + { + recvPacket.rfinish(); // prevent spam at ignore packet return; + } // client provided targets SpellCastTargets targets; - if (!targets.read(&recvPacket,mover)) - { - recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet - return; - } + targets.read(recvPacket, mover); + HandleClientCastFlags(recvPacket, castFlags, targets); // auto-selection buff level base at target level (in spellInfo) if (targets.getUnitTarget()) @@ -366,7 +388,7 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) } Spell *spell = new Spell(mover, spellInfo, false); - spell->m_cast_count = cast_count; // set count of casts + spell->m_cast_count = castCount; // set count of casts spell->prepare(&targets); } diff --git a/src/server/game/Server/Protocol/Handlers/TaxiHandler.cpp b/src/server/game/Server/Protocol/Handlers/TaxiHandler.cpp index 96cbece2240..324167791a7 100644 --- a/src/server/game/Server/Protocol/Handlers/TaxiHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/TaxiHandler.cpp @@ -202,9 +202,8 @@ void WorldSession::HandleMoveSplineDoneOpcode(WorldPacket& recv_data) { sLog.outDebug("WORLD: Received CMSG_MOVE_SPLINE_DONE"); - uint64 guid; // used only for proper packet read - if (!recv_data.readPackGUID(guid)) - return; + uint64 guid; // used only for proper packet read + recv_data.readPackGUID(guid); MovementInfo movementInfo; // used only for proper packet read ReadMovementInfo(recv_data, &movementInfo); diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 39d853e716d..695d3e23641 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -721,8 +721,7 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo *mi) if (mi->flags & MOVEMENTFLAG_ONTRANSPORT) { - if (!data.readPackGUID(mi->t_guid)) - return; + data.readPackGUID(mi->t_guid); data >> mi->t_pos.PositionXYZOStream(); data >> mi->t_time; diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index fe361e22b54..93d90cd9fe2 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -47,6 +47,7 @@ class WorldSocket; class QueryResult; class LoginQueryHolder; class CharacterHandler; +class SpellCastTargets; struct AreaTableEntry; enum AccountDataType @@ -211,7 +212,10 @@ class WorldSession void SendPetitionQueryOpcode(uint64 petitionguid); - //pet + // Spell + void HandleClientCastFlags(WorldPacket& recvPacket, uint8 castFlags, SpellCastTargets & targets); + + // Pet void SendPetNameQuery(uint64 guid, uint32 petnumber); void SendStablePet(uint64 guid); void SendStableResult(uint8 guid); diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index a3075b6fe9c..06abed00445 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -79,8 +79,12 @@ SpellCastTargets::SpellCastTargets() : m_elevation(0), m_speed(0) m_itemTargetGUID = 0; m_itemTargetEntry = 0; - m_srcPos.Relocate(0,0,0,0); - m_dstPos.Relocate(0,0,0,0); + m_srcTransGUID = 0; + m_srcTransOffset.Relocate(0, 0, 0, 0); + m_srcPos.Relocate(0, 0, 0, 0); + m_dstTransGUID = 0; + m_dstTransOffset.Relocate(0, 0, 0, 0); + m_dstPos.Relocate(0, 0, 0, 0); m_strTarget = ""; m_targetMask = 0; } @@ -102,33 +106,75 @@ void SpellCastTargets::setUnitTarget(Unit *target) void SpellCastTargets::setSrc(float x, float y, float z) { m_srcPos.Relocate(x, y, z); + m_srcTransGUID = 0; m_targetMask |= TARGET_FLAG_SOURCE_LOCATION; } -void SpellCastTargets::setSrc(Position *pos) +void SpellCastTargets::setSrc(Position &pos) { - if (pos) + m_srcPos.Relocate(pos); + m_srcTransGUID = 0; + m_targetMask |= TARGET_FLAG_SOURCE_LOCATION; +} + +void SpellCastTargets::setSrc(WorldObject &wObj) +{ + uint64 guid = wObj.GetTransGUID(); + m_srcTransGUID = guid; + m_srcTransOffset.Relocate(wObj.GetTransOffsetX(), wObj.GetTransOffsetY(), wObj.GetTransOffsetZ(), wObj.GetTransOffsetO()); + m_srcPos.Relocate(wObj); + m_targetMask |= TARGET_FLAG_SOURCE_LOCATION; +} + +void SpellCastTargets::modSrc(Position &pos) +{ + ASSERT(m_targetMask & TARGET_FLAG_SOURCE_LOCATION); + + if (m_srcTransGUID) { - m_srcPos.Relocate(pos); - m_targetMask |= TARGET_FLAG_SOURCE_LOCATION; + Position offset; + m_srcPos.GetPositionOffsetTo(pos, offset); + m_srcTransOffset.RelocateOffset(offset); } + m_srcPos.Relocate(pos); } void SpellCastTargets::setDst(float x, float y, float z, float orientation, uint32 mapId) { m_dstPos.Relocate(x, y, z, orientation); + m_dstTransGUID = 0; m_targetMask |= TARGET_FLAG_DEST_LOCATION; if (mapId != MAPID_INVALID) m_dstPos.m_mapId = mapId; } -void SpellCastTargets::setDst(Position *pos) +void SpellCastTargets::setDst(Position &pos) +{ + m_dstPos.Relocate(pos); + m_dstTransGUID = 0; + m_targetMask |= TARGET_FLAG_DEST_LOCATION; +} + +void SpellCastTargets::setDst(WorldObject &wObj) +{ + uint64 guid = wObj.GetTransGUID(); + m_dstTransGUID = guid; + m_dstTransOffset.Relocate(wObj.GetTransOffsetX(), wObj.GetTransOffsetY(), wObj.GetTransOffsetZ(), wObj.GetTransOffsetO()); + m_dstPos.Relocate(wObj); + m_targetMask |= TARGET_FLAG_DEST_LOCATION; +} + +void SpellCastTargets::modDst(Position &pos) { - if (pos) + ASSERT(m_targetMask & TARGET_FLAG_DEST_LOCATION); + + if (m_dstTransGUID) { - m_dstPos.Relocate(pos); - m_targetMask |= TARGET_FLAG_DEST_LOCATION; + Position offset; + m_dstPos.GetPositionOffsetTo(pos, offset); + m_dstTransOffset.RelocateOffset(offset); } + m_dstPos.Relocate(pos); } void SpellCastTargets::setGOTarget(GameObject *target) @@ -184,153 +230,187 @@ void SpellCastTargets::Update(Unit* caster) if (m_itemTarget) m_itemTargetEntry = m_itemTarget->GetEntry(); } + // update positions by transport move + if (m_srcTransGUID) + { + if (WorldObject * transport = ObjectAccessor::GetWorldObject(*caster, m_srcTransGUID)) + { + m_srcPos.Relocate(transport); + m_srcPos.RelocateOffset(m_srcTransOffset); + } + } + if (m_dstTransGUID) + { + if (WorldObject * transport = ObjectAccessor::GetWorldObject(*caster, m_dstTransGUID)) + { + m_dstPos.Relocate(transport); + m_dstPos.RelocateOffset(m_dstTransOffset); + } + } } -bool SpellCastTargets::read (WorldPacket * data, Unit *caster) +void SpellCastTargets::OutDebug() { - if (data->rpos() + 4 > data->size()) - return false; + if (!m_targetMask) + sLog.outString("TARGET_FLAG_SELF"); - uint8 clientCastFlags; - *data >> clientCastFlags; - *data >> m_targetMask; - //sLog.outDebug("Spell read, target mask = %u", m_targetMask); + if (m_targetMask & TARGET_FLAG_UNIT) + { + sLog.outString("TARGET_FLAG_UNIT: " UI64FMTD, m_unitTargetGUID); + } + if (m_targetMask & TARGET_FLAG_UNK17) + { + sLog.outString("TARGET_FLAG_UNK17: " UI64FMTD, m_unitTargetGUID); + } + if (m_targetMask & TARGET_FLAG_OBJECT) + { + sLog.outString("TARGET_FLAG_OBJECT: " UI64FMTD, m_GOTargetGUID); + } + if (m_targetMask & TARGET_FLAG_CORPSE) + { + sLog.outString("TARGET_FLAG_CORPSE: " UI64FMTD, m_CorpseTargetGUID); + } + if (m_targetMask & TARGET_FLAG_PVP_CORPSE) + { + sLog.outString("TARGET_FLAG_PVP_CORPSE: " UI64FMTD, m_CorpseTargetGUID); + } + if (m_targetMask & TARGET_FLAG_ITEM) + { + sLog.outString("TARGET_FLAG_ITEM: " UI64FMTD, m_itemTargetGUID); + } + if (m_targetMask & TARGET_FLAG_TRADE_ITEM) + { + sLog.outString("TARGET_FLAG_TRADE_ITEM: " UI64FMTD, m_itemTargetGUID); + } + if (m_targetMask & TARGET_FLAG_SOURCE_LOCATION) + { + sLog.outString("TARGET_FLAG_SOURCE_LOCATION: transport guid:" UI64FMTD " trans offset: %s position: %s", m_srcTransGUID, m_srcTransOffset.ToString().c_str(), m_srcPos.ToString().c_str()); + } + if (m_targetMask & TARGET_FLAG_DEST_LOCATION) + { + sLog.outString("TARGET_FLAG_DEST_LOCATION: transport guid:" UI64FMTD " trans offset: %s position: %s", m_dstTransGUID, m_dstTransOffset.ToString().c_str(), m_dstPos.ToString().c_str()); + } + if (m_targetMask & TARGET_FLAG_STRING) + { + sLog.outString("TARGET_FLAG_STRING: %s", m_strTarget); + } + sLog.outString("speed: %f", m_speed); + sLog.outString("elevation: %f", m_elevation); +} + +void SpellCastTargets::read (ByteBuffer & data, Unit * caster) +{ + data >> m_targetMask; if (m_targetMask == TARGET_FLAG_SELF) - return true; + return; if (m_targetMask & (TARGET_FLAG_UNIT | TARGET_FLAG_UNK17)) - { - if (!data->readPackGUID(m_unitTargetGUID)) - return false; - } + data.readPackGUID(m_unitTargetGUID); - if(m_targetMask & (TARGET_FLAG_OBJECT)) - { - if (!data->readPackGUID(m_GOTargetGUID)) - return false; - } + if (m_targetMask & (TARGET_FLAG_OBJECT)) + data.readPackGUID(m_GOTargetGUID); if(m_targetMask & (TARGET_FLAG_ITEM | TARGET_FLAG_TRADE_ITEM)) - { - if (caster->GetTypeId() != TYPEID_PLAYER) - return false; - if (!data->readPackGUID(m_itemTargetGUID)) - return false; - } + data.readPackGUID(m_itemTargetGUID); if(m_targetMask & (TARGET_FLAG_CORPSE | TARGET_FLAG_PVP_CORPSE)) - { - if (!data->readPackGUID(m_CorpseTargetGUID)) - return false; - } + data.readPackGUID(m_CorpseTargetGUID); if (m_targetMask & TARGET_FLAG_SOURCE_LOCATION) { - uint64 relativePositionObjGUID; - if (!data->readPackGUID(relativePositionObjGUID)) - return false; - *data >> m_srcPos.PositionXYZStream(); - if (!m_srcPos.IsPositionValid()) - return false; + data.readPackGUID(m_srcTransGUID); + if (m_srcTransGUID) + data >> m_srcTransOffset.PositionXYZStream(); + else + data >> m_srcPos.PositionXYZStream(); } else - m_srcPos.Relocate(caster); + { + m_srcTransGUID = caster->GetTransGUID(); + if (m_srcTransGUID) + m_srcTransOffset.Relocate(caster->GetTransOffsetX(), caster->GetTransOffsetY(), caster->GetTransOffsetZ(), caster->GetTransOffsetO()); + else + m_srcPos.Relocate(caster); + } if (m_targetMask & TARGET_FLAG_DEST_LOCATION) { - uint64 relativePositionObjGUID; - if (!data->readPackGUID(relativePositionObjGUID)) - return false; - *data >> m_dstPos.PositionXYZStream(); - if (!m_dstPos.IsPositionValid()) - return false; + data.readPackGUID(m_dstTransGUID); + if (m_dstTransGUID) + data >> m_dstTransOffset.PositionXYZStream(); + else + data >> m_dstPos.PositionXYZStream(); } else - m_dstPos.Relocate(caster); - - if(m_targetMask & TARGET_FLAG_STRING) { - if (data->rpos() + 1 > data->size()) - return false; - *data >> m_strTarget; + m_dstTransGUID = caster->GetTransGUID(); + if (m_dstTransGUID) + m_dstTransOffset.Relocate(caster->GetTransOffsetX(), caster->GetTransOffsetY(), caster->GetTransOffsetZ(), caster->GetTransOffsetO()); + else + m_dstPos.Relocate(caster); } - // some spell cast packet including more data (for projectiles?) - if (clientCastFlags & 0x02) - { - // not sure about these two - *data >> m_elevation; - *data >> m_speed; - uint8 hasMovementInfo; - *data >> hasMovementInfo; // bool - if (hasMovementInfo) - { - data->read_skip<uint32>(); // MSG_MOVE_STOP - hardcoded in client - uint64 guid = 0; // guid - unused - if (!data->readPackGUID(guid)) - return false; - - data->rpos(data->wpos()); // prevent spam at ignore packet - //MovementInfo movementInfo; - //ReadMovementInfo(*data, &movementInfo); - } - } + if(m_targetMask & TARGET_FLAG_STRING) + data >> m_strTarget; - // find real units/GOs Update(caster); - return true; } -void SpellCastTargets::write (WorldPacket * data) +void SpellCastTargets::write (ByteBuffer & data) { - *data << uint32(m_targetMask); - //sLog.outDebug("Spell write, target mask = %u", m_targetMask); + data << uint32(m_targetMask); if (m_targetMask & (TARGET_FLAG_UNIT | TARGET_FLAG_PVP_CORPSE | TARGET_FLAG_OBJECT | TARGET_FLAG_CORPSE | TARGET_FLAG_UNK17)) { if (m_targetMask & TARGET_FLAG_UNIT) { if (m_unitTarget) - data->append(m_unitTarget->GetPackGUID()); + data.append(m_unitTarget->GetPackGUID()); else - *data << uint8(0); + data << uint8(0); } else if (m_targetMask & TARGET_FLAG_OBJECT) { if(m_GOTarget) - data->append(m_GOTarget->GetPackGUID()); + data.append(m_GOTarget->GetPackGUID()); else - *data << uint8(0); + data << uint8(0); } else if (m_targetMask & ( TARGET_FLAG_CORPSE | TARGET_FLAG_PVP_CORPSE)) - data->appendPackGUID(m_CorpseTargetGUID); + data.appendPackGUID(m_CorpseTargetGUID); else - *data << uint8(0); + data << uint8(0); } if (m_targetMask & ( TARGET_FLAG_ITEM | TARGET_FLAG_TRADE_ITEM)) { if(m_itemTarget) - data->append(m_itemTarget->GetPackGUID()); + data.append(m_itemTarget->GetPackGUID()); else - *data << uint8(0); + data << uint8(0); } if (m_targetMask & TARGET_FLAG_SOURCE_LOCATION) { - *data << uint8(0); // relative position guid here - transport for example - *data << m_srcPos.PositionXYZStream(); + data.appendPackGUID(m_srcTransGUID); // relative position guid here - transport for example + if (m_srcTransGUID) + data << m_srcTransOffset.PositionXYZStream(); + else + data << m_srcPos.PositionXYZStream(); } if (m_targetMask & TARGET_FLAG_DEST_LOCATION) { - *data << uint8(0); // relative position guid here - transport for example - *data << m_dstPos.PositionXYZStream(); + data.appendPackGUID(m_dstTransGUID); // relative position guid here - transport for example + if (m_dstTransGUID) + data << m_dstTransOffset.PositionXYZStream(); + else + data << m_dstPos.PositionXYZStream(); } if (m_targetMask & TARGET_FLAG_STRING) - *data << m_strTarget; + data << m_strTarget; } Spell::Spell(Unit* Caster, SpellEntry const *info, bool triggered, uint64 originalCasterGUID, Spell** triggeringContainer, bool skipCheck) @@ -1919,7 +1999,6 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur) break; case TARGET_UNIT_CASTER_FISHING: { - //AddUnitTarget(m_caster, i); float min_dis = GetSpellMinRange(m_spellInfo, true); float max_dis = GetSpellMaxRange(m_spellInfo, true); float dis = rand_norm() * (max_dis - min_dis) + min_dis; @@ -2065,12 +2144,12 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur) { if (cur == TARGET_SRC_CASTER) { - m_targets.setSrc(m_caster); + m_targets.setSrc(*m_caster); break; } else if (cur == TARGET_DST_CASTER) { - m_targets.setDst(m_caster); + m_targets.setDst(*m_caster); break; } @@ -2104,7 +2183,8 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur) m_caster->GetFirstCollisionPosition(pos, dist, angle); else m_caster->GetNearPosition(pos, dist, angle); - m_targets.setDst(&pos); // also flag + m_targets.setDst(*m_caster); + m_targets.modDst(pos); break; } @@ -2119,7 +2199,7 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur) if (cur == TARGET_DST_TARGET_ENEMY || cur == TARGET_DEST_TARGET_ANY) { - m_targets.setDst(target); + m_targets.setDst(*target); break; } @@ -2147,7 +2227,8 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur) Position pos; target->GetNearPosition(pos, dist, angle); - m_targets.setDst(&pos); + m_targets.setDst(*target); + m_targets.modDst(pos); break; } @@ -2187,7 +2268,9 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur) dist *= rand_norm(); // must has dst, no need to set flag - m_caster->MovePosition(m_targets.m_dstPos, dist, angle); + Position pos = m_targets.m_dstPos; + m_caster->MovePosition(pos, dist, angle); + m_targets.modDst(pos); break; } @@ -2212,7 +2295,7 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur) Unit *target = NULL; if (uint64 guid = m_caster->GetUInt64Value(UNIT_FIELD_TARGET)) target = ObjectAccessor::GetUnit(*m_caster, guid); - m_targets.setDst(target ? target : m_caster); + m_targets.setDst(target ? *target : *m_caster); } break; case TARGET_DST_HOME: @@ -2225,7 +2308,7 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur) if (modOwner) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this); if (WorldObject *target = SearchNearbyTarget(range, SPELL_TARGETS_ENTRY)) - m_targets.setDst(target); + m_targets.setDst(*target); break; } } @@ -2253,7 +2336,7 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur) if (m_originalCaster->GetCurrentSpell(CURRENT_CHANNELED_SPELL)->m_targets.HasDst()) m_targets = m_originalCaster->GetCurrentSpell(CURRENT_CHANNELED_SPELL)->m_targets; else if (Unit* target = Unit::GetUnit(*m_caster, m_originalCaster->GetCurrentSpell(CURRENT_CHANNELED_SPELL)->m_targets.getUnitTargetGUID())) - m_targets.setDst(target); + m_targets.setDst(*target); else sLog.outError("SPELL: cannot find channel spell destination for spell ID %u", m_spellInfo->Id); break; @@ -2418,7 +2501,7 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur) switch(result->GetTypeId()) { case TYPEID_UNIT: - m_targets.setDst(result); + m_targets.setDst(*result); } } break; @@ -2774,7 +2857,7 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const * triggere } } if (!m_targets.HasSrc() && m_spellInfo->Targets & TARGET_FLAG_SOURCE_LOCATION) - m_targets.setSrc(m_caster); + m_targets.setSrc(*m_caster); if (!m_targets.HasDst() && m_spellInfo->Targets & TARGET_FLAG_DEST_LOCATION) { @@ -2788,7 +2871,7 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const * triggere } if (target) - m_targets.setDst(target); + m_targets.setDst(*target); else { SendCastResult(SPELL_FAILED_BAD_TARGETS); @@ -3358,7 +3441,7 @@ void Spell::_handle_immediate_phase() if (EffectTargetType[m_spellInfo->Effect[j]] == SPELL_REQUIRE_DEST) { if (!m_targets.HasDst()) // FIXME: this will ignore dest set in effect - m_targets.setDst(m_caster); + m_targets.setDst(*m_caster); HandleEffects(m_originalCaster, NULL, NULL, j); m_effectMask |= (1<<j); } @@ -3755,7 +3838,7 @@ void Spell::SendSpellStart() data << uint32(castFlags); // cast flags data << uint32(m_timer); // delay? - m_targets.write(&data); + m_targets.write(data); if (castFlags & CAST_FLAG_POWER_LEFT_SELF) data << uint32(m_caster->GetPower((Powers)m_spellInfo->powerType)); @@ -3833,7 +3916,7 @@ void Spell::SendSpellGo() WriteSpellGoTargets(&data); - m_targets.write(&data); + m_targets.write(data); if (castFlags & CAST_FLAG_POWER_LEFT_SELF) data << uint32(m_caster->GetPower((Powers)m_spellInfo->powerType)); @@ -4693,7 +4776,7 @@ SpellCastResult Spell::CheckCast(bool strict) if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->ToPlayer()->isMoving()) { // skip stuck spell to allow use it in falling case and apply spell limitations at movement - if ((!m_caster->ToPlayer()->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FALLING) || m_spellInfo->Effect[0] != SPELL_EFFECT_STUCK) && + if ((!m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING) || m_spellInfo->Effect[0] != SPELL_EFFECT_STUCK) && (IsAutoRepeat() || (m_spellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) != 0)) return SPELL_FAILED_MOVING; } @@ -5543,9 +5626,6 @@ SpellCastResult Spell::CheckCast(bool strict) if (m_caster->IsInWater()) return SPELL_FAILED_ONLY_ABOVEWATER; - if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->ToPlayer()->GetTransport()) - return SPELL_FAILED_NO_MOUNTS_ALLOWED; - // Ignore map check if spell have AreaId. AreaId already checked and this prevent special mount spells bool AllowMount = !m_caster->GetMap()->IsDungeon() || m_caster->GetMap()->IsBattlegroundOrArena(); InstanceTemplate const *it = sObjectMgr.GetInstanceTemplate(m_caster->GetMapId()); @@ -7168,7 +7248,9 @@ void Spell::SelectTrajTargets() } } - m_targets.setDst(x, y, z, m_caster->GetOrientation()); + Position trajDst; + trajDst.Relocate(x, y, z, m_caster->GetOrientation()); + m_targets.modDst(trajDst); } } diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 9245436a6dc..5c77782f654 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -29,10 +29,12 @@ class Unit; class Player; class GameObject; class DynamicObject; +class WorldObject; class Aura; -struct SpellEntry; class SpellScript; +struct SpellEntry; + enum SpellCastTargetFlags { TARGET_FLAG_SELF = 0x00000000, @@ -131,9 +133,6 @@ class SpellCastTargets SpellCastTargets(); ~SpellCastTargets(); - bool read (WorldPacket * data, Unit *caster); - void write (WorldPacket * data); - SpellCastTargets& operator=(const SpellCastTargets &target) { m_unitTarget = target.m_unitTarget; @@ -147,7 +146,12 @@ class SpellCastTargets m_itemTargetEntry = target.m_itemTargetEntry; + m_srcTransGUID = target.m_srcTransGUID; + m_srcTransOffset = target.m_srcTransOffset; m_srcPos = target.m_srcPos; + + m_dstTransGUID = target.m_dstTransGUID; + m_dstTransOffset = target.m_dstTransOffset; m_dstPos.Relocate(target.m_dstPos); m_elevation = target.m_elevation; @@ -159,6 +163,8 @@ class SpellCastTargets return *this; } + void read (ByteBuffer & data, Unit * caster); + void write (ByteBuffer & data); uint32 getTargetMask() const { return m_targetMask; } void setTargetMask(uint32 newMask) { m_targetMask = newMask; } @@ -167,9 +173,13 @@ class SpellCastTargets Unit *getUnitTarget() const { return m_unitTarget; } void setUnitTarget(Unit *target); void setSrc(float x, float y, float z); - void setSrc(Position *pos); + void setSrc(Position &pos); + void setSrc(WorldObject &wObj); + void modSrc(Position &pos); void setDst(float x, float y, float z, float orientation, uint32 mapId = MAPID_INVALID); - void setDst(Position *pos); + void setDst(Position &pos); + void setDst(WorldObject &wObj); + void modDst(Position &pos); uint64 getGOTargetGUID() const { return m_GOTargetGUID; } GameObject *getGOTarget() const { return m_GOTarget; } @@ -201,8 +211,13 @@ class SpellCastTargets float GetSpeedZ() const { return m_speed * sin(m_elevation); } void Update(Unit* caster); + void OutDebug(); + uint64 m_srcTransGUID; + Position m_srcTransOffset; Position m_srcPos; + uint64 m_dstTransGUID; + Position m_dstTransOffset; WorldLocation m_dstPos; float m_elevation, m_speed; std::string m_strTarget; @@ -451,8 +466,8 @@ class Spell bool CheckTarget(Unit* target, uint32 eff); bool CanAutoCast(Unit* target); - void CheckSrc() { if (!m_targets.HasSrc()) m_targets.setSrc(m_caster); } - void CheckDst() { if (!m_targets.HasDst()) m_targets.setDst(m_caster); } + void CheckSrc() { if (!m_targets.HasSrc()) m_targets.setSrc(*m_caster); } + void CheckDst() { if (!m_targets.HasDst()) m_targets.setDst(*m_caster); } static void SendCastResult(Player* caster, SpellEntry const* spellInfo, uint8 cast_count, SpellCastResult result); void SendCastResult(SpellCastResult result); diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 0405b8a8a33..645f050a21e 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -1815,11 +1815,11 @@ void Spell::EffectDummy(uint32 i) if (m_targets.HasDst()) { - targets.setDst(&m_targets.m_dstPos); + targets.setDst(m_targets.m_dstPos); } else { - targets.setDst(m_caster); + targets.setDst(*m_caster); // Corpse not found - take reagents (only not triggered cast can take them) triggered = false; } @@ -1831,7 +1831,7 @@ void Spell::EffectDummy(uint32 i) else if (m_spellInfo->Id == 48289) { if (m_targets.HasDst()) - targets.setDst(&m_targets.m_dstPos); + targets.setDst(m_targets.m_dstPos); spell_id = CalculateDamage(0, NULL); } diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h index de0d2d620bb..5534519bbc1 100644 --- a/src/server/shared/Packets/ByteBuffer.h +++ b/src/server/shared/Packets/ByteBuffer.h @@ -254,6 +254,11 @@ class ByteBuffer return _rpos; } + void rfinish() + { + _rpos = wpos(); + } + size_t wpos() const { return _wpos; } size_t wpos(size_t wpos_) @@ -296,10 +301,10 @@ class ByteBuffer _rpos += len; } - bool readPackGUID(uint64& guid) + void readPackGUID(uint64& guid) { if(rpos() + 1 > size()) - return false; + throw ByteBufferException(false, _rpos, 1, size()); guid = 0; @@ -311,15 +316,13 @@ class ByteBuffer if(guidmark & (uint8(1) << i)) { if(rpos() + 1 > size()) - return false; + throw ByteBufferException(false, _rpos, 1, size()); uint8 bit; (*this) >> bit; guid |= (uint64(bit) << (i * 8)); } } - - return true; } const uint8 *contents() const { return &_storage[0]; } |