public override IPickable TryToPickUpFromSlot(IPickable playerHoldPickable) { // we can only pick a soup when it's ready and Player has a Plate in hands, otherwise refuse if (!IsCookFinished || IsBurned) { return(null); } // we "lock" a soup if there are different ingredients. Player has to trash it away if (Ingredients[0].Type != Ingredients[1].Type || Ingredients[1].Type != Ingredients[2].Type || Ingredients[0].Type != Ingredients[2].Type) { // Debug.Log("[CookingPot] Soup with mixed ingredients! You must thrash it away! What a waste!"); return(null); } if (!(playerHoldPickable is Plate plate)) { return(null); } if (!plate.IsClean || !plate.IsEmpty()) { return(null); } plate.AddIngredients(Ingredients); EmptyPan(); return(null); }
/// <summary> /// Creates a new PickResult. /// </summary> /// <param name="ray">Ray used in the test</param> /// <param name="target">Target object</param> /// <param name="primIntersection">The primitive intersection record.</param> public PickResult(Ray ray, IPickable target, PrimitiveIntersectionRecord primIntersection) { _ray = ray; _target = target; _boundRecord = null; _primRecord = primIntersection; }
private IEnumerator AnimateAndDestroy(IPickable pickable) { if (pickable == null) { yield break; } // put pickable into slot pickable.gameObject.transform.SetParent(Slot); pickable.gameObject.transform.SetPositionAndRotation(Slot.position, Quaternion.identity); float currentTime = 0f; while (currentTime < TotalAnimTime) { // rotate and shrink pickable pickable.gameObject.transform.SetParent(null); pickable.gameObject.transform.Rotate(0f, AngularSpeed, 0f, Space.Self); pickable.gameObject.transform.localScale = Vector3.Lerp(Vector3.one, Vector3.zero, currentTime / TotalAnimTime); currentTime += Time.deltaTime; yield return(null); } Destroy(pickable.gameObject); }
/// <summary> /// Try to pick up a pickable object. Return true if successful. It may fail because /// the pickable object is being held by a picker whose <see cref="AllowSwitchingPicker"/> /// is false. /// </summary> /// <param name="pickable">The pickable object.</param> /// <returns>True if successful.</returns> protected bool AttachPickable(IPickable pickable) { if (pickable.IsPicked) { IPicker otherPicker = pickable.Picker; if (otherPicker == this) { Debug.LogError("Picking the same object."); return(false); } if (!otherPicker.AllowSwitchingPicker) { return(false); } else { // Switch picker otherPicker.SwitchPickerRelease(); } } PickedObj = pickable; IsHolding = true; pickable.OnPickedInit(this); return(true); }
public void Visit(IPickable pickable) { // pickable.PickedUp += e => // { // _animator.Shrink(e.Card); // }; }
/// <summary> /// Creates a new PickResult. /// </summary> /// <param name="ray">Ray used in the test</param> /// <param name="target">Target object</param> /// <param name="boundingIntersection">The bounding intersection record.</param> public PickResult(Ray ray, IPickable target, BoundingIntersectionRecord boundingIntersection) { _ray = ray; _target = target; _boundRecord = boundingIntersection; _primRecord = null; }
public void OnDrop(IPickable pickable) { if (pickable != null) { pickable.UserData = (object)ammoLeft; } }
private void ChangeStateRPC(bool enabled) { if (Upgrade) { UpgradePreview.SetActive(enabled); if (enabled) { m_upgradeableTarget = null; } } else { if (enabled) { CreatePreview(); } else { m_target = null; if (m_weaponOnSocket != null) { Destroy(m_weaponOnSocket.gameObject); } } } if (PhotonNetwork.IsMasterClient && enabled == false) { StartCoroutine(Respawn()); } ChangeState?.Invoke(enabled); Collider.enabled = enabled; }
// TODO refactor void tryPickUpObject() { Collider2D[] collidersInRange = Physics2D.OverlapCircleAll(transform.position, 1); foreach (Collider2D col in collidersInRange) { IPickable pickable = col.GetComponent <IPickable>(); if (pickable != null) { Coin coin; if (col.TryGetComponent <Coin>(out coin)) { coin.PickUp(); pocketCoins += 1; return; } var item = pickable.PickUp(); if (item != null) { item.parent = transform; item.localPosition = new Vector3(0, 1f); _heldItem = item; return; } } } }
void OnTriggerEnter2D(Collider2D other) { // 宝箱キャッチ if (other.gameObject.GetComponent <IPickable>() is var tresurebox && tresurebox != null) { if (isCatch.Value == true) { return; } targetTresurebox = tresurebox; } // 宝箱回収 if (other.gameObject.GetComponent <IRecoverable>() is var recoverArea && recoverArea != null) { if (isCatch.Value == false && tresurebox == null) { return; } // targetTresurebox.Recovery(); targetTresurebox = null; isCatch.Value = false; } }
/// <summary> /// Returns last vertex's id of picked geometry if the geometry represented by <paramref name="stageVertexId"/> belongs to this <paramref name="element"/> instance. /// <para>Returns false if <paramref name="stageVertexId"/> the primitive is in some other element.</para> /// </summary> /// <param name="element"></param> /// <param name="stageVertexId"></param> /// <param name="lastVertexId"></param> /// <returns></returns> public static bool GetLastVertexIdOfPickedGeometry(this IPickable element, uint stageVertexId, out uint lastVertexId) { lastVertexId = uint.MaxValue; bool result = false; if (element != null) { if (stageVertexId < element.PickingBaseId) // ID is in some previous element. { return(false); } uint vertexCount = element.GetVertexCount(); uint id = stageVertexId - element.PickingBaseId; if (id < vertexCount) { lastVertexId = id; result = true; } else // ID is in some subsequent element. { result = false; } } return(result); }
public void Release() { targetTresurebox.Normal(); targetTresurebox = null; isCatch.Value = false; }
private void CheckForPickables() { var pickables = Physics.OverlapSphere(PickupCheckOriginTransform.position, PickupRadius, LayerMask.GetMask(new string[] { "Pickable" })); if (pickables.Length > 0) { bool containsWeapon = pickables.Any(c => { var i = c.GetComponent <IPickable>(); return(i != null && i.GetType() == PickableType.Weapon); }); possiblePickable = pickables.OrderBy(c => { float dist = float.MaxValue; if (!containsWeapon || (containsWeapon && c.GetComponent <IPickable>().GetType() == PickableType.Weapon)) { dist = (c.transform.position - PickupCheckOriginTransform.position).magnitude; } return(dist); }).First().GetComponent <IPickable>(); } else { possiblePickable = null; } }
public void OnPickup(IPickable pickable) { if (pickable != null && pickable.UserData != null) { ammoLeft = (int)pickable.UserData; } }
private void OnTriggerStay(Collider other) { // cannot bring more than one box if (Pickable != null || IsDisabled) { return; } if (Input.GetButtonDown(("PickupDeploy") + PlayerNumber)) { IPickable otherPickable = other.GetComponent <IPickable>(); // it is not a pickable object if (otherPickable == null) { return; } // pickable object has already been picked up if (otherPickable.IsPickedUp) { return; } // caching pickable object Pickable = otherPickable; Pickable.PickUp(this); skipInputCall = true; } }
private void OnItemDropped(IPickable obj) { var v = _body.Velocity; v.x += LookDirection * 4f; v.y = 0f; obj.SetDropVelocity(v); }
public void Init() { pickObject = pickUpCounter.GetComponent <IPickable>(); if (pickObject == null) { Debug.LogError("Pick Up Counter object does not implement IPickable interface."); } }
void SetCurPickable(IPickable pickable) { HoverPicked(false); mPickedObj = pickable; mHoveredTime = 0f; mPickedObjChanged = true; }
public override bool TryToDropIntoSlot(IPickable pickableToDrop) { if (pickableToDrop is Ingredient) { return(TryDropIfNotOccupied(pickableToDrop)); } return(false); }
void OnTriggerEnter2D(Collider2D other) { if (other.gameObject.GetComponent <IPickable>() is var tresurebox && tresurebox != null) { targetTresurebox = tresurebox; Recover(); } }
public void Take(GameObject item) { IPickable pickable = item.GetComponent(typeof(IPickable)) as IPickable; pickable.Grab(_itemPosition); _grabing = item; }
public void Drop() { IPickable pickable = _grabing.GetComponent(typeof(IPickable)) as IPickable; pickable.Drop(); _grabing = null; }
//public PickedGeometry() { } /// <summary> /// The color-coded picking result. /// <para>Representing a primitive(point, line, triangle, quad, polygon).</para> /// </summary> /// <param name="geometryType"></param> /// <param name="positions"></param> /// <param name="vertexIds"></param> /// <param name="stageVertexId"></param> /// <param name="fromRenderer"></param> public PickedGeometry(GeometryType geometryType, vec3[] positions, uint[] vertexIds, uint stageVertexId, IPickable fromRenderer) { this.Type = geometryType; this.Positions = positions; this.VertexIds = vertexIds; this.StageVertexId = stageVertexId; this.FromRenderer = fromRenderer; }
void UpdateOpObject() { IPickable pickable = CheckPickable(); if (pickable != mPickedObj) { SetCurPickable(pickable); } }
private void OnCollisionExit2D(Collision2D collision) { IPickable pickable = collision.collider.GetComponent <IPickable>(); if (pickable != null) { pickable.OnLeft(gameObject); } }
//public PickedGeometry() { } /// <summary> /// The color-coded picking result. /// <para>Representing a primitive(point, line, triangle, quad, polygon).</para> /// </summary> /// <param name="fromViewPort"></param> /// <param name="geometryType"></param> /// <param name="positions"></param> /// <param name="vertexIds"></param> /// <param name="stageVertexId"></param> /// <param name="fromRenderer"></param> public PickedGeometry(ViewPort fromViewPort, PickingGeometryType geometryType, vec3[] positions, uint[] vertexIds, uint stageVertexId, IPickable fromRenderer) { this.FromViewPort = fromViewPort; this.GeometryType = geometryType; this.Positions = positions; this.VertexIds = vertexIds; this.StageVertexId = stageVertexId; this.FromRenderer = fromRenderer; }
protected override void PickUp(IPickable player) { if (player.currentHealth < player.health) { base.PickUp(player); player.PickUpMedkit(this); medkits.Remove(this); } }
public override IPickable TryToPickUpFromSlot(IPickable playerHoldPickable) { if (playerHoldPickable != null) { return(null); } return(_cleanPlates.Count > 0 ? _cleanPlates.Pop() : null); }
private void OnTriggerEnter2D(Collider2D collision) { IPickable _tempPick = collision.gameObject.GetComponent <IPickable>(); if (_tempPick != null) { scrap = Mathf.Round(scrap + _tempPick.PickItem()); } }
private void OnTriggerEnter(Collider other) { IPickable pickingPerson = other.GetComponentInParent <IPickable>(); if (pickingPerson != null && !other.isTrigger) { PickUp(pickingPerson); } }
public void Drop() { if (pickedupObject != null) { pickedupObject.Drop(); pickedupObject = null; PropRootRightHand.DropImmediate(); } }
public bool TryToPick(IPickable item) { bool picked = false; if (this.Inventory.Any(x => x == null)) { for (int i = 0; i < InventoryCapacity; i++) { if (this.Inventory[i] == null) { this.Inventory[i] = item; picked = true; break; } } return picked; } return picked; }
/// <summary> /// Runs a per-triangle picking algorithm over all the models in the scene, /// storing which triangle is currently under the cursor. /// </summary> public override void Update(GameTime gameTime) { ICameraService camera = this.Game.Services.GetService<ICameraService>(); ICursorService cursor = this.Game.Services.GetService<ICursorService>(); // Look up a collision ray based on the current cursor position. See the // Picking Sample documentation for a detailed explanation of this. Ray cursorRay = cursor.CalculateCursorRay(camera.Projection, camera.View); // Clear the previous picking results. insideBoundingSpheres.Clear(); IPickable pickedPickable = null; pickedRadius[1].Position = Vector3.Zero; // Keep track of the closest object we have seen so far, so we can // choose the closest one if there are several models under the cursor. float closestIntersection = float.MaxValue; // Loop over all our models. IEnumerable<IPickable> pickables = this.Game.Components.OfType<IPickable>(); foreach (IPickable pickable in pickables) { bool insideBoundingSphere; Vector3 vertex1, vertex2, vertex3; // Perform the ray to model intersection test. float? intersection = RayIntersectsModel(cursorRay, pickable, pickable.World, out insideBoundingSphere, out vertex1, out vertex2, out vertex3); // If this model passed the initial bounding sphere test, remember // that so we can display it at the top of the screen. if (insideBoundingSphere) insideBoundingSpheres.Add(pickable.Name); // Do we have a per-triangle intersection with this model? if (intersection != null) { // If so, is it closer than any other model we might have // previously intersected? if (intersection < closestIntersection) { // Store information about this model. closestIntersection = intersection.Value; pickedPickable = pickable; // Store vertex positions so we can display the picked triangle. pickedTriangle[0].Position = vertex1; pickedTriangle[1].Position = vertex2; pickedTriangle[2].Position = vertex3; // Store intersection point positions so we can display the picked radius pickedRadius[1].Position = cursorRay.Direction * 2000.0f; } } } Input.IMouseService lMouseService = this.Game.Services.GetService<Input.IMouseService>(); if (lMouseService.LeftClickPressed || SelectedPickable is Globe) SelectedPickableLocked = false; if (SelectedPickable != null && !SelectedPickableLocked) { SelectedPickable.IsSelected = false; SelectedPickable = null; } if (pickedPickable != null && !SelectedPickableLocked) { pickedPickable.IsSelected = true; SelectedPickable = pickedPickable; if (lMouseService.LeftClickPressed) SelectedPickableLocked = true; } if (SelectedPickable != null && SelectedPickable is Location) { LocationInfoPanel locationInfoPanel = this.Game.Components.OfType<LocationInfoPanel>().SingleOrDefault(); bool add = true; if (locationInfoPanel != null) { if (locationInfoPanel.LocationID != ((Location)SelectedPickable).LocationID) this.Game.Components.Remove(locationInfoPanel); else add = false; } if (add) { LocationInfoPanel panel = new LocationInfoPanel(this.Game, ((Location)SelectedPickable)); this.Game.Components.Add(panel); } } else { this.Game.Components.Remove(this.Game.Components.OfType<LocationInfoPanel>().SingleOrDefault()); } if (SelectedPickable != null && SelectedPickable is Route) { RouteInfoPanel panel = this.Game.Components.OfType<RouteInfoPanel>().SingleOrDefault(); bool add = true; if (panel != null) { if (panel.RouteID != ((Route)SelectedPickable).RouteInfo.Id) this.Game.Components.Remove(panel); else add = false; } if (add) { panel = new RouteInfoPanel(this.Game, ((Route)SelectedPickable)); this.Game.Components.Add(panel); } } else { this.Game.Components.Remove(this.Game.Components.OfType<RouteInfoPanel>().SingleOrDefault()); } base.Update(gameTime); }
/// <summary> /// Checks whether a ray intersects a model. This method needs to access /// the model vertex data, so the model must have been built using the /// custom TrianglePickingProcessor provided as part of this sample. /// Returns the distance along the ray to the point of intersection, or null /// if there is no intersection. /// </summary> private static float? RayIntersectsModel(Ray ray, IPickable pickable, Matrix modelTransform, out bool insideBoundingSphere, out Vector3 vertex1, out Vector3 vertex2, out Vector3 vertex3) { vertex1 = vertex2 = vertex3 = Vector3.Zero; // The input ray is in world space, but our model data is stored in object // space. We would normally have to transform all the model data by the // modelTransform matrix, moving it into world space before we test it // against the ray. That transform can be slow if there are a lot of // triangles in the model, however, so instead we do the opposite. // Transforming our ray by the inverse modelTransform moves it into object // space, where we can test it directly against our model data. Since there // is only one ray but typically many triangles, doing things this way // around can be much faster. Matrix inverseTransform = Matrix.Invert(modelTransform); ray.Position = Vector3.Transform(ray.Position, inverseTransform); ray.Direction = Vector3.TransformNormal(ray.Direction, inverseTransform); // Start off with a fast bounding sphere test. if (pickable.BoundingSphere.Intersects(ray) == null) { // If the ray does not intersect the bounding sphere, we cannot // possibly have picked this model, so there is no need to even // bother looking at the individual triangle data. insideBoundingSphere = false; return null; } else { // The bounding sphere test passed, so we need to do a full // triangle picking test. insideBoundingSphere = true; // Keep track of the closest triangle we found so far, // so we can always return the closest one. float? closestIntersection = null; // Loop over the vertex data, 3 at a time (3 vertices = 1 triangle). Vector3[] vertices = pickable.Vertices; for (int i = 0; i < vertices.Length - 2; i += pickable.PrimitiveStepCount) { // Perform a ray to triangle intersection test. float? intersection; RayIntersectsTriangle(ref ray, ref vertices[i], ref vertices[i + 1], ref vertices[i + 2], out intersection); // Does the ray intersect this triangle? if (intersection != null) { // If so, is it closer than any other previous triangle? if ((closestIntersection == null) || (intersection < closestIntersection)) { // Store the distance to this triangle. closestIntersection = intersection; // Transform the three vertex positions into world space, // and store them into the output vertex parameters. Vector3.Transform(ref vertices[i], ref modelTransform, out vertex1); Vector3.Transform(ref vertices[i + 1], ref modelTransform, out vertex2); Vector3.Transform(ref vertices[i + 2], ref modelTransform, out vertex3); } } } return closestIntersection; } }
public override void Update(GameTime gameTime) { // if (SavePointContact && _gamePadState.Buttons.Y == ButtonState.Released && _gamePadStatePrevious.Buttons.Y == ButtonState.Pressed) // { // PlayerLoad player; // if (PlayerIndex == PlayerIndex.One) // { // player = SaveGame.PlayerOne; // } // else // { // player = SaveGame.PlayerTwo; // } // player.NextScreen = NextScreen; // player.Position = Position; // Collectables = Collectable.JUMP; // player.Collectables = Collectables; // SaveGame.Health = MaxHealth; //#if (XBOX360) //#else //#endif // //FileStream fileStream = new FileStream(SaveGame.FileName, FileMode.Create); // //XmlSerializer xs = new XmlSerializer(SaveGame.GetType()); // //xs.Serialize(fileStream, SaveGame); // //fileStream.Close(); // } if (_fixtures.Count > 0) { if (_heldObject != null) { if (_gamePadState.Buttons.LeftShoulder == ButtonState.Pressed) { // While the button is pressed, update held object _heldObject.SetHeld(X, Y, _fixtures[0].Body.LinearVelocity, Direction); } else if (_gamePadStatePrevious.Buttons.LeftShoulder == ButtonState.Pressed) { // Once it's released _heldObject.Release(); _heldObject = null; } } if (ClimbableThings.Count > 0 && (Collectables & Collectable.GRAB) == Collectable.GRAB) { MoveState = MoveState.GROUND; } if (_gamePadState.IsButtonDown(Buttons.A)) { if ((Collectables & Collectable.JUMP) == Collectable.JUMP || ((Collectables & Collectable.GRAB) == Collectable.GRAB && ClimbableThings.Count > 0)) { if (MoveState == MoveState.GROUND && _jumpPressed == false) { MainFixture.Body.ApplyForce(new Vector2(0, 120.0f * (float)gameTime.ElapsedGameTime.TotalMilliseconds)); MoveState = MoveState.AIR; _jumpPressed = true; _jumpPower = Math.Abs(MainFixture.Body.LinearVelocity.X); _jumpTimer = 0; if ((Collectables & Collectable.JUMP) == Collectable.JUMP) _jumpSound.Play(0.5f, 0.0f, 0.0f); else _dragSound.Play(0.5f, 0.0f, 0.0f); } else if (_jumpTimer < 150) { MainFixture.Body.ApplyForce(new Vector2(0, _jumpPower * (float)(gameTime.ElapsedGameTime.TotalMilliseconds) * 0.2f)); } _jumpTimer += gameTime.ElapsedGameTime.Milliseconds; } if ((Collectables & Collectable.GRAB) == Collectable.GRAB && ClimbableThings.Count > 0) { if (MainFixture.Body.LinearVelocity.Y > 10) MainFixture.Body.LinearVelocity = new Vector2(MainFixture.Body.LinearVelocity.X, 10); } } else { _jumpPressed = false; if (Math.Abs(_body.Body.LinearVelocity.Y) <= 0.0001) _moveState = MoveState.GROUND; } if (_gamePadState.ThumbSticks.Left.X < -0.5 || _gamePadState.ThumbSticks.Left.X > 0.5) { if (!(_moveState == MoveState.AIR && _jumpPower == 0)) { _wheelBreak.Enabled = false; if (_gamePadState.ThumbSticks.Left.X < -0.5) { Direction = Direction.LEFT; _wheel.Body.ApplyForce(new Vector2(-3.0f * (float)gameTime.ElapsedGameTime.TotalMilliseconds, 0)); MainFixture.Body.ApplyForce(new Vector2(-3.0f * (float)gameTime.ElapsedGameTime.TotalMilliseconds, 0)); if (MainFixture.Body.LinearVelocity.X < -12) { MainFixture.Body.LinearVelocity = new Vector2(-12, MainFixture.Body.LinearVelocity.Y); } } if (_gamePadState.ThumbSticks.Left.X > 0.5) { Direction = Direction.RIGHT; _wheel.Body.ApplyForce(new Vector2(3.0f * (float)gameTime.ElapsedGameTime.TotalMilliseconds, 0)); MainFixture.Body.ApplyForce(new Vector2(3.0f * (float)gameTime.ElapsedGameTime.TotalMilliseconds, 0)); if (MainFixture.Body.LinearVelocity.X > 12) { MainFixture.Body.LinearVelocity = new Vector2(12, MainFixture.Body.LinearVelocity.Y); } } if (MoveState == MoveState.AIR) { if (MainFixture.Body.LinearVelocity.X < -_jumpPower - 3) { MainFixture.Body.LinearVelocity = new Vector2(-_jumpPower - 3, MainFixture.Body.LinearVelocity.Y); } else if (MainFixture.Body.LinearVelocity.X > _jumpPower + 3) { MainFixture.Body.LinearVelocity = new Vector2(_jumpPower + 3, MainFixture.Body.LinearVelocity.Y); } } } } else { // Enable the wheel break so we don't roll off forever _wheelBreak.TargetAngle = _fixtures[1].Body.Rotation; _wheelBreak.Enabled = true; } if (_invincibility <= 0) { foreach (Fixture fixture in _contactFixtures) { if (fixture.UserData is IHurty) { SharedHealth.CurrentHealth -= ((IHurty)fixture.UserData).GetDamage(); _invincibility = 2000; } } } else { _invincibility -= gameTime.ElapsedGameTime.TotalMilliseconds; } } base.Update(gameTime); }
public bool OnCollision(Fixture fix1, Fixture fix2, Contact contact) { if (fix2.UserData is Bullet && !((Bullet)fix2.UserData).Player && _invincibility <= 0) { SharedHealth.CurrentHealth -= fix2.Body.LinearVelocity.Length(); ((Bullet)fix2.UserData).Dispose(); _invincibility = 1500; } if (fix2.UserData is Spike) { if (((Spike)fix2.UserData).MainFixture.Body.BodyType == BodyType.Static) { ((Spike)fix2.UserData).MainFixture.Body.BodyType = BodyType.Dynamic; } } if (fix2.UserData is PickupSpecial) { PickupSpecial pickup = (PickupSpecial)fix2.UserData; if (pickup.PlayerIndex == PlayerIndex || pickup.PlayerIndex == PlayerIndex.Three) { switch (pickup.GameSwitch) { default: GameSave.CurrentGameSwitches |= pickup.GameSwitch; pickup.Dead = true; break; } } } if (fix2.UserData is Enemy && ((Enemy)fix2.UserData).TouchDamage > 0 && _invincibility <= 0) { _sharedHealth.CurrentHealth -= ((Enemy)fix2.UserData).TouchDamage; _invincibility = 1500; } if (fix2.UserData is Pickup) { Pickup pickup = (Pickup)fix2.UserData; if (pickup.PlayerIndex == PlayerIndex || pickup.PlayerIndex == PlayerIndex.Three) { switch (pickup.Collectable) { case Collectable.HEALTH: SharedHealth.CurrentHealth += 25; pickup.Dead = true; break; case Collectable.FULLHEALTH: SharedHealth.CurrentHealth = SharedHealth.MaxHealth; pickup.Dead = true; break; default: Collectables |= pickup.Collectable; pickup.Dead = true; break; } } } //if ((Collectables & Collectable.GRAB) != Collectable.GRAB) // _jumpPower = 0; if (_body.Body.LinearVelocity.Length() > 20) { Health -= _body.Body.LinearVelocity.Length() / 2.0; _invincibility = 1500; _bounceSound.Play(0.5f, 0, 0); } if (fix2.UserData is IPickable && _gamePadState.Buttons.LeftShoulder == ButtonState.Pressed && _heldObject == null && (Collectables & Collectable.GRAB) == Collectable.GRAB) { _heldObject = (IPickable)fix2.UserData; } //else if (fix2.UserData is IClibmableThing) //{ // ClimbableThings.Add(fix2); //} else if (fix2.UserData is IPassableBottom) { if (_fixtures[0].Body.LinearVelocity.Y > 0 || _fixtures[1].Body.Position.Y - 0.3 < fix2.Body.Position.Y) return false; } else if (!fix2.IsSensor) { // Check if the player is standing on a surface at less than pi/4 radians from the horizontal // First calculate the overall normal Vector2 normal = Vector2.Zero; Contact currentContact = contact; Vector2 nextNormal = Vector2.Zero; FixedArray2<Vector2> fx; // No idea what that is, but the function wants it lol // Iterate through the contacts, summing the normals do { Vector2 vec = Vector2.Zero; contact.GetWorldManifold(out vec, out fx); normal += vec; currentContact = currentContact.Next; } while (currentContact != null); double normalAngle = Math.Atan2(normal.X, normal.Y); if (Math.Abs(normalAngle) <= MathHelper.PiOver4) { _moveState = MoveState.GROUND; } else if (Math.Abs(normalAngle) < MathHelper.Pi) { _moveState = MoveState.SLIDING; } } return true; }