public static MoveResult MoveToward(Vector3 pos, float stoppingRange = .25f, bool stopAtEnd = true, float maxSpeed = 3f, bool debug = false) { if (pos == Vector3.Zero) { return(MoveResult.Complete); } var speed = Speed(Self); var posDelta = (pos - PlayerPosition); ObstructionFlags result = CheckObstruction(PlayerPosition, posDelta, debug); if (!IsWalkable(result)) { if (speed < .02f) { if (IsClimbable(result)) { SetControlValue(0, Control.Jump, 1.0f); // Attempt to jump over a positive obstruction } else { return(MoveResult.Failed); } } } Vector3 delta = Vector3.Normalize(posDelta); // Position(PlayerMatrix); float right = Vector3.Dot(delta, Right(CameraMatrix)); float up = Vector3.Dot(delta, Forward(CameraMatrix)); float dX, dY; SetControlValue(1, Control.MoveLeftRight, dX = MoveActivation(right, deadZone: -0.9f)); SetControlValue(1, Control.MoveUpDown, dY = MoveActivation(-up, deadZone: -0.9f)); var dist = DistanceToSelf(pos); if (debug) { DrawLine(HeadPosition(Self), pos, Color.Orange); UI.DrawTextInWorld(pos, $"dX:{right:F2}->{dX:F2} dY:{up:F2}->{dY:F2} dist:{DistanceToSelf(pos):F2}"); } return(dist < stoppingRange ? MoveResult.Complete : MoveResult.Continue); }
public static ObstructionFlags CheckObstruction(Vector3 start, Vector3 heading, bool debug = false) { ObstructionFlags ret = ObstructionFlags.None; if (IsRagdoll(Self)) // Call<bool>(IS_PED_RAGDOLL, Self) ) { { return(ret); } heading = new Vector3(heading.X, heading.Y, 0f); IntersectOptions opts = IntersectOptions.Map | IntersectOptions.Objects | IntersectOptions.Vehicles; float capsuleSize = .12f; float stepSize = .25f; heading = Vector3.Normalize(heading) * .5f; Vector3 head = HeadPosition(Self) + (Up * 5 * stepSize); for (int i = 1; i <= (int)ObstructionFlags.Knee; i *= 2) // do probes from top to bottom { RaycastResult headRay = Raycast(head, head + heading, capsuleSize, opts, Self); if (headRay.DidHit) { if (debug) { DrawSphere(headRay.HitPosition, .01f, Color.Red); } ret |= (ObstructionFlags)i; } head.Z -= stepSize; } if (debug) { string str = IsWalkable(ret) ? "Walkable" : IsClimbable(ret) ? "Climbable" : "Blocked"; UI.DrawTextInWorld(HeadPosition(Self) + heading, $"{str}"); } return(ret); }
public static bool IsWalkable(ObstructionFlags flags) => 0 == (flags & (ObstructionFlags.Waist | ObstructionFlags.Stomach | ObstructionFlags.Chest | ObstructionFlags.Shoulder | ObstructionFlags.Head | ObstructionFlags.Knee));
public static bool IsClimbable(ObstructionFlags flags) => (flags & ObstructionFlags.CannotClimb) == 0;