Decoded: Rogue (1980) by Toy, Arnold, Wichman DOS version (1983) by Mel Sibony and Jon Lane Source file: WEAPONS.C Beginner friendly, line-by-line code walkthrough by MaiZure WEAPONS.C provides weapon usage, item drop, and missile flight functions Original code: https://britzl.github.io/roguearchive/ Original code with line numbers http://www.maizure.org/projects/decoded-rogue/WEAPONS_linenum.txt 1 COMMENT 2 COMMENT 3 COMMENT 4 COMMENT 5 COMMENT 6 BLANK 7 Include game header 8 Include console management header 9 BLANK 10 Defines a placeholder value to tag non-projectile weapons 11 BLANK 12 Declares a weapon statistic structure 13 Wielding damage 14 Thrown damage 15 Launcher type 16 Other weapon flags 17 Initialize statistics for all 10 weapon types 18 Mace statistics 19 Long sword statistics 20 Bow statistics 21 Arrow statistics 22 Dagger statistics 23 Two-handed sword statistics 24 Dart statistics 25 Crossbow statistics 26 Crossbow bolt statistics 27 Spear statistics 28 End of weapon statistic definitions 29 BLANK 30 COMMENT 31 COMMENT 32 COMMENT 33 COMMENT SHOOT PROJECTILE 34 Defines missile with two arguments 35 Arguments 1 and 2 are the change in x and y per step (direction) 36 BLOCK START - missile, launches a projectile 37 Declare pointers to the object being launched and new copies of objects 38 BLANK 39 COMMENT 40 COMMENT 41 COMMENT 42 If the player fails to choose a weapon to shoot 43 Return failure 44 If the player chooses their current worn weapon or it's cursed 45 Return failure 46 COMMENT 47 COMMENT 48 COMMENT 49 COMMENT 50 COMMENT 51 Create a label to jump back and repeat a check 52 If there is only 1 item of the type in inventory... 53 Remove the item from inventory 54 Decrement the inventory counter 55 Otherwise this is a stack we're shooting (usually arrows/bolts) 56 COMMENT 57 COMMENT 58 COMMENT 59 Create a new item but if it fails... 60 Set the existing item stack to 1 61 Print a failure message 62 Redo from line 51, which will succeed now 63 End check for item creation failure 64 Decrement the stack counter 65 If the item is not in a group (not in inventory) 66 Decrement inventory counter 67 Copy the old object to the new object 68 Set the new object's count to 1 (only shoot 1 item at a time) 69 Reset the shooting object to the new item 70 End check for shooting from a multi-item stack 71 Animate the shot 72 COMMENT 73 COMMENT 74 COMMENT 75 COMMENT 76 If there is no monster at the item's position after animation.. 77 Or the item isn't covering a monster (Same thing?) 78 The item should fall to the ground 79 BLOCK END - missile 80 BLANK 81 COMMENT 82 COMMENT 83 COMMENT 84 COMMENT 85 COMMENT ANIMATE MISSILE 86 Defines do_motion with three arguments 87 Argument 1 is the pointer to an object 88 Arguments 2 and 3 are the direction deltas 89 BLOCK START - do_motion, animates projectiles 90 Declare a dud value for the floor position under the projectile 91 BLANK 92 COMMENT 93 COMMENT 94 COMMENT 95 Copy the player's position in to the object's position 96 Loop forever 97 Declare an integer used as a floor character 98 BLANK 99 COMMENT 100 COMMENT 101 COMMENT 102 If the projectile has moved, isn't at the player, but player can see it 103 Draw the floor character in place (remove projectile for new movement) 104 COMMENT 105 COMMENT 106 COMMENT 107 Update the projectile's y 108 Update the projectile's x 109 BLANK 110 If the projectile is in an open space and not at a doorway... 111 COMMENT 112 COMMENT 113 COMMENT 114 COMMENT 115 If the player can still see the projection 116 Save the floor character at the updated position 117 Draw the projectile on the map 118 Wait a tick 119 Otherwise, player can't see it anymore 120 Save the dud character since we won't be updating drawing anymore 121 Continue to next step 122 End check for projectile in an open space 123 Break from loop -- projectile stopped or travelled out of sight 124 Repeat infinite loop 125 BLOCK START - do_motion 126 BLANK GET ITEM SHORT NAME 127 short_name returns a pointer to a string 128 Defines short_name with one argument 129 Argument 1 is the input object 130 BLOCK START - short_name, returns the brief name (item type) 131 Switch on object type 132 CASE weapon: return the basic value from the weapon name table 133 CASE armor: return the basic value form the armor name table 134 CASE food: just return the string 'food' 135 CASE potion (fallthrough) 136 CASE scroll (fallthrough) 137 CASE amulet (fallthrough) 138 CASE wand/staff (fallthrough) 139 CASE ring 140 Return the name as shown in inventory 141 For all other object types (there aren't any...) 142 Return an unknown type string 143 End switch on object type 144 BLOCK END - short_name 145 BLANK 146 COMMENT 147 COMMENT 148 COMMENT 149 COMMENT ITEM DROP 150 Defines fall with two arguments 151 Argument 1 is the object to drop 152 Argument 2 is a flag to destory on drop 153 BLOCK START - fall, drops an item around around a location 154 Declare a fall coordinate 155 Declare a level position index 156 BLANK 157 Switch on the calculated fall position 158 BLOCK START - Switch on fall position 159 CASE regular fall to floor 160 Get the position within the level data array 161 Set the level data to the new object 162 Copy the position data to the object 163 If the player can see the object... 164 BLOCK START - Update player view after drop 165 If the object was dropped in a passage... 166 or a maze... 167 Apply highlighted text (inverted colors) 168 Draw the character 169 End extended formatting 170 If there is a monster at the dropped position 171 Update the monster's character buffer to the object it's now standing on 172 BLOCK END - Update player view after drop 173 Add the object to the level's object data 174 Return success 175 CASE fall in to a stack 176 No reason to destroy it - it was added to a floor stack 177 BLOCK END - Switch on fall position 178 If the destroy flag was set... 179 Print a message 180 and possibly an extended message 181 Remove the temp object from memory 182 BLOCK END - fall 183 BLANK 184 COMMENT 185 COMMENT 186 COMMENT 187 COMMENT INITIALIZE WEAPON OBJECT 188 Defines init_weapon with two arguments 189 Argument 1 is a pointer to a weapon 190 Argument 2 is a weapon type 191 BLOCK START - init_weapon, initializes weapon variables 192 Declare a pointer to the weapon statistics table 193 BLANK 194 Get the base weapon from the weapon table 195 Set the new weapon's damage from the table 196 Set the new weapon's hurl damage from the table 197 Set the new weapon's launcher type from the table 198 Set the new weapon's flags from the table 199 If the weapon is part of a stack (Arrows, etc) 200 BLOCK START - weapon stack 201 Add a randon stack size between 8 and 15 202 Add the weapon to a group 203 BLOCK END - weapon stack 204 Otherwise this is a single weapon 205 Count is one 206 BLOCK END - init_weapon 207 BLANK 208 COMMENT 209 COMMENT 210 COMMENT 211 COMMENT PROJECTILE HIT 212 Defines hit_monster with three arguments 213 Arguments 1 and 2 are position values 214 Argument 3 is a pointer to an object 215 BLOCK START - hit_monster, detects missile hit and applies damage 216 Declare a static coordinate (stays the same between calls) 217 Declare a pointe rto a monster 218 BLANK 219 If there is a monster at the input position... 220 Set the y coordinate 221 Set the x coordinate 222 Apply the projectile fight result to the monster 223 End check for monster at position 224 Return false - nothing hit 225 BLOCK END - hit_monster 226 BLANK 227 COMMENT 228 COMMENT 229 COMMENT 230 COMMENT CALCULATE WEAPON AUGMENTATION VALUES 231 num returns a pointer to a string of a value 232 Declare num with three arguments 233 Arguments 1 and 2 are statistic values 1 = Armor stat, 2 = weapon stat 234 Declares the type of number, armor or weapon values 235 BLOCK START - num, calculates the additional damage/protect description 236 Declare an output text buffer 237 BLANK 238 Get the augment sign, none or positive 239 If this is a weapon... 240 Use the second argument 241 Return the output description 242 BLOCK END - num 243 BLANK 244 COMMENT 245 COMMENT 246 COMMENT 247 COMMENT WIELD A WEAPON 248 Declares wield with no arguments 249 BLOCK START - wield, wears a weapon 250 Declares pointers to two objects, one wearing and one to be worn 251 Delcares a pointer to a string 252 BLANK 253 Get the current weapon 254 If player can't drop the current weapon... 255 BLOCK START - Cursed weapon 256 Keep the current weapon as the already worn choice 257 Return failure to wield 258 BLOCK END - Cursed weapon 259 Keep the current weapon as the already worn choice 260 If the player didn't choose a weapon to wield... 261 BLOCK START - Failed wield 262 Label to bad wield attempts 263 Do not pass time 264 Return failure 265 BLOCK END - Failed wield 266 BLANK 267 If the object to wield is armor 268 BLOCK START - Can't wield armor 269 Print failure message 270 Jump to bad wield on line 262 271 BLOCK END - Can't wield armor 272 If the chosen weapon is already worn 273 Return - nothing to do 274 BLANK 275 Otherwise, we've passed all checks - get the item's name 276 Set the item as the current weapon 277 Print success message 278 BLOCK END - wield 279 BLANK 280 COMMENT 281 COMMENT 282 COMMENT 283 COMMENT FIND DROP POSITION 284 Declare fallpos with two arguments 285 Argument 2 is the coordinate to return 286 Argument 1 is object to search around for a position 287 BLOCK START - fallpos, gets the fall position offset from a fixed point 288 Declare position position iterators, a character, and init a counter 289 Declare a pointer to a floor object 290 BLANK 291 Loop through all rows around the input object (top to bottom) 292 Loop through all columns around the input object (left to right) 293 COMMENT 294 COMMENT 295 COMMENT 296 COMMENT 297 COMMENT 298 If the player is at the identified position or it's off the map.. 299 Skip this position 300 If the character at the position is floor or passage (it's available) 301 Count the position and roll a random check starting at 50% 302 Set the y position of the drop 303 Set the x position of the drop 304 End check for choosing this drop position (Upper-left drop is favored) 305 Skip to next check 306 End check for empty space 307 If it's possible for the player to step on this position 308 And there's an object on the floor 309 And the object type matches the input object type 310 And the floor object has an item group 311 And the item groups match... 312 BLOCK START - Add dropping object to a stack 313 Add to the floor objects count 314 Return 2 315 BLOCK END - Add dropping object to a stack 316 End loop through adjacent positions 317 Return false if no positions are possible 318 BLOCK START - fallpos 319 BLANK BLOCK DURING TICK 320 Defines tick_pause with no arguments 321 BLOCK START - tick_pause, blocks processing during the same tick 322 Declare a variable to save the current tick 323 Import the actual current tick 324 BLANK 325 Match the tick counter... 326 While the ticks are the same (interrupt-driven update) 327 Loop forever 328 BLOCK END - tick_pause 329 EOF˙