void SetTargetLocation(T owner) { if (owner.HasUnitState(UnitState.Root | UnitState.Stunned | UnitState.Distracted)) { // if we are ROOT/STUNNED/DISTRACTED even after aura clear, finalize on next update - otherwise we would get stuck in evade skipToHome = true; return; } MoveSplineInit init = new MoveSplineInit(owner); float x, y, z, o; // at apply we can select more nice return points base at current movegen if (owner.GetMotionMaster().empty() || !owner.GetMotionMaster().top().GetResetPosition(owner, out x, out y, out z)) { owner.GetHomePosition(out x, out y, out z, out o); init.SetFacing(o); } init.MoveTo(x, y, z); init.SetWalk(false); init.Launch(); skipToHome = false; arrived = false; owner.ClearUnitState(UnitState.AllState & ~(UnitState.Evade | UnitState.IgnorePathfinding)); }
public override bool Execute(ulong e_time, uint p_time) { Contract.Assert(Passenger.IsInWorld); Contract.Assert(Target != null && Target.GetBase().IsInWorld); Contract.Assert(Target.GetBase().HasAuraTypeWithCaster(AuraType.ControlVehicle, Passenger.GetGUID())); Target.RemovePendingEventsForSeat(Seat.Key); Target.RemovePendingEventsForPassenger(Passenger); Passenger.SetVehicle(Target); Seat.Value.Passenger.Guid = Passenger.GetGUID(); Seat.Value.Passenger.IsUnselectable = Passenger.HasFlag(UnitFields.Flags, UnitFlags.NotSelectable); if (Seat.Value.SeatInfo.CanEnterOrExit()) { Contract.Assert(Target.UsableSeatNum != 0); --Target.UsableSeatNum; if (Target.UsableSeatNum == 0) { if (Target.GetBase().IsTypeId(TypeId.Player)) { Target.GetBase().RemoveFlag64(UnitFields.NpcFlags, NPCFlags.PlayerVehicle); } else { Target.GetBase().RemoveFlag64(UnitFields.NpcFlags, NPCFlags.SpellClick); } } } Passenger.InterruptNonMeleeSpells(false); Passenger.RemoveAurasByType(AuraType.Mounted); VehicleSeatRecord veSeat = Seat.Value.SeatInfo; Player player = Passenger.ToPlayer(); if (player != null) { // drop flag Battleground bg = player.GetBattleground(); if (bg) { bg.EventPlayerDroppedFlag(player); } player.StopCastingCharm(); player.StopCastingBindSight(); player.SendOnCancelExpectedVehicleRideAura(); if (!veSeat.Flags[1].HasAnyFlag((uint)VehicleSeatFlagsB.KeepPet)) { player.UnsummonPetTemporaryIfAny(); } } if (Seat.Value.SeatInfo.Flags[0].HasAnyFlag((uint)VehicleSeatFlags.PassengerNotSelectable)) { Passenger.SetFlag(UnitFields.Flags, UnitFlags.NotSelectable); } Passenger.m_movementInfo.transport.pos.Relocate(veSeat.AttachmentOffset.X, veSeat.AttachmentOffset.Y, veSeat.AttachmentOffset.Z); Passenger.m_movementInfo.transport.time = 0; Passenger.m_movementInfo.transport.seat = Seat.Key; Passenger.m_movementInfo.transport.guid = Target.GetBase().GetGUID(); if (Target.GetBase().IsTypeId(TypeId.Unit) && Passenger.IsTypeId(TypeId.Player) && Seat.Value.SeatInfo.Flags[0].HasAnyFlag((uint)VehicleSeatFlags.CanControl)) { Contract.Assert(Target.GetBase().SetCharmedBy(Passenger, CharmType.Vehicle)); // SMSG_CLIENT_CONTROL } Passenger.SendClearTarget(); // SMSG_BREAK_TARGET Passenger.SetControlled(true, UnitState.Root); // SMSG_FORCE_ROOT - In some cases we send SMSG_SPLINE_MOVE_ROOT here (for creatures) // also adds MOVEMENTFLAG_ROOT MoveSplineInit init = new MoveSplineInit(Passenger); init.DisableTransportPathTransformations(); init.MoveTo(veSeat.AttachmentOffset.X, veSeat.AttachmentOffset.Y, veSeat.AttachmentOffset.Z, false, true); init.SetFacing(0.0f); init.SetTransportEnter(); init.Launch(); Creature creature = Target.GetBase().ToCreature(); if (creature != null) { if (creature.IsAIEnabled) { creature.GetAI().PassengerBoarded(Passenger, Seat.Key, true); } Global.ScriptMgr.OnAddPassenger(Target, Passenger, Seat.Key); // Actually quite a redundant hook. Could just use OnAddPassenger and check for unit typemask inside script. if (Passenger.HasUnitTypeMask(UnitTypeMask.Accessory)) { Global.ScriptMgr.OnInstallAccessory(Target, Passenger.ToCreature()); } } return(true); }