public bool TryPush(Vector2Int dir, float speed = Single.NaN) { Vector3Int from = Pushable.ServerPosition; if (!CanPushServer(from, dir, speed)) { return(false); } bool success = Pushable.Push(dir, speed); Vector3Int target = from + dir.To3Int(); if (success) { if (IsBeingPulled && //Break pull only if pushable will end up far enough (pushRequestQueue.Count > 0 || !PlayerScript.IsInReach(PulledBy.registerTile.WorldPositionServer, target))) { StopFollowing(); } if (IsPullingSomethingServer && //Break pull only if pushable will end up far enough (pushRequestQueue.Count > 0 || !PlayerScript.IsInReach(PulledObjectServer.registerTile.WorldPositionServer, target))) { ReleaseControl(); } isBeingPushed = true; pushTarget = target; Logger.LogTraceFormat("{2}: Started push {0}->{1}", Category.PushPull, from, target, gameObject.name); this.RestartCoroutine(NoMoveSafeguard(from), ref revertIsBeingPushedHandle); } return(success); }
private bool TryFollow(Vector3Int from, Vector2Int dir, float speed = Single.NaN) { if (!IsBeingPulled || isNotPushable || isBeingPushed || Pushable == null) { return(false); } if (Mathf.Abs(dir.x) > 1 || Mathf.Abs(dir.y) > 1) { Logger.LogTrace("oops=" + dir, Category.PushPull); return(false); } Vector3Int target = from + Vector3Int.RoundToInt(( Vector2 )dir); if (!MatrixManager.IsPassableAt(from, target, isServer: true, includingPlayers: false)) //non-solid things can be pushed to player tile { return(false); } bool success = Pushable.Push(dir, speed, true); if (success) { pushTarget = target; // Logger.LogTraceFormat( "Following {0}->{1}", Category.PushPull, from, target ); } return(success); }
public bool TryPush(Vector3Int from, Vector2Int dir, float speed = Single.NaN) { if (!CanPush(from, dir, speed)) { return(false); } bool success = Pushable.Push(dir, speed); Vector3Int target = from + dir.To3Int(); if (success) { if (IsBeingPulled && //Break pull only if pushable will end up far enough (pushRequestQueue.Count > 0 || !PlayerScript.IsInReach(PulledBy.registerTile.WorldPosition, target))) { StopFollowing(); } if (IsPullingSomethingServer && //Break pull only if pushable will end up far enough (pushRequestQueue.Count > 0 || !PlayerScript.IsInReach(PulledObjectServer.registerTile.WorldPosition, target))) { ReleaseControl(); } isPushing = true; pushTarget = target; Logger.LogTraceFormat("Started push {0}->{1}", Category.PushPull, from, target); } return(success); }
private void FixedUpdate() { if (movementVector == Vector3.zero) { return; } playerPushable.Push(movementVector); movementVector = Vector3.zero; }
public override void OnTriggerStay(Collider other, PhysicsProp prop) { if (!isOwner) { return; } Pushable pushable = prop as Pushable; Vector3 motion_vector = player.GetMoveVector(); RaycastHit hit; if (Physics.Raycast(context.transform.position, motion_vector, out hit, player.cc.radius * 1.5f)) { // Avoid pushing if we are angled away from the surface if (Vector3.Dot(motion_vector, -hit.normal) < 0.8f) { return; } // Reset the push start buildup if we are no longer pushing if (utils.CheckTimer(PUSH_TIMER)) { utils.ResetTimer(PUSH_START_TIMER); } if (utils.CheckTimer(PUSH_START_TIMER)) { if (isServer) { pushable.Push(Vector3.Project(player.GetVelocity() - pushable.rigidbody.velocity, -hit.normal), true); } else { pushable.PushOnServer(-hit.normal * 12f); } } lastpushsurface = hit.normal; // We are not pushing if the analog is not being moved float move_mag = input_manager.GetMove().magnitude; if (move_mag > 0.5f) { utils.ResetTimer(PUSH_TIMER); } } }
// Update is called once per frame void Update() { //Sliding check if (!player.sliding) { //Check for input, player in position and the desired tile is not out of bounds. if (Input.GetButton("Right") && transform.position == pos && x < grid.width && grid.GetTileAt(x, y - 1)) { if (Physics2D.Raycast(transform.position, Vector3.right, 1) && Physics2D.Raycast(transform.position, Vector3.right, 1).transform.GetComponent <Pushable>()) { Pushable tempBlock = Physics2D.Raycast(transform.position, Vector3.right, 1).transform.GetComponent <Pushable>(); tempBlock.Push(transform); } //This if takes care of all the checks and special cases. --This is the same for all directions, the only difference is the x and y pos // The next block needs to be walkable. // If the next block is a door, the player must have the respective key to walk there // If the next block is water, unless the player has the snorkel they cannot walk there. if (grid.GetTileAt(x, y - 1).isWalkable || grid.GetTileAt(x, y - 1).type == Tile.TileType.Door && player.HasKey(grid.GetTileAt(x, y - 1).GetComponent <Door>().keyType) || grid.GetTileAt(x, y - 1).type == Tile.TileType.Water && player.HasItem(Item.Type.Snorkel) == true) { // Add a right direction to the position and increment x by 1 so when we move it picks the block to the right. pos += Vector3.right; x++; // Here is the stuff for Ice / Sliding physics. // This will basically just lock the player in a direction until they hit something that isn't ice. if (grid.GetTileAt(x, y - 1).type == Tile.TileType.Ice && player.HasItem(Item.Type.SpikeBoots) == false) { // Fix direction and begin sliding slideDir = Vector3.right; player.sliding = true; } } } else if (Input.GetButton("Left") && transform.position == pos && x > 1 && grid.GetTileAt(x - 2, y - 1)) { if (Physics2D.Raycast(transform.position, Vector3.left, 1) && Physics2D.Raycast(transform.position, Vector3.left, 1).transform.GetComponent <Pushable>()) { Pushable tempBlock = Physics2D.Raycast(transform.position, Vector3.left, 1).transform.GetComponent <Pushable>(); tempBlock.Push(transform); } if (grid.GetTileAt(x - 2, y - 1).isWalkable || grid.GetTileAt(x - 2, y - 1).type == Tile.TileType.Door && player.HasKey(grid.GetTileAt(x - 2, y - 1).GetComponent <Door>().keyType) || grid.GetTileAt(x - 2, y - 1).type == Tile.TileType.Water && player.HasItem(Item.Type.Snorkel) == true) { pos += Vector3.left; x--; if (grid.GetTileAt(x - 2, y - 1).type == Tile.TileType.Ice && player.HasItem(Item.Type.SpikeBoots) == false) { slideDir = Vector3.left; player.sliding = true; } } } else if (Input.GetButton("Up") && transform.position == pos && y < grid.height && grid.GetTileAt(x - 1, y)) { if (Physics2D.Raycast(transform.position, Vector3.up, 1) && Physics2D.Raycast(transform.position, Vector3.up, 1).transform.GetComponent <Pushable>()) { Pushable tempBlock = Physics2D.Raycast(transform.position, Vector3.up, 1).transform.GetComponent <Pushable>(); tempBlock.Push(transform); } if (grid.GetTileAt(x - 1, y).isWalkable || grid.GetTileAt(x - 1, y).type == Tile.TileType.Door && player.HasKey(grid.GetTileAt(x - 1, y).GetComponent <Door>().keyType) || grid.GetTileAt(x - 1, y).type == Tile.TileType.Water && player.HasItem(Item.Type.Snorkel) == true) { pos += Vector3.up; y++; if (grid.GetTileAt(x - 1, y).type == Tile.TileType.Ice && player.HasItem(Item.Type.SpikeBoots) == false) { slideDir = Vector3.up; player.sliding = true; } } } else if (Input.GetButton("Down") && transform.position == pos && y > 1 && grid.GetTileAt(x - 1, y - 2)) { if (Physics2D.Raycast(transform.position, Vector3.down, 1) && Physics2D.Raycast(transform.position, Vector3.down, 1).transform.GetComponent <Pushable>()) { Pushable tempBlock = Physics2D.Raycast(transform.position, Vector3.down, 1).transform.GetComponent <Pushable>(); tempBlock.Push(transform); } if (grid.GetTileAt(x - 1, y - 2).isWalkable || grid.GetTileAt(x - 1, y - 2).type == Tile.TileType.Door && player.HasKey(grid.GetTileAt(x - 1, y - 2).GetComponent <Door>().keyType) || grid.GetTileAt(x - 1, y - 2).type == Tile.TileType.Water && player.HasItem(Item.Type.Snorkel) == true) { pos += Vector3.down; y--; if (grid.GetTileAt(x - 1, y - 2).type == Tile.TileType.Ice && player.HasItem(Item.Type.SpikeBoots) == false) { slideDir = Vector3.down; player.sliding = true; } } } // Move to the desired spot on the grid. transform.position = Vector3.MoveTowards(transform.position, grid.GetGridPos(x - 1, y - 1), Time.deltaTime * player.speed); } else { // Only increment when the player is at the position. if (pos == transform.position) { x += (int)slideDir.x; y += (int)slideDir.y; pos += slideDir; } // MOVE! er SLIDE! transform.position = Vector3.MoveTowards(transform.position, grid.GetGridPos(x - 1, y - 1), Time.deltaTime * player.speed); // Stop sliding if the next tile is walkable and NOT ice // Also need to check two spaces away so that we don't clip into walls. if (grid.GetTileAt(x - 1, y - 1).isWalkable&& grid.GetTileAt(x - 1, y - 1).type != Tile.TileType.Ice || grid.GetTileAt(x + (int)slideDir.x - 1, y + (int)slideDir.y - 1).type == Tile.TileType.Wall) { player.sliding = false; } } if (grid.GetTileAt(transform.position).type == Tile.TileType.Mud) { grid.GetTileAt(transform.position).GetComponent <SpriteRenderer>().sprite = mudChangeTile; grid.GetTileAt(transform.position).type = Tile.TileType.Ground; } }