public void DropItem() { if (this.objHeld == null) { return; } Item item = this.objHeld; item.intangible = Systems.timer.Frame + 7; // Check what Main Layer has present at the throw-release tile: TilemapLevel tilemap = this.character.room.tilemap; bool isBlocked = false; bool faceRight = this.character.FaceRight; isBlocked = CollideTile.IsBlockingSquare(tilemap, faceRight ? item.GridX2 : item.GridX, item.GridY, DirCardinal.Up); // If the drop tiles are blocked, see if we can drop it in the tile below. if (isBlocked) { int limitY = item.GridY * (byte)TilemapEnum.TileHeight + (byte)TilemapEnum.TileHeight; int dist = limitY - (item.posY + item.bounds.Top); // If we only have to drop it 24 pixels (or less), we can just lower the item slightly. if (dist < 24) { item.physics.MoveToPosY(limitY - item.bounds.Top); isBlocked = CollideTile.IsBlockingSquare(tilemap, faceRight ? item.GridX2 : item.GridX, item.GridY, DirCardinal.Up); } } // If the tile is still blocked, then a Y-reposition didn't work. We'll have to move it to character's tile. if (isBlocked) { int limitX; // NOTE: MUST have it like this. I don't understand the nuanced difference here, but it works. if (faceRight) { limitX = item.GridX2 * (byte)TilemapEnum.TileWidth; } else { limitX = item.GridX * (byte)TilemapEnum.TileWidth + (byte)TilemapEnum.TileWidth; } item.physics.MoveToPosX(limitX - (faceRight ? item.bounds.Right : item.bounds.Left)); } // Assign Minimal Drop Physics (to smooth natural look) item.physics.velocity.X = FInt.Create(this.character.physics.velocity.X.RoundInt / 3); item.physics.velocity.Y = FInt.Create(-1.5); // Play Drop Sound this.character.room.PlaySound(Systems.sounds.wooshSubtle, 0.5f, this.character.posX + 16, this.character.posY + 16); this.ResetHeldItem(); }
private void DetermineSlamDistance() { TilemapLevel tilemap = this.actor.room.tilemap; // We know the slammer's starting position. short gridX = this.actor.GridX; short gridY = this.actor.GridY; this.viewY = this.actor.posY + ((byte)TilemapEnum.TileHeight * 2); this.viewHeight = 0; // Scan for solid tiles beneath the slammer, up to 17 below (for a full screen) for (short testY = (short)(gridY + 2); testY < gridY + 19; testY++) { if (testY > tilemap.YCount + (byte)TilemapEnum.GapUp) { return; } // If there is a blocking tile at this height below the slammer, we can determine it's final Y-position after a slam: if (CollideTile.IsBlockingSquare(tilemap, gridX, testY, DirCardinal.Up) || CollideTile.IsBlockingSquare(tilemap, (short)(gridX + 1), testY, DirCardinal.Up)) { this.endY = testY * (byte)TilemapEnum.TileHeight; this.viewHeight = (short)(this.endY - this.viewY - 10); break; } } }
// Returns TRUE if the character can phase to the horizontal location. public bool TestPhasingHorizontal(Character character, TilemapLevel tilemap, short toX, DirCardinal dir) { bool blocking = CollideTile.IsBlockingSquare(tilemap, toX, character.GridY, dir); if (blocking) { return(false); } if (character.GridY != character.GridY2) { blocking = CollideTile.IsBlockingSquare(tilemap, toX, character.GridY2, dir); } return(!blocking); }
// Returns TRUE if the character can phase to the vertical location. public bool TestPhasingVertical(Character character, TilemapLevel tilemap, short toY, DirCardinal dir) { bool blocking = CollideTile.IsBlockingSquare(tilemap, character.GridX, toY, dir); if (blocking) { return(false); } if (character.GridX != character.GridX2) { blocking = CollideTile.IsBlockingSquare(tilemap, character.GridX2, toY, dir); } return(!blocking); }
public void ThrowItem(bool useXMomentum = false) { if (this.objHeld == null) { return; } Item item = this.objHeld; // Item will release in the direction the character does. item.SetDirection(this.character.FaceRight); // Check what Main Layer has present at the throw-release tile: TilemapLevel tilemap = this.character.room.tilemap; bool isBlocked = CollideTile.IsBlockingSquare(tilemap, item.GridX, item.GridY, DirCardinal.Up); if (!isBlocked && item.GridX != item.GridX2) { isBlocked = CollideTile.IsBlockingSquare(tilemap, item.GridX2, item.GridY, DirCardinal.Up); } // Prevent Throw if (isBlocked) { this.DropItem(); return; } // Assign Item Physics + Thrown Properties item.intangible = Systems.timer.Frame + 5; item.releasedMomentum = useXMomentum ? (sbyte)Math.Round(this.character.physics.velocity.X.RoundInt / 2.5) : (sbyte)0; item.physics.velocity.X = FInt.Create(item.releasedMomentum); item.physics.velocity.Y = FInt.Create(-item.ThrowStrength); // Play Throw Sound this.character.room.PlaySound(Systems.sounds.wooshSubtle, 1f, this.character.posX + 16, this.character.posY + 16); // No longer holding object: this.ResetHeldItem(); }
private void PlaceDetectorsAbove(RoomScene room, short gridX, short gridY) { TilemapLevel tilemap = room.tilemap; // Scan for solid tiles above the flag, up to 18 above (for a full screen) for (short testY = (short)(gridY - 1); testY > gridY - 18; testY--) { if (testY < (byte)TilemapEnum.GapUp) { return; } // If there is a blocking tile at this grid sqare, stop placements. if (CollideTile.IsBlockingSquare(tilemap, gridX, testY, DirCardinal.Down)) { return; } // Otherwise, add a Detector. room.tilemap.SetMainTile(gridX, testY, (byte)TileEnum.DetectCheckpointPass, 0); } }