// Helper function to undo the turning of the vehicle to calculate a relative position of the passenger when boarding void VehicleInfo::CalculateBoardingPositionOf(float gx, float gy, float gz, float go, float& lx, float& ly, float& lz, float& lo) const { NormalizeRotatedPosition(gx - m_owner->GetPositionX(), gy - m_owner->GetPositionY(), lx, ly); lz = gz - m_owner->GetPositionZ(); lo = NormalizeOrientation(go - m_owner->GetOrientation()); }
void PacketBuilder::WriteCommonMonsterMovePart(const MoveSpline& move_spline, WorldPacket& data) { MoveSplineFlag splineflags = move_spline.splineflags; if (move_spline.transportGuid) { //DEBUG_LOG("Setting transport opcode for %s", move_spline.transport->GetGuidStr().c_str()); data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT); data << PackedGuid(move_spline.transportGuid); data << uint8(move_spline.transportSeat); data << uint8(0); data << (Vector3)move_spline.transportPos; } else { data << uint8(0); data << move_spline.spline.getPoint(move_spline.spline.first()); } data << move_spline.GetId(); switch(splineflags & MoveSplineFlag::Mask_Final_Facing) { default: data << uint8(MonsterMoveNormal); break; case MoveSplineFlag::Final_Target: data << uint8(MonsterMoveFacingTarget); data << move_spline.facing.target; break; case MoveSplineFlag::Final_Angle: data << uint8(MonsterMoveFacingAngle); data << NormalizeOrientation(move_spline.facing.angle); break; case MoveSplineFlag::Final_Point: data << uint8(MonsterMoveFacingSpot); data << move_spline.facing.f.x << move_spline.facing.f.y << move_spline.facing.f.z; break; } // add fake Enter_Cycle flag - needed for client-side cyclic movement (client will erase first spline vertex after first cycle done) splineflags.enter_cycle = move_spline.isCyclic(); data << uint32(splineflags & ~MoveSplineFlag::Mask_No_Monster_Move); if (splineflags.animation) { data << splineflags.getAnimationId(); data << move_spline.effect_start_time; } data << move_spline.Duration(); if (splineflags.parabolic) { data << move_spline.vertical_acceleration; data << move_spline.effect_start_time; } }
// Calculate a global position of local positions based on this transporter void TransportBase::CalculateGlobalPositionOf(float lx, float ly, float lz, float lo, float& gx, float& gy, float& gz, float& go) const { RotateLocalPosition(lx, ly, gx, gy); gx += m_owner->GetPositionX(); gy += m_owner->GetPositionY(); gz = lz + m_owner->GetPositionZ(); go = NormalizeOrientation(lo + m_owner->GetOrientation()); }
bool Position::HasInArc(float arc, const Position* obj, float border) const { // always have self in arc if (obj == this) return true; // move arc to range 0.. 2*pi arc = NormalizeOrientation(arc); float angle = GetAngle(obj); angle -= m_orientation; // move angle to range -pi ... +pi angle = NormalizeOrientation(angle); if (angle > float(M_PI)) angle -= 2.0f * float(M_PI); float lborder = -1 * (arc / border); // in range -pi..0 float rborder = (arc / border); // in range 0..pi return ((angle >= lborder) && (angle <= rborder)); }
void PacketBuilder::WriteCommonMonsterMovePart(const MoveSpline& move_spline, WorldPacket& data) { MoveSplineFlag splineflags = move_spline.splineflags; /*if (mov.IsBoarded()) { data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT); data << mov.GetTransport()->Owner.GetPackGUID(); data << int8(mov.m_unused.transport_seat); }*/ data << uint8(0); data << move_spline.spline.getPoint(move_spline.spline.first()); data << move_spline.GetId(); switch (splineflags & MoveSplineFlag::Mask_Final_Facing) { default: data << uint8(MonsterMoveNormal); break; case MoveSplineFlag::Final_Target: data << uint8(MonsterMoveFacingTarget); data << move_spline.facing.target; break; case MoveSplineFlag::Final_Angle: data << uint8(MonsterMoveFacingAngle); data << NormalizeOrientation(move_spline.facing.angle); break; case MoveSplineFlag::Final_Point: data << uint8(MonsterMoveFacingSpot); data << move_spline.facing.f.x << move_spline.facing.f.y << move_spline.facing.f.z; break; } // add fake Enter_Cycle flag - needed for client-side cyclic movement (client will erase first spline vertex after first cycle done) splineflags.enter_cycle = move_spline.isCyclic(); data << uint32(splineflags & ~MoveSplineFlag::Mask_No_Monster_Move); if (splineflags.animation) { data << splineflags.getAnimationId(); data << move_spline.effect_start_time; } data << move_spline.Duration(); if (splineflags.parabolic) { data << move_spline.vertical_acceleration; data << move_spline.effect_start_time; } }
void PacketBuilder::WriteCreateBytes(const MoveSpline& move_spline, ByteBuffer& data) { if (!move_spline.Finalized()) { MoveSplineFlag splineFlags = move_spline.splineflags; uint32 nodes = move_spline.getPath().size(); bool hasSplineStartTime = move_spline.splineflags & (MoveSplineFlag::Trajectory | MoveSplineFlag::Animation); bool hasSplineVerticalAcceleration = (move_spline.splineflags & MoveSplineFlag::Trajectory) && move_spline.effect_start_time < move_spline.Duration(); if (hasSplineVerticalAcceleration) data << float(move_spline.vertical_acceleration); // added in 3.1 data << int32(move_spline.timePassed()); if (move_spline.splineflags & MoveSplineFlag::Final_Angle) data << float(NormalizeOrientation(move_spline.facing.angle)); else if (move_spline.splineflags & MoveSplineFlag::Final_Target) data.WriteGuidBytes<5, 3, 7, 1, 6, 4, 2, 0>(ObjectGuid(move_spline.facing.target)); for (uint32 i = 0; i < nodes; ++i) { data << float(move_spline.getPath()[i].z); data << float(move_spline.getPath()[i].x); data << float(move_spline.getPath()[i].y); } if (move_spline.splineflags & MoveSplineFlag::Final_Point) data << float(move_spline.facing.f.x) << float(move_spline.facing.f.z) << float(move_spline.facing.f.y); data << float(1.f); data << int32(move_spline.Duration()); if (hasSplineStartTime) data << int32(move_spline.effect_start_time); // added in 3.1 data << float(1.f); } if (!move_spline.isCyclic()) { Vector3 dest = move_spline.FinalDestination(); data << float(dest.z); data << float(dest.x); data << float(dest.y); } else data << Vector3::zero(); data << uint32(move_spline.GetId()); }
// Update every now and then (after some change of transporter's position) // This is used to calculate global positions (which don't have to be exact, they are only required for some server-side calculations void TransportBase::Update(uint32 diff) { if (m_updatePositionsTimer < diff) { if (fabs(m_owner->GetPositionX() - m_lastPosition.x) + fabs(m_owner->GetPositionY() - m_lastPosition.y) + fabs(m_owner->GetPositionZ() - m_lastPosition.z) > 1.0f || NormalizeOrientation(m_owner->GetOrientation() - m_lastPosition.o) > 0.01f) UpdateGlobalPositions(); m_updatePositionsTimer = 500; } else m_updatePositionsTimer -= diff; }
// Update the global positions of all passengers void TransportBase::UpdateGlobalPositions() { Position pos(m_owner->GetPositionX(), m_owner->GetPositionY(), m_owner->GetPositionZ(), m_owner->GetOrientation()); // Calculate new direction multipliers if (NormalizeOrientation(pos.o - m_lastPosition.o) > 0.01f) { m_sinO = sin(pos.o); m_cosO = cos(pos.o); } // Update global positions for (PassengerMap::const_iterator itr = m_passengers.begin(); itr != m_passengers.end(); ++itr) UpdateGlobalPositionOf(itr->first, itr->second->GetLocalPositionX(), itr->second->GetLocalPositionY(), itr->second->GetLocalPositionZ(), itr->second->GetLocalOrientation()); m_lastPosition = pos; }