From 911498fdd3fa713f76937404be5ef34783fe2866 Mon Sep 17 00:00:00 2001 From: "Jesse J. Bethel" Date: Wed, 13 Jul 2016 20:17:39 -0500 Subject: [PATCH] Removed index.html (from an IRC application example?) Corrections to index.adoc Cleaned up grammar and typos Clean up grammar and typos for second chapter Cleanup for part 3 Grammar and spelling corrections (a bit spotty after chapter 11, where my project diverged) --- doc/index.adoc | 16 +++++++-------- doc/index.html | 10 ---------- doc/part-1-graphics.adoc | 30 ++++++++++++++-------------- doc/part-10-menu-saving.adoc | 12 +++++------ doc/part-11-dungeon-progression.adoc | 2 +- doc/part-13-adventure-gear.adoc | 4 ++-- doc/part-2-object-map.adoc | 18 ++++++++--------- doc/part-3-dungeon.adoc | 10 +++++----- doc/part-4-fov-exploration.adoc | 6 +++--- doc/part-5-combat.adoc | 27 ++++++++++++------------- doc/part-6-going-berserk.adoc | 20 +++++++++---------- doc/part-7-gui.adoc | 4 ++-- doc/part-8-items.adoc | 2 +- doc/part-9-spells.adoc | 12 +++++------ 14 files changed, 81 insertions(+), 92 deletions(-) delete mode 100644 doc/index.html diff --git a/doc/index.adoc b/doc/index.adoc index 8e16eb2..2eee12a 100644 --- a/doc/index.adoc +++ b/doc/index.adoc @@ -44,12 +44,12 @@ https://github.com/tomassedovic/roguelike-tutorial/ Rust is a systems programming language targeting roughly the same space as C{plusplus}. That means it's fast and is generally used for things where you need a fair bit of control over how are things structured in -the memory, etc. Rust is a good candidate for writing a browser, +memory, etc. Rust is a good candidate for writing a browser, database, operating system, web server and... games. What attracted me personally to Rust was the fact that it was reasonably low-level (i.e. I could use it for things where I'd -normally go for C or C{plusplus}), with a good support for calling into +normally go for C or C{plusplus}), with good support for calling into libraries written in C/C{plusplus} but feeling much more modern. It has a real module system, closures, powerful macros and it protects @@ -62,8 +62,8 @@ As a *wonderful* cherry on top, it doesn't have null pointers or references. `libtcod` is a library specifically designed for writing roguelikes. It deals with rendering ASCII characters in a grid, mouse and keyboard -input and provides useful utilities for path finding, field of view, -noise toolkit and a name generator. +input and provides useful utilities for path finding and field of view, +a noise toolkit and a name generator. In other words, it provides a good chunk of what a typical roguelike would need. @@ -107,7 +107,7 @@ All in one file:: The original Python tutorial is all one file. That's not something you want to end up with -- especially when you're collaborating on the -project -- but the final result is still not _that_ big and it's makes +project -- but the final result is still not _that_ big and it makes writing and following the tutorial easier when you don't have to worry about where each code snippet goes. @@ -123,10 +123,10 @@ Sameness:: The original Python tutorial is a bit infamous because games that people do after going through it all look samey. That's not a reason to shun the tutorial, though. Just don't get caught in the game -desighn of it. The purpose of this is to teach you how to write a game +design of it. The purpose of this is to teach you how to write a game using libtcod. There's little of game design here. What I'd recommend is: go through this, absorb the concepts but then start from scratch -when actually writing your game. And think about how to make it +when actually writing your game, and think about how to make it unique. == Start the tutorial @@ -139,7 +139,7 @@ Start your game right away by setting up the screen, printing the <>:: This introduces two new concepts: the generic object system that - will be the basis for the whole game, and a general map object that + will be the basis for the whole game and a general map object that you'll use to hold your dungeon. <>:: diff --git a/doc/index.html b/doc/index.html deleted file mode 100644 index db13083..0000000 --- a/doc/index.html +++ /dev/null @@ -1,10 +0,0 @@ - - - Talk To Me! An IRC clien - -

Talk To Me!

-

Messages:

-
    -
- - diff --git a/doc/part-1-graphics.adoc b/doc/part-1-graphics.adoc index 95681cc..ac825d9 100644 --- a/doc/part-1-graphics.adoc +++ b/doc/part-1-graphics.adoc @@ -28,7 +28,7 @@ $ cargo new --bin roguelike $ cd roguelike/ ---- -It will create two files: `Cargo.toml` and `main.rs` in the `src` +This will create two files: `Cargo.toml` and `main.rs` in the `src` directory. `Cargo.toml` contains metadata for the project and any dependencies you're going to need (such as libtcod). @@ -62,13 +62,13 @@ Hello, world! .... Rust will first compile `main.rs` and any other files it needs (there -are none yet). The resulting binary program will called `roguelike` +are none yet). The resulting binary program will be called `roguelike` and placed in the `target/release` directory. Cargo will then run the program which will print `Hello, world!`. NOTE: Rust (and Cargo) can compile programs in two modes: _with -optimisations_ and _without_. Code compiled without opmimisations is +optimisations_ and _without_. Code compiled without optimisations is *really slow*, but it's easier to work with under a debugger. We will be using the optimised mode in the tutorial (with the `--release` option), to make sure no one is making speed claims without @@ -120,7 +120,7 @@ the asterisk (`*`) as the name means to import everything under `BackgroundFlag`, etc. -Now we'll add some constants so we're don't end up littering the +Now we'll add some constants so we don't end up littering the source code with a bunch of opaque numbers: [source,rust] @@ -145,7 +145,7 @@ the `println!` macro with code that sets up the libtcod window and renders a character on it. To create a window we call `Root::initializer(). ... .init()`. -In-between go custom settings. Default values are going to be used for +In between go custom settings. Default values are going to be used for any option that's not specified. [source,rust] @@ -179,7 +179,7 @@ let mut root: Root = Root::initializer(). ... .init(); Now let's have a look at the window options we're passing in. First, we're setting up a font. Libtcod uses bitmap fonts of various -formats. Calling the `font` methods let's us set our own font using a +formats. Calling the `font` methods lets us set our own font using a file name and a font layout. `font_type` is another option for loading a font. @@ -224,7 +224,7 @@ The next line sets a default _foreground_ colour to white. This is the colour everything will be drawn with unless specified otherwise. The `tcod::colors` module contains values for common colours as well -as the `Color` struct that let's you use your own. +as the `Color` struct that lets you use your own. Next we draw the `@` character at the coordinates `1, 1` on the screen. The `0, 0` coordinate is at the top left corner of the window. @@ -232,7 +232,7 @@ screen. The `0, 0` coordinate is at the top left corner of the window. Using `BackgroundFlag::None` says to ignore the default _background_ colour. -Calling `flush`, which will draw everything on the window at once. +Calling `flush` will draw everything on the window at once. And finally, we also need to call `wait_for_keypress` even though we're not processing keyboard input yet. This is because libtcod @@ -282,11 +282,11 @@ fn handle_keys(root: &mut Root, player_x: &mut i32, player_y: &mut i32) -> bool ---- A function signature in Rust is `fn function_name(parameter: -type, ...) -> return_type`. Here we call our function `handle_keys`, +type, ...) -> return_type`. Here we call our function `handle_keys`; it accepts three parameters -- the root console (of type `tcod::console::Root`), the x coordinate and the y coordinate (of type -`i32`) and it returns a boolean value. `true` says "exit the game", -`false` means "keep going" +`i32`) -- and it returns a boolean value. `true` says "exit the game", +`false` means "keep going". The &mut` bits before the types are borrowing operators. You can read about them (and the ownership they're strongly tied to) in the Rust @@ -304,7 +304,7 @@ could only read their values but it could not change them. Since we want to update them based on the key the player pressed, we'll get them as mutable references. Then we can assign a new value using the dereference operator (e.g. `*player_x = 10`) and that will show up -back in the caller code. +back in the calling scope. Right now, the function's body is empty, except that it always returns `false` (which means, keep the game going). Let's add the keyboard @@ -338,7 +338,7 @@ there are others for `alt`, `ctrl`, etc. The two dots at the end mean "I don't care about the other fields". If it wasn't there, it would not compile until you specified values -fore every field of the `Key` struct. +for every field of the `Key` struct. Rust requires that `match` arms are _exhaustive_. That means you have to specify all the possible values. However, as we don't care about @@ -375,7 +375,7 @@ use tcod::input::KeyCode::*; ---- Now, we could put it on top of the file next to the existing imports, -but: Rust lets you place them in individual functions as well, which +but Rust lets you place them in individual functions as well, which will make them available only for that function. Since we'll contain our keyboard-handling code in `handle_keys`, let's make it the first thing there. @@ -404,7 +404,7 @@ Now update our drawing function to use the player coordinates: root.put_char(player_x, player_y, '@', BackgroundFlag::None); ---- -And we also need to clear the _previous_ position position -- +And we also need to clear the _previous_ player position -- otherwise we'd leave a trail of `@` on the screen! Put this right before the `let exit = handle_keys(...)` call: diff --git a/doc/part-10-menu-saving.adoc b/doc/part-10-menu-saving.adoc index e5c9055..91b612e 100644 --- a/doc/part-10-menu-saving.adoc +++ b/doc/part-10-menu-saving.adoc @@ -32,7 +32,7 @@ struct Game { } ---- -So right it'll just hold the map, the message log and the inventory. +So right now it'll just hold the map, the message log and the inventory. We'll add more things later on, but let's start small. Now let's move our initialisation code under this struct. In `main`: @@ -196,7 +196,7 @@ wraps the underlying `Vec<(String, Color)>` and has the `add()` method (_BORING_) or *we put the method the vec type directly*. I know, right? -Rust let's you implement traits to types you don't control (e.g. +Rust lets you implement traits to types you don't control (e.g. because they come from the standard library like our `Vec`) assuming you control the trait. @@ -228,7 +228,7 @@ impl MessageLog for Vec<(String, Color)> { ---- This is basically the same thing as our `message` function does, -expect it's a method (so it takes an explicit `&mut self`) and we +except it's a method (so it takes an explicit `&mut self`) and we don't bother with the message count check. And now, we can just add messages to the log by calling: @@ -306,10 +306,10 @@ fn new_game(tcod: &mut Tcod) -> (Vec, Game) { } ---- -We return use a tuple to return two arguments: the vec of `Objects` and +We return a tuple with two elements: the vec of `Objects` and the `Game` struct. -`new_game` is calling `initialise_fov` so we need create it and move +`new_game` is calling `initialise_fov` so we need to create it and move the FOV-related code to it: [source] @@ -730,7 +730,7 @@ failure is `Err`. There's also the {error}[Error trait] which represents an error and lets you get its textual description. All the file-handling -serialiastion errors in our save/load code implement Error. +serialisation errors in our save/load code implement Error. So, looking at `save_game`, the `json::encode` call returns either `Ok(String)` with the encoded value or diff --git a/doc/part-11-dungeon-progression.adoc b/doc/part-11-dungeon-progression.adoc index 5cd4f6a..553a0de 100644 --- a/doc/part-11-dungeon-progression.adoc +++ b/doc/part-11-dungeon-progression.adoc @@ -244,7 +244,7 @@ pub fn take_damage(&mut self, damage: i32, game: &mut Game) -> Option { // } ---- <1> May return a number of XP if `take_damage` killed the monster -<2> We did kill the monster, return it's XP +<2> We did kill the monster, return its XP <3> We did not kill the monster, don't return anything diff --git a/doc/part-13-adventure-gear.adoc b/doc/part-13-adventure-gear.adoc index 8f59b89..bcb9f5a 100644 --- a/doc/part-13-adventure-gear.adoc +++ b/doc/part-13-adventure-gear.adoc @@ -14,7 +14,7 @@ and so on? We need equipment. It differs from the items we have in two ways: you can only equip it in limited slots and it enhances your abilities -while it's being worn. Unlike our items which are one-use-only (though +while it's being worn. This is unlike our items which are one-use-only (though they don't have to be!). == Basic equipment @@ -132,7 +132,7 @@ Game` here instead and you'll see the problem when we get to How do we equip our items? We can rely on the existing `Item` mechanism -- when you try to "use" or "cast" an equipment (which you -can do since it's an `Item`, too), we'll equip or dequip it. +can do since it's an `Item`, too), we'll equip or unequip it. First, let's add a new Item type: diff --git a/doc/part-2-object-map.adoc b/doc/part-2-object-map.adoc index 4d60cc2..49ffcb5 100644 --- a/doc/part-2-object-map.adoc +++ b/doc/part-2-object-map.adoc @@ -6,7 +6,7 @@ ifdef::env-github[:outfilesuffix: .adoc] == Off-screen consoles -Before we continue, let's talk about _consoles_. In libtocd, console +Before we continue, let's talk about _consoles_. In libtcod, console is where we _draw stuff_. We've only used one so far -- the root console. It is connected to the game window and anything you want to show must eventually make its way there. @@ -32,7 +32,7 @@ instead of `root`. And finally, blit the contents of the new console to the root console to display them. The `blit` function takes a lot of parameters, but -the meaning is straight forward. We take the console we want to blit +the meaning is straightforward. We take the console we want to blit _from_ (i.e. `con`), the coordinates where to start and the width and height of the area we want to blit (we'll blit it all). Then the destination (`root`), _where_ to start blitting (we'll use the @@ -116,8 +116,8 @@ let mut objects = [player, npc]; Now we'll need to do a few changes to make it work. First in `handle_keys` we'll use player's `move_by` method to change the -coordinates. This means we'll need to pass (mutable reference to) the -player object in. +coordinates. This means we'll need to pass in (a mutable reference to) the +player object. [source,rust] ---- @@ -174,7 +174,7 @@ const MAP_HEIGHT: i32 = 45; Next we'll define colours for the tiles. We'll have two tiles for now: _wall_ and _ground_. Let's define their _dark_ variants. When we add -field of view, we'll have add set for when they're lit. +field of view, we'll have to add a set for when they're lit. [source,rust] ---- @@ -215,7 +215,7 @@ The `#[derive(...)]` bit automatically implements certain behaviours there. `Debug` is to let us print the Tile's contents and `Clone` and `Copy` will let us _copy_ the values on assignment or function call instead of _moving_ them. So they'll behave like e.g. integers in this -matter. +respect. We don't want the `Copy` behaviour for `Object` (we could accidentally modify a copy instead of the original and get our changes lost for @@ -265,11 +265,11 @@ map[30][22] = Tile::wall(); map[50][22] = Tile::wall(); ---- -(you can also access the tile's properties directly like sof: +(you can also access the tile's properties directly like so: `map[30][22].blocked = true`) -Next we need to draw the draw the map on our window. Since we need to +Next we need to draw the map on our window. Since we need to draw both the objects and the map, let's create a new function that renders everything and call it from the main loop. @@ -325,7 +325,7 @@ if !map[(self.x + dx) as usize][(self.y + dy) as usize].blocked { We'll have to pass a reference to the map to `move_by` and `handle_keys` which calls it. This may look annoying now but as the -code grows, it will be gook to know which functions can see (and +code grows, it will be good to know which functions can see (and change!) what. Finally, since the `con` console is for objects and the map only, we diff --git a/doc/part-3-dungeon.adoc b/doc/part-3-dungeon.adoc index 1a60b92..cbc4423 100644 --- a/doc/part-3-dungeon.adoc +++ b/doc/part-3-dungeon.adoc @@ -8,9 +8,9 @@ ifdef::env-github[:outfilesuffix: .adoc] Having a painstakingly handmade room with artfully placed pillars is all well and good, but roguelikes are about procedural generation! How -about adding some randomness to the mix. +about adding some randomness to the mix? -We're going to carve rooms and tunnels in an underground rock. In this +We're going to carve rooms and tunnels in underground rock. In this section we'll build some helper functions which we'll then use to generate the whole dungeon. @@ -36,7 +36,7 @@ impl Rect { The rectangle stores the coordinates for the top-left and bottom-right points. -This function will take a rect and place it in the map, by making sure +This function will take a rect and place it in the map, making sure all the tiles are empty. [source,rust] @@ -201,7 +201,7 @@ use rand::Rng; With that out of the way, let's actually implement the algorithm in `make_map`. Remove the previous code that created the example rooms -and tunnel and instead make a loop goes through the maximum number of +and tunnel and instead make a loop that goes through the maximum number of rooms, assigning random coordinates and size to each one as we go. [source,rust] @@ -295,7 +295,7 @@ tunnels between the rooms. For every room except the first one we connect it to the previous one. Now, sometimes we can't connect them with a straight line (horizontal -or vertiral) but we need two tunnels. +or vertical) but we need two tunnels. We could start with a horizontal tunnel to reach the same level as the new room and then connect it with a vertical one or we can do the diff --git a/doc/part-4-fov-exploration.adoc b/doc/part-4-fov-exploration.adoc index 1c54245..e21034b 100644 --- a/doc/part-4-fov-exploration.adoc +++ b/doc/part-4-fov-exploration.adoc @@ -22,7 +22,7 @@ comparing the different algorithms. We'll define the chosen algorithm along with some other constants so they can be changed later. For now we'll just use the default -(`Basic`) algorithm. There's also an option to light walls or not, +(`Basic`) algorithm. There's also an option to light walls or not; this is a matter of preference. Another important constant is the maximum radius for FOV calculations, how far the player can see in the dungeon. (Whether this is due to the player's sight range or the light @@ -47,7 +47,7 @@ const COLOR_LIGHT_GROUND: Color = Color { r: 200, g: 180, b: 50 }; ---- The fov map object in `tcod` is called `Map`, which conflicts with our -own dungeon map type. So we'll rename the tcod's one to `FovMap` on +own dungeon map type. So we'll rename tcod's to `FovMap` on import: [source,rust] @@ -92,7 +92,7 @@ let mut previous_player_position = (-1, -1); time through the loop) Then this right before `handle_keys` (which is where the player's -position could change) +position could change): [source,rust] ---- diff --git a/doc/part-5-combat.adoc b/doc/part-5-combat.adoc index a85f6c5..4e3d10b 100644 --- a/doc/part-5-combat.adoc +++ b/doc/part-5-combat.adoc @@ -42,8 +42,7 @@ fn place_objects(room: Rect, objects: &mut Vec) { } ---- -We'll define the `MAX_ROOM_MONSTERS = 3` constant on top of the file -again. +We'll define the `MAX_ROOM_MONSTERS = 3` constant at the top of the file. Calling `rand::random::()` will produce an `f32` number between `0.0` and `1.0`. 80% of that is `0.8`. @@ -70,7 +69,7 @@ Let's also remove the dummy NPC from the initial objects list. We won't need it anymore. -== Getting hold of Player's position +== Getting hold of the Player's position Before we move further, there are two things we can do to make working with the _player_ object easier and also to get and set the position @@ -107,14 +106,14 @@ pub fn set_pos(&mut self, x: i32, y: i32) { These give us a shorthand for getting or setting both coordinates (`x` and `y`) at once. This will again simplify some code in `main`, the -`move_by` method of Object as well as setting player's initial +`move_by` method of Object as well as setting the player's initial position in `make_map`. == Blocking objects -If you tried to walk up to a monster, you'd seen that the player -walked right through! That's clearly not what we want to happen in +If you tried to walk up to a monster, you'd see that the player +would walk right through! That's clearly not what we want to happen in general. Plus, we don't want multiple monsters standing on the same tile. @@ -156,7 +155,7 @@ items, scrolls, stairs, etc. and the balance will shift. Better set things alive explicitly than turn it off. It's easy to see when you've missed setting `alive = true` but hard to do the opposite. -Now we'll create a function that tests if a file is blocked -- whether +Now we'll create a function that tests if a tile is blocked -- whether due to a wall or an object blocking it. [source,rust] @@ -244,7 +243,7 @@ fn move_by(id: usize, dx: i32, dy: i32, map: &Map, objects: &mut [Object]) { } ---- -Now we no longer have the problem, because we first call get the +Now we no longer have the problem, because we first get the object's position (immutable borrow that ends immediately), then call `is_blocked` with `objects` (again, immutable borrow that ends right after the call) and finally, with no borrows to burden us, we set the @@ -252,7 +251,7 @@ position. This is what Rust people sometimes refer to as "fighting the borrow checker". When you start with the language, you'll likely encounter a -lot of these situations. As you get more experienced though, you'll +lot of these situations. As you get more experienced, though, you'll learn which patterns will cause trouble and structure your code differently. @@ -436,7 +435,7 @@ For movement, we only want it to work when the player is alive so: [source] ---- -(Key { code: Up, .. }, Playing) => // move player +(Key { code: Up, .. }, true) => // move player ---- and so on. @@ -449,7 +448,7 @@ easier to read and it makes sure we never forget to handle the game state when we add a new key. -And now we need to go back to the main loop though and handle +And now we need to go back to the main loop and handle `PlayerAction` there. Change the end of the loop to: [source] @@ -505,7 +504,7 @@ With: [source] ---- -player_move_or_attack(PLAYER, 1, 0, map, objects) +player_move_or_attack(1, 0, map, objects) ---- Now let's write the function itself: @@ -542,10 +541,10 @@ It's possible no match will be found, so it actually returns `Option` here. We then test whether we have found a target at that position (in which case -we know it's index) and print out a message or whether we can just +we know its index), and either print out a message or just move into that place. -And that's it! You test it out. No one's dealing any damage, but the +And that's it! Test it out. No one's dealing any damage, but the game now detects when you're trying to attack a monster. And you can see the monsters taking their turns after you. diff --git a/doc/part-6-going-berserk.adoc b/doc/part-6-going-berserk.adoc index daf12d5..a611431 100644 --- a/doc/part-6-going-berserk.adoc +++ b/doc/part-6-going-berserk.adoc @@ -8,13 +8,13 @@ ifdef::env-github[:outfilesuffix: .adoc] == The Components -TODO: talk about composition vs. inhericance and how this isn't a real ECS whatever that means... +TODO: talk about composition vs. inheritance and how this isn't a real ECS whatever that means... Our components will be plain `structs` with related bits of data and not much else. Each `Object` will have some (or all or none) of the components attached and that will drive their behaviour. Only things with the `Fighter` component will be able to attack or be attacked, -etc.. +for example. Let's create the `Fighter` component. It will have hit points, maximum hit points (for healing), defense and attack power. @@ -71,7 +71,7 @@ changing it now) And next the monsters. Each monster will get a `Fighter` component as -well as the `Ai` one. In `place_objcets` where the monsters are +well as the `Ai` one. In `place_objects` where the monsters are defined: [source] @@ -93,12 +93,12 @@ if ... { == AI -We went through all this trouble and yet nothing happens? Let's that +We went through all this trouble and yet nothing happens? Let's fix that by actually using our newly-minted components! The monsters have been growling for too long and are ready to fight now. We'll start by creating a function that will cause an object (monster, -usually) move towards a position (the player's coordinates, usually). +usually) to move towards a position (the player's coordinates, usually). [source] ---- @@ -281,7 +281,7 @@ attack you. This is how you make a simple GUI! At the end of the ---- // show the player's stats if let Some(fighter) = objects[PLAYER].fighter { - con.print_ex(1, SCREEN_HEIGHT - 2, BackgroundFlag::None, TextAlignment::Left, + root.print_ex(1, SCREEN_HEIGHT - 2, BackgroundFlag::None, TextAlignment::Left, format!("HP: {}/{} ", fighter.hp, fighter.max_hp)); } ---- @@ -372,8 +372,8 @@ The first `if let` check looks almost identical to the one that's already there for taking the hit points down. There is a difference, however. It boils down to ownership again. The first `if let` takes a mutable -reference of `self.fighter`. That means, for the duration of that -block, we can't take a mutable reference to `self`, because it's part +reference to `self.fighter`. That means, for the duration of that +block, we can't take a mutable reference to `self`, because a part of it (`fighter`) is already borrowed. But we do need a mutable reference to pass it to the `on_death` @@ -466,7 +466,7 @@ for object in &to_draw { } ---- -Instead of going through the `objects` list and we clone it into a +Instead of going through the `objects` list we clone it into a mutable vector (`render_all` is taking `&[Object]` so it can't change the list directly -- nor should it). Then we sort the vector such that all non-blocking objects come before all the blocking ones. Since we can't @@ -491,7 +491,7 @@ for object in &to_draw { } ---- -It's finally ready to play, and it actually feels like a game! It was +It's finally ready to play, and it actually feels like a game! It's been a long journey since we first printed the `@` character, but we've got random dungeons, FOV, exploration, enemies, AI, and a true combat system. You can now beat those pesky monsters into a pulp and walk diff --git a/doc/part-7-gui.adoc b/doc/part-7-gui.adoc index 276e54a..101bf36 100644 --- a/doc/part-7-gui.adoc +++ b/doc/part-7-gui.adoc @@ -210,9 +210,9 @@ then repeat. When we have `y` lower than zero, it would mean we'd draw *above* the panel. Libtcod wouldn't let us, but since that means we've ran out of -space, why we may as well break out of the loop. +space, we may as well break out of the loop. -Again, we need to pass the messages argument to `render_all`. It's +Again, we need to pass the messages argument to `render_all`. Its signature is now: [source] diff --git a/doc/part-8-items.adoc b/doc/part-8-items.adoc index 735dc97..856ca2e 100644 --- a/doc/part-8-items.adoc +++ b/doc/part-8-items.adoc @@ -163,7 +163,7 @@ arrow-handling and the final `return DidntTakeTurn` line: And we need to pass inventory to `handle_keys`. And we'll _also_ have to change the `&mut [Object]` argument to `&mut Vec`, because that's what `pick_item_up` expects. The difference is that the former -is a mutable reference to an `array` -- we can change it's items but +is a mutable reference to an `array` -- we can change its items but not its _size_. The latter is a full vector, which means we can also grow or shrink it. diff --git a/doc/part-9-spells.adoc b/doc/part-9-spells.adoc index 0964172..59b89b8 100644 --- a/doc/part-9-spells.adoc +++ b/doc/part-9-spells.adoc @@ -62,7 +62,7 @@ let mut tcod = Tcod { }; ---- -(and remove the `fov_map` and `mouse` initialisation code, too since +(and remove the `fov_map` and `mouse` initialisation code, too, since it's in here) And next, let the compiler guide us. @@ -183,7 +183,7 @@ Now we need to write the `cast_lightning` function! fn cast_lightning(_inventory_id: usize, objects: &mut [Object], messages: &mut Messages, tcod: &mut Tcod) -> UseResult { - // find closest enemy (inside a maximum range and damage it) + // find closest enemy (inside a maximum range) and damage it let monster_id = closest_monster(LIGHTNING_RANGE, objects, tcod); if let Some(monster_id) = monster_id { // zap it! @@ -449,7 +449,7 @@ with an asterisk to return the boxed value -- `Ai`. If we didn't put the asterisk there, we'd return `Box`, which is not what `ai_take_turn` expects. -Now, the actual scroll that uses this AI! For it to appear in the +Now, the actual scroll that causes this AI! For it to appear in the dungeon it must be added to `place_objects`. Notice that the chance of getting a lightning bolt scroll must change: @@ -512,7 +512,7 @@ it with the `Confused` one. `target_monster` should always return a monster that has the `Ai` component, but the `Object.ai` still contains `Option` rather than bare `Ai` (not every Object has AI even though we expect each monster -to have one). We could use {unwrap}[the unwrap] or {expect}[expect] +to have one). We could use the {unwrap}[unwrap] or {expect}[expect] methods to get the inner value, but this would crash the program (`expect` would print a custom message). Here we use {unwrap_or}[unwrap_or] instead which will return the `Basic` AI in @@ -630,7 +630,7 @@ range from the clicked position to the player is lower or equal. We also make sure that the target is within FOV to prevent firing through walls. -Finally, we need a way of cancel the targeting UI: +Finally, we need a way to cancel the targeting UI: [source] ---- @@ -743,7 +743,7 @@ required it yet. Since they all must have the same function signature, we have to add it to `cast_heal`, `cast_lightning`, `cast_confuse` as well as `use_item`. -Here's what `on_use` bit looks like now: +Here's what the `on_use` bit looks like now: [source] ----