int32 MoveSplineInit::Launch() { MoveSpline& move_spline = *unit->movespline; Location real_position(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZMinusOffset(), unit->GetOrientation()); // Elevators also use MOVEMENTFLAG_ONTRANSPORT but we do not keep track of their position changes if (unit->GetTransGUID()) { real_position.x = unit->GetTransOffsetX(); real_position.y = unit->GetTransOffsetY(); real_position.z = unit->GetTransOffsetZ(); real_position.orientation = unit->GetTransOffsetO(); } // there is a big chance that current position is unknown if current state is not finalized, need compute it // this also allows calculate spline position and update map position in much greater intervals // Don't compute for transport movement if the unit is in a motion between two transports if (!move_spline.Finalized() && move_spline.onTransport == (unit->GetTransGUID() != 0)) real_position = move_spline.ComputePosition(); // should i do the things that user should do? - no. if (args.path.empty()) return 0; // correct first vertex args.path[0] = real_position; args.initialOrientation = real_position.orientation; move_spline.onTransport = (unit->GetTransGUID() != 0); uint32 moveFlags = unit->m_movementInfo.GetMovementFlags(); moveFlags |= MOVEMENTFLAG_FORWARD; if (moveFlags & MOVEMENTFLAG_ROOT) moveFlags &= ~MOVEMENTFLAG_MASK_MOVING; if (!args.HasVelocity) { // If spline is initialized with SetWalk method it only means we need to select // walk move speed for it but not add walk flag to unit uint32 moveFlagsForSpeed = moveFlags; if (args.flags.walkmode) moveFlagsForSpeed |= MOVEMENTFLAG_WALKING; else moveFlagsForSpeed &= ~MOVEMENTFLAG_WALKING; args.velocity = unit->GetSpeed(SelectSpeedType(moveFlagsForSpeed)); } if (!args.Validate(unit)) return 0; unit->m_movementInfo.SetMovementFlags(moveFlags); move_spline.Initialize(args); WorldPacket data(SMSG_MONSTER_MOVE, 64); PacketBuilder::WriteMonsterMove(move_spline, data, unit); unit->SendMessageToSet(&data, true); return move_spline.Duration(); }
void MoveSplineInit::Launch() { MoveSpline& move_spline = *unit.movespline; bool transport = false; Location real_position(unit.GetPositionX(), unit.GetPositionY(), unit.GetPositionZMinusOffset(), unit.GetOrientation()); // Elevators also use MOVEMENTFLAG_ONTRANSPORT but we do not keep track of their position changes if (unit.HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && unit.GetTransGUID()) { transport = true; real_position.x = unit.GetTransOffsetX(); real_position.y = unit.GetTransOffsetY(); real_position.z = unit.GetTransOffsetZ(); real_position.orientation = unit.GetTransOffsetO(); } // there is a big chance that current position is unknown if current state is not finalized, need compute it // this also allows calculate spline position and update map position in much greater intervals if (!move_spline.Finalized()) real_position = move_spline.ComputePosition(); // should i do the things that user should do? - no. if (args.path.empty()) return; // corrent first vertex args.path[0] = real_position; args.initialOrientation = real_position.orientation; uint32 moveFlags = unit.m_movementInfo.GetMovementFlags(); if (args.flags.walkmode) moveFlags |= MOVEMENTFLAG_WALKING; else moveFlags &= ~MOVEMENTFLAG_WALKING; moveFlags |= (MOVEMENTFLAG_SPLINE_ENABLED|MOVEMENTFLAG_FORWARD); if (!args.HasVelocity) args.velocity = unit.GetSpeed(SelectSpeedType(moveFlags)); if (!args.Validate()) return; if (moveFlags & MOVEMENTFLAG_ROOT) moveFlags &= ~MOVEMENTFLAG_MASK_MOVING; unit.m_movementInfo.SetMovementFlags((MovementFlags)moveFlags); move_spline.Initialize(args); WorldPacket data(!transport ? SMSG_MONSTER_MOVE : SMSG_MONSTER_MOVE_TRANSPORT, 64); data.append(unit.GetPackGUID()); if (transport) { data.appendPackGUID(unit.GetTransGUID()); data << int8(unit.GetTransSeat()); } PacketBuilder::WriteMonsterMove(move_spline, data); unit.SendMessageToSet(&data,true); }
int32 MoveSplineInit::Launch() { MoveSpline& move_spline = *unit.movespline; TransportInfo* transportInfo = unit.GetTransportInfo(); Location real_position(unit.GetPositionX(), unit.GetPositionY(), unit.GetPositionZ(), unit.GetOrientation()); // If boarded use current local position if (transportInfo) transportInfo->GetLocalPosition(real_position.x, real_position.y, real_position.z, real_position.orientation); // there is a big chane that current position is unknown if current state is not finalized, need compute it // this also allows calculate spline position and update map position in much greater intervals if (!move_spline.Finalized() && !transportInfo) real_position = move_spline.ComputePosition(); if (args.path.empty()) { // should i do the things that user should do? MoveTo(real_position); } // corrent first vertex args.path[0] = real_position; args.initialOrientation = real_position.orientation; uint32 moveFlags = unit.m_movementInfo.GetMovementFlags(); if (args.flags.walkmode) moveFlags |= MOVEFLAG_WALK_MODE; else moveFlags &= ~MOVEFLAG_WALK_MODE; moveFlags |= (MOVEFLAG_SPLINE_ENABLED | MOVEFLAG_FORWARD); if (args.velocity == 0.f) args.velocity = unit.GetSpeed(SelectSpeedType(moveFlags)); if (!args.Validate(&unit)) return 0; unit.m_movementInfo.SetMovementFlags((MovementFlags)moveFlags); move_spline.Initialize(args); WorldPacket data(SMSG_MONSTER_MOVE, 64); data << unit.GetPackGUID(); if (transportInfo) { data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT); data << transportInfo->GetTransportGuid().WriteAsPacked(); data << int8(transportInfo->GetTransportSeat()); } PacketBuilder::WriteMonsterMove(move_spline, data); unit.SendMessageToSet(&data, true); return move_spline.Duration(); }
int32 MoveSplineInit::Launch(int32 maxTravelTime, bool hideMovement) { MoveSpline& move_spline = *unit.movespline; Vector3 real_position(unit.GetPositionX(), unit.GetPositionY(), unit.GetPositionZ()); // there is a big chane that current position is unknown if current state is not finalized, need compute it // this also allows calculate spline position and update map position in much greater intervals if (!move_spline.Finalized()) real_position = move_spline.ComputePosition(); if (args.path.empty()) { // should i do the things that user should do? MoveTo(real_position); } // corrent first vertex args.path[0] = real_position; uint32 moveFlags = unit.m_movementInfo.GetMovementFlags(); if (args.flags.runmode) moveFlags &= ~MOVEFLAG_WALK_MODE; else moveFlags |= MOVEFLAG_WALK_MODE; moveFlags |= (MOVEFLAG_SPLINE_ENABLED | MOVEFLAG_FORWARD); if (args.velocity == 0.f) args.velocity = unit.GetSpeed(SelectSpeedType(moveFlags)); if (!args.Validate(&unit)) return 0; unit.m_movementInfo.SetMovementFlags((MovementFlags)moveFlags); move_spline.Initialize(args); auto duration = move_spline.Duration(); if (maxTravelTime && duration > maxTravelTime) { auto dest = args.path[args.path.size() - 1]; dest.z += 1.f; args.path_Idx_offset = 0; args.path.resize(2); args.path[1] = dest; move_spline.Initialize(args); } if (hideMovement) return duration; WorldPacket data(SMSG_MONSTER_MOVE, 64); data << unit.GetPackGUID(); PacketBuilder::WriteMonsterMove(move_spline, data); unit.SendMessageToSet(&data, true); return duration; }
// void MoveSplineInit::Launch() int32 MoveSplineInit::Launch() { MoveSpline& move_spline = *unit.movespline; Location real_position(unit.GetPositionX(),unit.GetPositionY(),unit.GetPositionZ(),unit.GetOrientation()); // there is a big chane that current position is unknown if current state is not finalized, need compute it // this also allows calculate spline position and update map position in much greater intervals if (!move_spline.Finalized()) real_position = move_spline.ComputePosition(); if (args.path.empty()) { // should i do the things that user should do? MoveTo(real_position); } // corrent first vertex args.path[0] = real_position; args.initialOrientation = real_position.orientation; uint32 moveFlags = unit._movementInfo.GetMovementFlags(); if (args.flags.walkmode) moveFlags |= MOVEMENTFLAG_WALKING; else moveFlags &= ~MOVEMENTFLAG_WALKING; moveFlags |= (MOVEMENTFLAG_SPLINE_ENABLED|MOVEMENTFLAG_FORWARD); if (args.velocity == 0.f) args.velocity = unit.GetSpeed(SelectSpeedType(moveFlags)); if (!args.Validate()) return 0; if (moveFlags & MOVEMENTFLAG_ROOT) moveFlags &= ~MOVEMENTFLAG_MASK_MOVING; unit._movementInfo.SetMovementFlags((MovementFlags)moveFlags); move_spline.Initialize(args); WorldPacket data(SMSG_MONSTER_MOVE, 64); data.append(unit.GetPackGUID()); PacketBuilder::WriteMonsterMove(move_spline, data); unit.SendMessageToSet(&data, true); return move_spline.Duration(); }
int32 MoveSplineInit::Launch() { MoveSpline& move_spline = *unit.movespline; Vector3 real_position(unit.GetPositionX(), unit.GetPositionY(), unit.GetPositionZ()); // there is a big chane that current position is unknown if current state is not finalized, need compute it // this also allows calculate spline position and update map position in much greater intervals if (!move_spline.Finalized()) { real_position = move_spline.ComputePosition(); } if (args.path.empty()) { // should i do the things that user should do? MoveTo(real_position); } // corrent first vertex args.path[0] = real_position; uint32 moveFlags = unit.m_movementInfo.GetMovementFlags(); if (args.flags.runmode) { moveFlags &= ~MOVEFLAG_WALK_MODE; } else { moveFlags |= MOVEFLAG_WALK_MODE; } moveFlags |= (MOVEFLAG_MOVE_FORWARD); if (args.velocity == 0.f) { args.velocity = unit.GetSpeed(SelectSpeedType(moveFlags)); } if (!args.Validate(&unit)) { return 0; } unit.m_movementInfo.SetMovementFlags((MovementFlags)moveFlags); move_spline.Initialize(args); WorldPacket data(SMSG_MONSTER_MOVE, 64); data << unit.GetPackGUID(); PacketBuilder::WriteMonsterMove(move_spline, data); unit.SendMessageToSet(&data, true); return move_spline.Duration(); }
int32 MoveSplineInit::Launch() { MoveSpline& move_spline = *unit->movespline; bool transport = !unit->GetTransGUID().IsEmpty(); Location real_position; // there is a big chance that current position is unknown if current state is not finalized, need compute it // this also allows calculate spline position and update map position in much greater intervals // Don't compute for transport movement if the unit is in a motion between two transports if (!move_spline.Finalized() && move_spline.onTransport == transport) real_position = move_spline.ComputePosition(); else { Position const* pos; if (!transport) pos = unit; else pos = &unit->m_movementInfo.transport.pos; real_position.x = pos->GetPositionX(); real_position.y = pos->GetPositionY(); real_position.z = pos->GetPositionZ(); real_position.orientation = unit->GetOrientation(); } // should i do the things that user should do? - no. if (args.path.empty()) return 0; // correct first vertex args.path[0] = real_position; args.initialOrientation = real_position.orientation; move_spline.onTransport = !unit->GetTransGUID().IsEmpty(); uint32 moveFlags = unit->m_movementInfo.GetMovementFlags(); moveFlags |= MOVEMENTFLAG_FORWARD; if (moveFlags & MOVEMENTFLAG_ROOT) moveFlags &= ~MOVEMENTFLAG_MASK_MOVING; if (!args.HasVelocity) { // If spline is initialized with SetWalk method it only means we need to select // walk move speed for it but not add walk flag to unit uint32 moveFlagsForSpeed = moveFlags; if (args.flags.walkmode) moveFlagsForSpeed |= MOVEMENTFLAG_WALKING; else moveFlagsForSpeed &= ~MOVEMENTFLAG_WALKING; args.velocity = unit->GetSpeed(SelectSpeedType(moveFlagsForSpeed)); } if (!args.Validate(unit)) return 0; unit->m_movementInfo.SetMovementFlags(moveFlags); move_spline.Initialize(args); WorldPackets::Movement::MonsterMove packet; packet.MoverGUID = unit->GetGUID(); packet.Pos = real_position; packet.InitializeSplineData(move_spline); if (transport) { packet.SplineData.Move.TransportGUID = unit->GetTransGUID(); packet.SplineData.Move.VehicleSeat = unit->GetTransSeat(); } unit->SendMessageToSet(packet.Write(), true); return move_spline.Duration(); }
int32 MoveSplineInit::Launch() { MoveSpline& move_spline = *unit->movespline; bool transport = unit->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && unit->GetTransGUID(); Location real_position; // there is a big chance that current position is unknown if current state is not finalized, need compute it // this also allows CalculatePath spline position and update map position in much greater intervals // Don't compute for transport movement if the unit is in a motion between two transports if (!move_spline.Finalized() && move_spline.onTransport == transport) real_position = move_spline.ComputePosition(); else { Position const* pos; if (!transport) pos = unit; else pos = &unit->m_movementInfo.transport.pos; real_position.x = pos->GetPositionX(); real_position.y = pos->GetPositionY(); real_position.z = pos->GetPositionZ(); real_position.orientation = unit->GetOrientation(); } // should i do the things that user should do? - no. if (args.path.empty()) return 0; // corrent first vertex args.path[0] = real_position; args.initialOrientation = real_position.orientation; move_spline.onTransport = transport; uint32 moveFlags = unit->m_movementInfo.GetMovementFlags(); moveFlags |= (MOVEMENTFLAG_SPLINE_ENABLED|MOVEMENTFLAG_FORWARD); if (moveFlags & MOVEMENTFLAG_ROOT) moveFlags &= ~MOVEMENTFLAG_MASK_MOVING; if (!args.HasVelocity) { // If spline is initialized with SetWalk method it only means we need to select // walk move speed for it but not add walk flag to unit uint32 moveFlagsForSpeed = moveFlags; if (args.flags.walkmode) moveFlagsForSpeed |= MOVEMENTFLAG_WALKING; else moveFlagsForSpeed &= ~MOVEMENTFLAG_WALKING; args.velocity = unit->GetSpeed(SelectSpeedType(moveFlagsForSpeed)); } if (!args.Validate(unit)) return 0; unit->m_movementInfo.SetMovementFlags(moveFlags); move_spline.Initialize(args); WorldPacket data(SMSG_MONSTER_MOVE, 64); data.append(unit->GetPackGUID()); if (transport) { data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT); data.appendPackGUID(unit->GetTransGUID()); data << int8(unit->GetTransSeat()); } Movement::SplineBase::ControlArray* visualPoints = const_cast<Movement::SplineBase::ControlArray*>(move_spline._Spline().allocateVisualPoints()); visualPoints->resize(move_spline._Spline().getPointCount()); // Xinef: Apply hover in creature movement packet if (unit->IsHovering()) std::transform(move_spline._Spline().getPoints(false).begin(), move_spline._Spline().getPoints(false).end(), visualPoints->begin(), HoverMovementTransform(unit->GetHoverHeight())); else std::copy(move_spline._Spline().getPoints(false).begin(), move_spline._Spline().getPoints(false).end(), visualPoints->begin()); PacketBuilder::WriteMonsterMove(move_spline, data); unit->SendMessageToSet(&data,true); return move_spline.Duration(); }
int32 MoveSplineInit::Launch() { float realSpeedRun = 0.0f; MoveSpline& move_spline = *unit.movespline; Transport* newTransport = NULL; if (args.transportGuid) newTransport = HashMapHolder<Transport>::Find(ObjectGuid(HIGHGUID_MO_TRANSPORT, args.transportGuid)); Vector3 real_position(unit.GetPositionX(), unit.GetPositionY(), unit.GetPositionZ()); // there is a big chance that current position is unknown if current state is not finalized, need compute it // this also allows calculate spline position and update map position in much greater intervals if (!move_spline.Finalized()) { real_position = move_spline.ComputePosition(); Transport* oldTransport = NULL; if (move_spline.GetTransportGuid()) oldTransport = HashMapHolder<Transport>::Find(ObjectGuid(HIGHGUID_MO_TRANSPORT, move_spline.GetTransportGuid())); if (oldTransport) oldTransport->CalculatePassengerPosition(real_position.x, real_position.y, real_position.z); } if (newTransport) newTransport->CalculatePassengerOffset(real_position.x, real_position.y, real_position.z); if (args.path.empty()) { // should i do the things that user should do? MoveTo(real_position); } // corrent first vertex args.path[0] = real_position; uint32 moveFlags = unit.m_movementInfo.GetMovementFlags(); uint32 oldMoveFlags = moveFlags; if (args.flags.done) { args.flags = MoveSplineFlag::Done; moveFlags &= ~(MOVEFLAG_SPLINE_ENABLED | MOVEFLAG_MASK_MOVING); } else { moveFlags |= (MOVEFLAG_SPLINE_ENABLED | MOVEFLAG_FORWARD); if (args.flags.runmode) moveFlags &= ~MOVEFLAG_WALK_MODE; else moveFlags |= MOVEFLAG_WALK_MODE; } if (newTransport) moveFlags |= MOVEFLAG_ONTRANSPORT; else moveFlags &= ~MOVEFLAG_ONTRANSPORT; if (args.velocity == 0.f) realSpeedRun = args.velocity = unit.GetSpeed(SelectSpeedType(moveFlags)); else realSpeedRun = unit.GetSpeed(MOVE_RUN); if (!args.Validate(&unit)) return 0; unit.m_movementInfo.SetMovementFlags((MovementFlags)moveFlags); unit.clearUnitState(UNIT_STAT_CLIENT_ROOT); move_spline.SetMovementOrigin(movementType); move_spline.Initialize(args); WorldPacket data(SMSG_MONSTER_MOVE, 64); data << unit.GetPackGUID(); if (newTransport) { data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT); data << newTransport->GetPackGUID(); } if (unit.GetTransport() && unit.GetTransport() != newTransport) unit.GetTransport()->RemovePassenger(&unit); if (newTransport && unit.GetTransport() != newTransport) newTransport->AddPassenger(&unit); // Stop packet if (args.flags.done) { data << real_position.x << real_position.y << real_position.z; data << move_spline.GetId(); data << uint8(1); // MonsterMoveStop=1 } else move_spline.setLastPointSent(PacketBuilder::WriteMonsterMove(move_spline, data)); // Compress data or not ? bool compress = false; if (!args.flags.done && args.velocity > 4 * realSpeedRun) compress = true; else if ((data.wpos() + 2) > 0x10) compress = true; else if (unit.hasUnitState(UNIT_STAT_CLIENT_ROOT)) compress = true; // Since packet size is stored with an uint8, packet size is limited for compressed packets if ((data.wpos() + 2) > 0xFF) compress = false; MovementData mvtData(compress ? NULL : &unit); // Nostalrius: client has a hardcoded limit to spline movement speed : 4*runSpeed. // We need to fix this, in case of charges for example (if character has movement slowing effects) if (args.velocity > 4 * realSpeedRun && !args.flags.done) // From client mvtData.SetUnitSpeed(SMSG_SPLINE_SET_RUN_SPEED, unit.GetObjectGuid(), args.velocity); if (unit.hasUnitState(UNIT_STAT_CLIENT_ROOT)) mvtData.SetSplineOpcode(SMSG_SPLINE_MOVE_UNROOT, unit.GetObjectGuid()); if (oldMoveFlags & MOVEFLAG_WALK_MODE && !(moveFlags & MOVEFLAG_WALK_MODE)) // Switch to run mode mvtData.SetSplineOpcode(SMSG_SPLINE_MOVE_SET_RUN_MODE, unit.GetObjectGuid()); if (moveFlags & MOVEFLAG_WALK_MODE && !(oldMoveFlags & MOVEFLAG_WALK_MODE)) // Switch to walk mode mvtData.SetSplineOpcode(SMSG_SPLINE_MOVE_SET_WALK_MODE, unit.GetObjectGuid()); mvtData.AddPacket(data); // Do not forget to restore velocity after movement ! if (args.velocity > 4 * realSpeedRun && !args.flags.done) mvtData.SetUnitSpeed(SMSG_SPLINE_SET_RUN_SPEED, unit.GetObjectGuid(), realSpeedRun); // Restore correct walk mode for players if (unit.GetTypeId() == TYPEID_PLAYER && (moveFlags & MOVEFLAG_WALK_MODE) != (oldMoveFlags & MOVEFLAG_WALK_MODE)) mvtData.SetSplineOpcode(oldMoveFlags & MOVEFLAG_WALK_MODE ? SMSG_SPLINE_MOVE_SET_WALK_MODE : SMSG_SPLINE_MOVE_SET_RUN_MODE, unit.GetObjectGuid()); if (compress) { WorldPacket data2; mvtData.BuildPacket(data2); unit.SendMovementMessageToSet(std::move(data2), true); } return move_spline.Duration(); }
int32 MoveSplineInit<Unit*>::Launch() { MoveSpline& move_spline = *unit.movespline; TransportInfo* transportInfo = unit.GetTransportInfo(); Position real_position = transportInfo ? transportInfo->GetLocalPosition() : unit.GetPosition(); // there is a big chane that current position is unknown if current state is not finalized, need compute it // this also allows calculate spline position and update map position in much greater intervals if (!move_spline.Finalized() && !transportInfo) real_position = move_spline.ComputePosition(); if (args.path.empty()) { // form final position only for rotate if (!args.flags.isFacing()) return 0; MoveTo(real_position); } else { // check path equivalence if (!args.flags.isFacing() && args.path[0] == args.path[args.path.size() - 1]) return 0; } // corrent first vertex args.path[0] = real_position; args.initialOrientation = real_position.orientation; uint32 moveFlags = unit.m_movementInfo.GetMovementFlags(); if (args.flags.walkmode) moveFlags |= MOVEFLAG_WALK_MODE; else moveFlags &= ~MOVEFLAG_WALK_MODE; moveFlags |= (MOVEFLAG_SPLINE_ENABLED | MOVEFLAG_FORWARD); if (fabs(args.velocity) < M_NULL_F) args.velocity = unit.GetSpeed(SelectSpeedType(moveFlags)); if (!args.Validate(&unit)) return 0; if (moveFlags & MOVEFLAG_ROOT) moveFlags &= ~MOVEFLAG_MASK_MOVING; unit.m_movementInfo.SetMovementFlags((MovementFlags)moveFlags); move_spline.Initialize(args); WorldPacket data(SMSG_MONSTER_MOVE, 64); data << unit.GetPackGUID(); if (transportInfo) { data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT); data << transportInfo->GetTransportGuid().WriteAsPacked(); data << int8(transportInfo->GetTransportSeat()); } PacketBuilder::WriteMonsterMove(move_spline, data); unit.SendMessageToSet(&data, true); return move_spline.Duration(); }
int32 MoveSplineInit::Launch() { MoveSpline& move_spline = *unit->movespline; // Elevators also use MOVEMENTFLAG_ONTRANSPORT but we do not keep track of their position changes (movementInfo.transport.guid is 0 in that case) bool transport = unit->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && unit->GetTransGUID(); Location real_position; // there is a big chance that current position is unknown if current state is not finalized, need compute it // this also allows CalculatePath spline position and update map position in much greater intervals // Don't compute for transport movement if the unit is in a motion between two transports if (!move_spline.Finalized() && move_spline.onTransport == transport) real_position = move_spline.ComputePosition(); else { Position const* pos; if (!transport) pos = unit; else pos = &unit->m_movementInfo.transport.pos; real_position.x = pos->GetPositionX(); real_position.y = pos->GetPositionY(); real_position.z = pos->GetPositionZ(); real_position.orientation = unit->GetOrientation(); } // should i do the things that user should do? - no. if (args.path.empty()) return 0; // corrent first vertex args.path[0] = real_position; args.initialOrientation = real_position.orientation; move_spline.onTransport = transport; uint32 moveFlags = unit->m_movementInfo.GetMovementFlags(); moveFlags |= MOVEMENTFLAG_SPLINE_ENABLED; if (!args.flags.backward) moveFlags = (moveFlags & ~(MOVEMENTFLAG_BACKWARD)) | MOVEMENTFLAG_FORWARD; else moveFlags = (moveFlags & ~(MOVEMENTFLAG_FORWARD)) | MOVEMENTFLAG_BACKWARD; if (moveFlags & MOVEMENTFLAG_ROOT) moveFlags &= ~MOVEMENTFLAG_MASK_MOVING; if (!args.HasVelocity) { // If spline is initialized with SetWalk method it only means we need to select // walk move speed for it but not add walk flag to unit uint32 moveFlagsForSpeed = moveFlags; if (args.walk) moveFlagsForSpeed |= MOVEMENTFLAG_WALKING; else moveFlagsForSpeed &= ~MOVEMENTFLAG_WALKING; args.velocity = unit->GetSpeed(SelectSpeedType(moveFlagsForSpeed)); } if (!args.Validate(unit)) return 0; unit->m_movementInfo.SetMovementFlags(moveFlags); move_spline.Initialize(args); WorldPacket data(SMSG_MONSTER_MOVE, 64); data << unit->GetPackGUID(); if (transport) { data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT); data << unit->GetTransGUID().WriteAsPacked(); data << int8(unit->GetTransSeat()); } PacketBuilder::WriteMonsterMove(move_spline, data); unit->SendMessageToSet(&data, true); return move_spline.Duration(); }