/// /// <summary> /// Changes the height of a particular tile's corner. /// </summary> /// /// <param name="tileX">The tile's X position.</param> /// <param name="tileZ">The tile's Z position.</param> /// <param name="corner">The corner to change.</param> /// <param name="change">The amount to change the height by (positive or negative integer).</param> /// public void changeHeight(int tileX, int tileZ, Tile.TileCorner corner, int change) { int displacementX = 0; int displacementZ = 0; switch (corner) { case Tile.TileCorner.TopLeft: displacementX = -1; displacementZ = -1; break; case Tile.TileCorner.TopRight: displacementX = 1; displacementZ = -1; break; case Tile.TileCorner.BottomLeft: displacementX = -1; displacementZ = 1; break; case Tile.TileCorner.BottomRight: displacementX = 1; displacementZ = 1; break; } try { this.tiles[tileX, tileZ].changeHeight(corner, change); } catch { } try { this.tiles[tileX + displacementX, tileZ].changeHeight(Tile.swapHorizontally(corner), change); } catch { } try { this.tiles[tileX, tileZ + displacementZ].changeHeight(Tile.swapVertically(corner), change); } catch { } try { this.tiles[tileX + displacementX, tileZ + displacementZ].changeHeight(Tile.swapVertically(Tile.swapHorizontally(corner)), change); } catch { } }
/// /// <summary> /// Gets the height of a particular tile's corner. /// </summary> /// /// <param name="tileX">The tile's X position.</param> /// <param name="tileZ">The tile's Z position.</param> /// <param name="corner">The corner in question.</param> /// public int getHeight(int tileX, int tileZ, Tile.TileCorner corner) { try { Tile tileQuery = this.tiles[tileX, tileZ]; if (tileQuery == null) { return(0); } // Get the height. return(tileQuery.getHeight(corner)); } catch { return(0); } }
/// /// <summary> /// Performs the action (finally!). /// </summary> /// /// <param name="client">The network client that represents the game.</param> /// <param name="world">The world object.</param> /// <param name="skills">The skillset of the player performing the action.</param> /// public void perform( NetClient client, World world, SkillSet skills, ref List <Notification> notifications) { Boolean fail = Program.random.NextDouble() > action.chance; switch (action.operation) { case Action.Operation.Examine: if (fail) { break; } switch (action.targetType) { case Action.TargetType.Tile: notifications.Add(new Notification(world.tiles[action.tileTarget.X, action.tileTarget.Y].getDescription())); break; case Action.TargetType.Item: notifications.Add(new Notification(action.targetItem.getDescription())); break; } break; case Action.Operation.Dig: skills.digging.increase(notifications); // Determine the tile the point is on top of. //TODO: Move this outside of the switch, so all 'cases' have access to it. int tileX = (int)(world.player.position.X / Tile.TILE_WIDTH); int tileZ = (int)(world.player.position.Z / Tile.TILE_WIDTH); // Force the player to fail if they're digging on a tile which doesn't allow it. fail = !world.tiles[tileX, tileZ].diggable; if (fail) { notifications.Add(new Notification("The ground is too hard to dig.")); break; } // Now that we know the tile we're on, we need to find the quadrant. float tilePositionX = (world.player.position.X - (float)(tileX * Tile.TILE_WIDTH)) / Tile.TILE_WIDTH; float tilePositionZ = (world.player.position.Z - (float)(tileZ * Tile.TILE_WIDTH)) / Tile.TILE_WIDTH; Tile.TileCorner currentCorner = Tile.TileCorner.TopLeft; if (tilePositionX < 0.5F && tilePositionZ < 0.5F) { currentCorner = Tile.TileCorner.TopLeft; } else if (tilePositionX >= 0.5F && tilePositionZ < 0.5F) { currentCorner = Tile.TileCorner.TopRight; } else if (tilePositionX < 0.5F && tilePositionZ >= 0.5F) { currentCorner = Tile.TileCorner.BottomLeft; } else if (tilePositionX >= 0.5F && tilePositionZ >= 0.5F) { currentCorner = Tile.TileCorner.BottomRight; } world.tiles[tileX, tileZ].onDig(skills, world, tileX, tileZ); world.changeHeight(tileX, tileZ, currentCorner, -1); int minX = action.tileTarget.X - 1; int minZ = action.tileTarget.Y - 1; int maxX = action.tileTarget.X + 1; int maxZ = action.tileTarget.Y + 1; if (minX < 0) { minX = 0; } if (minZ < 0) { minZ = 0; } if (maxX >= world.width) { maxX = world.width - 1; } if (maxZ >= world.height) { maxZ = world.height - 1; } for (int x = minX; x <= maxX; x++) { for (int z = minZ; z <= maxZ; z++) { updateTile(world, client, x, z); } } notifications.Add(new Notification("You excavate some " + world.tiles[tileX, tileZ].getName() + ".")); break; case Action.Operation.Forage: skills.foraging.increase(notifications); if (fail) { notifications.Add(new Notification("You fail to find anything of use.")); break; } Item foragedItem = Item.generateForagedItem(); world.player.inventory.store(foragedItem); world.tiles[action.tileTarget.X, action.tileTarget.Y].fruitful = false; updateTile(world, client, action.tileTarget.X, action.tileTarget.Y); notifications.Add(new Notification("You find a " + foragedItem.getName() + "!")); break; case Action.Operation.Cultivate: skills.farming.increase(notifications); skills.digging.increase(notifications); if (fail) { break; } world.replaceTile(action.tileTarget.X, action.tileTarget.Y, new DirtTile()); updateTile(world, client, action.tileTarget.X, action.tileTarget.Y); notifications.Add(new Notification("The tile is now cultivated.")); break; case Action.Operation.CutDown: skills.woodcutting.increase(notifications); if (fail) { break; } world.replaceTile(action.tileTarget.X, action.tileTarget.Y, new GrassTile()); notifications.Add(new Notification("You cut down the tree.")); break; default: Console.WriteLine("Unhandled action: '" + action.operation.ToString() + "'"); return; } }
//public Vector3 getNormalAtPoint( // float positionX, // float positionZ) //{ // // Get the heightmap of the point. // float[] heightmap = new float[4]; // Boolean flipped = this.getQuadrantHeightmap(positionX, positionZ, ref heightmap); // // Calculate position on the tile... // float tilePositionX = (positionX - (float)((int)(positionX / Tile.TILE_WIDTH) * Tile.TILE_WIDTH)) / Tile.TILE_WIDTH; // float tilePositionZ = (positionZ - (float)((int)(positionZ / Tile.TILE_WIDTH) * Tile.TILE_WIDTH)) / Tile.TILE_WIDTH; // float sqX = (tilePositionX < 0.5F ? tilePositionX * 2.0F : ((tilePositionX - 0.5F) * 2.0F)); // float sqZ = (tilePositionZ < 0.5F ? tilePositionZ * 2.0F : ((tilePositionZ - 0.5F) * 2.0F)); // float averageHeight = this.getHeightAtPoint( // (int)(positionX / Tile.TILE_WIDTH) + (Tile.TILE_WIDTH / 2.0F), // (int)(positionZ / Tile.TILE_WIDTH) + (Tile.TILE_WIDTH / 2.0F)); // VertexPositionNormalTexture[] vpnt = Tile.calculateTileVertices(this.tiles[tileX, tileZ].heights); // if (flipped) // { // if (sqX < sqZ) // { // // 0, 2, 3 // return vpnt // } // else // { // // 0, 1, 3 // } // } // else // { // if (sqX + sqZ < 1.0F) // { // // 0, 1, 2 // } // else // { // // 1, 2, 3 // } // } //} /// /// <summary> /// Gets the quadrant heightmap. /// </summary> /// /// <param name="positionX">The position x.</param> /// <param name="positionZ">The position z.</param> /// <param name="flipped">if set to <c>true</c> [flipped].</param> /// <param name="tilePositionX">The tile position x.</param> /// <param name="tilePositionZ">The tile position z.</param> /// /// <returns> /// Whether or not the quadrant is 'flipped'. /// </returns> /// private Boolean getQuadrantHeightmap( float positionX, float positionZ, ref float[] heightmap) { // Generate the float array. heightmap = new float[4] { 0.0F, 0.0F, 0.0F, 0.0F }; // If the position is outside of the world... if (positionX < 0.0F || positionZ < 0.0F || positionX >= Tile.TILE_WIDTH * this.width || positionZ >= Tile.TILE_WIDTH * this.height) { // Return the hightmap as it is, with no important values. return(false); } // Determine the tile the point is on top of. int tileX = (int)(positionX / Tile.TILE_WIDTH); int tileZ = (int)(positionZ / Tile.TILE_WIDTH); // Now that we know the tile we're on, we need to find the quadrant. float tilePositionX = (positionX - (float)(tileX * Tile.TILE_WIDTH)) / Tile.TILE_WIDTH; float tilePositionZ = (positionZ - (float)(tileZ * Tile.TILE_WIDTH)) / Tile.TILE_WIDTH; Tile.TileCorner currentCorner = Tile.TileCorner.TopLeft; if (tilePositionX < 0.5F && tilePositionZ < 0.5F) { currentCorner = Tile.TileCorner.TopLeft; } else if (tilePositionX >= 0.5F && tilePositionZ < 0.5F) { currentCorner = Tile.TileCorner.TopRight; } else if (tilePositionX < 0.5F && tilePositionZ >= 0.5F) { currentCorner = Tile.TileCorner.BottomLeft; } else if (tilePositionX >= 0.5F && tilePositionZ >= 0.5F) { currentCorner = Tile.TileCorner.BottomRight; } // Now we need to find the heightmap of the quadrant we're on. switch (currentCorner) { case Tile.TileCorner.TopLeft: heightmap[0] = getHeight(tileX, tileZ, Tile.TileCorner.TopLeft) * Tile.HEIGHT_STEP; heightmap[1] = ((getHeight(tileX, tileZ, Tile.TileCorner.TopLeft) + getHeight(tileX, tileZ, Tile.TileCorner.TopRight)) / 2.0F) * Tile.HEIGHT_STEP; heightmap[2] = ((getHeight(tileX, tileZ, Tile.TileCorner.TopLeft) + getHeight(tileX, tileZ, Tile.TileCorner.BottomLeft)) / 2.0F) * Tile.HEIGHT_STEP; heightmap[3] = tiles[tileX, tileZ].getAverageHeight() * Tile.HEIGHT_STEP; return(true); case Tile.TileCorner.TopRight: heightmap[0] = ((getHeight(tileX, tileZ, Tile.TileCorner.TopLeft) + getHeight(tileX, tileZ, Tile.TileCorner.TopRight)) / 2.0F) * Tile.HEIGHT_STEP; heightmap[1] = getHeight(tileX, tileZ, Tile.TileCorner.TopRight) * Tile.HEIGHT_STEP; heightmap[2] = tiles[tileX, tileZ].getAverageHeight() * Tile.HEIGHT_STEP; heightmap[3] = ((getHeight(tileX, tileZ, Tile.TileCorner.TopRight) + getHeight(tileX, tileZ, Tile.TileCorner.BottomRight)) / 2.0F) * Tile.HEIGHT_STEP; return(false); case Tile.TileCorner.BottomLeft: heightmap[0] = ((getHeight(tileX, tileZ, Tile.TileCorner.TopLeft) + getHeight(tileX, tileZ, Tile.TileCorner.BottomLeft)) / 2.0F) * Tile.HEIGHT_STEP; heightmap[1] = tiles[tileX, tileZ].getAverageHeight() * Tile.HEIGHT_STEP; heightmap[2] = getHeight(tileX, tileZ, Tile.TileCorner.BottomLeft) * Tile.HEIGHT_STEP; heightmap[3] = ((getHeight(tileX, tileZ, Tile.TileCorner.BottomLeft) + getHeight(tileX, tileZ, Tile.TileCorner.BottomRight)) / 2.0F) * Tile.HEIGHT_STEP; return(false); case Tile.TileCorner.BottomRight: heightmap[0] = tiles[tileX, tileZ].getAverageHeight() * Tile.HEIGHT_STEP; heightmap[1] = ((getHeight(tileX, tileZ, Tile.TileCorner.TopRight) + getHeight(tileX, tileZ, Tile.TileCorner.BottomRight)) / 2.0F) * Tile.HEIGHT_STEP; heightmap[2] = ((getHeight(tileX, tileZ, Tile.TileCorner.BottomLeft) + getHeight(tileX, tileZ, Tile.TileCorner.BottomRight)) / 2.0F) * Tile.HEIGHT_STEP; heightmap[3] = getHeight(tileX, tileZ, Tile.TileCorner.BottomRight) * Tile.HEIGHT_STEP; return(true); default: return(false); } }