Only in angband-282: LOG diff -c -r angband-282/README angband-283/README *** angband-282/README Wed Sep 10 19:53:04 1997 --- angband-283/README Mon Feb 9 07:00:26 1998 *************** *** 1,37 **** - This is the README file for Angband 2.8.2 (09/01/97) - Angband 2.8.2 is a stable official release (hopefully!) incorporating all - of the improvements added since the last official release (Angband 2.7.8). ! See the Official Angband Home Page "http://www.voicenet.com/~benh/Angband/" ! for more information about exactly what has changed recently. ! See the various Angband ftp sites (including "export.andrew.cmu.edu" and ! "ftp.cis.ksu.edu") for the latest files, patches, and executables. ! Contact Ben Harrison ("benh@voicenet.com") to report any bugs or make any ! suggestions. Use the newsgroup "rec.games.roguelike.angband" to ask any ! general questions about the game. ! === General information === Angband is a "graphical" dungeon adventure game using textual characters to represent the walls and floors of a dungeon and the inhabitants therein, in the vein of "rogue", "hack", "nethack", and "moria". ! There are extensive ascii "on line help" files in the "lib/help" directory. This version of Angband will run on Macintosh, Windows, Unix (X11/Curses), ! Linux (X11/Curses), Acorn, Amiga, various IBM machines, and many others... See Makefile, h-config.h, and config.h for details on compiling. See "Makefile.xxx" and "main-xxx.c" for various supported systems. - - Visit the Angband Home Page ("http://www.voicenet.com/~benh/Angband/"), - and browse through the Angband newsgroup ("rec.games.roguelike.angband"). - - Send bug reports, suggestions, etc, to Ben Harrison ("benh@voicenet.com"). === Quick and dirty compilation instructions === --- 1,54 ---- ! ************************************************** ! ** Angband 2.8.3 ** The Pits of Angband ** ! ************************************************** ! Based on Moria: Copyright (c) 1985 Robert Alan Koeneke ! and Umoria: Copyright (c) 1989 James E. Wilson ! Angband 2.0 - 2.4 - 2.6.2 by: ! Alex Cutler, Andy Astrand, Sean Marsh, ! Geoff Hill, Charles Teague, Charles Swiger ! ! Angband 2.8.3: Copyright (c) 1997 Ben Harrison + Send comments, bug reports, and patches, to "benh@phial.com" + Visit the Angband Home Page at "http://www.phial.com/angband/" + Browse the Angband newsgroup at "news:rec.games.roguelike.angband" + Read the online help files, especially "general.txt" and "version.txt" + Angband is available for Unix, X11, DOS, Windows, Macintosh, Amiga, etc. ! ! ! === General Info === ! ! This is the README file for Angband 2.8.3 (1998-02-09) Angband is a "graphical" dungeon adventure game using textual characters to represent the walls and floors of a dungeon and the inhabitants therein, in the vein of "rogue", "hack", "nethack", and "moria". ! There are some ascii "on line help" files in the "lib/help" directory. ! ! Angband 2.8.3 is a stable official release incorporating all the changes ! and improvements added since the last official release (Angband 2.7.8). ! ! See the Official Angband Home Page "http://www.phial.com/angband/" for ! a list (mostly complete) of what has changed in each recent version. ! ! See the various Angband ftp sites (including "export.andrew.cmu.edu" and ! "ftp.cis.ksu.edu") for the latest files, patches, and executables. ! ! Contact Ben Harrison ("benh@phial.com") to report any bugs or to make any ! suggestions. Use the newsgroup "rec.games.roguelike.angband" to ask any ! general questions about the game, including compilation question. This version of Angband will run on Macintosh, Windows, Unix (X11/Curses), ! Linux (X11/Curses), Acorn, Amiga, various DOS machines, and many others... See Makefile, h-config.h, and config.h for details on compiling. See "Makefile.xxx" and "main-xxx.c" for various supported systems. === Quick and dirty compilation instructions === diff -c -r angband-282/lib/edit/a_info.txt angband-283/lib/edit/a_info.txt *** angband-282/lib/edit/a_info.txt Wed Sep 3 00:11:54 1997 --- angband-283/lib/edit/a_info.txt Fri Jan 30 00:47:03 1998 *************** *** 19,25 **** # Version stamp (required) ! V:2.8.2 --- 19,25 ---- # Version stamp (required) ! V:2.8.3 diff -c -r angband-282/lib/edit/e_info.txt angband-283/lib/edit/e_info.txt *** angband-282/lib/edit/e_info.txt Wed Sep 3 00:11:58 1997 --- angband-283/lib/edit/e_info.txt Fri Jan 30 00:47:08 1998 *************** *** 22,28 **** # Version stamp (required) ! V:2.8.2 ### Body Armor ### --- 22,28 ---- # Version stamp (required) ! V:2.8.3 ### Body Armor ### diff -c -r angband-282/lib/edit/f_info.txt angband-283/lib/edit/f_info.txt *** angband-282/lib/edit/f_info.txt Wed Sep 3 00:12:01 1997 --- angband-283/lib/edit/f_info.txt Fri Jan 30 00:47:11 1998 *************** *** 16,22 **** # Version stamp (required) ! V:2.8.2 # 0x00 --> nothing --- 16,22 ---- # Version stamp (required) ! V:2.8.3 # 0x00 --> nothing diff -c -r angband-282/lib/edit/k_info.txt angband-283/lib/edit/k_info.txt *** angband-282/lib/edit/k_info.txt Wed Sep 3 00:12:13 1997 --- angband-283/lib/edit/k_info.txt Fri Jan 30 00:47:14 1998 *************** *** 23,29 **** # Version stamp (required) ! V:2.8.2 ##### Something special ##### --- 23,29 ---- # Version stamp (required) ! V:2.8.3 ##### Something special ##### diff -c -r angband-282/lib/edit/r_info.txt angband-283/lib/edit/r_info.txt *** angband-282/lib/edit/r_info.txt Wed Sep 3 00:13:08 1997 --- angband-283/lib/edit/r_info.txt Fri Jan 30 00:47:21 1998 *************** *** 108,114 **** # Version stamp (required) ! V:2.8.2 ##### The Player ##### --- 108,114 ---- # Version stamp (required) ! V:2.8.3 ##### The Player ##### *************** *** 2693,2699 **** B:HIT:HURT:3d5 B:HIT:HURT:3d5 F:UNIQUE | MALE | ! F:FORCE_MAXHP | FORCE_SLEEP | DROP_1D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | F:IM_FIRE | IM_COLD | IM_POIS | NO_CONF | NO_SLEEP S:1_IN_6 | --- 2693,2700 ---- B:HIT:HURT:3d5 B:HIT:HURT:3d5 F:UNIQUE | MALE | ! F:FORCE_MAXHP | FORCE_SLEEP | ! F:ONLY_ITEM | DROP_1D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | F:IM_FIRE | IM_COLD | IM_POIS | NO_CONF | NO_SLEEP S:1_IN_6 | diff -c -r angband-282/lib/edit/v_info.txt angband-283/lib/edit/v_info.txt *** angband-282/lib/edit/v_info.txt Wed Sep 3 00:13:12 1997 --- angband-283/lib/edit/v_info.txt Fri Jan 30 00:47:26 1998 *************** *** 13,19 **** # Version stamp (required) ! V:2.8.2 ### Simple Vaults (type 7) -- maximum size 44x22 ### --- 13,19 ---- # Version stamp (required) ! V:2.8.3 ### Simple Vaults (type 7) -- maximum size 44x22 ### diff -c -r angband-282/lib/file/news.txt angband-283/lib/file/news.txt *** angband-282/lib/file/news.txt Wed Sep 3 00:13:16 1997 --- angband-283/lib/file/news.txt Sun Feb 8 04:56:22 1998 *************** *** 1,22 **** ! *********************** ! ** Angband 2.8.2 ** ! *********************** - Based on Moria: Copyright (c) 1985 Robert Alan Koeneke - and Umoria: Copyright (c) 1989 James E. Wilson - Angband 2.0 - 2.4: Alex Cutler, Andy Astrand, Sean Marsh, - Geoff Hill, Charles Teague, and others - Angband 2.5 - 2.6: Charles Swiger (cs4w+@andrew.cmu.edu) - Angband 2.7 - 2.8: Ben Harrison (benh@voicenet.com) - Curses/X11 Module: Ben Harrison, Torbj|rn Lindgren - - Angband 2.8.2 is available for Unix, X11, Macintosh, IBM, Windows, etc. - Be sure to read the online help, especially "general.txt" and "version.txt". - - Visit the Angband Home Page at "http://www.voicenet.com/~benh/Angband/". - Send all comments, bug reports, patches, etc, to "benh@voicenet.com". --- 1,24 ---- ! ************************************************** ! ** Angband 2.8.3 ** The Pits of Angband ** ! ************************************************** ! ! Based on Moria: Copyright (c) 1985 Robert Alan Koeneke ! and Umoria: Copyright (c) 1989 James E. Wilson ! ! Angband 2.0 - 2.4 - 2.6.2 by: ! Alex Cutler, Andy Astrand, Sean Marsh, ! Geoff Hill, Charles Teague, Charles Swiger ! ! Angband 2.8.3: Copyright (c) 1997 Ben Harrison ! ! Send comments, bug reports, and patches, to "benh@phial.com" ! Visit the Angband Home Page at "http://www.phial.com/angband/" ! Browse the Angband newsgroup at "news:rec.games.roguelike.angband" ! Read the online help files, especially "general.txt" and "version.txt" ! Angband is available for Unix, X11, DOS, Windows, Macintosh, Amiga, etc. diff -c -r angband-282/lib/help/general.txt angband-283/lib/help/general.txt *** angband-282/lib/help/general.txt Wed Sep 10 20:38:47 1997 --- angband-283/lib/help/general.txt Sun Feb 8 04:04:55 1998 *************** *** 55,82 **** it contained a few minor (non-fatal) bugs (see the web page). You can give Angband 2.7.8 to your friends while they wait for Angband 2.8.2. ! Angband 2.8.2 will be the next official "stable" version. A whole lot of changes have been made since Angband 2.7.8 was released, and there is now a web page listing all of the changes made in each version since that one. ! Angband 2.7.9v1, 2.7.9v2, 2.7.9v3, 2.7.9v4, 2.7.9v5, 2.7.9v6, 2.8.0, and ! 2.8.1 are intended as "transition" versions leading up to Angband 2.8.2, ! and they are all still available (for now) at the ftp sites. Note that ! Angband 2.8.2 is based on Angband 2.8.1, and will incorporate only those ! changes needed to fix problems encountered in Angband 2.8.1, so it should ! be available as soon as the public beta testing phase is complete. ! ! See the Official Angband Home Page "http://www.voicenet.com/~benh/Angband" ! for up to date information about the latest version of Angband, including ! a complete list of recent modifications and known bugs. You can obtain the latest source and pre-compiled executables from various places, try "ftp://ftp.cis.ksu.edu/pub/Games/Angband/Angband-2.7.x" and the developer site at "ftp://export.andrew.cmu.edu/angband". ! You can email compliments, complaints, bug reports, and presents to ! me ("benh@voicenet.com"), and you can post interesting experiences, ! general questions, compilation questions and code suggestions to the ! newsgroup ("rec.games.roguelike.angband"). You may freely distribute the game, and its source, though you are bound not only by the existing copyright notice from 1984, but also whatever --- 55,80 ---- it contained a few minor (non-fatal) bugs (see the web page). You can give Angband 2.7.8 to your friends while they wait for Angband 2.8.2. ! Angband 2.8.3 will be the next official "stable" version. A whole lot of changes have been made since Angband 2.7.8 was released, and there is now a web page listing all of the changes made in each version since that one. ! Angband 2.7.9v1, 2.7.9v2, 2.7.9v3, 2.7.9v4, 2.7.9v5, 2.7.9v6, 2.8.0, 2.8.1, ! and 2.8.2, are basically "transition" versions leading up to Angband 2.8.3, ! and they are all still available (for now) at the ftp sites. Angband 2.8.3 ! is based on all previous versions, and incorporates bug fixes in addition to ! new features. ! ! See the Official Angband Home Page ("http://www.phial.com/angband/") for up ! to date information about the latest version of Angband, including a complete ! list of recent modifications and known bugs. You can obtain the latest source and pre-compiled executables from various places, try "ftp://ftp.cis.ksu.edu/pub/Games/Angband/Angband-2.7.x" and the developer site at "ftp://export.andrew.cmu.edu/angband". ! You can email compliments, complaints, suggestions, bug reports, and patches ! to me ("benh@phial.com"), and you can post interesting experiences and basic ! questions to the newsgroup ("rec.games.roguelike.angband"). You may freely distribute the game, and its source, though you are bound not only by the existing copyright notice from 1984, but also whatever *************** *** 97,102 **** --- 95,102 ---- specified external directory, to allow access via the "online help" system. Remember to tell all your friends about how much you like Angband... + + === A quick demonstration === diff -c -r angband-282/lib/help/option.txt angband-283/lib/help/option.txt *** angband-282/lib/help/option.txt Wed Sep 10 20:53:39 1997 --- angband-283/lib/help/option.txt Wed Feb 11 06:30:27 1998 *************** *** 65,100 **** discounts. The resulting stack keeps the largest discount. This option may cause you to lose "value", but will give you optimal pack usage. ! Show labels in object lists [show_labels] ! Display the "labels" for objects in the "equipment" list, and in any ! "special" window which is displaying the "equipment". These labels ! indicate what the player is "using" the object for, such as "wielding" ! or "wearing" (in a given location). After you have played for a while, ! this information is no longer useful, and can be annoying. ! ! Show weights in object lists [show_weights] ! Display the weights of objects in the "inventory" and "equipment" lists, ! and in "stores", and in any "special" window which is displaying objects. ! ! Show choices in certain sub-windows [show_choices] ! Display "choices" in any sub-windows which are being used to display ! your inventory or equipment. Also, if exactly one sub-window is being ! used to display your inventory or equipment, then it will (temporarily) ! be toggled as needed to always show the "appropriate" set of objects. ! ! Show details in certain sub-windows [show_details] ! Display extra details in any sub-windows (and the main screen) which ! are being used to display monster recall. These details include the ! number of monsters killed and the textual descriptions. Audible bell (on errors, etc) [ring_bell] Attempt to make a "bell" noise when various "errors" occur. - Use color for inventory listings [inventory_colors] - Use color for object descriptions whenever the inventory, equipment, - or store contents are being displayed. The colors are based on object - types, not on actual object colors. - === Option Set 2 -- Disturbance === --- 65,97 ---- discounts. The resulting stack keeps the largest discount. This option may cause you to lose "value", but will give you optimal pack usage. ! Show labels in equipment listings [show_labels] ! Display "labels" (what an object is being used for) for objects in all ! "equipment" listings. ! ! Show weights in all object listings [show_weights] ! Display "weights" (in pounds) of objects in all "inventory", "equipment", ! "store items", and "home items" listings. ! ! Show choices in inven/equip listings [show_choices] ! Display "choices" (legal responses) in any sub-windows which are being ! used to display your inventory or equipment. Also, if one sub-window ! is being used to display your inventory or equipment, then this option ! will cause it to be (temporarily) toggled as needed to always show the ! "appropriate" set of objects (inventory or equipment). ! ! Show details in monster descriptions [show_details] ! Display "details" (including number of monsters killed, and textual ! descriptions) in monster descriptions. ! are displaying the monster. ! ! Show flavors in object descriptions [show_flavors] ! Display "flavors" (color or variety) in object descriptions, even for ! objects whose type is known. This does not affect objects in stores. Audible bell (on errors, etc) [ring_bell] Attempt to make a "bell" noise when various "errors" occur. === Option Set 2 -- Disturbance === *************** *** 148,153 **** --- 145,160 ---- Produce a "bell" noise, and flush all pending input, when various "failures" occur, as described above. + Verify destruction of objects [verify_destroy] + Prompt for verification of the "destroy" command. + + Verify use of special commands [verify_special] + Prompt for verification of the "special" commands (borg and debug). + + Allow quantity specification [allow_quantity] + Prompt for a quantity when necessary, instead of defaulting to a + single object. + === Option Set 3 -- Game-play === *************** *** 224,237 **** option is extremely slow, but can produce viciously smart monsters. Monsters chase recent locations (v.slow) [flow_by_smell] ! As above, but also allow monsters to take advantage of "old" trails ! that you may have left in the dungeon. ! ! Monsters follow the player (beta) [track_follow] ! This option is currently non-functional. ! ! Monsters target the player (beta) [track_target] ! This option is currently non-functional. Monsters learn from their mistakes [smart_learn] Allow monsters to learn what spell attacks you are resistant to, --- 231,238 ---- option is extremely slow, but can produce viciously smart monsters. Monsters chase recent locations (v.slow) [flow_by_smell] ! Allow monsters to take advantage of "old" trails that you may have left ! in the dungeon. This has no effect unless "flow_by_sound" is also set. Monsters learn from their mistakes [smart_learn] Allow monsters to learn what spell attacks you are resistant to, *************** *** 247,260 **** Reduce lite-radius when running [view_reduce_lite] Reduce the "radius" of the player's "lite" to that of a "torch" when the player is "running", which makes running more "efficient", ! but is extremely annoying. Certain older versions of Angband used ! this behavior always, so "purists" should turn it on. ! Reduce view-radius in town [view_reduce_view] ! Reduce the "radius" of the player's "view" by half when the player ! is in town. This makes running faster in town, and also allows the ! player to ignore monsters in town which are more than ten grids away, ! which is usually safe, since none have distance attacks. Avoid checking for user abort [avoid_abort] Avoid checking to see if the user has pressed a key during resting --- 248,258 ---- Reduce lite-radius when running [view_reduce_lite] Reduce the "radius" of the player's "lite" to that of a "torch" when the player is "running", which makes running more "efficient", ! but is extremely annoying. ! Hide player symbol when running [hidden_player] ! Hide the player symbol when the player is "running", which makes the ! game somewhat faster. Avoid checking for user abort [avoid_abort] Avoid checking to see if the user has pressed a key during resting *************** *** 293,302 **** time, since it will prevent you from continuing your macro while being attacked by a monster. - Flush input before every command [flush_command] - This option forces the game to flush all pending input before every - command. This option is silly, unless you are very paranoid. - Flush output before every command [fresh_before] This option forces the game to flush all output before every command. This will give you maximal information, but may slow down the game --- 291,296 ---- *************** *** 304,320 **** resting, running, or repeating commands, since the outout is always flushed when the game is waiting for a keypress from the user. ! Flush output after every command [fresh_after] This option forces the game to flush all output after not only every player command, but also after every round of processing monsters and ! objects, which will give you maximal information, but may slow down ! the game a lot, especially on slower machines, and on faster machines ! you normally do not have a chance to see the results anyway. ! ! Flush output after every message [fresh_message] ! This option forces the game to flush all output after every message ! displayed by the game. This will give you maximal information, but ! may slow down the game somewhat. Compress messages in savefiles [compress_savefile] Compress the savefile, by only saving the most recent "messages" that --- 298,309 ---- resting, running, or repeating commands, since the outout is always flushed when the game is waiting for a keypress from the user. ! Flush output after certain things [fresh_after] This option forces the game to flush all output after not only every player command, but also after every round of processing monsters and ! objects, and after every message, which will maximize your information, ! but may slow down the game a lot, especially on slower machines, and on ! faster machines you cannot see the results anyway. Compress messages in savefiles [compress_savefile] Compress the savefile, by only saving the most recent "messages" that *************** *** 410,415 **** --- 399,409 ---- Display a brief description of the character, including a breakdown of the current player "skills" (including attacks/shots per round). + Display player flags + Display a brief description of the character, including a breakdown + of the contributions of each equipment item to various resistances + and stats. + Display messages Display the most recently generated "messages". *************** *** 442,459 **** at which the player is warned that he may die. It is also used as the cut-off for using red to display both hitpoints and mana. ! The "delay_factor" value, if non-zero, is used to "slow down" the game, which is ! useful to allow you to "observe" the temporal effects of bolt, beam, and ball ! attacks. The actual delay is equal to "delay_factor" cubed, in milliseconds. ! The "preserve" flag, if set when the character was created, cancels all level feelings of the "special" variety, but allows "missed" artifacts to be "saved" by wandering monsters and found again at a later time. This only works for ! non-identified artifacts. ! The "maximize" flag, if set when the character was created, causes the "race" and "class" stat bonuses to be applied as "equipment" bonuses. This usually makes the character harder at the beginning of the game, but easier later on, ! since the stats are no longer limited to a "natural" value of "18/100". --- 436,455 ---- at which the player is warned that he may die. It is also used as the cut-off for using red to display both hitpoints and mana. ! The "delay_factor" value, if non-zero, will slow down the visual effects used ! for missile, bolt, beam, and ball attacks. The actual time delay is equal to ! "delay_factor" cubed, in milliseconds. ! The "preserve" flag (specified when a character is created) cancels all level feelings of the "special" variety, but allows "missed" artifacts to be "saved" by wandering monsters and found again at a later time. This only works for ! non-identified artifacts. The character description screen shows the value ! of this flag. ! The "maximize" flag (specified when a character is created) causes the "race" and "class" stat bonuses to be applied as "equipment" bonuses. This usually makes the character harder at the beginning of the game, but easier later on, ! since the stats are no longer limited to a "natural" value of "18/100". The ! character description screen shows the value of this flag. diff -c -r angband-282/lib/help/playing.txt angband-283/lib/help/playing.txt *** angband-282/lib/help/playing.txt Thu Sep 11 22:59:24 1997 --- angband-283/lib/help/playing.txt Sun Feb 8 03:53:56 1998 *************** *** 19,29 **** includes many more "capital" and "control" keys, as shown below. Note that any keys that are not required for access to the underlying ! command set may be used by the user as "command macro" triggers (see below). ! You may always specify any "underlying command" directly by pressing backslash ! ("\") plus the "underlying command" key. This is normally only used in "macro" ! definitions. You may often enter "control-keys" as a caret ("^") plus the key ! (so "^" + "p" often yields "^P"). Some commands allow an optional "repeat count", which allows you to tell the game that you wish to do the command multiple times, unless you press a --- 19,29 ---- includes many more "capital" and "control" keys, as shown below. Note that any keys that are not required for access to the underlying ! command set may be used by the user to extend the "keyset" which is being ! used, by defining new "keymaps". To avoid the use of any "keymaps", press ! backslash ("\") plus the "underlying command" key. This is normally only ! used in "macro" definitions. You may enter "control-keys" as a caret ("^") ! plus the key (so "^" + "p" yields "^P"). Some commands allow an optional "repeat count", which allows you to tell the game that you wish to do the command multiple times, unless you press a *************** *** 69,80 **** allow the use of the "5" key to "stand still", which is most convenient when using the original keyset. ! Note that on many systems, it is possible to define "macros" (or "command ! macros") to various keys, or key combinations, so that it is often possible to ! make macros which, for example, allow the use of the shift or control modifier ! keys, plus a numeric keypad key, to specify the "run" or "alter" command, with ! the given direction, regardless of any keymap definitions, by using the fact ! that you can always, for example, use "\" + "." + "6", to specify "run east". --- 69,80 ---- allow the use of the "5" key to "stand still", which is most convenient when using the original keyset. ! Note that on many systems, it is possible to define "macros" to various ! keys, or key combinations, so that it is often possible to make macros which, ! for example, allow the use of the shift and/or control modifier keys, plus a ! numeric keypad key, to specify the "run" or "alter" command, with the given ! direction, regardless of any keymap definitions, by using the fact that you ! can always, for example, use "\" + "." + "6", to specify "run east". *************** *** 365,437 **** "macros", which are mappings from a single logical keypress to a sequence of keypresses, allowing you to use special keys on the keyboard, such as function keys or keypad keys, possibly in conjunction with modifier keys, ! to "automate" repetitive multi-keypress commands that you use a lot. The ! macros can be marked as "normal" macros, which means they will fire any ! time you press the trigger key, or as "command" macros, which means they ! will only fire if you are being asked for a command. The command macros ! are a hack which allow you to use keys which are not used for any command ! to trigger a macro, without inducing strange behavior if you attempt to ! use those keys in a special situation, such as entering an inscription. ! Since macros represent sequences of keypresses, and not all keypresses have a printable representation, macro triggers and actions must often be "encoded" into a human readible form. This is done using several types ! of encoding, including "\xHH" for character number HH in hexidecimal, ! "\NNN" for character number NNN in octal, "\e" for the "escape" code, ! "\n" for the "newline" code, "\r" for the "return" code, "\s" for the ! "space" code, "\\" for backslash, "\^" for caret, and "^X" for the code ! for any "control" key "ctrl-X". Note that the "action" of a macro will ! not be checked against other macro triggers, so you cannot make infinite loops. You may specify extremely long macros, but you are limited in length by the underlying input mechanisms, which in general limit you to about 1024 keys in both triggers and actions. The special "\" command (which must be encoded in macros as "\\") ! is very useful in macros, since it bypasses all macros and keymaps and the ! next keystroke is considered a command in the underlying Angband command ! set. For a list of the Angband command set, see the section on Command ! Descriptions below. For example, a macro which maps Shift-KP6 to "\" + ! "." + "6" will induce the "run east" behavior, regardless of what keyset ! the user has chosen, and regardless of what keymaps have been defined. ! ! Command macros, as mentioned above, can only be triggered when the ! player is in "command" mode (when Angband is expecting a normal command). ! This is useful for defining new commands or shortcuts that you want to map ! to normal keys. For example, by default, the "X" key is bound via a ! command macro to "w0", as mentioned above, so that you can use it to ! quickly switch between two weapons (or a digger and a weapon). Were this ! defined as a regular macro rather than a command macro, you would never be ! able, for example, to enter the filename "BOXES.TXT", since the macro would ! fire, chaning your input to "BOw0ES.Tw0T". In general, you will want to use ! command macros rather than normal macros, though, for example, normal macros ! can be told to produce a leading sequence of keys starting with "\e\e\e\e", ! which will clear any "-more-" prompts or other silliness. --- User Pref Files (Keymaps) --- The "Interact with macros" command also allows you to define "keymaps", which are vaguely related to macros. A keymap maps a single ! keypress to another single keypress with an optional direction. Angband ! uses keymaps internally to map both the original and the roguelike keysets ! to the underlying command set. This means that when you are defining ! keymaps, the keypress you map a key to must be an underlying command, not ! a keypress from the original or roguelike keysets. Note that the original ! keyset is almost identical to the underlying keyset, except that "numbers" ! are mapped to "," or ";" plus a direction, "T" is mapped to "+", and a few ! control-keys are mapped to various things. See below for the full set of ! underlying commands. Normally, there is no reason to use a keymap, unless ! you want to prevent accidental use of certain commands, and you are afraid ! those commands might be contained in some macro action. Also, you could ! use a keymap to allow the use of a single set of macros which included the ! "pray prayer" ("p") or "cast spell" ("m") command, as appropriate, by using ! "m" in the macros, and making a keymap from "m" to "p" when using a priest. ! ! There is only one way to specify a "keymap" in a user pref commands. ! The "S:::" command activates a keymap from the "" key to ! the "" key, with optional direction "". Note that both "" and ! "" must currently be specified as ascii values, and "" should be a ! "numeric" direction, 1 to 9, or "zero" for "no direction". Eventually, the ! use of the "5" direction might be allowed to specify automatic use of the ! current target (if legal) with the given keymap. --- User Pref Files (Visuals) --- --- 365,415 ---- "macros", which are mappings from a single logical keypress to a sequence of keypresses, allowing you to use special keys on the keyboard, such as function keys or keypad keys, possibly in conjunction with modifier keys, ! to "automate" repetitive multi-keypress commands that you use a lot. ! ! Since macros represent keypress sequences, and not all keypresses have a printable representation, macro triggers and actions must often be "encoded" into a human readible form. This is done using several types ! of encoding, including "\xHH" for character number HH in hexidecimal, "\e" ! for the "escape" code, "\n" for the "newline" code, "\r" for the "return" ! code, "\s" for the "space" code, "\\" for backslash, "\^" for caret, and ! "^X" for the code for any "control" key "ctrl-X". Note that the "action" ! of a macro will not be checked against other macro triggers (unless the ! macro action contains a "control-backslash"), so you cannot make infinite loops. You may specify extremely long macros, but you are limited in length by the underlying input mechanisms, which in general limit you to about 1024 keys in both triggers and actions. The special "\" command (which must be encoded in macros as "\\") ! is very useful in macros, since it bypasses all keymaps and allows the next ! keystroke to be considered a command in the underlying Angband command set. ! For a list of the Angband command set, see the "command.txt" help file. ! For example, a macro which maps Shift-KP6 to "\" + "." + "6" will induce ! the "run east" behavior, regardless of what keyset the user has chosen, and ! regardless of what keymaps have been defined. ! ! Macros can be specified in user pref files as a pair of lines, one ! of the form "A:", which defines the encoded macro action, and one of ! the form "P:", which defines the encoded macro trigger. --- User Pref Files (Keymaps) --- The "Interact with macros" command also allows you to define "keymaps", which are vaguely related to macros. A keymap maps a single ! keypress to a series of keypresses, which bypass both other keymaps and ! any macros. Angband uses keymaps to map the original and the roguelike ! keysets to the underlying command set, and allows the user to modify or ! add keymaps of their own. Note that all keymap actions must be specified ! using underlying commands, not keypresses from the original or roguelike ! keysets. The original keyset is almost identical to the underlying keyset, ! except that "numbers" are mapped to ";" plus a direction, "5" is mapped to ! ",", and a few control-keys are mapped to various things. See "command.txt" ! for the full set of underlying commands. Some uses for keymaps include the ! ability to "disable" a command by mapping it to "\x00", ! ! Keymaps can be specified in user pref files as line of the form ! "M: ", where is the keyset (0/1 for original/roguelike), ! is the encoded trigger key, and is the encoded keymap action. --- User Pref Files (Visuals) --- *************** *** 453,458 **** --- 431,439 ---- Note that this command can be abused in various ways, and if you must do so, remember that you are only cheating yourself. + Keymaps can be specified in user pref files as line of the form + "R::/" or "K::/" or "F::/" or "U::/". + --- User Pref Files (Colors) --- The "Interact with colors" command allows you to change the actual *************** *** 461,466 **** --- 442,450 ---- change the actual RGB values used to represent each of the 16 colors used by Angband, and perhaps even allow you to define new colors which are not currently used by Angband. + + Colors can be specified in user pref files as line of the form + "V:::::". --- User Pref Files (Options) --- diff -c -r angband-282/lib/help/version.txt angband-283/lib/help/version.txt *** angband-282/lib/help/version.txt Wed Sep 10 20:44:46 1997 --- angband-283/lib/help/version.txt Sun Feb 8 04:08:00 1998 *************** *** 1,12 **** === Version Information === ! This file was last updated for Angband 2.8.2. ! Make sure to read the newsgroup "rec.games.roguelike.angband", and to ! visit the website "http://www.voicenet.com/~benh/Angband/" for the most up to date information about Angband. ! Angband 2.8.2 has an incredibly complex history, and is the result of a lot of work by a lot of people, all of whom have contributed their time and energy for free, being rewarded only by the pleasure of keeping alive one of the best freeware games available anywhere. --- 1,12 ---- === Version Information === ! This file was last updated for Angband 2.8.3. ! Make sure to read the newsgroup ("rec.games.roguelike.angband"), and to visit ! the Official Angband Home Page ("http://www.phial.com/angband/") for the most up to date information about Angband. ! Angband 2.8.3 has an incredibly complex history, and is the result of a lot of work by a lot of people, all of whom have contributed their time and energy for free, being rewarded only by the pleasure of keeping alive one of the best freeware games available anywhere. *************** *** 16,21 **** --- 16,22 ---- we must rely on simpler methods, such as change logs, source file diffs, and word of mouth. Some of this information is summarized in this file. + Please be sure to read the copyright information at the end of this file. === Brief Version History === *************** *** 92,115 **** After Angband 2.7.8 was released, I created a web site to keep track of all the changes made in each version (though a few may have been missed), and acquired the use of a new develoepement ftp server to supplement the ! official "mirror" server. The next few releases, from Angband 2.7.9v1 ! through Angband 2.7.9v6, really should have been given their own separate ! version numbers, but I kept thinking that I wanted to save Angband 2.8.0 ! for a really special release. Angband 2.8.0 and Angband 2.8.1 were then ! released using a more normal version scheme. Angband 2.8.2 will hopefully ! be an official stable release cleanup, and includes mostly just bug fixes ! and general cleanup of Angband 2.8.1, plus a few minor new features. Note ! that almost all changes made in each version released after Angband 2.7.8 ! can be found at the Official Angband Home Page, and I just wish that I had ! thought of keeping a change log for the earlier versions as well. ! The Official Angband Home Page ("http://www.voicenet.com/~benh/Angband/") ! was created to serve as the most up to date description of Angband, listing changes made between versions, and changes planned for upcoming versions, ! and to list various email addresses and web sites related to Angband. ! === Some of the changes from Angband 2.6.1 to Angband 2.7.9 === It is very hard to pin down, along the way from 2.6.2 to 2.7.8, exactly what changes were made, and exactly when they were made. Most releases --- 93,113 ---- After Angband 2.7.8 was released, I created a web site to keep track of all the changes made in each version (though a few may have been missed), and acquired the use of a new develoepement ftp server to supplement the ! official "mirror" server. This web site is now permanently located at ! the Official Angband Home Page (http://www.phial.com). Unfortunately, ! the next six versions were numbered Angband 2.7.9v1 to Angband 2.7.9v6, ! but really each were rather major updates. Angband 2.8.0 and 2.8.1 were ! released using a more normal version scheme. Angband 2.8.2 and 2.8.3 add ! a few random features, clean up some code, and provide graphics support ! and such for a few more platforms. ! The Official Angband Home Page ("http://www.phial.com/angband/") serves ! not only as the most up to date description of Angband, but also lists changes made between versions, and changes planned for upcoming versions, ! and lists various email addresses and web sites related to Angband. ! === Some of the changes between Angband 2.6.1 and Angband 2.7.8 === It is very hard to pin down, along the way from 2.6.2 to 2.7.8, exactly what changes were made, and exactly when they were made. Most releases *************** *** 118,125 **** Most of the changes, with the notable exception of the creation of some of the new "main-xxx.c" files for the various new platforms, and a few other minor exceptions generally noted directly in comments in the source, were ! written by myself, either spontaneously, or, more commonly, as the result of ! a suggestion or comment by an Angband player. The most important modification was a massive "code level cleanup" that made all of my other modifications much simpler and safer. This cleanup was so --- 116,123 ---- Most of the changes, with the notable exception of the creation of some of the new "main-xxx.c" files for the various new platforms, and a few other minor exceptions generally noted directly in comments in the source, were ! written by myself, either spontaneously, or, more commonly, as the result ! of a suggestion or comment by an Angband player. The most important modification was a massive "code level cleanup" that made all of my other modifications much simpler and safer. This cleanup was so *************** *** 431,435 **** --- 429,442 ---- Angband Version 2.7 : 01/01/95 Ben Harrison Angband Version 2.8 : 01/01/97 Ben Harrison + + + + Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke + + This software may be copied and distributed for educational, research, + and not for profit purposes provided that this copyright and statement + are included in all such copies. Other copyrights may also apply. + diff -c -r angband-282/lib/user/font-ami.prf angband-283/lib/user/font-ami.prf *** angband-282/lib/user/font-ami.prf Wed Sep 3 00:14:25 1997 --- angband-283/lib/user/font-ami.prf Mon Feb 9 06:30:11 1998 *************** *** 1,9 **** ! # font-ami.prf # # This file contains text remapping data # currently used in the Amiga version. # # Lars Haugseth # Color palette - Text --- 1,11 ---- ! # File: font-ami.prf ! # # This file contains text remapping data # currently used in the Amiga version. # # Lars Haugseth + # # Color palette - Text Only in angband-283/lib/user: font-dos.prf Only in angband-283/lib/user: font-x11.prf Only in angband-283/lib/user: font-xxx.prf diff -c -r angband-282/lib/user/font.prf angband-283/lib/user/font.prf *** angband-282/lib/user/font.prf Wed Sep 3 00:14:32 1997 --- angband-283/lib/user/font.prf Mon Feb 9 04:51:59 1998 *************** *** 9,26 **** # ! ## # OPTION: Display "veins" (white "%") as "normal walls" (white "#") ! ## # This replaces the old method of setting "notice_seams" to false, ! ## # which no longer works as of Angband 2.7.9, for various reasons. ! ## ! ## F:50:1/35 ! ## F:51:1/35 ! ## F:52:1/35 ! ## F:53:1/35 ##### System Specific Subfiles ##### ?:[EQU $SYS ami] %:font-ami.prf --- 9,36 ---- # ! ## # ! ## # OPTION: Display "veins" (white "%") as "normal walls" (white "#"). ! ## # ! ## F:50:0x01/0x23 ! ## F:51:0x01/0x23 ! ## F:52:0x01/0x23 ! ## F:53:0x01/0x23 ! ! ! ##### Standard font file ##### ! ! %:font-xxx.prf ##### System Specific Subfiles ##### + ?:[IOR [EQU $SYS xaw] [EQU $SYS x11]] + %:font-x11.prf + + ?:[EQU $SYS gcu] + %:font-gcu.prf + ?:[EQU $SYS ami] %:font-ami.prf *************** *** 30,35 **** --- 40,57 ---- ?:[EQU $SYS win] %:font-win.prf + ?:[EQU $SYS dos] + %:font-dos.prf + ?:[EQU $SYS ibm] %:font-ibm.prf + + ?:[EQU $SYS emx] + %:font-emx.prf + + ?:[EQU $SYS acn] + %:font-acn.prf + + ?:1 + diff -c -r angband-282/lib/user/graf-ami.prf angband-283/lib/user/graf-ami.prf *** angband-282/lib/user/graf-ami.prf Wed Sep 3 00:14:33 1997 --- angband-283/lib/user/graf-ami.prf Mon Feb 9 06:30:01 1998 *************** *** 1,9 **** ! # graf-ami.prf # # This file contains color definitions and # graphics remapping for the Amiga version. # # Lars Haugseth # Color palette - Graphics --- 1,11 ---- ! # File: graf-ami.prf ! # # This file contains color definitions and # graphics remapping for the Amiga version. # # Lars Haugseth + # # Color palette - Graphics *************** *** 23,28 **** --- 25,31 ---- V:13:0x01:0x90:0x00:0xB0 V:14:0x01:0x00:0x60:0x10 V:15:0x01:0x60:0xF0:0x40 + # Color palette - Text V:16:0x01:0x00:0x00:0x00 Only in angband-283/lib/user: graf-ibm.prf Only in angband-283/lib/user: graf-x11.prf diff -c -r angband-282/lib/user/graf-xxx.prf angband-283/lib/user/graf-xxx.prf *** angband-282/lib/user/graf-xxx.prf Wed Sep 3 00:14:48 1997 --- angband-283/lib/user/graf-xxx.prf Wed Feb 11 06:30:27 1998 *************** *** 7,48 **** # # This file is included by any platform which uses the "standard" Angband # bitmap file (a 32x32 collection of 8x8 bitmaps), including "pref-ami.prf", ! # "pref-mac.prf", and "pref-win.prf". # # Adapted from the file "graf-ami.prf", provided, along with the original # pixmap file itself, by Lars Haugseth . # - ### Graphics codes for "unknown objects" ! # Unknown Amulet ! U:40:0x87/0x81 - # Unknown Ring - U:45:0x82/0x81 ! # Unknown Staff ! U:55:0x86/0x99 - # Unknown Wand - U:65:0x86/0x8F - # Unknown Rod - U:66:0x86/0x94 ! # Unknown Scroll ! U:70:0x86/0x80 - # Unknown Potion - U:75:0x86/0x85 - - # Unknown Food - U:80:0x8A/0x94 - - - - ### Feature attr/char definitions # nothing F:0:0x81/0x80 --- 7,315 ---- # # This file is included by any platform which uses the "standard" Angband # bitmap file (a 32x32 collection of 8x8 bitmaps), including "pref-ami.prf", ! # "pref-mac.prf", "pref-win.prf", "pref-dos.prf", and "pref-x11.prf". # # Adapted from the file "graf-ami.prf", provided, along with the original # pixmap file itself, by Lars Haugseth . # ! ##### Special attr/char values ##### ! ## # Unused (@) ! ## S:0x00:0x00/0x40 ! ## S:0x01:0x01/0x40 ! ## S:0x02:0x02/0x40 ! ## S:0x03:0x03/0x40 ! ## S:0x04:0x04/0x40 ! ## S:0x05:0x05/0x40 ! ## S:0x06:0x06/0x40 ! ## S:0x07:0x07/0x40 ! ## S:0x08:0x08/0x40 ! ## S:0x09:0x09/0x40 ! ## S:0x0A:0x0A/0x40 ! ## S:0x0B:0x0B/0x40 ! ## S:0x0C:0x0C/0x40 ! ## S:0x0D:0x0D/0x40 ! ## S:0x0E:0x0E/0x40 ! ## S:0x0F:0x0F/0x40 ! ! ## # Unused (@) ! ## S:0x10:0x00/0x40 ! ## S:0x11:0x01/0x40 ! ## S:0x12:0x02/0x40 ! ## S:0x13:0x03/0x40 ! ## S:0x14:0x04/0x40 ! ## S:0x15:0x05/0x40 ! ## S:0x16:0x06/0x40 ! ## S:0x17:0x07/0x40 ! ## S:0x18:0x08/0x40 ! ## S:0x19:0x09/0x40 ! ## S:0x1A:0x0A/0x40 ! ## S:0x1B:0x0B/0x40 ! ## S:0x1C:0x0C/0x40 ! ## S:0x1D:0x0D/0x40 ! ## S:0x1E:0x0E/0x40 ! ## S:0x1F:0x0F/0x40 ! ! ## # Unused (@) ! ## S:0x20:0x00/0x40 ! ## S:0x21:0x01/0x40 ! ## S:0x22:0x02/0x40 ! ## S:0x23:0x03/0x40 ! ## S:0x24:0x04/0x40 ! ## S:0x25:0x05/0x40 ! ## S:0x26:0x06/0x40 ! ## S:0x27:0x07/0x40 ! ## S:0x28:0x08/0x40 ! ## S:0x29:0x09/0x40 ! ## S:0x2A:0x0A/0x40 ! ## S:0x2B:0x0B/0x40 ! ## S:0x2C:0x0C/0x40 ! ## S:0x2D:0x0D/0x40 ! ## S:0x2E:0x0E/0x40 ! ## S:0x2F:0x0F/0x40 ! ! # Spells (*) ! S:0x30:0x85/0x92 ! S:0x31:0x85/0x92 ! S:0x32:0x85/0x92 ! S:0x33:0x85/0x92 ! S:0x34:0x85/0x92 ! S:0x35:0x85/0x92 ! S:0x36:0x85/0x92 ! S:0x37:0x85/0x92 ! S:0x38:0x85/0x92 ! S:0x39:0x85/0x92 ! S:0x3A:0x85/0x92 ! S:0x3B:0x85/0x92 ! S:0x3C:0x85/0x92 ! S:0x3D:0x85/0x92 ! S:0x3E:0x85/0x92 ! S:0x3F:0x85/0x92 ! ! # Spells (|) ! S:0x40:0x84/0x98 ! S:0x41:0x84/0x98 ! S:0x42:0x84/0x98 ! S:0x43:0x84/0x98 ! S:0x44:0x84/0x98 ! S:0x45:0x84/0x98 ! S:0x46:0x84/0x98 ! S:0x47:0x84/0x98 ! S:0x48:0x84/0x98 ! S:0x49:0x84/0x98 ! S:0x4A:0x84/0x98 ! S:0x4B:0x84/0x98 ! S:0x4C:0x84/0x98 ! S:0x4D:0x84/0x98 ! S:0x4E:0x84/0x98 ! S:0x4F:0x84/0x98 ! ! # Spells (-) ! S:0x50:0x84/0x99 ! S:0x51:0x84/0x99 ! S:0x52:0x84/0x99 ! S:0x53:0x84/0x99 ! S:0x54:0x84/0x99 ! S:0x55:0x84/0x99 ! S:0x56:0x84/0x99 ! S:0x57:0x84/0x99 ! S:0x58:0x84/0x99 ! S:0x59:0x84/0x99 ! S:0x5A:0x84/0x99 ! S:0x5B:0x84/0x99 ! S:0x5C:0x84/0x99 ! S:0x5D:0x84/0x99 ! S:0x5E:0x84/0x99 ! S:0x5F:0x84/0x99 ! ! # Spells (/) ! S:0x60:0x84/0x9A ! S:0x61:0x84/0x9A ! S:0x62:0x84/0x9A ! S:0x63:0x84/0x9A ! S:0x64:0x84/0x9A ! S:0x65:0x84/0x9A ! S:0x66:0x84/0x9A ! S:0x67:0x84/0x9A ! S:0x68:0x84/0x9A ! S:0x69:0x84/0x9A ! S:0x6A:0x84/0x9A ! S:0x6B:0x84/0x9A ! S:0x6C:0x84/0x9A ! S:0x6D:0x84/0x9A ! S:0x6E:0x84/0x9A ! S:0x6F:0x84/0x9A ! ! # Spells (\) ! S:0x70:0x84/0x9B ! S:0x71:0x84/0x9B ! S:0x72:0x84/0x9B ! S:0x73:0x84/0x9B ! S:0x74:0x84/0x9B ! S:0x75:0x84/0x9B ! S:0x76:0x84/0x9B ! S:0x77:0x84/0x9B ! S:0x78:0x84/0x9B ! S:0x79:0x84/0x9B ! S:0x7A:0x84/0x9B ! S:0x7B:0x84/0x9B ! S:0x7C:0x84/0x9B ! S:0x7D:0x84/0x9B ! S:0x7E:0x84/0x9B ! S:0x7F:0x84/0x9B ! ! # Amulets (") ! S:0x80:0x87/0x82 ! S:0x81:0x87/0x82 ! S:0x82:0x87/0x82 ! S:0x83:0x87/0x82 ! S:0x84:0x87/0x82 ! S:0x85:0x87/0x82 ! S:0x86:0x87/0x82 ! S:0x87:0x87/0x82 ! S:0x88:0x87/0x82 ! S:0x89:0x87/0x82 ! S:0x8A:0x87/0x82 ! S:0x8B:0x87/0x82 ! S:0x8C:0x87/0x82 ! S:0x8D:0x87/0x82 ! S:0x8E:0x87/0x82 ! S:0x8F:0x87/0x82 ! ! # Rings (=) ! S:0x90:0x82/0x83 ! S:0x91:0x82/0x83 ! S:0x92:0x82/0x83 ! S:0x93:0x82/0x83 ! S:0x94:0x82/0x83 ! S:0x95:0x82/0x83 ! S:0x96:0x82/0x83 ! S:0x97:0x82/0x83 ! S:0x98:0x82/0x83 ! S:0x99:0x82/0x83 ! S:0x9A:0x82/0x83 ! S:0x9B:0x82/0x83 ! S:0x9C:0x82/0x83 ! S:0x9D:0x82/0x83 ! S:0x9E:0x82/0x83 ! S:0x9F:0x82/0x83 ! ! # Staffs (_) ! S:0xA0:0x86/0x9A ! S:0xA1:0x86/0x9A ! S:0xA2:0x86/0x9A ! S:0xA3:0x86/0x9A ! S:0xA4:0x86/0x9A ! S:0xA5:0x86/0x9A ! S:0xA6:0x86/0x9A ! S:0xA7:0x86/0x9A ! S:0xA8:0x86/0x9A ! S:0xA9:0x86/0x9A ! S:0xAA:0x86/0x9A ! S:0xAB:0x86/0x9A ! S:0xAC:0x86/0x9A ! S:0xAD:0x86/0x9A ! S:0xAE:0x86/0x9A ! S:0xAF:0x86/0x9A ! ! # Wands (-) ! S:0xB0:0x86/0x8F ! S:0xB1:0x86/0x8F ! S:0xB2:0x86/0x8F ! S:0xB3:0x86/0x8F ! S:0xB4:0x86/0x8F ! S:0xB5:0x86/0x8F ! S:0xB6:0x86/0x8F ! S:0xB7:0x86/0x8F ! S:0xB8:0x86/0x8F ! S:0xB9:0x86/0x8F ! S:0xBA:0x86/0x8F ! S:0xBB:0x86/0x8F ! S:0xBC:0x86/0x8F ! S:0xBD:0x86/0x8F ! S:0xBE:0x86/0x8F ! S:0xBF:0x86/0x8F ! ! # Rods (-) ! S:0xC0:0x86/0x94 ! S:0xC1:0x86/0x94 ! S:0xC2:0x86/0x94 ! S:0xC3:0x86/0x94 ! S:0xC4:0x86/0x94 ! S:0xC5:0x86/0x94 ! S:0xC6:0x86/0x94 ! S:0xC7:0x86/0x94 ! S:0xC8:0x86/0x94 ! S:0xC9:0x86/0x94 ! S:0xCA:0x86/0x94 ! S:0xCB:0x86/0x94 ! S:0xCC:0x86/0x94 ! S:0xCD:0x86/0x94 ! S:0xCE:0x86/0x94 ! S:0xCF:0x86/0x94 ! ! # Scrolls (?) ! S:0xD0:0x86/0x82 ! S:0xD1:0x86/0x82 ! S:0xD2:0x86/0x82 ! S:0xD3:0x86/0x82 ! S:0xD4:0x86/0x82 ! S:0xD5:0x86/0x82 ! S:0xD6:0x86/0x82 ! S:0xD7:0x86/0x82 ! S:0xD8:0x86/0x82 ! S:0xD9:0x86/0x82 ! S:0xDA:0x86/0x82 ! S:0xDB:0x86/0x82 ! S:0xDC:0x86/0x82 ! S:0xDD:0x86/0x82 ! S:0xDE:0x86/0x82 ! S:0xDF:0x86/0x82 ! ! # Potions (!) ! S:0xE0:0x86/0x8D ! S:0xE1:0x86/0x8D ! S:0xE2:0x86/0x8D ! S:0xE3:0x86/0x8D ! S:0xE4:0x86/0x8D ! S:0xE5:0x86/0x8D ! S:0xE6:0x86/0x8D ! S:0xE7:0x86/0x8D ! S:0xE8:0x86/0x8D ! S:0xE9:0x86/0x8D ! S:0xEA:0x86/0x8D ! S:0xEB:0x86/0x8D ! S:0xEC:0x86/0x8D ! S:0xED:0x86/0x8D ! S:0xEE:0x86/0x8D ! S:0xEF:0x86/0x8D ! ! # Food (,) ! S:0xF0:0x8B/0x81 ! S:0xF1:0x8B/0x81 ! S:0xF2:0x8B/0x81 ! S:0xF3:0x8B/0x81 ! S:0xF4:0x8B/0x81 ! S:0xF5:0x8B/0x81 ! S:0xF6:0x8B/0x81 ! S:0xF7:0x8B/0x81 ! S:0xF8:0x8B/0x81 ! S:0xF9:0x8B/0x81 ! S:0xFA:0x8B/0x81 ! S:0xFB:0x8B/0x81 ! S:0xFC:0x8B/0x81 ! S:0xFD:0x8B/0x81 ! S:0xFE:0x8B/0x81 ! S:0xFF:0x8B/0x81 ! ##### Feature attr/char definitions ##### # nothing F:0:0x81/0x80 *************** *** 238,244 **** ! ### Object attr/char definitions # something K:0:0x01/0x20 --- 505,512 ---- ! ##### Object attr/char definitions ##### ! # something K:0:0x01/0x20 *************** *** 1550,1556 **** ! ### Monster attr/char definitions # Player R:0:0x8C/0x80 --- 1818,1825 ---- ! ##### Monster attr/char definitions ##### ! # Player R:0:0x8C/0x80 *************** *** 3197,3200 **** --- 3466,3471 ---- R:547:0x92/0x9E + # Load the special player pictures + %:xtra-xxx.prf diff -c -r angband-282/lib/user/graf.prf angband-283/lib/user/graf.prf *** angband-282/lib/user/graf.prf Wed Sep 3 00:14:49 1997 --- angband-283/lib/user/graf.prf Mon Feb 9 04:53:06 1998 *************** *** 9,25 **** # ##### System Specific Subfiles ##### ?:[EQU $SYS ami] %:graf-ami.prf ?:[EQU $SYS mac] %:graf-mac.prf ! ?:[EQU $SYS win] %:graf-win.prf ! ## ?:[EQU $SYS ibm] ! ## %:graf-ibm.prf --- 9,45 ---- # + ##### Standard font file ##### + + %:font-xxx.prf + + ##### System Specific Subfiles ##### + ?:[IOR [EQU $SYS xaw] [EQU $SYS x11]] + %:graf-x11.prf + + ?:[EQU $SYS gcu] + %:graf-gcu.prf + ?:[EQU $SYS ami] %:graf-ami.prf ?:[EQU $SYS mac] %:graf-mac.prf ! ?:[IOR [EQU $SYS win] [EQU $SYS dos]] %:graf-win.prf ! ?:[EQU $SYS ibm] ! %:graf-ibm.prf ! ! ?:[EQU $SYS emx] ! %:graf-emx.prf ! ! ?:[EQU $SYS acn] ! %:graf-acn.prf ! ! ?:1 ! diff -c -r angband-282/lib/user/pref-emx.prf angband-283/lib/user/pref-emx.prf *** angband-282/lib/user/pref-emx.prf Wed Sep 3 00:14:53 1997 --- angband-283/lib/user/pref-emx.prf Wed Feb 11 06:18:29 1998 *************** *** 1,163 **** # File: pref-emx.prf # ! # This file is used by Angband (when it was compiled using "main-emx.c") ! # to specify various "user preferences". This file specifies some visual ! # attr/char remappings, which allow the use of some of OS/2's built in ! # pseudo-graphic pictures for walls and such. This file defines some basic ! # macros, which allow the use of the "keypad", alone, and with the shift or ! # control modifier keys. All "special" keys are translated by "main-emx.c" ! # into special "macro triggers" of the encoded form "^_SSS\r", where the ! # two digit decimal scan code of the keypress is stored in "SSS", see ! # "main-emx.c" for info. # ! # This file is only used by the VIO (text mode) version of Angband. The PM (graphical) ! # version uses *ibm.prf. The macro triggers of these two versions are not ! # compatible or interchangable. # ! ! ! ! ### Terrain Features ### ! ! ! # ! # Floors (white / centered dot) ! # ! ! F:1:1/-7 ! # ! # Invis traps (white / centered dot) ! # ! ! F:2:1/-7 ! ! ! # ! # Magma (slate / special solid block) ! # ! ! F:50:2/-80 ! F:52:2/-80 ! ! # - # Quartz (light slate / special solid block) - # - - F:51:9/-80 - F:53:9/-80 - - - # - # Secret door (white / solid block) - # - - F:48:1/-79 - - # - # Granite walls (white / solid block) - # - - F:56:1/-79 - F:57:1/-79 - F:58:1/-79 - F:59:1/-79 - - # - # Permanent rock (white / solid block) - # - - F:60:1/-79 - F:61:1/-79 - F:62:1/-79 - F:63:1/-79 - - - - ### Basic Macros ### - - - # - # Keypad (7,8,9,-,4,5,6,+,1,2,3,0,.) - # - - A:7 - P:^_071\r - - A:8 - P:^_072\r - - A:9 - P:^_073\r - - A:- - P:^_074\r - - A:4 - P:^_075\r - - A:5 - P:^_076\r - - A:6 - P:^_077\r - - A:+ - P:^_078\r - - A:1 - P:^_079\r - - A:2 - P:^_080\r - - A:3 - P:^_081\r - - A:0 - P:^_082\r - - A:. - P:^_083\r - - - # - # Shift-Keypad-8, for example, is exactly '8', so these cannot be used for macros - # - - # - # Control + Keypad (1,2,3,4,5,6,7,8,9) - # - # Run, Run, Run, Run, Run, Run, Run, Run, RUN! - # - - A:\e\e\\.1 - C:^_117\r - - A:\e\e\\.2 - C:^_145\r - - A:\e\e\\.3 - C:^_118\r - - A:\e\e\\.4 - C:^_115\r - - A:\e\e\\.5 - C:^_143\r - - A:\e\e\\.6 - C:^_116\r - - A:\e\e\\.7 - C:^_119\r - - A:\e\e\\.8 - C:^_141\r ! A:\e\e\\.9 ! C:^_132\r --- 1,16 ---- # File: pref-emx.prf # ! # Include "pref-ibm.prf" to get the default macros. # ! # Note that, while most key-to-trigger mappings are the same as DOS/Win, ! # some few odd keys will be different or not available at all. # ! # Examples: Ctrl-Escape, Alt-PrintScreen # ! # What's NOT working: color palette redefinitions. # ! %:pref-win.prf diff -c -r angband-282/lib/user/pref-gcu.prf angband-283/lib/user/pref-gcu.prf *** angband-282/lib/user/pref-gcu.prf Wed Sep 3 00:14:55 1997 --- angband-283/lib/user/pref-gcu.prf Sun Feb 8 05:02:05 1998 *************** *** 16,21 **** --- 16,22 ---- A:. P:\e[3~ + A:0 P:\e[2~ *************** *** 24,43 **** --- 25,70 ---- A:1 P:\e[4~ + P:\e[F + A:2 P:\e[B + A:3 P:\e[6~ + A:4 P:\e[D + A:5 P:\e[G + A:6 P:\e[C + A:7 P:\e[1~ + P:\e[H + A:8 P:\e[A + A:9 P:\e[5~ + + + # Basic function keys (F1 - F4) + + A:\e + P:\eOP + + A:\e + P:\eOQ + + A:\e + P:\eOR + + A:\e + P:\eOS + diff -c -r angband-282/lib/user/pref-win.prf angband-283/lib/user/pref-win.prf *** angband-282/lib/user/pref-win.prf Wed Sep 3 00:14:59 1997 --- angband-283/lib/user/pref-win.prf Tue Jan 27 01:16:44 1998 *************** *** 1,17 **** # File: pref-ibm.prf # ! # This file is used by Angband (when it was compiled using "main-ibm.c") ! # to specify various "user preferences", including "macros". # # This file defines some basic macros, which allow the use of the "keypad", # alone, and with the shift and/or control modifier keys. All "special" ! # keys are translated by "main-ibm.c" into special "macro triggers" of the ! # encoded form "^_MMMxSS\r", where the "modifier" flags are stored in "MMM", ! # and the two digit hexidecimal scan code of the keypress is stored in "SS", ! # see "main-ibm.c" for info. # - # --- 1,30 ---- # File: pref-ibm.prf # ! # This file is used by Angband (when it was compiled using "main-ibm.c" ! # or "main-dos.c" or "main-win.c") to specify various "user preferences", ! # including "macros". # # This file defines some basic macros, which allow the use of the "keypad", # alone, and with the shift and/or control modifier keys. All "special" ! # keys are translated by "main-ibm.c" (or "main-win.c") into special "macro ! # triggers" of the encoded form "^_MMMxSS\r", where the "modifier" flags are ! # stored in "MMM", and the two digit hexidecimal scan code of the keypress is ! # stored in "SS". ! # ! # The "main-ibm.prf" and "main-dos.prf" files may not be able to recognize ! # the "/" and "*" keys on the keypad, because it mistakenly classifies the ! # "0x35" and "0x37" codes as the keycodes of "normal" keys. ! # ! # The "main-win.prf" file should not be using the final "control + keypad" ! # section in this file, it was created for "main-ibm.c" and "main-dos.c". ! # ! # The "main-win.prf" file may actually send the "ascii" equivalent of some ! # keypad keys after the keypad key itself, especially if "numlock" is down, ! # which may cause problems. Or it may not, it is hard to tell. This is bad. ! # ! # See "main-ibm.c" and "main-dos.c" and "main-win.c" for more info. # # *************** *** 30,38 **** # ! # Keypad (7,8,9,-,4,5,6,+,1,2,3,0,.) # A:7 P:^_x47\r --- 43,57 ---- # ! # Keypad (/,*,7,8,9,-,4,5,6,+,1,2,3,0,.) # + A:/ + P:^_x35\r + + A:* + P:^_x37\r + A:7 P:^_x47\r *************** *** 74,82 **** # ! # Shift + Keypad (7,8,9,-,4,5,6,+,1,2,3,0,.) # A:\e\e\\.7 P:^_Sx47\r --- 93,107 ---- # ! # Shift + Keypad (/,*,7,8,9,-,4,5,6,+,1,2,3,0,.) # + A:\e\e\e + P:^_Sx35\r + + A:\e\e\e + P:^_Sx37\r + A:\e\e\\.7 P:^_Sx47\r *************** *** 118,126 **** # ! # Control + Keypad (7,8,9,-,4,5,6,+,1,2,3,0,.) # A:\e\e\\+7 P:^_Cx47\r --- 143,157 ---- # ! # Control + Keypad (/,*,7,8,9,-,4,5,6,+,1,2,3,0,.) # + A:\e\e\e + P:^_Cx35\r + + A:\e\e\e + P:^_Cx37\r + A:\e\e\\+7 P:^_Cx47\r *************** *** 162,169 **** # ! # Control + Keypad (7,8,9,-,4,5,6,+,1,2,3,0,.) # A:\e\e\\+7 P:^_Cx77\r --- 193,206 ---- # ! # Control + Keypad (/,*,7,8,9,-,4,5,6,+,1,2,3,0,.) # + + A:\e\e\e + P:^_Cx95\r + + A:\e\e\e + P:^_Cx96\r A:\e\e\\+7 P:^_Cx77\r diff -c -r angband-282/lib/user/pref.prf angband-283/lib/user/pref.prf *** angband-282/lib/user/pref.prf Wed Sep 3 00:15:03 1997 --- angband-283/lib/user/pref.prf Mon Feb 9 01:43:33 1998 *************** *** 7,21 **** # # See "lib/help/command.txt" and "src/files.c" for more information. # ! # Command macro -- "X" will now "swap weapons" as long as both weapons ! # contain the inscription "@0". For example, inscribe your main weapon ! # as "@1@0" and your digger (or secondary weapon) as "@2@0". ! ! A:w0 ! C:X ! ## # Option -- Default to original commands ## X:rogue_like_commands --- 7,20 ---- # # See "lib/help/command.txt" and "src/files.c" for more information. # + # Note that the "X" key is mapped in both keysets to the key sequence + # "w0", which will "swap weapons" as long as both weapons contain the + # inscription "@0". For example, inscribe your main weapon as "@1@0" + # and your digger (or secondary weapon) as "@2@0". + # ! ##### Force certain options ##### ## # Option -- Default to original commands ## X:rogue_like_commands *************** *** 24,36 **** ## Y:rogue_like_commands ##### System Specific Subfiles ##### ! ?:[IOR [EQU $SYS x11] [EQU $SYS xaw]] %:pref-x11.prf ! ## ?:[EQU $SYS gcu] ! ## %:pref-gcu.prf ?:[EQU $SYS ami] %:pref-ami.prf --- 23,223 ---- ## Y:rogue_like_commands + ##### Original Keyset Mappings ##### + + # Stay still + A:, + C:0:5 + + # Movement + A:;1 + C:0:1 + A:;2 + C:0:2 + A:;3 + C:0:3 + A:;4 + C:0:4 + A:;6 + C:0:6 + A:;7 + C:0:7 + A:;8 + C:0:8 + A:;9 + C:0:9 + + # Hack -- Return + A:\r + C:0:^J + + # Hack -- Commit suicide + A:Q + C:0:^K + + # Hack -- Commit suicide + A:Q + C:0:^C + + # Hack -- swap equipment + A:w0 + C:0:X + + + ##### Roguelike Keyset Mappings ##### + + # Run + A:. + C:1:, + + # Stay still + A:, + C:1:. + + # Stay still + A:, + C:1:5 + + # Movement + A:;1 + C:1:1 + A:;2 + C:1:2 + A:;3 + C:1:3 + A:;4 + C:1:4 + A:;6 + C:1:6 + A:;7 + C:1:7 + A:;8 + C:1:8 + A:;9 + C:1:9 + + # Movement (rogue keys) + A:;1 + C:1:b + A:;2 + C:1:j + A:;3 + C:1:n + A:;4 + C:1:h + A:;6 + C:1:l + A:;7 + C:1:y + A:;8 + C:1:k + A:;9 + C:1:u + + # Running (shift + rogue keys) + A:.1 + C:1:B + A:.2 + C:1:J + A:.3 + C:1:N + A:.4 + C:1:H + A:.6 + C:1:L + A:.7 + C:1:Y + A:.8 + C:1:K + A:.9 + C:1:U + + # Altering (control + rogue keys) + A:+1 + C:1:^B + A:+2 + C:1:^J + A:+3 + C:1:^N + A:+4 + C:1:^H + A:+6 + C:1:^L + A:+7 + C:1:^Y + A:+8 + C:1:^K + A:+9 + C:1:^U + + # Allow use of the "tunnel" command + A:T + C:1:^T + + # Allow use of the "destroy" command + A:k + C:1:^D + + # Locate player on map + A:L + C:1:W + + # Browse a book (Peruse) + A:b + C:1:P + + # Jam a door (Spike) + A:j + C:1:S + + # Toggle search mode + A:S + C:1:# + + # Use a staff (Zap) + A:u + C:1:Z + + # Take off equipment + A:t + C:1:T + + # Fire an item + A:f + C:1:t + + # Bash a door (Force) + A:B + C:1:f + + # Look around (examine) + A:l + C:1:x + + # Aim a wand (Zap) + A:a + C:1:z + + # Zap a rod (Activate) + A:z + C:1:a + + # Hack -- Commit suicide + A:Q + C:1:^C + + # Hack -- swap equipment + A:w0 + C:1:X + + ##### System Specific Subfiles ##### ! ?:[IOR [EQU $SYS xaw] [EQU $SYS x11]] %:pref-x11.prf ! ?:[EQU $SYS gcu] ! %:pref-gcu.prf ?:[EQU $SYS ami] %:pref-ami.prf *************** *** 38,44 **** ?:[EQU $SYS mac] %:pref-mac.prf ! ?:[IOR [EQU $SYS win] [EQU $SYS ibm]] %:pref-win.prf ?:[EQU $SYS emx] --- 225,231 ---- ?:[EQU $SYS mac] %:pref-mac.prf ! ?:[IOR [EQU $SYS win] [EQU $SYS dos] [EQU $SYS ibm]] %:pref-win.prf ?:[EQU $SYS emx] *************** *** 46,49 **** --- 233,239 ---- ?:[EQU $SYS acn] %:pref-acn.prf + + ?:1 + diff -c -r angband-282/lib/user/user.prf angband-283/lib/user/user.prf *** angband-282/lib/user/user.prf Wed Sep 3 00:15:06 1997 --- angband-283/lib/user/user.prf Tue Feb 3 22:23:20 1998 *************** *** 18,41 **** ##### System Specific Subfiles ##### ! ## ?:[IOR [EQU $SYS x11] [EQU $SYS xaw]] ! ## %:user-x11.prf ! ## ?:[EQU $SYS gcu] ! ## %:user-gcu.prf ! ## ?:[EQU $SYS ami] ! ## %:user-ami.prf ?:[EQU $SYS mac] %:user-mac.prf ! ## ?:[IOR [EQU $SYS win] [EQU $SYS ibm]] ! ## %:user-win.prf ! ## ?:[EQU $SYS emx] ! ## %:user-emx.prf - ## ?:[EQU $SYS acn] - ## %:user-acn.prf --- 18,44 ---- ##### System Specific Subfiles ##### ! ?:[IOR [EQU $SYS xaw] [EQU $SYS x11]] ! %:user-x11.prf ! ?:[EQU $SYS gcu] ! %:user-gcu.prf ! ?:[EQU $SYS ami] ! %:user-ami.prf ?:[EQU $SYS mac] %:user-mac.prf ! ?:[IOR [EQU $SYS win] [EQU $SYS dos] [EQU $SYS ibm]] ! %:user-win.prf ! ?:[EQU $SYS emx] ! %:user-emx.prf ! ! ?:[EQU $SYS acn] ! %:user-acn.prf ! ! ?:1 Only in angband-282/src: Makefile diff -c -r angband-282/src/Makefile.acn angband-283/src/Makefile.acn *** angband-282/src/Makefile.acn Wed Sep 3 11:57:32 1997 --- angband-283/src/Makefile.acn Fri Feb 6 04:08:39 1998 *************** *** 49,51 **** --- 49,52 ---- # Dynamic dependencies: + Only in angband-283/src: Makefile.dos diff -c -r angband-282/src/Makefile.emx angband-283/src/Makefile.emx *** angband-282/src/Makefile.emx Wed Sep 3 11:57:32 1997 --- angband-283/src/Makefile.emx Wed Feb 11 06:17:46 1998 *************** *** 3,11 **** # Purpose: Makefile support for "main-emx.c" # Note: Use 'dmake -B -r -f makefile.emx' to compile (see "main-emx.c" for details). - # Since "dmake" does not demand "hard" tab stops as delimiters, - # don't bother to add them. - # # Use 'dmake -B -r -f makefile.emx install' to install the executables # and the batch file used for multiple VIO windows in the parent directory. # --- 3,8 ---- *************** *** 18,24 **** # all changed files (diff -c). "..\exp\patches.uue" will # contain the same file gziped and uuencodes. "..\exp\files.uue" # will contain the three emx-specific files tared, gziped and ! # uuencoded. Needs 4OS2. # # 'export': The file "..\exp\$(EXPORT)" is created so that it # can directly be uploaded as an official distribution archive. --- 15,21 ---- # all changed files (diff -c). "..\exp\patches.uue" will # contain the same file gziped and uuencodes. "..\exp\files.uue" # will contain the three emx-specific files tared, gziped and ! # uuencoded. Needs 4OS2. # # 'export': The file "..\exp\$(EXPORT)" is created so that it # can directly be uploaded as an official distribution archive. *************** *** 28,40 **** VERSION = 279v5 EXPORT = angband-$(VERSION).os2.zip ! CC = gcc AR = ar ! CFLAGS = -MMD -O3 -DUSE_EMX -Zmt ! LFLAGS = -lvideo # Uncomment this if you have nice installed ! NICE = nice -i -n -30 ################################################################################### --- 25,37 ---- VERSION = 279v5 EXPORT = angband-$(VERSION).os2.zip ! CC = gcc AR = ar ! CFLAGS = -MMD -O3 -DUSE_EMX -Zmt ! LFLAGS = -lvideo # Uncomment this if you have nice installed ! NICE = nice -i -n -30 ################################################################################### *************** *** 45,57 **** install: ..\angband.exe ..\aclient.exe ..\startwnd.cmd clean: ! -+@ del angband.exe ! -+@ del aclient.exe ! -+@ del depends ! -+@ del _state.mk ! -+@ del *.a ! -+@ del *.d ! -+@ del *.o patches: ..\patches.txt ..\exp\patches.uue ..\exp\files.uue --- 42,54 ---- install: ..\angband.exe ..\aclient.exe ..\startwnd.cmd clean: ! -+@ del angband.exe ! -+@ del aclient.exe ! -+@ del depends ! -+@ del _state.mk ! -+@ del *.a ! -+@ del *.d ! -+@ del *.o patches: ..\patches.txt ..\exp\patches.uue ..\exp\files.uue *************** *** 62,139 **** #################################################################################### OBJS = \ ! z-util.o z-virt.o z-form.o z-rand.o z-term.o \ ! variable.o tables.o util.o cave.o \ ! object1.o object2.o monster1.o monster2.o \ ! xtra1.o xtra2.o spells1.o spells2.o \ ! melee1.o melee2.o save.o files.o \ ! cmd1.o cmd2.o cmd3.o cmd4.o cmd5.o cmd6.o \ ! store.o birth.o load1.o load2.o \ ! wizard1.o wizard2.o \ ! generate.o dungeon.o init1.o init2.o .c.o: ! $(NICE) $(CC) $(CFLAGS) -c $*.c all .PHONY: angband.exe aclient.exe ! +@echo. ! +@echo Now type ! +@echo. ! +@echo '$(MAKECMD) $(MFLAGS) $(MAKEFILE) install' ! +@echo. ! +@echo to install Angband in the parent directory, and/or ! +@echo. ! +@echo '$(MAKECMD) $(MFLAGS) $(MAKEFILE) clean' ! +@echo. ! +@echo to remove a bunch of temporary files used during compilation! ! +@echo You may want to remove the src subdirectory, now that you have ! +@echo working executables. ! +@echo. EXPFILES = angband.exe;aclient.exe;patches.txt;readme;startwnd.cmd ..\exp\$(EXPORT) .PHONY .IGNORE: install patches # Needs 4OS2! ! +@ md ..\exp >& nul ^ \ ! md ..\exp\tmpdir >& nul ^ \ ! cd ..\exp\tmpdir ^ \ ! copy ...\$(EXPFILES) > nul ^ \ ! md lib ^ \ ! copy ...\lib\ lib\ /s >& nul ^ \ ! del lib\save\player >& nul ^ \ ! zip -m -r $(EXPORT) * > nul ^ \ ! move $(EXPORT) .. ^ \ ! cd .. ^ \ ! del tmpdir /xsqy >& nul ! PATCHFILES = *.c *.h makefile* ..\lib\user\pref-emx.prf # Needs 4OS2! ..\patches.txt .PHONY .IGNORE: ! +@ echo These are the changes to the original source > ..\patches.txt ^ \ ! echo archive ($(VERSION)). You don't need to apply them >> ..\patches.txt ^ \ ! echo if you can get the latest archive, which will >> ..\patches.txt ^ \ ! echo have them applied already. >> ..\patches.txt ^ \ ! echo. >> ..\patches.txt ^ \ ! except (*~) for %a in ($(PATCHFILES)) \ ! do (diff -c ..\old\src\%a %a >> ..\patches.txt) # Needs 4OS2! ..\exp\patches.uue: ..\patches.txt ! +@ md ..\exp >& nul ^ \ ! cd ..\exp ^ \ ! copy ..\patches.txt patches-$(VERSION).os2 ^ \ ! gzip -f patches-$(VERSION).os2 ^ \ ! uuencode patches-$(VERSION).os2.gz >& nul ^ \ ! del patches-$(VERSION).os2.gz ^ \ ! move patches-$(VERSION).os2.gz.uue patches.uue FILES = main-emx.c makefile.emx ..\lib\user\pref-emx.prf FILESP = main-emx.c makefile.emx pref-emx.prf # Needs 4OS2! ..\exp\files.uue: $(FILES) ! +@ md ..\exp >& nul ^ \ cd ..\exp ^ \ for %a in ($(FILES)) copy ..\src\%a > nul ^ \ tar -cvf files.tar $(FILESP) ^ \ --- 59,136 ---- #################################################################################### OBJS = \ ! z-util.o z-virt.o z-form.o z-rand.o z-term.o \ ! variable.o tables.o util.o cave.o \ ! object1.o object2.o monster1.o monster2.o \ ! xtra1.o xtra2.o spells1.o spells2.o \ ! melee1.o melee2.o save.o files.o \ ! cmd1.o cmd2.o cmd3.o cmd4.o cmd5.o cmd6.o \ ! store.o birth.o load1.o load2.o \ ! wizard1.o wizard2.o \ ! generate.o dungeon.o init1.o init2.o .c.o: ! $(NICE) $(CC) $(CFLAGS) -c $*.c all .PHONY: angband.exe aclient.exe ! +@echo. ! +@echo Now type ! +@echo. ! +@echo '$(MAKECMD) $(MFLAGS) $(MAKEFILE) install' ! +@echo. ! +@echo to install Angband in the parent directory, and/or ! +@echo. ! +@echo '$(MAKECMD) $(MFLAGS) $(MAKEFILE) clean' ! +@echo. ! +@echo to remove a bunch of temporary files used during compilation! ! +@echo You may want to remove the src subdirectory, now that you have ! +@echo working executables. ! +@echo. EXPFILES = angband.exe;aclient.exe;patches.txt;readme;startwnd.cmd ..\exp\$(EXPORT) .PHONY .IGNORE: install patches # Needs 4OS2! ! +@ md ..\exp >& nul ^ \ ! md ..\exp\tmpdir >& nul ^ \ ! cd ..\exp\tmpdir ^ \ ! copy ...\$(EXPFILES) > nul ^ \ ! md lib ^ \ ! copy ...\lib\ lib\ /s >& nul ^ \ ! del lib\save\player >& nul ^ \ ! zip -m -r $(EXPORT) * > nul ^ \ ! move $(EXPORT) .. ^ \ ! cd .. ^ \ ! del tmpdir /xsqy >& nul ! PATCHFILES = *.c *.h makefile* ..\lib\user\pref-emx.prf # Needs 4OS2! ..\patches.txt .PHONY .IGNORE: ! +@ echo These are the changes to the original source > ..\patches.txt ^ \ ! echo archive ($(VERSION)). You don't need to apply them >> ..\patches.txt ^ \ ! echo if you can get the latest archive, which will >> ..\patches.txt ^ \ ! echo have them applied already. >> ..\patches.txt ^ \ ! echo. >> ..\patches.txt ^ \ ! except (*~) for %a in ($(PATCHFILES)) \ ! do (diff -c ..\old\src\%a %a >> ..\patches.txt) # Needs 4OS2! ..\exp\patches.uue: ..\patches.txt ! +@ md ..\exp >& nul ^ \ ! cd ..\exp ^ \ ! copy ..\patches.txt patches-$(VERSION).os2 ^ \ ! gzip -f patches-$(VERSION).os2 ^ \ ! uuencode patches-$(VERSION).os2.gz >& nul ^ \ ! del patches-$(VERSION).os2.gz ^ \ ! move patches-$(VERSION).os2.gz.uue patches.uue FILES = main-emx.c makefile.emx ..\lib\user\pref-emx.prf FILESP = main-emx.c makefile.emx pref-emx.prf # Needs 4OS2! ..\exp\files.uue: $(FILES) ! +@ md ..\exp >& nul ^ \ cd ..\exp ^ \ for %a in ($(FILES)) copy ..\src\%a > nul ^ \ tar -cvf files.tar $(FILESP) ^ \ *************** *** 144,202 **** move files.tar.gz.uue files.uue depends .IGNORE: $(OBJS) ! + echo. > depends ! + for %a in (*.d) type %a >> depends ..\angband.exe: angband.exe ! + copy angband.exe .. ! emxbind -s ..\angband.exe ..\aclient.exe: aclient.exe ! + copy aclient.exe .. ! emxbind -s ..\aclient.exe EC=+@ echo ECF=>> ..\startwnd.cmd ..\startwnd.cmd: ! $(EC) @echo off > ..\startwnd.cmd ! $(EC) REM This file starts up Angband and up to three other views. The $(ECF) ! $(EC) REM optional number behind the name sets the number of lines for $(ECF) ! $(EC) REM that screen. $(ECF) ! $(EC) REM $(ECF) ! $(EC) REM The function of the three views: $(ECF) ! $(EC) REM $(ECF) ! $(EC) REM recall window - display monster recall info $(ECF) ! $(EC) REM choice window - display equipment and inventory $(ECF) ! $(EC) REM mirror window - display both of them as new information $(ECF) ! $(EC) REM pops up - use this if you've got a small $(ECF) ! $(EC) REM screen that doesn't comfortably allow for $(ECF) ! $(EC) REM three windows. $(ECF) ! $(EC). $(ECF) ! $(EC) start /win /n aclient recall 10 $(ECF) ! $(EC) start /win /n aclient choice $(ECF) ! $(EC) rem start /win /n aclient mirror $(ECF) ! $(EC) delay $(ECF) ! $(EC) angband %1 %2 %3 %4 %5 %6 %7 %8 %9 $(ECF) angband.exe: angband.a main.o main-emx.o main-epm.o ! $(CC) -o angband.exe main.o main-emx.o angband.a $(LFLAGS) angband.a: $(OBJS) ! $(AR) r angband.a $(OBJS) aclient.exe: main-emx.c ! $(NICE) $(CC) $(CFLAGS) -Wall -D__EMX__CLIENT__ -o aclient.exe main-emx.c -lvideo main-emx.o: main-emx.c ! $(NICE) $(CC) $(CFLAGS) -Wall -c main-emx.c -o main-emx.o main-epm.o: main-emx.c ! $(NICE) $(CC) $(CFLAGS) -Wall -DEMXPM -c main-emx.c -o main-epm.o # Forgive me :) ":-)": ! +@echo. .INCLUDE .IGNORE: depends --- 141,191 ---- move files.tar.gz.uue files.uue depends .IGNORE: $(OBJS) ! + echo. > depends ! + for %a in (*.d) type %a >> depends ..\angband.exe: angband.exe ! + copy angband.exe .. ! emxbind -s ..\angband.exe ..\aclient.exe: aclient.exe ! + copy aclient.exe .. ! emxbind -s ..\aclient.exe EC=+@ echo ECF=>> ..\startwnd.cmd ..\startwnd.cmd: ! $(EC) @echo off > ..\startwnd.cmd ! $(EC) REM This file starts up Angband and up to seven other views. The $(ECF) ! $(EC) REM optional number behind the name sets the number of lines for $(ECF) ! $(EC) REM that screen. Choose contents for each via the game options. $(ECF) ! $(EC) REM $(ECF) ! $(EC). $(ECF) ! $(EC) start /win /n aclient Term-1 $(ECF) ! $(EC) start /win /n aclient Term-2 10 $(ECF) ! $(EC) rem start /win /n aclient Term-3 24 $(ECF) ! $(EC) delay $(ECF) ! $(EC) angband %1 %2 %3 %4 %5 %6 %7 %8 %9 $(ECF) angband.exe: angband.a main.o main-emx.o main-epm.o ! $(CC) -o angband.exe main.o main-emx.o angband.a $(LFLAGS) angband.a: $(OBJS) ! $(AR) r angband.a $(OBJS) aclient.exe: main-emx.c ! $(NICE) $(CC) $(CFLAGS) -Wall -D__EMX__CLIENT__ -o aclient.exe main-emx.c -lvideo main-emx.o: main-emx.c ! $(NICE) $(CC) $(CFLAGS) -Wall -c main-emx.c -o main-emx.o main-epm.o: main-emx.c ! $(NICE) $(CC) $(CFLAGS) -Wall -DEMXPM -c main-emx.c -o main-epm.o # Forgive me :) ":-)": ! +@echo. .INCLUDE .IGNORE: depends diff -c -r angband-282/src/Makefile.ibm angband-283/src/Makefile.ibm *** angband-282/src/Makefile.ibm Wed Sep 3 11:57:32 1997 --- angband-283/src/Makefile.ibm Fri Feb 6 04:08:39 1998 *************** *** 1,61 **** # File: Makefile.ibm ! # Purpose: Makefile support for "main-ibm.c" and Gnu C - # Note: Rename to "Makefile" before using - # Added extra targets: mrmarcel@eos.ncsu.edu (Mike Marcelais) OBJS = \ ! z-util.o z-virt.o z-form.o z-rand.o z-term.o \ ! variable.o tables.o util.o cave.o \ ! object1.o object2.o monster1.o monster2.o \ ! xtra1.o xtra2.o spells1.o spells2.o melee1.o melee2.o \ ! load1.o load2.o save.o files.o \ ! cmd1.o cmd2.o cmd3.o cmd4.o cmd5.o cmd6.o \ ! store.o birth.o wizard1.o wizard2.o \ generate.o dungeon.o init1.o init2.o \ ! main-ibm.o main.o ! # Compiler - CC = gcc # Compiler flags ! ! CFLAGS = -Wall -O2 -DUSE_IBM # Libraries - LIBS = -lpc - GLIBS= -lgrx20 - - # Name of Program - PROGRAM = angband.exe makepref.exe gredit.exe ! ! all: $(PROGRAM) ! ! # Generate binary file angband.exe: $(OBJS) ! $(CC) $(CFLAGS) -o angband.bin $(OBJS) $(LIBS) gredit.exe: gredit.o ! $(CC) $(CFLAGS) -o gredit.bin gredit.o $(LIBS) $(GLIBS) ! makepref.exe: makepref.o ! $(CC) $(CFLAGS) -o makepref.bin makepref.o $(LIBS) # Compile source files .c.o: $(CC) $(CFLAGS) -c $*.c # Clean up clean: ! del *.o $(PROGRAM) *.bin --- 1,85 ---- # File: Makefile.ibm ! # ! # Makefile support for "main-ibm.c" ! # ! # See "main-ibm.c" for more information. ! # + # + # Basic definitions + # + + # Objects OBJS = \ ! main.o main-ibm.o \ generate.o dungeon.o init1.o init2.o \ ! store.o birth.o wizard1.o wizard2.o \ ! cmd1.o cmd2.o cmd3.o cmd4.o cmd5.o cmd6.o \ ! load1.o load2.o save.o files.o \ ! xtra1.o xtra2.o spells1.o spells2.o melee1.o melee2.o \ ! object1.o object2.o monster1.o monster2.o \ ! variable.o tables.o util.o cave.o \ ! z-term.o z-rand.o z-form.o z-virt.o z-util.o # Compiler CC = gcc # Compiler flags ! CFLAGS = -Wall -O2 -s -DUSE_IBM # Libraries LIBS = -lpc ! # ! # Targets ! # ! ! default: angband.exe ! copy angband.exe .. ! del angband.exe ! ! install: angband.exe makepref.exe gredit.exe ! copy angband.exe .. ! copy makepref.exe .. ! copy gredit.exe .. ! ! all: angband.exe makepref.exe gredit.exe ! @echo All done. Use 'make install' to install. ! ! ! # ! # Link executables ! # angband.exe: $(OBJS) ! $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) ! ! makepref.exe: makepref.o ! $(CC) $(CFLAGS) -o $@ makepref.o $(LIBS) gredit.exe: gredit.o ! $(CC) $(CFLAGS) -o $@ gredit.o $(LIBS) -lgrx20 ! ! # # Compile source files + # .c.o: $(CC) $(CFLAGS) -c $*.c + # # Clean up + # clean: ! del *.o ! del *.bin + cleanall: clean + del *.exe diff -c -r angband-282/src/Makefile.std angband-283/src/Makefile.std *** angband-282/src/Makefile.std Wed Sep 3 11:57:32 1997 --- angband-283/src/Makefile.std Wed Feb 11 06:30:28 1998 *************** *** 32,39 **** # with special compilers. # # If you are able to construct "main-xxx.c" and/or "Makefile.xxx" ! # files for a currently unsupported system, please send them to me ! # (benh@voicenet.com) for inclusion in future versions. # # This Makefile comes with "default" dependancies that may be obsolete. # --- 32,39 ---- # with special compilers. # # If you are able to construct "main-xxx.c" and/or "Makefile.xxx" ! # files for a currently unsupported system, please send them to ! # Ben Harrison (benh@phial.com) for inclusion in future versions. # # This Makefile comes with "default" dependancies that may be obsolete. # diff -c -r angband-282/src/Makefile.wat angband-283/src/Makefile.wat *** angband-282/src/Makefile.wat Wed Sep 3 11:57:32 1997 --- angband-283/src/Makefile.wat Fri Feb 6 04:08:39 1998 *************** *** 3,14 **** # Purpose: Makefile support for "main-ibm.c" for Watcom C/C++ # From: akemi@netcom.com (David Boeren) ! # Extra program targets by: mrmarcel@eos.ncsu.edu (Mike Marcelais) CC = wcc386 ! CFLAGS = /mf /3r /3 /wx /s /oneatx /DUSE_IBM /DUSE_WAT ! # CFLAGS = /mf /3r /3 /wx /oaeilmnrt /DUSE_IBM /DUSE_WAT OBJS = & z-util.obj z-virt.obj z-form.obj z-rand.obj z-term.obj & --- 3,20 ---- # Purpose: Makefile support for "main-ibm.c" for Watcom C/C++ # From: akemi@netcom.com (David Boeren) ! # Extra program targets by: michmarc@microsoft.com (Mike Marcelais) CC = wcc386 ! # For Watcom v11 ! CFLAGS = /mf /3r /3 /wx /s /oabhiklrsx /DUSE_IBM /DUSE_WAT ! ! # For Watcom v10 ! # CFLAGS = /mf /3r /3 /wx /s /oneasx /DUSE_IBM /DUSE_WAT ! ! # For debugging ! # CFLAGS = /mf /3r /3 /wx /d2 /od /DUSE_IBM /DUSE_WAT OBJS = & z-util.obj z-virt.obj z-form.obj z-rand.obj z-term.obj & *************** *** 25,42 **** # Use whichever of these two you wish... angband.exe: $(OBJS) angband.lnk ! wlink system dos4g @angband.lnk ! # wlink system pmodew @angband.lnk # Use whichever of these two you wish... gredit.exe: gredit.obj gredit.lnk ! wlink system dos4g @gredit.lnk ! # wlink system pmodew @gredit.lnk # Use whichever of these two you wish... makepref.exe: makepref.obj makepref.lnk ! wlink system dos4g @makepref.lnk ! # wlink system pmodew @makepref.lnk angband.lnk: %create angband.lnk --- 31,48 ---- # Use whichever of these two you wish... angband.exe: $(OBJS) angband.lnk ! # wlink system dos4g @angband.lnk ! wlink system pmodew @angband.lnk # Use whichever of these two you wish... gredit.exe: gredit.obj gredit.lnk ! # wlink system dos4g @gredit.lnk ! wlink system pmodew @gredit.lnk # Use whichever of these two you wish... makepref.exe: makepref.obj makepref.lnk ! # wlink system dos4g @makepref.lnk ! wlink system pmodew @makepref.lnk angband.lnk: %create angband.lnk *************** *** 66,69 **** $(CC) $(CFLAGS) $[*.c clean: ! del *.err *.obj *.exe *.lnk --- 72,79 ---- $(CC) $(CFLAGS) $[*.c clean: ! del *.err ! del *.obj ! del *.exe ! del *.lnk ! diff -c -r angband-282/src/Makefile.win angband-283/src/Makefile.win *** angband-282/src/Makefile.win Wed Sep 3 11:57:32 1997 --- angband-283/src/Makefile.win Fri Feb 6 04:08:39 1998 *************** *** 202,204 **** --- 202,205 ---- ..\angband32.exe,..\angband.map,import32 cw32,..\ext-win\src\angband.def | $(RC32) -w32 ..\ext-win\src\angband.rc ..\angband32.exe + diff -c -r angband-282/src/angband.h angband-283/src/angband.h *** angband-282/src/angband.h Wed Sep 3 11:57:32 1997 --- angband-283/src/angband.h Fri Feb 6 04:10:31 1998 *************** *** 84,86 **** --- 84,87 ---- #endif + diff -c -r angband-282/src/birth.c angband-283/src/birth.c *** angband-282/src/birth.c Wed Sep 3 11:57:32 1997 --- angband-283/src/birth.c Mon Feb 9 07:29:31 1998 *************** *** 744,758 **** /* Calculate the height/weight for males */ if (p_ptr->psex == SEX_MALE) { ! p_ptr->ht = randnor(rp_ptr->m_b_ht, rp_ptr->m_m_ht); ! p_ptr->wt = randnor(rp_ptr->m_b_wt, rp_ptr->m_m_wt); } /* Calculate the height/weight for females */ else if (p_ptr->psex == SEX_FEMALE) { ! p_ptr->ht = randnor(rp_ptr->f_b_ht, rp_ptr->f_m_ht); ! p_ptr->wt = randnor(rp_ptr->f_b_wt, rp_ptr->f_m_wt); } } --- 744,758 ---- /* Calculate the height/weight for males */ if (p_ptr->psex == SEX_MALE) { ! p_ptr->ht = Rand_normal(rp_ptr->m_b_ht, rp_ptr->m_m_ht); ! p_ptr->wt = Rand_normal(rp_ptr->m_b_wt, rp_ptr->m_m_wt); } /* Calculate the height/weight for females */ else if (p_ptr->psex == SEX_FEMALE) { ! p_ptr->ht = Rand_normal(rp_ptr->f_b_ht, rp_ptr->f_m_ht); ! p_ptr->wt = Rand_normal(rp_ptr->f_b_wt, rp_ptr->f_m_wt); } } *************** *** 795,816 **** /* * Display stat values, subset of "put_stats()" * ! * See 'display_player()' for basic method. */ static void birth_put_stats(void) { int i, p; byte attr; char buf[80]; /* Put the stats (and percents) */ for (i = 0; i < 6; i++) { /* Put the stat */ cnv_stat(stat_use[i], buf); ! c_put_str(TERM_L_GREEN, buf, 2 + i, 66); /* Put the percent */ if (stat_match[i]) --- 795,820 ---- /* * Display stat values, subset of "put_stats()" * ! * See 'display_player()' for screen layout constraints. */ static void birth_put_stats(void) { + int col; int i, p; byte attr; char buf[80]; + col = 42; + + /* Put the stats (and percents) */ for (i = 0; i < 6; i++) { /* Put the stat */ cnv_stat(stat_use[i], buf); ! c_put_str(TERM_L_GREEN, buf, 3+i, col+24); /* Put the percent */ if (stat_match[i]) *************** *** 818,830 **** p = 1000L * stat_match[i] / auto_round; attr = (p < 100) ? TERM_YELLOW : TERM_L_GREEN; sprintf(buf, "%3d.%d%%", p/10, p%10); ! c_put_str(attr, buf, 2 + i, 73); } /* Never happened */ else { ! c_put_str(TERM_RED, "(NONE)", 2 + i, 73); } } } --- 822,834 ---- p = 1000L * stat_match[i] / auto_round; attr = (p < 100) ? TERM_YELLOW : TERM_L_GREEN; sprintf(buf, "%3d.%d%%", p/10, p%10); ! c_put_str(attr, buf, 3+i, col+13); } /* Never happened */ else { ! c_put_str(TERM_RED, "(NONE)", 3+i, col+13); } } } *************** *** 1029,1041 **** * The delay may be reduced, but is recommended to keep players * from continuously rolling up characters, which can be VERY * expensive CPU wise. And it cuts down on player stupidity. */ static bool player_birth_aux() { int i, j, k, m, n, v; - int mode = 0; - bool flag = FALSE; bool prev = FALSE; --- 1033,1045 ---- * The delay may be reduced, but is recommended to keep players * from continuously rolling up characters, which can be VERY * expensive CPU wise. And it cuts down on player stupidity. + * + * See "display_player" for screen layout code. */ static bool player_birth_aux() { int i, j, k, m, n, v; bool flag = FALSE; bool prev = FALSE; *************** *** 1055,1077 **** bool autoroll = FALSE; ! /*** Intro ***/ /* Clear screen */ Term_clear(); - /* Title everything */ - put_str("Name :", 2, 1); - put_str("Sex :", 3, 1); - put_str("Race :", 4, 1); - put_str("Class :", 5, 1); - - /* Dump the default name */ - c_put_str(TERM_L_BLUE, op_ptr->full_name, 2, 15); - - - /*** Instructions ***/ - /* Display some helpful information */ Term_putstr(5, 10, -1, TERM_WHITE, "Please answer the following questions. Most of the questions"); --- 1059,1069 ---- bool autoroll = FALSE; ! /*** Instructions ***/ /* Clear screen */ Term_clear(); /* Display some helpful information */ Term_putstr(5, 10, -1, TERM_WHITE, "Please answer the following questions. Most of the questions"); *************** *** 1110,1128 **** c = inkey(); if (c == 'Q') quit(NULL); if (c == 'S') return (FALSE); k = (islower(c) ? A2I(c) : -1); if ((k >= 0) && (k < n)) break; if (c == '?') do_cmd_help(); ! else bell(); } /* Set sex */ p_ptr->psex = k; sp_ptr = &sex_info[p_ptr->psex]; - str = sp_ptr->title; - - /* Display */ - c_put_str(TERM_L_BLUE, str, 3, 15); /* Clean up */ clear_from(15); --- 1102,1117 ---- c = inkey(); if (c == 'Q') quit(NULL); if (c == 'S') return (FALSE); + if (c == ESCAPE) c = 'a'; k = (islower(c) ? A2I(c) : -1); if ((k >= 0) && (k < n)) break; if (c == '?') do_cmd_help(); ! else bell("Illegal sex!"); } /* Set sex */ p_ptr->psex = k; sp_ptr = &sex_info[p_ptr->psex]; /* Clean up */ clear_from(15); *************** *** 1155,1173 **** c = inkey(); if (c == 'Q') quit(NULL); if (c == 'S') return (FALSE); k = (islower(c) ? A2I(c) : -1); if ((k >= 0) && (k < n)) break; if (c == '?') do_cmd_help(); ! else bell(); } /* Set race */ p_ptr->prace = k; rp_ptr = &race_info[p_ptr->prace]; - str = rp_ptr->title; - - /* Display */ - c_put_str(TERM_L_BLUE, str, 4, 15); /* Clean up */ clear_from(15); --- 1144,1159 ---- c = inkey(); if (c == 'Q') quit(NULL); if (c == 'S') return (FALSE); + if (c == ESCAPE) c = 'a'; k = (islower(c) ? A2I(c) : -1); if ((k >= 0) && (k < n)) break; if (c == '?') do_cmd_help(); ! else bell("Illegal race!"); } /* Set race */ p_ptr->prace = k; rp_ptr = &race_info[p_ptr->prace]; /* Clean up */ clear_from(15); *************** *** 1208,1227 **** c = inkey(); if (c == 'Q') quit(NULL); if (c == 'S') return (FALSE); k = (islower(c) ? A2I(c) : -1); if ((k >= 0) && (k < n)) break; if (c == '?') do_cmd_help(); ! else bell(); } /* Set class */ p_ptr->pclass = k; cp_ptr = &class_info[p_ptr->pclass]; mp_ptr = &magic_info[p_ptr->pclass]; - str = cp_ptr->title; - - /* Display */ - c_put_str(TERM_L_BLUE, cp_ptr->title, 5, 15); /* Clean up */ clear_from(15); --- 1194,1210 ---- c = inkey(); if (c == 'Q') quit(NULL); if (c == 'S') return (FALSE); + if (c == ESCAPE) c = 'a'; k = (islower(c) ? A2I(c) : -1); if ((k >= 0) && (k < n)) break; if (c == '?') do_cmd_help(); ! else bell("Illegal class!"); } /* Set class */ p_ptr->pclass = k; cp_ptr = &class_info[p_ptr->pclass]; mp_ptr = &magic_info[p_ptr->pclass]; /* Clean up */ clear_from(15); *************** *** 1245,1251 **** if (c == ESCAPE) break; if ((c == 'y') || (c == 'n')) break; if (c == '?') do_cmd_help(); ! else bell(); } /* Set "maximize" mode */ --- 1228,1234 ---- if (c == ESCAPE) break; if ((c == 'y') || (c == 'n')) break; if (c == '?') do_cmd_help(); ! else bell("Illegal maximize flag!"); } /* Set "maximize" mode */ *************** *** 1273,1279 **** if (c == ESCAPE) break; if ((c == 'y') || (c == 'n')) break; if (c == '?') do_cmd_help(); ! else bell(); } /* Set "preserve" mode */ --- 1256,1262 ---- if (c == ESCAPE) break; if ((c == 'y') || (c == 'n')) break; if (c == '?') do_cmd_help(); ! else bell("Illegal preserve flag!"); } /* Set "preserve" mode */ *************** *** 1303,1309 **** if (c == ESCAPE) break; if ((c == 'y') || (c == 'n')) break; if (c == '?') do_cmd_help(); ! else bell(); } /* Set "autoroll" */ --- 1286,1292 ---- if (c == ESCAPE) break; if ((c == 'y') || (c == 'n')) break; if (c == '?') do_cmd_help(); ! else bell("Illegal autoroller flag!"); } /* Set "autoroll" */ *************** *** 1417,1453 **** /* Roll */ while (TRUE) { /* Feedback */ if (autoroll) { Term_clear(); ! put_str("Name :", 2, 1); ! put_str("Sex :", 3, 1); ! put_str("Race :", 4, 1); ! put_str("Class :", 5, 1); ! ! c_put_str(TERM_L_BLUE, op_ptr->full_name, 2, 15); ! c_put_str(TERM_L_BLUE, sp_ptr->title, 3, 15); ! c_put_str(TERM_L_BLUE, rp_ptr->title, 4, 15); ! c_put_str(TERM_L_BLUE, cp_ptr->title, 5, 15); ! ! /* Label stats */ ! put_str("STR:", 2 + A_STR, 61); ! put_str("INT:", 2 + A_INT, 61); ! put_str("WIS:", 2 + A_WIS, 61); ! put_str("DEX:", 2 + A_DEX, 61); ! put_str("CON:", 2 + A_CON, 61); ! put_str("CHR:", 2 + A_CHR, 61); /* Note when we started */ last_round = auto_round; - /* Indicate the state */ - put_str("(Hit ESC to abort)", 11, 61); - /* Label count */ ! put_str("Round:", 9, 61); } /* Otherwise just get a character */ --- 1400,1442 ---- /* Roll */ while (TRUE) { + int col; + + col = 42; + /* Feedback */ if (autoroll) { Term_clear(); ! /* Label */ ! put_str(" Limit", 2, col+5); ! ! /* Label */ ! put_str(" Freq", 2, col+13); ! ! /* Label */ ! put_str(" Roll", 2, col+24); ! ! /* Put the minimal stats */ ! for (i = 0; i < 6; i++) ! { ! /* Label stats */ ! put_str(stat_names[i], 3+i, col); ! ! /* Put the stat */ ! cnv_stat(stat_limit[i], buf); ! c_put_str(TERM_L_BLUE, buf, 3+i, col+5); ! } /* Note when we started */ last_round = auto_round; /* Label count */ ! put_str("Round:", 10, col+13); ! ! /* Indicate the state */ ! put_str("(Hit ESC to stop)", 12, col+13); } /* Otherwise just get a character */ *************** *** 1500,1506 **** birth_put_stats(); /* Dump round */ ! put_str(format("%6ld", auto_round), 9, 73); /* Make sure they see everything */ Term_fresh(); --- 1489,1495 ---- birth_put_stats(); /* Dump round */ ! put_str(format("%10ld", auto_round), 10, col+20); /* Make sure they see everything */ Term_fresh(); *************** *** 1522,1530 **** /*** Display ***/ - /* Mode */ - mode = 0; - /* Roll for base hitpoints */ get_extra(); --- 1511,1516 ---- *************** *** 1553,1567 **** p_ptr->csp = p_ptr->msp; /* Display the player */ ! display_player(mode); /* Prepare a prompt (must squeeze everything in) */ Term_gotoxy(2, 23); Term_addch(TERM_WHITE, b1); Term_addstr(-1, TERM_WHITE, "'r' to reroll"); if (prev) Term_addstr(-1, TERM_WHITE, ", 'p' for prev"); - if (mode) Term_addstr(-1, TERM_WHITE, ", 'h' for Misc."); - else Term_addstr(-1, TERM_WHITE, ", 'h' for History"); Term_addstr(-1, TERM_WHITE, ", or ESC to accept"); Term_addch(TERM_WHITE, b2); --- 1539,1551 ---- p_ptr->csp = p_ptr->msp; /* Display the player */ ! display_player(0); /* Prepare a prompt (must squeeze everything in) */ Term_gotoxy(2, 23); Term_addch(TERM_WHITE, b1); Term_addstr(-1, TERM_WHITE, "'r' to reroll"); if (prev) Term_addstr(-1, TERM_WHITE, ", 'p' for prev"); Term_addstr(-1, TERM_WHITE, ", or ESC to accept"); Term_addch(TERM_WHITE, b2); *************** *** 1572,1578 **** if (c == 'Q') quit(NULL); /* Start over */ ! if (c == 'S') return (FALSE); /* Escape accepts the roll */ if (c == ESCAPE) break; --- 1556,1562 ---- if (c == 'Q') quit(NULL); /* Start over */ ! if (c == 'S') return (FALSE); /* Escape accepts the roll */ if (c == ESCAPE) break; *************** *** 1587,1599 **** continue; } - /* Toggle the display */ - if ((c == 'H') || (c == 'h')) - { - mode = ((mode != 0) ? 0 : 1); - continue; - } - /* Help */ if (c == '?') { --- 1571,1576 ---- *************** *** 1602,1608 **** } /* Warning */ ! bell(); } /* Are we done? */ --- 1579,1585 ---- } /* Warning */ ! bell("Illegal autoroller command!"); } /* Are we done? */ *************** *** 1621,1628 **** /*** Finish up ***/ ! /* Get a name, recolor it, prepare savefile */ get_name(); /* Prompt for it */ prt("['Q' to suicide, 'S' to start over, or ESC to continue]", 23, 10); --- 1598,1608 ---- /*** Finish up ***/ ! /* Get a name, prepare savefile */ get_name(); + + /* Display the player */ + display_player(0); /* Prompt for it */ prt("['Q' to suicide, 'S' to start over, or ESC to continue]", 23, 10); diff -c -r angband-282/src/cave.c angband-283/src/cave.c *** angband-282/src/cave.c Wed Sep 3 11:57:32 1997 --- angband-283/src/cave.c Mon Feb 9 01:18:52 1998 *************** *** 12,18 **** - /* * Approximate Distance between two points. * --- 12,17 ---- *************** *** 22,40 **** * * Algorithm: hypot(dy,dx) = max(dy,dx) + min(dy,dx) / 2 */ ! int distance(int y1, int x1, int y2, int x2) { ! int dy, dx, d; /* Find the absolute y/x distance components */ ! dy = (y1 > y2) ? (y1 - y2) : (y2 - y1); ! dx = (x1 > x2) ? (x1 - x2) : (x2 - x1); /* Hack -- approximate the distance */ ! d = (dy > dx) ? (dy + (dx>>1)) : (dx + (dy>>1)); ! ! /* Return the distance */ ! return (d); } --- 21,36 ---- * * Algorithm: hypot(dy,dx) = max(dy,dx) + min(dy,dx) / 2 */ ! sint distance(int y1, int x1, int y2, int x2) { ! int ay, ax; /* Find the absolute y/x distance components */ ! ay = (y1 > y2) ? (y1 - y2) : (y2 - y1); ! ax = (x1 > x2) ? (x1 - x2) : (x2 - x1); /* Hack -- approximate the distance */ ! return ((ay > ax) ? (ay + (ax>>1)) : (ax + (ay>>1))); } *************** *** 42,77 **** * A simple, fast, integer-based line-of-sight algorithm. By Joseph Hall, * 4116 Brewster Drive, Raleigh NC 27606. Email to jnh@ecemwl.ncsu.edu. * ! * Returns TRUE if a line of sight can be traced from (x1,y1) to (x2,y2). ! * ! * The LOS begins at the center of the tile (x1,y1) and ends at the center of ! * the tile (x2,y2). If los() is to return TRUE, all of the tiles this line ! * passes through must be floor tiles, except for (x1,y1) and (x2,y2). ! * ! * We assume that the "mathematical corner" of a non-floor tile does not ! * block line of sight. ! * ! * Because this function uses (short) ints for all calculations, overflow may ! * occur if dx and dy exceed 90. ! * ! * Once all the degenerate cases are eliminated, the values "qx", "qy", and ! * "m" are multiplied by a scale factor "f1 = abs(dx * dy * 2)", so that ! * we can use integer arithmetic. ! * ! * We travel from start to finish along the longer axis, starting at the border ! * between the first and second tiles, where the y offset = .5 * slope, taking ! * into account the scale factor. See below. ! * ! * Also note that this function and the "move towards target" code do NOT ! * share the same properties. Thus, you can see someone, target them, and ! * then fire a bolt at them, but the bolt may hit a wall, not them. However, ! * by clever choice of target locations, you can sometimes throw a "curve". ! * ! * Note that "line of sight" is not "reflexive" in all cases. ! * ! * Use the "projectable()" routine to test "spell/missile line of sight". ! * ! * Use the "update_view()" function to determine player line-of-sight. */ bool los(int y1, int x1, int y2, int x2) { --- 38,74 ---- * A simple, fast, integer-based line-of-sight algorithm. By Joseph Hall, * 4116 Brewster Drive, Raleigh NC 27606. Email to jnh@ecemwl.ncsu.edu. * ! * This function returns TRUE if a "line of sight" can be traced from the ! * center of the grid (x1,y1) to the center of the grid (x2,y2), with all ! * of the grids along this path (except for the endpoints) being non-wall ! * grids. Actually, the "chess knight move" situation is handled by some ! * special case code which allows the grid diagonally next to the player ! * to be obstructed, because this yields better gameplay semantics. This ! * algorithm is totally reflexive, except for "knight move" situations. ! * ! * Because this function uses (short) ints for all calculations, overflow ! * may occur if dx and dy exceed 90. ! * ! * Once all the degenerate cases are eliminated, we determine the "slope" ! * ("m"), and we use special "fixed point" mathematics in which we use a ! * special "fractional component" for one of the two location components ! * ("qy" or "qx"), which, along with the slope itself, are "scaled" by a ! * scale factor equal to "abs(dy*dx*2)" to keep the math simple. Then we ! * simply travel from start to finish along the longer axis, starting at ! * the border between the first and second tiles (where the y offset is ! * thus half the slope), using slope and the fractional component to see ! * when motion along the shorter axis is necessary. Since we assume that ! * vision is not blocked by "brushing" the corner of any grid, we must do ! * some special checks to avoid testing grids which are "brushed" but not ! * actually "entered". ! * ! * Angband three different "line of sight" type concepts, including this ! * function (which is used almost nowhere), the "project()" method (which ! * is used for determining the paths of projectables and spells and such), ! * and the "update_view()" concept (which is used to determine which grids ! * are "viewable" by the player, which is used for many things, such as ! * determining which grids are illuminated by the player's torch, and which ! * grids and monsters can be "seen" by the player, etc). */ bool los(int y1, int x1, int y2, int x2) { *************** *** 294,400 **** - - - /* - * Can the player "see" the given grid? - * - * He must have vision, illumination, and line of sight. - * - * If the player is "blind", then no grids can be "seen". - * - * Note that "CAVE_LITE" means that a grid is lit by the player's torch, - * which means that the grid is "lit" and "viewable", so all such grids - * can, by definition, be "seen". - * - * Note that "CAVE_GLOW" means that a grid is "permanently illuminated", - * which, normally, means that if the grid is "viewable", then it can be - * "seen". But for wall/door grids, since they are not "translucent", - * this is only true if, in addition, the grid which is closest to the - * player and adjacent to the wall grid is also "permanently lit". - * - * This bizarre method for handling perma-lit wall grids may be more - * expensive than simply assuming that perma-lit wall grids, like the - * floor grids, can be seen when viewable, but it provides a somewhat - * more "correct" semantics, in particular, it prevents the player from - * "seeing" the wall of a room from a hallway running next to the room. - * - * Technically, we should check all eight grids adjacent to the wall grid, - * and if any of them are "perma-lit" non-wall grids which are "viewable" - * to the player, then the wall grid, if perma-lit itself, can be "seen", - * but this is extremely expensive, and dangerous, if the wall grid is - * adjacent to any "illegal" grids. But the semantics would be slightly - * better, for example, currently, wall grids which frame the "entrance" - * to a lit room cannot be "seen" by a player in a dark hallway. - * - * We must be very careful about combining this function, in particular, - * the parts which deal with "perma-lit" wall grids, with any optimized - * algorithms, such as the "update_view()" code, which only calls the - * "note_spot()" function (which uses an "inline" version of this code) - * for grids which "change" viewability, since strange things may happen - * if we are not careful. For example, when a player enters a lit room, - * from a dark hall, through a closed door, with no torch, we must ensure - * that the walls adjacent to the door are "seen" from the doorway. - * - * The "doorway" example is responsible for the "optional" method shown - * below, in which we check three adjacent grids instead of just a single - * adjacent grid, and we forbid these grids from being walls. - * - * See also the various "inline" versions of "player_can_see_bold()", for - * example, in the "note_spot()" and "map_info()" functions. - */ - bool player_can_see_bold(int y, int x) - { - /* Blind players see nothing */ - if (p_ptr->blind) return (FALSE); - - /* Note that "torch-lite" yields "illumination" */ - if (cave_info[y][x] & (CAVE_LITE)) return (TRUE); - - /* Require line of sight to the grid */ - if (!player_has_los_bold(y, x)) return (FALSE); - - /* Require "perma-lite" of the grid */ - if (!(cave_info[y][x] & (CAVE_GLOW))) return (FALSE); - - /* Floors are simple */ - if (cave_floor_bold(y, x)) return (TRUE); - - /* Walls */ - if (TRUE) - { - int py = p_ptr->py; - int px = p_ptr->px; - - /* Hack -- move towards player */ - int yy = (y < py) ? (y + 1) : (y > py) ? (y - 1) : y; - int xx = (x < px) ? (x + 1) : (x > px) ? (x - 1) : x; - - #if 0 - /* Alternative method */ - if ((cave_floor_bold(yy, xx) && (cave_info[yy][xx] & (CAVE_GLOW))) || - (cave_floor_bold(y, xx) && (cave_info[y][xx] & (CAVE_GLOW))) || - (cave_floor_bold(yy, x) && (cave_info[yy][x] & (CAVE_GLOW)))) - { - /* Assume the wall is really illuminated */ - return (TRUE); - } - #endif - - /* Check for "local" illumination */ - if (cave_info[yy][xx] & (CAVE_GLOW)) - { - /* Assume the wall is really illuminated */ - return (TRUE); - } - } - - /* Assume not visible */ - return (FALSE); - } - - - /* * Returns true if the player's grid is dark */ --- 291,296 ---- *************** *** 443,509 **** - - - - /* * Hack -- Legal monster codes */ ! static cptr image_monster_hack = \ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; /* ! * Mega-Hack -- Hallucinatory monster */ ! static void image_monster(byte *ap, char *cp) { ! int n = strlen(image_monster_hack); ! /* Random symbol from set above */ ! (*cp) = (image_monster_hack[rand_int(n)]); /* Random color */ ! (*ap) = randint(15); } /* * Hack -- Legal object codes */ ! static cptr image_object_hack = \ ! "?/|\\\"!$()_-=[]{},~"; /* ! * Mega-Hack -- Hallucinatory object */ ! static void image_object(byte *ap, char *cp) { ! int n = strlen(image_object_hack); ! /* Random symbol from set above */ ! (*cp) = (image_object_hack[rand_int(n)]); /* Random color */ ! (*ap) = randint(15); } /* * Hack -- Random hallucination */ ! static void image_random(byte *ap, char *cp) { /* Normally, assume monsters */ if (rand_int(100) < 75) { ! image_monster(ap, cp); } /* Otherwise, assume objects */ else { ! image_object(ap, cp); } } --- 339,409 ---- /* * Hack -- Legal monster codes */ ! static const char image_monster_hack[] = \ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; /* ! * Hack -- Hallucinatory monster */ ! static u16b image_monster(void) { ! byte a; ! char c; ! /* Random symbol from set above (not including final nul) */ ! c = image_monster_hack[rand_int(sizeof(image_monster_hack) - 1)]; /* Random color */ ! a = randint(15); ! ! /* Encode */ ! return (PICT(a,c)); } /* * Hack -- Legal object codes */ ! static const char image_object_hack[] = \ ! "?/|\\\"!$()_-=[]{},~"; /* " */ /* ! * Hack -- Hallucinatory object */ ! static u16b image_object(void) { ! byte a; ! char c; ! /* Random symbol from set above (not including final nul) */ ! c = image_object_hack[rand_int(sizeof(image_object_hack) - 1)]; /* Random color */ ! a = randint(15); ! ! /* Encode */ ! return (PICT(a,c)); } /* * Hack -- Random hallucination */ ! static u16b image_random(void) { /* Normally, assume monsters */ if (rand_int(100) < 75) { ! return (image_monster()); } /* Otherwise, assume objects */ else { ! return (image_object()); } } *************** *** 512,704 **** /* * Extract the attr/char to display at the given (legal) map location * ! * Basically, we "paint" the chosen attr/char in several passes, starting ! * with any known "terrain features" (defaulting to darkness), then adding ! * any known "objects", then adding any known "monsters", and then adding ! * the player if needed. This is not the fastest method but since most of ! * the calls to this function are made for grids with no objects, monsters, ! * or players, it should be fast enough. * * Note that the "zero" entry in the feature/object/monster arrays are * used to provide "special" attr/char codes, with "monster zero" being * used for the player attr/char, "object zero" being used for the "stack" ! * attr/char, and "feature zero" being used for the "nothing" attr/char, ! * though this function makes use of only "feature zero". XXX XXX XXX * ! * Note that monsters can have some "special" flags, including "ATTR_MULTI", ! * which means their color changes, and "ATTR_CLEAR", which means they take ! * the color of whatever is under them, and "CHAR_CLEAR", which means that ! * they take the symbol of whatever is under them. Technically, the flag ! * "CHAR_MULTI" is supposed to indicate that a monster looks strange when ! * examined, but this flag is currently ignored. All of these flags are ! * ignored if the "avoid_other" option is set, since checking for these ! * conditions is expensive and annoying on some systems. * - * Currently, we do nothing with multi-hued objects, because there are - * not any. If there were, they would have to set "shimmer_objects" - * when they were created, and then new "shimmer" code in "dungeon.c" - * would have to be created handle the "shimmer" effect, and the code - * in "cave.c" would have to be updated to create the shimmer effect. * ! * Note the effects of hallucination. Objects always appear as random ! * "objects", monsters as random "monsters", and normal grids occasionally ! * appear as random "monsters" or "objects", but note that these random ! * "monsters" and "objects" are really just "colored ascii symbols". ! * ! * Note that "floors" and "invisible traps" (and "zero" features) are ! * drawn as "floors" using a special check for optimization purposes, ! * and these are the only features which get drawn using the special ! * lighting effects activated by "view_special_lite". * * Note the use of the "mimic" field in the "terrain feature" processing, * which allows any feature to "pretend" to be another feature. This is * used to "hide" secret doors, and to make all "doors" appear the same, * and all "walls" appear the same, and "hidden" treasure stay hidden. ! * It is possible to use this field to make a feature "look" like a floor, ! * but the "special lighting effects" for floors will not be used. * - * Note the use of the new "terrain feature" information. Note that the - * assumption that all interesting "objects" and "terrain features" are - * memorized allows extremely optimized processing below. Note the use - * of separate flags on objects to mark them as memorized allows a grid - * to have memorized "terrain" without granting knowledge of any object - * which may appear in that grid. - * - * Note the efficient code used to determine if a "floor" grid is - * "memorized" or "viewable" by the player, where the test for the - * grid being "viewable" is based on the facts that (1) the grid - * must be "lit" (torch-lit or perma-lit), (2) the grid must be in - * line of sight, and (3) the player must not be blind, and uses the - * assumption that all torch-lit grids are in line of sight. - * - * Note that floors (and invisible traps) are the only grids which are - * not memorized when seen, so only these grids need to check to see if - * the grid is "viewable" to the player (if it is not memorized). Since - * most non-memorized grids are in fact walls, this induces *massive* - * efficiency, at the cost of *forcing* the memorization of non-floor - * grids when they are first seen. Note that "invisible traps" are - * always treated exactly like "floors", which prevents "cheating". - * - * Note the "special lighting effects" which can be activated for floor - * grids using the "view_special_lite" option (for "white" floor grids), - * causing certain grids to be displayed using special colors. If the - * player is "blind", we will use "dark gray", else if the grid is lit - * by the torch, and the "view_yellow_lite" option is set, we will use - * "yellow", else if the grid is "dark", we will use "dark gray", else - * if the grid is not "viewable", and the "view_bright_lite" option is - * set, and the we will use "slate" (gray). We will use "white" for all - * other cases, in particular, for illuminated viewable floor grids. - * - * Note the "special lighting effects" which can be activated for wall - * grids using the "view_granite_lite" option (for "white" wall grids), - * causing certain grids to be displayed using special colors. If the - * player is "blind", we will use "dark gray", else if the grid is lit - * by the torch, and the "view_yellow_lite" option is set, we will use - * "yellow", else if the "view_bright_lite" option is set, and the grid - * is not "viewable", or is "dark", or is glowing, but not when viewed - * from the player's current location, we will use "slate" (gray). We - * will use "white" for all other cases, in particular, for correctly - * illuminated viewable wall grids. - * - * Note that, when "view_granite_lite" is set, we use an inline version - * of the "player_can_see_bold()" function to check the "viewability" of - * grids when the "view_bright_lite" option is set, and we do NOT use - * any special colors for "dark" wall grids, since this would allow the - * player to notice the walls of illuminated rooms from a hallway that - * happened to run beside the room. * ! * Note that bizarre things must be done when the "attr" and/or "char" ! * codes have the "high-bit" set, since these values are used to encode ! * various "special" pictures in some versions, and certain situations, ! * such as "multi-hued" or "clear" monsters, cause the attr/char codes ! * to be "scrambled" in various ways. * - * Note that eventually we may use the "&" symbol for embedded treasure, - * and use the "*" symbol to indicate multiple objects, though this will - * have to wait for Angband 2.8.2 or later. Currently, we simply use - * the attr/char of the first "marked" object in the stack. If we did - * use some special symbol, it could be stored in "f_info[0]". * ! * Note the assumption that doing "x_ptr = &x_info[x]" plus a few of ! * "x_ptr->xxx", is quicker than "x_info[x].xxx", if this is incorrect ! * then a whole lot of code should be changed... XXX XXX XXX */ void map_info(int y, int x, byte *ap, char *cp) { feature_type *f_ptr; s16b this_o_idx, next_o_idx = 0; ! int feat; ! byte a; ! char c; ! /* Feature code */ feat = cave_feat[y][x]; ! /* Floors (etc) */ ! if (feat <= FEAT_INVIS) { ! /* Memorized (or visible) floor */ ! if ((cave_info[y][x] & (CAVE_MARK)) || ! (((cave_info[y][x] & (CAVE_LITE)) || ! ((cave_info[y][x] & (CAVE_GLOW)) && ! (cave_info[y][x] & (CAVE_VIEW)))) && ! !p_ptr->blind)) { /* Access floor */ f_ptr = &f_info[FEAT_FLOOR]; /* Normal char */ ! (*cp) = f_ptr->z_char; /* Normal attr */ ! a = f_ptr->z_attr; /* Special lighting effects */ if (view_special_lite && (a == TERM_WHITE)) { ! /* Handle "blind" */ ! if (p_ptr->blind) ! { ! /* Use "dark gray" */ ! a = TERM_L_DARK; ! } ! ! /* Handle "torch-lit" grids */ ! else if (cave_info[y][x] & (CAVE_LITE)) { ! /* Torch lite */ ! if (view_yellow_lite) { /* Use "yellow" */ a = TERM_YELLOW; } } /* Handle "dark" grids */ ! else if (!(cave_info[y][x] & (CAVE_GLOW))) { /* Use "dark gray" */ a = TERM_L_DARK; } ! /* Handle "out-of-sight" grids */ ! else if (!(cave_info[y][x] & (CAVE_VIEW))) { ! /* Special flag */ ! if (view_bright_lite) ! { ! /* Use "gray" */ ! a = TERM_SLATE; ! } } } - - /* The attr */ - (*ap) = a; } /* Unknown */ --- 412,692 ---- /* * Extract the attr/char to display at the given (legal) map location * ! * Note that this function, since it is called by "lite_spot()" which ! * is called by "update_view()", is a major efficiency concern. ! * ! * Basically, we examine each "layer" of the world (terrain, objects, ! * monsters/players), from the bottom up, extracting a new attr/char ! * if necessary at each layer, and defaulting to "darkness". This is ! * not the fastest method, but it is very simple, and it is about as ! * fast as it could be for grids which contain no "marked" objects or ! * "visible" monsters. ! * ! * We apply the effects of hallucination during each layer. Objects will ! * always appear as random "objects", monsters will always appear as random ! * "monsters", and normal grids occasionally appear as random "monsters" or ! * "objects", but note that these random "monsters" and "objects" are really ! * just "colored ascii symbols" (which may look silly on some machines). ! * ! * The hallucination functions avoid taking any pointers to local variables ! * because some compilers refuse to use registers for any local variables ! * whose address is taken anywhere in the function. ! * ! * As an optimization, we can handle the "player" grid as a special case. ! * ! * Note that the memorization of "objects" and "monsters" is not related ! * to the memorization of "terrain". This allows the player to memorize ! * the terrain of a grid without memorizing any objects in that grid, and ! * to detect monsters without detecting anything about the terrain of the ! * grid containing the monster. ! * ! * The fact that all interesting "objects" and "terrain features" are ! * memorized as soon as they become visible for the first time means ! * that we only have to check the "CAVE_SEEN" flag for "boring" grids. ! * ! * Note that bizarre things must be done when the "attr" and/or "char" ! * codes have the "high-bit" set, since these values are used to encode ! * various "special" pictures in some versions, and certain situations, ! * such as "multi-hued" or "clear" monsters, cause the attr/char codes ! * to be "scrambled" in various ways. * * Note that the "zero" entry in the feature/object/monster arrays are * used to provide "special" attr/char codes, with "monster zero" being * used for the player attr/char, "object zero" being used for the "stack" ! * attr/char, and "feature zero" being used for the "nothing" attr/char. * ! * Note that eventually we may want to use the "&" symbol for embedded ! * treasure, and use the "*" symbol to indicate multiple objects, but ! * currently, we simply use the attr/char of the first "marked" object ! * in the stack, if any, and so "object zero" is unused. XXX XXX XXX ! * ! * Note the assumption that doing "x_ptr = &x_info[x]" plus a few of ! * "x_ptr->xxx", is quicker than "x_info[x].xxx", even if "x" is a fixed ! * constant. If this is incorrect then a lot of code should be changed. * * ! * Some comments on the "terrain" layer... ! * ! * Note that "boring" grids (floors, invisible traps, and any illegal grids) ! * are very different from "interesting" grids (all other terrain features), ! * and the two types of grids are handled completely separately. The most ! * important distinction is that "boring" grids may or may not be memorized ! * when they are first encountered, and so we must use the "CAVE_SEEN" flag ! * to see if they are "see-able". ! * ! * ! * Some comments on the "terrain" layer (boring grids)... ! * ! * Note that "boring" grids are always drawn using the picture for "empty ! * floors", which is stored in "f_info[FEAT_FLOOR]". Sometimes, special ! * lighting effects may cause this picture to be modified. ! * ! * Note that "invisible traps" are always displayes exactly like "empty ! * floors", which prevents various forms of "cheating", with no loss of ! * efficiency. There are still a few ways to "guess" where traps may be ! * located, for example, objects will never fall into a grid containing ! * an invisible trap. XXX XXX ! * ! * To determine if a "boring" grid should be displayed, we simply check to ! * see if it is either memorized ("CAVE_MARK"), or currently "see-able" by ! * the player ("CAVE_SEEN"). Note that "CAVE_SEEN" is now maintained by the ! * "update_view()" function. ! * ! * Note the "special lighting effects" which can be activated for "boring" ! * grids using the "view_special_lite" option, causing certain such grids ! * to be displayed using special colors (if they are normally "white"). ! * If the grid is "see-able" by the player, we will use the normal "white" ! * (except that, if the "view_yellow_lite" option is set, and the grid ! * is *only* "see-able" because of the player's torch, then we will use ! * "yellow"), else if the player is "blind", we will use "dark gray", ! * else if the grid is not "illuminated", we will use "dark gray", else ! * if the "view_bright_lite" option is set, we will use "slate" (gray), ! * else we will use the normal "white". ! * ! * ! * Some comments on the "terrain" layer (non-boring grids)... * * Note the use of the "mimic" field in the "terrain feature" processing, * which allows any feature to "pretend" to be another feature. This is * used to "hide" secret doors, and to make all "doors" appear the same, * and all "walls" appear the same, and "hidden" treasure stay hidden. ! * Note that it is possible to use this field to make a feature "look" ! * like a floor, but the "view_special_lite" flag only affects actual ! * "boring" grids. ! * ! * Since "interesting" grids are always memorized as soon as they become ! * "see-able" by the player ("CAVE_SEEN"), such a grid only needs to be ! * displayed if it is memorized ("CAVE_MARK"). Most "interesting" grids ! * are in fact non-memorized, non-see-able, wall grids, so the fact that ! * we do not have to check the "CAVE_SEEN" flag adds some efficiency, at ! * the cost of *forcing* the memorization of all "interesting" grids when ! * they are first seen. Since the "CAVE_SEEN" flag is now maintained by ! * the "update_view()" function, this efficiency is not as significant as ! * it was in previous versions, and could perhaps be removed. ! * ! * Note the "special lighting effects" which can be activated for "wall" ! * grids using the "view_granite_lite" option, causing certain such grids ! * to be displayed using special colors (if they are normally "white"). ! * If the grid is "see-able" by the player, we will use the normal "white" ! * else if the player is "blind", we will use "dark gray", else if the ! * "view_bright_lite" option is set, we will use "slate" (gray), else we ! * will use the normal "white". ! * ! * Note that "wall" grids are more complicated than "boring" grids, due to ! * the fact that "CAVE_GLOW" for a "wall" grid means that the grid *might* ! * be glowing, depending on where the player is standing in relation to the ! * wall. In particular, the wall of an illuminated room should look just ! * like any other (dark) wall unless the player is actually inside the room. ! * ! * Thus, we do not support as many visual special effects for "wall" grids ! * as we do for "boring" grids, since many of them would give the player ! * information about the "CAVE_GLOW" flag of the wall grid, in particular, ! * it would allow the player to notice the walls of illuminated rooms from ! * a dark hallway that happened to run beside the room. * * ! * Some comments on the "object" layer... ! * ! * Currently, we do nothing with multi-hued objects, because there are ! * not any. If there were, they would have to set "shimmer_objects" ! * when they were created, and then new "shimmer" code in "dungeon.c" ! * would have to be created handle the "shimmer" effect, and the code ! * in "cave.c" would have to be updated to create the shimmer effect. ! * This did not seem worth the effort. XXX XXX * * ! * Some comments on the "monster"/"player" layer... ! * ! * Note that monsters can have some "special" flags, including "ATTR_MULTI", ! * which means their color changes, and "ATTR_CLEAR", which means they take ! * the color of whatever is under them, and "CHAR_CLEAR", which means that ! * they take the symbol of whatever is under them. Technically, the flag ! * "CHAR_MULTI" is supposed to indicate that a monster looks strange when ! * examined, but this flag is currently ignored. All of these flags are ! * ignored if the "avoid_other" option is set, since checking for these ! * conditions is expensive (and annoying) on some systems. ! * ! * Normally, players could be handled just like monsters, except that the ! * concept of the "torch lite" of others player would add complications. ! * For efficiency, however, we handle the (only) player first, since the ! * "player" symbol always "pre-empts" any other facts about the grid. ! * ! * The "hidden_player" efficiency option, which only makes sense with a ! * single player, allows the player symbol to be hidden while running. */ void map_info(int y, int x, byte *ap, char *cp) { + byte a; + char c; + + byte feat; + byte info; + feature_type *f_ptr; s16b this_o_idx, next_o_idx = 0; ! s16b m_idx; ! bool image = p_ptr->image; ! ! ! /* Monster/Player */ ! m_idx = cave_m_idx[y][x]; ! ! #ifdef MAP_INFO_MULTIPLE_PLAYERS ! ! /* Handle "player" grids below */ ! ! #else /* MAP_INFO_MULTIPLE_PLAYERS */ ! ! /* Handle "player" */ ! if ((m_idx < 0) && !(p_ptr->running && hidden_player)) ! { ! monster_race *r_ptr = &r_info[0]; ! ! /* Get the "player" attr */ ! a = r_ptr->x_attr; ! ! /* Get the "player" char */ ! c = r_ptr->x_char; + /* Result */ + (*ap) = a; + (*cp) = c; ! /* Done */ ! return; ! } ! ! #endif /* MAP_INFO_MULTIPLE_PLAYERS */ ! ! ! /* Feature */ feat = cave_feat[y][x]; ! /* Cave flags */ ! info = cave_info[y][x]; ! ! /* Hack -- rare random hallucination on non-outer walls */ ! if (image && (!rand_int(256)) && (feat < FEAT_PERM_SOLID)) ! { ! int i = image_random(); ! a = PICT_A(i); ! c = PICT_C(i); ! } ! ! /* Boring grids (floors, etc) */ ! else if (feat <= FEAT_INVIS) { ! /* Memorized (or seen) floor */ ! if ((info & (CAVE_MARK)) || ! (info & (CAVE_SEEN))) { /* Access floor */ f_ptr = &f_info[FEAT_FLOOR]; /* Normal char */ ! c = f_ptr->x_char; /* Normal attr */ ! a = f_ptr->x_attr; /* Special lighting effects */ if (view_special_lite && (a == TERM_WHITE)) { ! /* Handle "seen" grids */ ! if (info & (CAVE_SEEN)) { ! /* Only lit by "torch" lite */ ! if (view_yellow_lite && !(info & (CAVE_GLOW))) { /* Use "yellow" */ a = TERM_YELLOW; } } + /* Handle "blind" */ + else if (p_ptr->blind) + { + /* Use "dark gray" */ + a = TERM_L_DARK; + } + /* Handle "dark" grids */ ! else if (!(info & (CAVE_GLOW))) { /* Use "dark gray" */ a = TERM_L_DARK; } ! /* Handle "view_bright_lite" */ ! else if (view_bright_lite) { ! /* Use "gray" */ ! a = TERM_SLATE; } } } /* Unknown */ *************** *** 708,725 **** f_ptr = &f_info[FEAT_NONE]; /* Normal attr */ ! (*ap) = f_ptr->z_attr; /* Normal char */ ! (*cp) = f_ptr->z_char; } } ! /* Non floors */ else { /* Memorized grids */ ! if (cave_info[y][x] & (CAVE_MARK)) { /* Apply "mimic" field */ feat = f_info[feat].mimic; --- 696,713 ---- f_ptr = &f_info[FEAT_NONE]; /* Normal attr */ ! a = f_ptr->x_attr; /* Normal char */ ! c = f_ptr->x_char; } } ! /* Interesting grids (non-floors) */ else { /* Memorized grids */ ! if (info & (CAVE_MARK)) { /* Apply "mimic" field */ feat = f_info[feat].mimic; *************** *** 728,798 **** f_ptr = &f_info[feat]; /* Normal char */ ! (*cp) = f_ptr->z_char; /* Normal attr */ ! a = f_ptr->z_attr; ! /* Special lighting effects */ ! if (view_granite_lite && (a == TERM_WHITE) && (feat >= FEAT_SECRET)) { ! /* Handle "blind" */ ! if (p_ptr->blind) { ! /* Use "dark gray" */ ! a = TERM_L_DARK; } ! /* Handle "torch-lit" grids */ ! else if (cave_info[y][x] & (CAVE_LITE)) { ! /* Torch lite */ ! if (view_yellow_lite) ! { ! /* Use "yellow" */ ! a = TERM_YELLOW; ! } } /* Handle "view_bright_lite" */ else if (view_bright_lite) { ! /* Not viewable */ ! if (!(cave_info[y][x] & (CAVE_VIEW))) ! { ! /* Use "gray" */ ! a = TERM_SLATE; ! } ! ! /* Not glowing */ ! else if (!(cave_info[y][x] & (CAVE_GLOW))) ! { ! /* Use "gray" */ ! a = TERM_SLATE; ! } ! ! /* Not glowing correctly */ ! else ! { ! int py = p_ptr->py; ! int px = p_ptr->px; ! ! /* Hack -- move towards player */ ! int yy = (y < py) ? (y + 1) : (y > py) ? (y - 1) : y; ! int xx = (x < px) ? (x + 1) : (x > px) ? (x - 1) : x; ! ! /* Check for "local" illumination */ ! if (!(cave_info[yy][xx] & (CAVE_GLOW))) ! { ! /* Use "gray" */ ! a = TERM_SLATE; ! } ! } } } - - /* The attr */ - (*ap) = a; } /* Unknown */ --- 716,750 ---- f_ptr = &f_info[feat]; /* Normal char */ ! c = f_ptr->x_char; /* Normal attr */ ! a = f_ptr->x_attr; ! /* Special lighting effects (walls only) */ ! if (view_granite_lite && (a == TERM_WHITE) && ! (feat >= FEAT_SECRET)) { ! /* Handle "seen" grids */ ! if (info & (CAVE_SEEN)) { ! /* Use "white" */ } ! /* Handle "blind" */ ! else if (p_ptr->blind) { ! /* Use "dark gray" */ ! a = TERM_L_DARK; } /* Handle "view_bright_lite" */ else if (view_bright_lite) { ! /* Use "gray" */ ! a = TERM_SLATE; } } } /* Unknown */ *************** *** 802,821 **** f_ptr = &f_info[FEAT_NONE]; /* Normal attr */ ! (*ap) = f_ptr->z_attr; /* Normal char */ ! (*cp) = f_ptr->z_char; } } - /* Hack -- rare random hallucination, except on outer dungeon walls */ - if (p_ptr->image && (!rand_int(256)) && (cave_feat[y][x] < FEAT_PERM_SOLID)) - { - /* Hallucinate */ - image_random(ap, cp); - } - /* Objects */ for (this_o_idx = cave_o_idx[y][x]; this_o_idx; this_o_idx = next_o_idx) --- 754,766 ---- f_ptr = &f_info[FEAT_NONE]; /* Normal attr */ ! a = f_ptr->x_attr; /* Normal char */ ! c = f_ptr->x_char; } } /* Objects */ for (this_o_idx = cave_o_idx[y][x]; this_o_idx; this_o_idx = next_o_idx) *************** *** 831,844 **** /* Memorized objects */ if (o_ptr->marked) { ! /* Normal char */ ! (*cp) = object_char(o_ptr); ! /* Normal attr */ ! (*ap) = object_attr(o_ptr); ! /* Hack -- hallucination */ ! if (p_ptr->image) image_object(ap, cp); /* Done */ break; --- 776,798 ---- /* Memorized objects */ if (o_ptr->marked) { ! /* Hack -- object hallucination */ ! if (image) ! { ! int i = image_object(); ! a = PICT_A(i); ! c = PICT_C(i); ! } ! /* Normal */ ! else ! { ! /* Normal char */ ! c = object_char(o_ptr); ! /* Normal attr */ ! a = object_attr(o_ptr); ! } /* Done */ break; *************** *** 846,962 **** } ! /* Handle monsters */ ! if (cave_m_idx[y][x] > 0) { ! monster_type *m_ptr = &m_list[cave_m_idx[y][x]]; /* Visible monster */ if (m_ptr->ml) { monster_race *r_ptr = &r_info[m_ptr->r_idx]; /* Desired attr */ ! a = r_ptr->x_attr; /* Desired char */ ! c = r_ptr->x_char; /* Ignore weird codes */ ! if (avoid_other) { /* Use char */ ! (*cp) = c; /* Use attr */ ! (*ap) = a; } /* Special attr/char codes */ ! else if ((a & 0x80) && (c & 0x80)) { /* Use char */ ! (*cp) = c; /* Use attr */ ! (*ap) = a; } /* Multi-hued monster */ else if (r_ptr->flags1 & (RF1_ATTR_MULTI)) { /* Normal char */ ! (*cp) = c; /* Multi-hued attr */ ! (*ap) = randint(15); } /* Normal monster (not "clear" in any way) */ else if (!(r_ptr->flags1 & (RF1_ATTR_CLEAR | RF1_CHAR_CLEAR))) { /* Use char */ ! (*cp) = c; /* Use attr */ ! (*ap) = a; } /* Hack -- Bizarre grid under monster */ ! else if ((*ap & 0x80) || (*cp & 0x80)) { /* Use char */ ! (*cp) = c; /* Use attr */ ! (*ap) = a; } ! /* Normal */ ! else { ! /* Normal (non-clear char) monster */ ! if (!(r_ptr->flags1 & (RF1_CHAR_CLEAR))) ! { ! /* Normal char */ ! (*cp) = c; ! } ! ! /* Normal (non-clear attr) monster */ ! else if (!(r_ptr->flags1 & (RF1_ATTR_CLEAR))) ! { ! /* Normal attr */ ! (*ap) = a; ! } } ! /* Hack -- hallucination */ ! if (p_ptr->image) { ! /* Hallucinatory monster */ ! image_monster(ap, cp); } } } ! /* Handle "player" */ ! if (cave_m_idx[y][x] < 0) { monster_race *r_ptr = &r_info[0]; /* Get the "player" attr */ ! (*ap) = r_ptr->x_attr; /* Get the "player" char */ ! (*cp) = r_ptr->x_char; } } /* ! * Move the cursor to a given map location */ void move_cursor_relative(int y, int x) { --- 800,926 ---- } ! /* Monsters */ ! if (m_idx > 0) { ! monster_type *m_ptr = &m_list[m_idx]; /* Visible monster */ if (m_ptr->ml) { monster_race *r_ptr = &r_info[m_ptr->r_idx]; + byte da; + char dc; + /* Desired attr */ ! da = r_ptr->x_attr; /* Desired char */ ! dc = r_ptr->x_char; ! ! /* Hack -- monster hallucination */ ! if (image) ! { ! int i = image_monster(); ! a = PICT_A(i); ! c = PICT_C(i); ! } /* Ignore weird codes */ ! else if (avoid_other) { /* Use char */ ! c = dc; /* Use attr */ ! a = da; } /* Special attr/char codes */ ! else if ((da & 0x80) && (dc & 0x80)) { /* Use char */ ! c = dc; /* Use attr */ ! a = da; } /* Multi-hued monster */ else if (r_ptr->flags1 & (RF1_ATTR_MULTI)) { /* Normal char */ ! c = dc; /* Multi-hued attr */ ! a = randint(15); } /* Normal monster (not "clear" in any way) */ else if (!(r_ptr->flags1 & (RF1_ATTR_CLEAR | RF1_CHAR_CLEAR))) { /* Use char */ ! c = dc; /* Use attr */ ! a = da; } /* Hack -- Bizarre grid under monster */ ! else if ((a & 0x80) || (c & 0x80)) { /* Use char */ ! c = dc; /* Use attr */ ! a = da; } ! /* Normal char, Clear attr, monster */ ! else if (!(r_ptr->flags1 & (RF1_CHAR_CLEAR))) { ! /* Normal char */ ! c = dc; } ! /* Normal attr, Clear char, monster */ ! else if (!(r_ptr->flags1 & (RF1_ATTR_CLEAR))) { ! /* Normal attr */ ! a = da; } } } + #ifdef MAP_INFO_MULTIPLE_PLAYERS ! /* Players */ ! else if (m_idx < 0) { monster_race *r_ptr = &r_info[0]; /* Get the "player" attr */ ! a = r_ptr->x_attr; /* Get the "player" char */ ! c = r_ptr->x_char; } + + #endif + + + /* Result */ + (*ap) = a; + (*cp) = c; } /* ! * Move the cursor to a given map location. ! * ! * The main screen will always be at least 24x80 in size. */ void move_cursor_relative(int y, int x) { *************** *** 978,992 **** /* Location in window */ vy = ky + ROW_MAP; - /* Verify location */ - if (vy >= (unsigned)(Term->hgt)) return; - /* Location in window */ vx = kx + COL_MAP; - /* Verify location */ - if (vx >= (unsigned)(Term->wid)) return; - /* Go there */ Term_gotoxy(vx, vy); } --- 942,950 ---- *************** *** 999,1004 **** --- 957,964 ---- * Note the inline use of "panel_contains()" for efficiency. * * Note the use of "Term_queue_char()" for efficiency. + * + * The main screen will always be at least 24x80 in size. */ void print_rel(char c, byte a, int y, int x) { *************** *** 1020,1034 **** /* Location in window */ vy = ky + ROW_MAP; - /* Verify location */ - if (vy >= (unsigned)(Term->hgt)) return; - /* Location in window */ vx = kx + COL_MAP; - /* Verify location */ - if (vx >= (unsigned)(Term->wid)) return; - /* Hack -- Queue it */ Term_queue_char(vx, vy, a, c); } --- 980,988 ---- *************** *** 1041,1098 **** * * This function should only be called on "legal" grids. * ! * This function will memorize the object and/or feature in the given ! * grid, if they are (1) viewable and (2) interesting. Note that all ! * objects are interesting, all terrain features except floors (and ! * invisible traps) are interesting, and floors (and invisible traps) ! * are interesting sometimes (depending on various options involving ! * the illumination of floor grids). ! * ! * The automatic memorization of all objects and non-floor terrain ! * features as soon as they are displayed allows incredible amounts ! * of optimization in various places, especially "map_info()". ! * ! * Note that the memorization of objects is completely separate from ! * the memorization of terrain features, preventing annoying floor ! * memorization when a detected object is picked up from a dark floor, ! * and object memorization when an object is dropped into a floor grid ! * which is memorized but out-of-sight. ! * ! * This function should be called every time the "memorization" of ! * a grid (or the object in a grid) is called into question, such ! * as when an object is created in a grid, when a terrain feature ! * "changes" from "floor" to "non-floor", when any grid becomes ! * "illuminated" or "viewable", and when a "floor" grid becomes ! * "torch-lit". ! * ! * Note the relatively efficient use of this function by the various ! * "update_view()" and "update_lite()" calls, to allow objects and ! * terrain features to be memorized (and drawn) whenever they become ! * viewable or illuminated in any way, but not when they "maintain" ! * or "lose" their previous viewability or illumination. ! * ! * Note the butchered "inline" version of "player_can_see_bold()", ! * optimized primarily for the most common cases, that is, for the ! * non-marked floor grids. See "player_can_see_bold()" for some ! * warnings about possible problems with this technique. */ void note_spot(int y, int x) { ! s16b this_o_idx, next_o_idx = 0; - /* Blind players see nothing */ - if (p_ptr->blind) return; ! /* Analyze non-torch-lit grids */ ! if (!(cave_info[y][x] & (CAVE_LITE))) ! { ! /* Require line of sight to the grid */ ! if (!(cave_info[y][x] & (CAVE_VIEW))) return; ! /* Require "perma-lite" of the grid */ ! if (!(cave_info[y][x] & (CAVE_GLOW))) return; ! } /* Hack -- memorize objects */ --- 995,1036 ---- * * This function should only be called on "legal" grids. * ! * This function will memorize the object and/or feature in the given grid, ! * if they are (1) see-able and (2) interesting. Note that all objects are ! * interesting, all terrain features except floors (and invisible traps) are ! * interesting, and floors (and invisible traps) are interesting sometimes ! * (depending on various options involving the illumination of floor grids). ! * ! * The automatic memorization of all objects and non-floor terrain features ! * as soon as they are displayed allows incredible amounts of optimization ! * in various places, especially "map_info()" and this function itself. ! * ! * Note that the memorization of objects is completely separate from the ! * memorization of terrain features, preventing annoying floor memorization ! * when a detected object is picked up from a dark floor, and object ! * memorization when an object is dropped into a floor grid which is ! * memorized but out-of-sight. ! * ! * This function should be called every time the "memorization" of a grid ! * (or the object in a grid) is called into question, such as when an object ! * is created in a grid, when a terrain feature "changes" from "floor" to ! * "non-floor", and when any grid becomes "see-able" for any reason. ! * ! * This function is called primarily from the "update_view()" function, for ! * each grid which becomes newly "see-able". */ void note_spot(int y, int x) { ! byte info; + s16b this_o_idx, next_o_idx = 0; ! /* Get cave info */ ! info = cave_info[y][x]; ! /* Require "seen" flag */ ! if (!(info & (CAVE_SEEN))) return; /* Hack -- memorize objects */ *************** *** 1109,1165 **** /* Hack -- memorize grids */ ! if (!(cave_info[y][x] & (CAVE_MARK))) { ! /* Handle floor grids first */ if (cave_feat[y][x] <= FEAT_INVIS) { ! /* Option -- memorize all torch-lit floors */ ! if (view_torch_grids && (cave_info[y][x] & (CAVE_LITE))) ! { ! /* Memorize */ ! cave_info[y][x] |= (CAVE_MARK); ! } ! ! /* Option -- memorize all perma-lit floors */ ! else if (view_perma_grids && (cave_info[y][x] & (CAVE_GLOW))) { /* Memorize */ cave_info[y][x] |= (CAVE_MARK); } } ! /* Memorize normal grids */ ! else if (cave_floor_bold(y, x)) ! { ! /* Memorize */ ! cave_info[y][x] |= (CAVE_MARK); ! } ! ! /* Memorize torch-lit walls */ ! else if (cave_info[y][x] & (CAVE_LITE)) { /* Memorize */ cave_info[y][x] |= (CAVE_MARK); } - - /* Memorize certain non-torch-lit wall grids */ - else - { - int py = p_ptr->py; - int px = p_ptr->px; - - /* Hack -- move towards player */ - int yy = (y < py) ? (y + 1) : (y > py) ? (y - 1) : y; - int xx = (x < px) ? (x + 1) : (x > px) ? (x - 1) : x; - - /* Check for "local" illumination */ - if (cave_info[yy][xx] & (CAVE_GLOW)) - { - /* Memorize */ - cave_info[y][x] |= (CAVE_MARK); - } - } } } --- 1047,1072 ---- /* Hack -- memorize grids */ ! if (!(info & (CAVE_MARK))) { ! /* Memorize some "boring" grids */ if (cave_feat[y][x] <= FEAT_INVIS) { ! /* Option -- memorize certain floors */ ! if (((info & (CAVE_GLOW)) && view_perma_grids) || ! view_torch_grids) { /* Memorize */ cave_info[y][x] |= (CAVE_MARK); } } ! /* Memorize all "interesting" grids */ ! else { /* Memorize */ cave_info[y][x] |= (CAVE_MARK); } } } *************** *** 1167,1175 **** /* * Redraw (on the screen) a given map location * ! * Note the inline use of "panel_contains()" for efficiency. * ! * Note the use of "Term_queue_char()" for efficiency. */ void lite_spot(int y, int x) { --- 1074,1084 ---- /* * Redraw (on the screen) a given map location * ! * This function should only be called on "legal" grids. * ! * Note the inline use of "print_rel()" for efficiency. ! * ! * The main screen will always be at least 24x80 in size. */ void lite_spot(int y, int x) { *************** *** 1194,1209 **** /* Location in window */ vy = ky + ROW_MAP; - /* Verify location */ - if (vy >= (unsigned)(Term->hgt)) return; - /* Location in window */ vx = kx + COL_MAP; ! /* Verify location */ ! if (vx >= (unsigned)(Term->wid)) return; ! ! /* Examine the grid */ map_info(y, x, &a, &c); /* Hack -- Queue it */ --- 1103,1112 ---- /* Location in window */ vy = ky + ROW_MAP; /* Location in window */ vx = kx + COL_MAP; ! /* Hack -- redraw the grid */ map_info(y, x, &a, &c); /* Hack -- Queue it */ *************** *** 1212,1224 **** - /* ! * Prints the map of the dungeon * ! * Note that, for efficiency, we contain an "optimized" version ! * of both "lite_spot()" and "print_rel()", and that we use the ! * "lite_spot()" function to display the player grid, if needed. */ void prt_map(void) { --- 1115,1126 ---- /* ! * Redraw (on the screen) the current map panel * ! * Note the inline use of "lite_spot()" for efficiency. ! * ! * The main screen will always be at least 24x80 in size. */ void prt_map(void) { *************** *** 1233,1242 **** ty = ROW_MAP + SCREEN_HGT; tx = COL_MAP + SCREEN_WID; - /* Take account of reduced windows */ - if (ty > Term->hgt) ty = Term->hgt; - if (tx > Term->wid) tx = Term->wid; - /* Dump the map */ for (y = p_ptr->wy, vy = ROW_MAP; vy < ty; vy++, y++) { --- 1135,1140 ---- *************** *** 1336,1342 **** f_ptr = &f_info[p0]; /* Check character and attribute, accept matches */ ! if ((f_ptr->z_char == c) && (f_ptr->z_attr == a)) return (p1); } /* Default */ --- 1234,1240 ---- f_ptr = &f_info[p0]; /* Check character and attribute, accept matches */ ! if ((f_ptr->x_char == c) && (f_ptr->x_attr == a)) return (p1); } /* Default */ *************** *** 1473,1491 **** /* ! * Display a "small-scale" map of the dungeon for the player * ! * Currently, the "player" is displayed on the map. XXX XXX XXX */ void do_cmd_view_map(void) { int cy, cx; ! /* Enter "icky" mode */ ! character_icky = TRUE; ! ! /* Save the screen */ ! Term_save(); /* Note */ prt("Please wait...", 0, 0); --- 1371,1386 ---- /* ! * Display a "small-scale" map of the dungeon. * ! * Note that the "player" is always displayed on the map. */ void do_cmd_view_map(void) { int cy, cx; ! /* Save screen */ ! screen_save(); /* Note */ prt("Please wait...", 0, 0); *************** *** 1506,2706 **** move_cursor(cy, cx); /* Get any key */ ! inkey(); ! ! /* Restore the screen */ ! Term_load(); ! /* Leave "icky" mode */ ! character_icky = FALSE; } - - /* ! * Some comments on the cave grid flags. ! * ! * ! * One of the major bottlenecks in ancient versions of Angband was in ! * the calculation of "line of sight" from the player to various grids, ! * such as monsters, using the relatively expensive "los()" function. ! * This was such a nasty bottleneck that a lot of silly things were done ! * to reduce the dependancy on "line of sight", for example, you could ! * not "see" any grids in a lit room until you actually entered the room, ! * at which point every grid in the room became "illuminated", and there ! * were all kinds of bizarre grid flags to support this behavior. There ! * were other somewhat related bottlenecks involved in the determination ! * of which grids were illuminated by the player's light source. ! * ! * These bottlenecks led to the developement of special new functions to * optimize issues involved with "line of sight" and "torch lit grids". * ! * The "update_view()" function, below, is used to pre-calculate the ! * entire "field of view" for the player, which, once calculated, can ! * be used to provide an extremely fast method for determining if a grid ! * is in "line of sight" of the player. It sets the "CAVE_VIEW" flag ! * on every cave grid in the player's field of view, and maintains an ! * array of all such grids in the global "view_n" array. See also the ! * "player_has_los_bold()" function. ! * ! * The "update_lite()" function, below, is used to pre-calculate the ! * entire "set of torch lit grids", which, once calculated, can be used ! * by the "player_can_see_bold()" function to provide an extremely fast ! * method for determining if a particular grid is illuminated. It sets ! * the "CAVE_LITE" flag on every cave grid lit by the player's torch, and ! * and maintains an array of all such grids in the global "lite_n" array. ! * See also the "player_has_los_bold()" function. ! * ! * The special arrays maintained by the "update_view()" and "update_lite()" ! * functions can be used not only to quickly scan through all the grids in ! * the dungeon with one of the two related cave grid flags set, but also, ! * in conjunction with another special temporary array, and the "CAVE_TEMP" ! * cave grid flag, are used to redraw any grid which enters or leaves the ! * player's field of view or torch lit range. This allows the use of some ! * interesting "special lighting effects" (see elsewhere). ! * ! * The "CAVE_TEMP" flag, and the array of "CAVE_TEMP" grids, is also used ! * for various other purposes, all temporary, such as spreading lite or ! * darkness during "lite_room()" / "unlite_room()", and for calculating ! * monster flow. This flag is always cleared when we are done. * ! * The current "update_view()" algorithm uses the "CAVE_XTRA" flag as a * temporary internal flag to mark those grids which are not only in view, * but which are also "easily" in line of sight of the player. This flag ! * is always cleared when we are done. * ! * For various subtle reasons described in the "player_can_see_bold()" ! * function, any perma-lit wall grids which "remain" in the field of view ! * must be redrawn each time the field of view is recalculated, as if they ! * are just entering the field of view. ! * ! * For efficiency, the "update_lite()" function uses the results of the ! * "update_view()" function, so "update_view()" must be called before ! * "update_lite()". ! * ! * For efficiency, the "update_lite()" function is optimized for the ! * standard cases of a torch lite radius less than or equal to three. ! * ! * For efficiency, the "update_view()" function is only called when the ! * player moves, and when a wall grid becomes a floor grid, or vice versa, ! * while in the player's field of view. ! * ! * For efficiency, the "update_lite()" function is only called when the ! * player moves, when a wall grid becomes a floor grid, or vice versa, ! * while in the player's field of view, or when the player's torch lite ! * radius changes. ! * ! * Note that when the player is resting, or performing most repeated ! * actions, such as digging, there is no need to call either of these ! * two functions. This means that the game is extremely fast unless ! * the player is running through the dungeon. ! * ! * I wouldn't be surprised if slight modifications to the "update_view()" ! * function would allow us to determine "reverse line-of-sight" as well ! * as "normal line-of-sight", which would allow monsters to use a more ! * "correct" calculation to determine if they can "see" the player. For ! * now, monsters simply "cheat" somewhat and assume that if the player ! * has "line of sight" to the monster, then the monster can "pretend" ! * that it has "line of sight" to the player. ! * ! * ! * Any grid can be marked as "CAVE_GLOW" which means that the grid itself is ! * in some way permanently lit. However, for the player to "see" anything ! * in the grid, as determined by "player_can_see_bold()", the player must not ! * be blind, the grid must be marked as "CAVE_VIEW", and, in addition, "wall" ! * grids, even if marked as "perma lit", are only illuminated if they touch ! * a grid which is not a wall and is marked both "CAVE_GLOW" and "CAVE_VIEW", ! * and that grid must be closer to the player than the wall grid. Note that ! * this last condition can cause problems, see "player_can_see_bold()". ! * ! * To simplify various things, a grid may be marked as "CAVE_MARK", meaning ! * that even if the player cannot "see" the grid, he "knows" the terrain in ! * that grid. This is used to "remember" walls/doors/stairs/floors when they ! * are "seen" or "detected", and also to "memorize" floors, after "wiz_lite()", ! * or when one of the "memorize floor grids" options induces memorization. * ! * Objects are "memorized" in a different way, using a special "marked" flag ! * on the object itself, which is set when an object is observed or detected. * ! * A grid may be marked as "CAVE_ROOM" which means that it is part of a "room", ! * and should be illuminated by "lite room" and "darkness" spells. * - * A grid may be marked as "CAVE_ICKY" which means it is part of a "vault", - * and should be unavailable for "teleportation" destinations. * * ! * The "view_perma_grids" allows the player to "memorize" every perma-lit grid ! * which is observed, and the "view_torch_grids" allows the player to memorize ! * every torch-lit grid. The player will always memorize important walls, ! * doors, stairs, and other terrain features, as well as any "detected" grids. * - * Note that the new "update_view()" method allows, among other things, a room - * to be "partially" seen as the player approaches it, with a growing cone of - * floor appearing as the player gets closer to the door. Also, by not turning - * on the "memorize perma-lit grids" option, the player will only "see" those - * floor grids which are actually in line of sight. * ! * And my favorite "plus" is that you can now use a special option to draw the ! * "floors" in the "viewable region" brightly (actually, to draw the *other* ! * grids dimly), providing a "pretty" effect as the player runs around, and ! * to efficiently display the "torch lite" in a special color. ! */ ! ! ! ! ! ! /* ! * Some comments on the "update_lite()" function... * ! * The "update_lite()" function uses the results of "update_view()". * - * Note that "blindness" does NOT affect "torch lite". But it does affect - * the importance of torch lite. See "player_can_see_bold()" for more info. * ! * We optimize most lites (all non-artifact lites) by using "obvious" ! * facts about the results of "small" lite radius, and we attempt to ! * list the "nearby" grids before the more "distant" ones in the ! * array of torch-lit grids. * ! * We will correctly handle "large" radius lites, though currently, ! * it is impossible for the player to have more than radius 3 lite. * ! * We assume that "radius zero" lite is in fact no lite at all. * ! * Torch Lantern Artifacts ! * (etc) ! * *** ! * *** ***** ! * *** ***** ******* ! * *@* **@** ***@*** ! * *** ***** ******* ! * *** ***** ! * *** */ /* ! * Forget the "CAVE_LITE" grids, redrawing as needed. */ ! void forget_lite(void) ! { ! int i, x, y; - /* None to forget */ - if (!lite_n) return; ! /* Clear them all */ ! for (i = 0; i < lite_n; i++) ! { ! y = lite_y[i]; ! x = lite_x[i]; ! ! /* Forget "LITE" flag */ ! cave_info[y][x] &= ~(CAVE_LITE); - /* Redraw */ - lite_spot(y, x); - } ! /* None left */ ! lite_n = 0; ! } /* ! * Simplify the "update_lite()" function XXX XXX XXX ! * ! * This macro allows us to efficiently add a grid to the "lite" array, ! * note that we are never called for illegal grids, or for grids which ! * have already been placed into the "lite" array, and we are never ! * called when the "lite" array is full. */ ! #define cave_lite_hack(Y,X) \ ! do { \ ! cave_info[Y][X] |= (CAVE_LITE); \ ! lite_y[lite_n] = (Y); \ ! lite_x[lite_n] = (X); \ ! lite_n++; \ ! } while (0) /* ! * Update the "CAVE_LITE" grids, redrawing as needed. */ ! void update_lite(void) { ! int py = p_ptr->py; ! int px = p_ptr->px; ! int r = p_ptr->cur_lite; ! int i, y, x; - /*** Special case ***/ - /* Hack -- Player has no lite */ - if (r <= 0) - { - /* Forget the old lite */ - forget_lite(); ! /* Draw the player */ ! lite_spot(py, px); - /* All done */ - return; - } - /*** Save the old "lite" grids for later ***/ ! /* Clear them all */ ! for (i = 0; i < lite_n; i++) ! { ! y = lite_y[i]; ! x = lite_x[i]; ! /* Mark the grid as not "lite" */ ! cave_info[y][x] &= ~(CAVE_LITE); ! /* Mark the grid as "seen" */ ! cave_info[y][x] |= (CAVE_TEMP); ! /* Add it to the "seen" set */ ! temp_y[temp_n] = y; ! temp_x[temp_n] = x; ! temp_n++; ! } - /* None left */ - lite_n = 0; ! /*** Collect the new "lite" grids ***/ ! /* Player grid */ ! cave_lite_hack(py, px); - /* Radius 1 -- torch radius */ - if (r >= 1) - { - /* Adjacent grid */ - cave_lite_hack(py+1, px); - cave_lite_hack(py-1, px); - cave_lite_hack(py, px+1); - cave_lite_hack(py, px-1); ! /* Diagonal grids */ ! cave_lite_hack(py+1, px+1); ! cave_lite_hack(py+1, px-1); ! cave_lite_hack(py-1, px+1); ! cave_lite_hack(py-1, px-1); ! } ! /* Radius 2 -- lantern radius */ ! if (r >= 2) ! { ! /* South of the player */ ! if (cave_floor_bold(py+1, px)) ! { ! cave_lite_hack(py+2, px); ! cave_lite_hack(py+2, px+1); ! cave_lite_hack(py+2, px-1); ! } ! /* North of the player */ ! if (cave_floor_bold(py-1, px)) ! { ! cave_lite_hack(py-2, px); ! cave_lite_hack(py-2, px+1); ! cave_lite_hack(py-2, px-1); ! } ! /* East of the player */ ! if (cave_floor_bold(py, px+1)) { ! cave_lite_hack(py, px+2); ! cave_lite_hack(py+1, px+2); ! cave_lite_hack(py-1, px+2); } ! /* West of the player */ ! if (cave_floor_bold(py, px-1)) { ! cave_lite_hack(py, px-2); ! cave_lite_hack(py+1, px-2); ! cave_lite_hack(py-1, px-2); } } ! /* Radius 3+ -- artifact radius */ ! if (r >= 3) ! { ! int y1, y2, x1, x2; - /* Paranoia */ - if (r > 5) r = 5; - /* South-East of the player */ - if (cave_floor_bold(py+1, px+1)) - { - cave_lite_hack(py+2, px+2); - } ! /* South-West of the player */ ! if (cave_floor_bold(py+1, px-1)) ! { ! cave_lite_hack(py+2, px-2); ! } ! /* North-East of the player */ ! if (cave_floor_bold(py-1, px+1)) ! { ! cave_lite_hack(py-2, px+2); ! } ! /* North-West of the player */ ! if (cave_floor_bold(py-1, px-1)) ! { ! cave_lite_hack(py-2, px-2); ! } ! /* Maximal north */ ! y1 = py - r; ! if (y1 < 0) y1 = 0; ! /* Maximal south */ ! y2 = py + r; ! if (y2 > DUNGEON_HGT-1) y2 = DUNGEON_HGT-1; - /* Maximal west */ - x1 = px - r; - if (x1 < 0) x1 = 0; ! /* Maximal east */ ! x2 = px + r; ! if (x2 > DUNGEON_WID-1) x2 = DUNGEON_WID-1; ! /* Scan the maximal box */ ! for (y = y1; y <= y2; y++) { ! for (x = x1; x <= x2; x++) ! { ! int d; ! int dy = (py > y) ? (py - y) : (y - py); ! int dx = (px > x) ? (px - x) : (x - px); ! /* Skip the "central" grids (above) */ ! if ((dy <= 2) && (dx <= 2)) continue; ! /* Hack -- approximate the distance */ ! d = (dy > dx) ? (dy + (dx>>1)) : (dx + (dy>>1)); ! /* Skip distant grids */ ! if (d > r) continue; ! /* Viewable grids get "torch lit" */ ! if (cave_info[y][x] & (CAVE_VIEW)) ! { ! /* This grid is "torch lit" */ ! cave_lite_hack(y, x); ! } ! } ! } ! } ! /*** Complete the algorithm ***/ ! /* Process "new" grids */ ! for (i = 0; i < lite_n; i++) ! { ! y = lite_y[i]; ! x = lite_x[i]; ! /* Update/Redraw "new" grids */ ! if (!(cave_info[y][x] & (CAVE_TEMP))) ! { ! /* Note */ ! note_spot(y, x); ! /* Redraw */ ! lite_spot(y, x); } } - /* Process "old" grids */ - for (i = 0; i < temp_n; i++) - { - y = temp_y[i]; - x = temp_x[i]; ! /* No longer in the array */ ! cave_info[y][x] &= ~(CAVE_TEMP); ! /* Redraw "old" grids */ ! if (!(cave_info[y][x] & (CAVE_LITE))) ! { ! /* Redraw */ ! lite_spot(y, x); ! } } - /* None left */ - temp_n = 0; - } ! /* ! * Some comments on the "update_view()" algorithm... ! * ! * Algorithm summary: ! * ! * 1: Process the player ! * 1a: The player is always (easily) viewable ! * 2: Process the diagonals ! * 2a: The diagonals are (easily) viewable up to the first wall ! * 2b: But never go more than 2/3 of the "full" distance ! * 3: Process the main axes ! * 3a: The main axes are (easily) viewable up to the first wall ! * 3b: But never go more than the "full" distance ! * 4: Process sequential "strips" in each of the eight octants ! * 4a: Each strip runs along the previous strip ! * 4b: The main axes are "previous" to the first strip ! * 4c: Process both "sides" of each "direction" of each strip ! * 4c1: Each side aborts as soon as possible ! * 4c2: Each side tells the next strip how far it has to check ! * ! * Note that the octant processing involves some pretty interesting ! * observations involving when a grid might possibly be viewable from ! * a given grid, and on the order in which the strips are processed. ! * ! * Note the use of the mathematical facts shown below, which derive ! * from the fact that (1 < sqrt(2) < 1.5), and that the length of the ! * hypotenuse of a right triangle is primarily determined by the length ! * of the longest side, when one side is small, and is strictly less ! * than one-and-a-half times as long as the longest side when both of ! * the sides are large. ! * ! * if (manhatten(dy,dx) < R) then (hypot(dy,dx) < R) ! * if (manhatten(dy,dx) > R*3/2) then (hypot(dy,dx) > R) ! * ! * hypot(dy,dx) is approximated by (dx+dy+MAX(dx,dy)) / 2 ! * ! * These observations are important because the calculation of the actual ! * value of "hypot(dx,dy)" is extremely expensive, involving square roots, ! * while for small values (up to about 20 or so), the approximations above ! * are correct to within an error of at most one grid or so. ! * ! * Observe the use of "full" and "over" in the code below, and the use of ! * the specialized calculation involving "limit", all of which derive from ! * the observations given above. Basically, we note that the "circle" of ! * view is completely contained in an "octagon" whose bounds are easy to ! * determine, and that only a few steps are needed to derive the actual ! * bounds of the circle given the bounds of the octagon. ! * ! * Note that by skipping all the grids in the corners of the octagon, we ! * place an upper limit on the number of grids in the field of view, given ! * that "full" is never more than 20. Of the 1681 grids in the "square" of ! * view, only about 1475 of these are in the "octagon" of view, and even ! * fewer are in the "circle" of view, so 1500 or 1536 is more than enough ! * entries to completely contain the actual field of view. ! * ! * Note also the care taken to prevent "running off the map". The use of ! * explicit checks on the "validity" of the "diagonal", and the fact that ! * the loops are never allowed to "leave" the map, lets "update_view_aux()" ! * use the optimized "cave_floor_bold()" macro, and to avoid the overhead ! * of multiple checks on the validity of grids. Note that for months we ! * were using a meaningless test for "East strip, South side", so it looks ! * like perhaps the first half of each of those tests is obsolete given the ! * test for the "optimizations" below. ! * ! * The bizarre "se","sw","ne","nw","es","en","ws","wn" variables are very ! * important. They indicate, for each "strip" (named by major axis and ! * then minor direction), the maximal distance which may be traveled along ! * that strip. They start out as the maximum viewable distance, modified ! * if needed to avoid leaving the dungeon. Then, for example, consider the ! * "se" variable. While moving down the south-bound strip just to the east ! * of the main south axis, as soon as we get to a grid which does not allow ! * "viewing" to pass, if all previous related strips (including the primary ! * "south" axis) have terminated at or before the same point, then we can ! * stop, and reset the "max distance" to ourself. Draw a picture if needed. ! * ! * Note the use of efficiency macros. The "cave_view_hack()" macro is a ! * chunk of code which adds the given location to the "view" array if it ! * is not already there, using both the actual location and a pointer to ! * the cave grid. See above. ! * ! * By the way, the purpose of this code is to reduce the dependancy on the ! * "los()" function which is slow, and, in some cases, not very accurate. ! * ! * It is very possible that I am the only person who fully understands this ! * function, and for that I am truly sorry, but efficiency was very important ! * and the "simple" version of this function was just not fast enough. I am ! * more than willing to replace this function with a simpler one, if it is ! * equally efficient, and especially willing if the new function happens to ! * derive "reverse-line-of-sight" at the same time, since currently monsters ! * just use an optimized hack of "you see me, so I see you", and then use the ! * actual "projectable()" function to check spell attacks. ! * ! * The algorithm is very fast, since it spreads "obvious" grids very quickly, ! * and only has to call "los()" on the borderline cases. The major axes/diags ! * even terminate early when they hit walls. I need to find a quick way ! * to "terminate" the other scans. ! * ! * Note that in the worst case (a big empty area with say 5% scattered walls), ! * each of the 1500 or so nearby grids is checked once, most of them getting ! * an "instant" rating, and only a small portion requiring a call to "los()". ! * ! * The only time that the algorithm appears to be "noticeably" too slow is ! * when running, and this is usually only important in town, since the town ! * provides about the worst scenario possible, with large open regions and ! * a few scattered obstructions. There is a special "efficiency" option to ! * allow the player to reduce his field of view in town, if needed. ! * ! * In the "best" case (say, a normal stretch of corridor), the algorithm ! * makes one check for each viewable grid, and makes no calls to "los()". ! * So running in corridors is very fast, and if a lot of monsters are ! * nearby, it is much faster than the old methods. ! * ! * Note that resting, most normal commands, and several forms of running, ! * plus all commands executed near large groups of monsters, are strictly ! * more efficient with "update_view()" that with the old "compute los() on ! * demand" method, primarily because once the "field of view" has been ! * calculated, it does not have to be recalculated until the player moves ! * (or a wall or door is created or destroyed). ! * ! * Note that we no longer have to do as many "los()" checks, since once the ! * "view" region has been built, very few things cause it to be "changed" ! * (player movement, and the opening/closing of doors, changes in wall status). ! * Note that door/wall changes are only relevant when the door/wall itself is ! * in the "view" region. ! * ! * The algorithm seems to only call "los()" from zero to ten times, usually ! * only when coming down a corridor into a room, or standing in a room, just ! * misaligned with a corridor. So if, say, there are five "nearby" monsters, ! * we will be reducing the calls to "los()". ! * ! * I am thinking in terms of an algorithm that "walks" from the central point ! * out to the maximal "distance", at each point, determining the "view" code ! * (above). For each grid not on a major axis or diagonal, the "view" code ! * depends on the "cave_floor_bold()" and "view" of exactly two other grids ! * (the one along the nearest diagonal, and the one next to that one, see ! * "update_view_aux()"...). ! * ! * In the worst "normal" case (in the middle of the town), the reachable space ! * actually reaches to more than half of the largest possible "circle" of view, ! * or about 800 grids, and in the worse case (in the middle of a dungeon level ! * where all the walls have been removed), the reachable space actually reaches ! * the theoretical maximum size of just under 1500 grids. ! * ! * The picture below shows the player and one quandrant (two octants) of the ! * viewable region, and the order in which the grids are processed. The pure ! * diagonals and main axes are processed first, up to the appropriate distance, ! * and then the sequential strips are processed (one in each octant), also up ! * to the appropriate distance. ! * ! * @11111111 ! * 112222222 ! * 12133333: ! * 12314444: ! * 1234155:: ! * 123451::. ! * 12345::.. ! * 1234::... ! * 12:::.... ! */ ! /* ! * Forget the "CAVE_VIEW" grids, redrawing as needed ! */ ! void forget_view(void) ! { ! int i; ! /* None to forget */ ! if (!view_n) return; ! /* Clear them all */ ! for (i = 0; i < view_n; i++) ! { ! int y = view_y[i]; ! int x = view_x[i]; ! /* Forget that the grid is viewable */ ! cave_info[y][x] &= ~(CAVE_VIEW); - /* Update the screen */ - lite_spot(y, x); - } ! /* None left */ ! view_n = 0; ! } ! /* ! * Simplify the "update_view()" function XXX XXX XXX ! * ! * This macro allows us to efficiently add a grid to the "view" array, ! * note that we are never called for illegal grids, or for grids which ! * have already been placed into the "view" array, and we are never ! * called when the "view" array is full. ! */ ! #define cave_view_hack(Y,X) \ ! do { \ ! cave_info[Y][X] |= (CAVE_VIEW); \ ! view_y[view_n] = (Y); \ ! view_x[view_n] = (X); \ ! view_n++; \ ! } while (0) - /* - * Helper function for "update_view()" below - * - * This function processes the "viewability" of the grid (y,x). - * - * Grid (y1,x1) is on the "diagonal" between (py,px) and (y,x) - * Grid (y2,x2) is "adjacent", also between (py,px) and (y,x). - * - * This function returns "TRUE" if vision is "blocked" by grid (y,x). - */ - static bool update_view_aux(int y, int x, int y1, int x1, int y2, int x2) - { - bool f1, f2, v1, v2, z1, z2, wall; ! /* Check for walls */ ! f1 = (cave_floor_bold(y1, x1)); ! f2 = (cave_floor_bold(y2, x2)); ! /* Totally blocked by physical walls */ ! if (!f1 && !f2) return (TRUE); - /* Check for visibility */ - v1 = (f1 && (cave_info[y1][x1] & (CAVE_VIEW))); - v2 = (f2 && (cave_info[y2][x2] & (CAVE_VIEW))); ! /* Totally blocked by "unviewable neighbors" */ ! if (!v1 && !v2) return (TRUE); ! /* Check for walls */ ! wall = (!cave_floor_bold(y, x)); - /* Check the "ease" of visibility */ - z1 = (v1 && (cave_info[y1][x1] & (CAVE_XTRA))); - z2 = (v2 && (cave_info[y2][x2] & (CAVE_XTRA))); ! /* Hack -- "easy" plus "easy" yields "easy" */ ! if (z1 && z2) ! { ! cave_info[y][x] |= (CAVE_XTRA); - cave_view_hack(y, x); ! return (wall); } - /* Hack -- primary "easy" yields "viewed" */ - if (z1) - { - cave_view_hack(y, x); ! return (wall); } ! /* Hack -- "view" plus "view" yields "view" */ ! if (v1 && v2) ! { ! /* cave_info[y][x] |= (CAVE_XTRA); */ - cave_view_hack(y, x); ! return (wall); ! } - /* Mega-Hack -- the "los()" function works poorly on walls */ - if (wall) - { - cave_view_hack(y, x); ! return (wall); ! } ! /* Actual line of sight test */ ! if (TRUE) { ! int py = p_ptr->py; ! int px = p_ptr->px; ! /* Hack -- check line of sight */ ! if (los(py, px, y, x)) ! { ! cave_view_hack(y, x); ! return (wall); ! } } ! /* Assume no line of sight. */ ! return (TRUE); } - /* - * Hack -- keep the code below simple - */ - #define DY1 0 - #define DY2 (DUNGEON_HGT-1) - #define DX1 0 - #define DX2 (DUNGEON_WID-1) - /* ! * Update the "CAVE_VIEW" grids, redrawing as needed */ void update_view(void) { int py = p_ptr->py; int px = p_ptr->px; ! int n, m, d, k, y, x, z; ! int se, sw, ne, nw, es, en, ws, wn; ! int full, over; ! /*** Initialize ***/ ! ! /* Optimize */ ! if (view_reduce_view && !p_ptr->depth) ! { ! /* Full radius (10) */ ! full = MAX_SIGHT / 2; ! ! /* Octagon factor (15) */ ! over = MAX_SIGHT * 3 / 4; ! } ! /* Normal */ ! else ! { ! /* Full radius (20) */ ! full = MAX_SIGHT; ! /* Octagon factor (30) */ ! over = MAX_SIGHT * 3 / 2; ! } /*** Step 0 -- Begin ***/ /* Save the old "view" grids for later */ ! for (n = 0; n < view_n; n++) { ! y = view_y[n]; ! x = view_x[n]; ! /* Mark the grid as not in "view" */ ! cave_info[y][x] &= ~(CAVE_VIEW); ! /* Mark the grid as "seen" */ ! cave_info[y][x] |= (CAVE_TEMP); ! ! /* Add it to the "seen" set */ ! temp_y[temp_n] = y; ! temp_x[temp_n] = x; ! temp_n++; ! } ! ! /* Start over with the "view" array */ ! view_n = 0; ! ! ! /*** Step 1 -- adjacent grids ***/ ! /* Now start on the player */ ! y = py; ! x = px; ! /* Assume the player grid is easily viewable */ ! cave_info[y][x] |= (CAVE_XTRA); ! /* Assume the player grid is viewable */ ! cave_view_hack(y, x); ! /*** Step 2 -- Major Diagonals ***/ ! /* Hack -- Limit */ ! z = full * 2 / 3; ! /* Scan south-east */ ! for (d = 1; d <= z; d++) ! { ! cave_info[y+d][x+d] |= (CAVE_XTRA); ! cave_view_hack(y+d, x+d); ! if (!cave_floor_bold(y+d, x+d)) break; ! } - /* Scan south-west */ - for (d = 1; d <= z; d++) - { - cave_info[y+d][x-d] |= (CAVE_XTRA); - cave_view_hack(y+d, x-d); - if (!cave_floor_bold(y+d, x-d)) break; - } ! /* Scan north-east */ ! for (d = 1; d <= z; d++) ! { ! cave_info[y-d][x+d] |= (CAVE_XTRA); ! cave_view_hack(y-d, x+d); ! if (!cave_floor_bold(y-d, x+d)) break; ! } ! /* Scan north-west */ ! for (d = 1; d <= z; d++) ! { ! cave_info[y-d][x-d] |= (CAVE_XTRA); ! cave_view_hack(y-d, x-d); ! if (!cave_floor_bold(y-d, x-d)) break; ! } ! /*** Step 3 -- major axes ***/ ! /* Scan south */ ! for (d = 1; d <= full; d++) { ! cave_info[y+d][x] |= (CAVE_XTRA); ! cave_view_hack(y+d, x); ! if (!cave_floor_bold(y+d, x)) break; ! } ! /* Initialize the "south strips" */ ! se = sw = d; ! ! /* Scan north */ ! for (d = 1; d <= full; d++) ! { ! cave_info[y-d][x] |= (CAVE_XTRA); ! cave_view_hack(y-d, x); ! if (!cave_floor_bold(y-d, x)) break; } ! /* Initialize the "north strips" */ ! ne = nw = d; ! ! /* Scan east */ ! for (d = 1; d <= full; d++) { ! cave_info[y][x+d] |= (CAVE_XTRA); ! cave_view_hack(y, x+d); ! if (!cave_floor_bold(y, x+d)) break; } ! /* Initialize the "east strips" */ ! es = en = d; ! ! /* Scan west */ ! for (d = 1; d <= full; d++) ! { ! cave_info[y][x-d] |= (CAVE_XTRA); ! cave_view_hack(y, x-d); ! if (!cave_floor_bold(y, x-d)) break; ! } ! /* Initialize the "west strips" */ ! ws = wn = d; ! /*** Step 4 -- Divide each "octant" into "strips" ***/ ! /* Now check each "strip" */ ! for (n = 1; n <= over / 2; n++) { ! int ypn, ymn, ypnpd, ymnmd; ! int xpn, xmn, xpnpd, xmnmd; ! /* Acquire the "bounds" of the maximal circle */ ! z = over - n - n; ! if (z > full - n) z = full - n; ! while ((z + n + (n>>1)) > full) z--; ! /* Access the four diagonal grids */ ! ypn = y + n; ! ymn = y - n; ! xpn = x + n; ! xmn = x - n; ! /* South strip */ ! if (ypn < DY2) { ! /* Maximum distance */ ! m = MIN(z, DY2 - ypn); ! /* East side */ ! if (n < se) { ! /* Scan */ ! for (k = n, ypnpd = ypn+1, d = 1; d <= m; d++, ypnpd++) ! { ! /* Check grid "d" in strip "n", notice "blockage" */ ! if (update_view_aux(ypnpd, xpn, ypnpd-1, xpn-1, ypnpd-1, xpn)) ! { ! if (n + d >= se) break; ! } ! ! /* Track most distant "non-blockage" */ ! else ! { ! k = n + d; ! } ! } ! ! /* Limit the next strip */ ! se = k + 1; ! } ! ! /* West side */ ! if (n < sw) ! { ! /* Scan */ ! for (k = n, ypnpd = ypn+1, d = 1; d <= m; d++, ypnpd++) ! { ! /* Check grid "d" in strip "n", notice "blockage" */ ! if (update_view_aux(ypnpd, xmn, ypnpd-1, xmn+1, ypnpd-1, xmn)) ! { ! if (n + d >= sw) break; ! } ! ! /* Track most distant "non-blockage" */ ! else ! { ! k = n + d; ! } ! } ! /* Limit the next strip */ ! sw = k + 1; ! } ! } ! ! ! /* North strip */ ! if (ymn > DY1) ! { ! /* Maximum distance */ ! m = MIN(z, ymn - DY1); ! /* East side */ ! if (n < ne) ! { ! /* Scan */ ! for (k = n, ymnmd = ymn-1, d = 1; d <= m; d++, ymnmd--) { ! /* Check grid "d" in strip "n", notice "blockage" */ ! if (update_view_aux(ymnmd, xpn, ymnmd+1, xpn-1, ymnmd+1, xpn)) ! { ! if (n + d >= ne) break; ! } ! /* Track most distant "non-blockage" */ ! else { ! k = n + d; ! } ! } ! /* Limit the next strip */ ! ne = k + 1; ! } ! /* West side */ ! if (n < nw) ! { ! /* Scan */ ! for (k = n, ymnmd = ymn-1, d = 1; d <= m; d++, ymnmd--) ! { ! /* Check grid "d" in strip "n", notice "blockage" */ ! if (update_view_aux(ymnmd, xmn, ymnmd+1, xmn+1, ymnmd+1, xmn)) ! { ! if (n + d >= nw) break; ! } ! /* Track most distant "non-blockage" */ ! else ! { ! k = n + d; ! } ! } ! /* Limit the next strip */ ! nw = k + 1; ! } ! } ! /* East strip */ ! if (xpn < DX2) ! { ! /* Maximum distance */ ! m = MIN(z, DX2 - xpn); ! /* South side */ ! if (n < es) ! { ! /* Scan */ ! for (k = n, xpnpd = xpn+1, d = 1; d <= m; d++, xpnpd++) ! { ! /* Check grid "d" in strip "n", notice "blockage" */ ! if (update_view_aux(ypn, xpnpd, ypn-1, xpnpd-1, ypn, xpnpd-1)) ! { ! if (n + d >= es) break; ! } ! /* Track most distant "non-blockage" */ ! else ! { ! k = n + d; } } ! /* Limit the next strip */ ! es = k + 1; ! } ! ! /* North side */ ! if (n < en) ! { ! /* Scan */ ! for (k = n, xpnpd = xpn+1, d = 1; d <= m; d++, xpnpd++) { ! /* Check grid "d" in strip "n", notice "blockage" */ ! if (update_view_aux(ymn, xpnpd, ymn+1, xpnpd-1, ymn, xpnpd-1)) { ! if (n + d >= en) break; } ! /* Track most distant "non-blockage" */ ! else { ! k = n + d; } - } ! /* Limit the next strip */ ! en = k + 1; ! } ! } ! ! ! /* West strip */ ! if (xmn > DX1) ! { ! /* Maximum distance */ ! m = MIN(z, xmn - DX1); ! ! /* South side */ ! if (n < ws) ! { ! /* Scan */ ! for (k = n, xmnmd = xmn-1, d = 1; d <= m; d++, xmnmd--) ! { ! /* Check grid "d" in strip "n", notice "blockage" */ ! if (update_view_aux(ypn, xmnmd, ypn-1, xmnmd+1, ypn, xmnmd+1)) { ! if (n + d >= ws) break; ! } ! /* Track most distant "non-blockage" */ ! else ! { ! k = n + d; ! } ! } ! /* Limit the next strip */ ! ws = k + 1; ! } ! /* North side */ ! if (n < wn) ! { ! /* Scan */ ! for (k = n, xmnmd = xmn-1, d = 1; d <= m; d++, xmnmd--) ! { ! /* Check grid "d" in strip "n", notice "blockage" */ ! if (update_view_aux(ymn, xmnmd, ymn+1, xmnmd+1, ymn, xmnmd+1)) ! { ! if (n + d >= wn) break; ! } ! /* Track most distant "non-blockage" */ ! else ! { ! k = n + d; } } - - /* Limit the next strip */ - wn = k + 1; } } } ! /*** Step 5 -- Complete the algorithm ***/ /* Process "new" grids */ ! for (n = 0; n < view_n; n++) { ! y = view_y[n]; ! x = view_x[n]; ! /* Clear the "CAVE_XTRA" flag */ ! cave_info[y][x] &= ~(CAVE_XTRA); ! /* Update/Redraw "new" grids */ ! if (!(cave_info[y][x] & (CAVE_TEMP))) { ! /* Note */ ! note_spot(y, x); ! /* Redraw */ ! lite_spot(y, x); ! } - /* Update/Redraw all perma-lit wall grids */ - else if ((cave_info[y][x] & (CAVE_GLOW)) && - !cave_floor_bold(y, x)) - { /* Note */ note_spot(y, x); --- 1401,2721 ---- move_cursor(cy, cx); /* Get any key */ ! (void)inkey(); ! /* Load screen */ ! screen_load(); } /* ! * Some comments on the dungeon related data structures and functions... ! * ! * Angband is primarily a dungeon exploration game, and it should come as ! * no surprise that the internal representation of the dungeon has evolved ! * over time in much the same way as the game itself, to provide semantic ! * changes to the game itself, to make the code simpler to understand, and ! * to make the executable itself faster or more efficient in various ways. ! * ! * There are a variety of dungeon related data structures, and associated ! * functions, which store information about the dungeon, and provide methods ! * by which this information can be accessed or modified. ! * ! * Some of this information applies to the dungeon as a whole, such as the ! * list of unique monsters which are still alive. Some of this information ! * only applies to the current dungeon level, such as the current depth, or ! * the list of monsters currently inhabiting the level. And some of the ! * information only applies to a single grid of the current dungeon level, ! * such as whether the grid is illuminated, or whether the grid contains a ! * monster, or whether the grid can be seen by the player. If Angband was ! * to be turned into a multi-player game, some of the information currently ! * associated with the dungeon should really be associated with the player, ! * such as whether a given grid is viewable by a given player. ! * ! * One of the major bottlenecks in ancient versions of Angband was in the ! * calculation of "line of sight" from the player to various grids, such ! * as those containing monsters, using the relatively expensive "los()" ! * function. This was such a nasty bottleneck that a lot of silly things ! * were done to reduce the dependancy on "line of sight", for example, you ! * could not "see" any grids in a lit room until you actually entered the ! * room, at which point every grid in the room became "illuminated" and ! * all of the grids in the room were "memorized" forever. Other major ! * bottlenecks involved the determination of whether a grid was lit by the ! * player's torch, and whether a grid blocked the player's line of sight. ! * These bottlenecks led to the development of special new functions to * optimize issues involved with "line of sight" and "torch lit grids". + * These optimizations led to entirely new additions to the game, such as + * the ability to display the player's entire field of view using different + * colors than were used for the "memorized" portions of the dungeon, and + * the ability to memorize dark floor grids, but to indicate by the way in + * which they are displayed that they are not actually illuminated. And + * of course many of them simply made the game itself faster or more fun. + * Also, over time, the definition of "line of sight" has been relaxed to + * allow the player to see a wider "field of view", which is slightly more + * realistic, and only slightly more expensive to maintain. + * + * Currently, a lot of the information about the dungeon is stored in ways + * that make it very efficient to access or modify the information, while + * still attempting to be relatively conservative about memory usage, even + * if this means that some information is stored in multiple places, or in + * ways which require the use of special code idioms. For example, each + * monster record in the monster array contains the location of the monster, + * and each cave grid has an index into the monster array, or a zero if no + * monster is in the grid. This allows the monster code to efficiently see + * where the monster is located, while allowing the dungeon code to quickly + * determine not only if a monster is present in a given grid, but also to + * find out which monster. The extra space used to store the information + * twice is inconsequential compared to the speed increase. + * + * Some of the information about the dungeon is used by functions which can + * constitute the "critical efficiency path" of the game itself, and so the + * way in which they are stored and accessed has been optimized in order to + * optimize the game itself. For example, the "update_view()" function was + * originally created to speed up the game itself (when the player was not + * running), but then it took on extra responsibility as the provider of the + * new "special effects lighting code", and became one of the most important + * bottlenecks when the player was running. So many rounds of optimization + * were performed on both the function itself, and the data structures which + * it uses, resulting eventually in a function which not only made the game + * faster than before, but which was responsible for even more calculations + * (including the determination of which grids are "viewable" by the player, + * which grids are illuminated by the player's torch, and which grids can be + * "seen" in some way by the player), as well as for providing the guts of + * the special effects lighting code, and for the efficient redisplay of any + * grids whose visual representation may have changed. + * + * Several pieces of information about each cave grid are stored in various + * two dimensional arrays, with one unit of information for each grid in the + * dungeon. Some of these arrays have been intentionally expanded by a small + * factor to make the two dimensional array accesses faster by allowing the + * use of shifting instead of multiplication. + * + * Several pieces of information about each cave grid are stored in the + * "cave_info" array, which is a special two dimensional array of bytes, + * one for each cave grid, each containing eight separate "flags" which + * describe some property of the cave grid. These flags can be checked and + * modified extremely quickly, especially when special idioms are used to + * force the compiler to keep a local register pointing to the base of the + * array. Special location offset macros can be used to minimize the number + * of computations which must be performed at runtime. Note that using a + * byte for each flag set may be slightly more efficient than using a larger + * unit, so if another flag (or two) is needed later, and it must be fast, + * then the two existing flags which do not have to be fast should be moved + * out into some other data structure and the new flags should take their + * place. This may require a few minor changes in the savefile code. + * + * The "CAVE_ROOM" flag is saved in the savefile and is used to determine + * which grids are part of "rooms", and thus which grids are affected by + * "illumination" spells. This flag does not have to be very fast. + * + * The "CAVE_ICKY" flag is saved in the savefile and is used to determine + * which grids are part of "vaults", and thus which grids cannot serve as + * the destinations of player teleportation. This flag does not have to + * be very fast. + * + * The "CAVE_MARK" flag is saved in the savefile and is used to determine + * which grids have been "memorized" by the player. This flag is used by + * the "map_info()" function to determine if a grid should be displayed. + * This flag is used in a few other places to determine if the player can + * "know" about a given grid. This flag must be very fast. + * + * The "CAVE_GLOW" flag is saved in the savefile and is used to determine + * which grids are "permanently illuminated". This flag is used by the + * "update_view()" function to help determine which viewable flags may + * be "seen" by the player. This flag is used by the "map_info" function + * to determine if a grid is only lit by the player's torch. This flag + * has special semantics for wall grids (see "update_view()"). This flag + * must be very fast. + * + * The "CAVE_WALL" flag is used to determine which grids block the player's + * line of sight. This flag is used by the "update_view()" function to + * determine which grids block line of sight, and to help determine which + * grids can be "seen" by the player. This flag must be very fast. + * + * The "CAVE_VIEW" flag is used to determine which grids are currently in + * line of sight of the player. This flag is set by (and used by) the + * "update_view()" function. This flag is used by any code which needs to + * know if the player can "view" a given grid. This flag is used by the + * "map_info()" function for some optional special lighting effects. The + * "player_has_los_bold()" macro wraps an abstraction around this flag, but + * certain code idioms are much more efficient. This flag is used to check + * if a modification to a terrain feature might affect the player's field of + * view. This flag is used to see if certain monsters are "visible" to the + * player. This flag is used to allow any monster in the player's field of + * view to "sense" the presence of the player. This flag must be very fast. + * + * The "CAVE_SEEN" flag is used to determine which grids are currently in + * line of sight of the player and also illuminated in some way. This flag + * is set by the "update_view()" function, using computations based on the + * "CAVE_VIEW" and "CAVE_WALL" and "CAVE_GLOW" flags of various grids. This + * flag is used by any code which needs to know if the player can "see" a + * given grid. This flag is used by the "map_info()" function both to see + * if a given "boring" grid can be seen by the player, and for some optional + * special lighting effects. The "player_can_see_bold()" macro wraps an + * abstraction around this flag, but certain code idioms are much more + * efficient. This flag is used to see if certain monsters are "visible" to + * the player. This flag is never set for a grid unless "CAVE_VIEW" is also + * set for the grid. Whenever the "CAVE_WALL" or "CAVE_GLOW" flag changes + * for a grid which has the "CAVE_VIEW" flag set, the "CAVE_SEEN" flag must + * be recalculated. The simplest way to do this is to call "forget_view()" + * and "update_view()" whenever the "CAVE_WALL" or "CAVE_GLOW" flags change + * for a grid which has "CAVE_VIEW" set. This flag must be very fast. + * + * The "CAVE_TEMP" flag is used for a variety of temporary purposes. This + * flag is used to determine if the "CAVE_SEEN" flag for a grid has changed + * during the "update_view()" function. This flag is used to "spread" light + * or darkness through a room. This flag is used by the "monster flow code". + * This flag must always be cleared by any code which sets it, often, this + * can be optimized by the use of the special "temp_g", "temp_y", "temp_x" + * arrays (and the special "temp_n" global). This flag must be very fast. + * + * Note that the "CAVE_MARK" flag is used for many reasons, some of which + * are strictly for optimization purposes. The "CAVE_MARK" flag means that + * even if the player cannot "see" the grid, he "knows" about the terrain in + * that grid. This is used to "memorize" grids when they are first "seen" by + * the player, and to allow certain grids to be "detected" by certain magic. + * Note that most grids are always memorized when they are first "seen", but + * "boring" grids (floor grids) are only memorized if the "view_torch_grids" + * option is set, or if the "view_perma_grids" option is set, and the grid + * in question has the "CAVE_GLOW" flag set. + * + * Objects are "memorized" in a different way, using a special "marked" flag + * on the object itself, which is set when an object is observed or detected. + * This allows objects to be "memorized" independant of the terrain features. * ! * The "update_view()" function is an extremely important function. It is ! * called only when the player moves, significant terrain changes, or the ! * player's blindness or torch radius changes. Note that when the player ! * is resting, or performing any repeated actions (like digging, disarming, ! * farming, etc), there is no need to call the "update_view()" function, so ! * even if it was not very efficient, this would really only matter when the ! * player was "running" through the dungeon. It sets the "CAVE_VIEW" flag ! * on every cave grid in the player's field of view, and maintains an array ! * of all such grids in the global "view_g" array. It also checks the torch ! * radius of the player, and sets the "CAVE_SEEN" flag for every grid which ! * is in the "field of view" of the player and which is also "illuminated", ! * either by the players torch (if any) or by any permanent light source. ! * It could use and help maintain information about multiple light sources, ! * which would be helpful in a multi-player version of Angband. ! * ! * The "update_view()" function maintains the special "view_g" array, which ! * contains exactly those grids which have the "CAVE_VIEW" flag set. This ! * array is used by "update_view()" to (only) memorize grids which become ! * newly "seen", and to (only) redraw grids whose "seen" value changes, which ! * allows the use of some interesting (and very efficient) "special lighting ! * effects". In addition, this array could be used elsewhere to quickly scan ! * through all the grids which are in the player's field of view. ! * ! * Note that the "update_view()" function allows, among other things, a room ! * to be "partially" seen as the player approaches it, with a growing cone ! * of floor appearing as the player gets closer to the door. Also, by not ! * turning on the "memorize perma-lit grids" option, the player will only ! * "see" those floor grids which are actually in line of sight. And best ! * of all, you can now activate the special lighting effects to indicate ! * which grids are actually in the player's field of view by using dimmer ! * colors for grids which are not in the player's field of view, and/or to ! * indicate which grids are illuminated only by the player's torch by using ! * the color yellow for those grids. * ! * The old "update_view()" algorithm uses the special "CAVE_EASY" flag as a * temporary internal flag to mark those grids which are not only in view, * but which are also "easily" in line of sight of the player. This flag ! * is actually just the "CAVE_SEEN" flag, and the "update_view()" function ! * makes sure to clear it for all old "CAVE_SEEN" grids, and then use it in ! * the algorithm as "CAVE_EASY", and then clear it for all "CAVE_EASY" grids, ! * and then reset it as appropriate for all new "CAVE_SEEN" grids. This is ! * kind of messy, but it works. The old algorithm may disappear eventually. * ! * The new "update_view()" algorithm uses a faster and more mathematically ! * correct algorithm, assisted by a large machine generated static array, to ! * determine the "CAVE_VIEW" and "CAVE_SEEN" flags simultaneously. See below. * ! * It seems as though slight modifications to the "update_view()" functions ! * would allow us to determine "reverse" line-of-sight as well as "normal" ! * line-of-sight", which would allow monsters to have a more "correct" way ! * to determine if they can "see" the player, since right now, they "cheat" ! * somewhat and assume that if the player has "line of sight" to them, then ! * they can "pretend" that they have "line of sight" to the player. But if ! * such a change was attempted, the monsters would actually start to exhibit ! * some undesirable behavior, such as "freezing" near the entrances to long ! * hallways containing the player, and code would have to be added to make ! * the monsters move around even if the player was not detectable, and to ! * "remember" where the player was last seen, to avoid looking stupid. * ! * Note that the "CAVE_GLOW" flag means that a grid is permanently lit in ! * some way. However, for the player to "see" the grid, as determined by ! * the "CAVE_SEEN" flag, the player must not be blind, the grid must have ! * the "CAVE_VIEW" flag set, and if the grid is a "wall" grid, and it is ! * not lit by the player's torch, then it must touch a grid which does not ! * have the "CAVE_WALL" flag set, but which does have both the "CAVE_GLOW" ! * and "CAVE_VIEW" flags set. This last part about wall grids is induced ! * by the semantics of "CAVE_GLOW" as applied to wall grids, and checking ! * the technical requirements can be very expensive, especially since the ! * grid may be touching some "illegal" grids. Luckily, it is more or less ! * correct to restrict the "touching" grids from the eight "possible" grids ! * to the (at most) three grids which are touching the grid, and which are ! * closer to the player than the grid itself, which eliminates more than ! * half of the work, including all of the potentially "illegal" grids, if ! * at most one of the three grids is a "diagonal" grid. In addition, in ! * almost every situation, it is possible to ignore the "CAVE_VIEW" flag ! * on these three "touching" grids, for a variety of technical reasons. ! * Finally, note that in most situations, it is only necessary to check ! * a single "touching" grid, in fact, the grid which is strictly closest ! * to the player of all the touching grids, and in fact, it is normally ! * only necessary to check the "CAVE_GLOW" flag of that grid, again, for ! * various technical reasons. However, one of the situations which does ! * not work with this last reduction is the very common one in which the ! * player approaches an illuminated room from a dark hallway, in which the ! * two wall grids which form the "entrance" to the room would not be marked ! * as "CAVE_SEEN", since of the three "touching" grids nearer to the player ! * than each wall grid, only the farthest of these grids is itself marked ! * "CAVE_GLOW". * * + * Here are some pictures of the legal "light source" radius values, in + * which the numbers indicate the "order" in which the grids could have + * been calculated, if desired. Note that the code will work with larger + * radiuses, though currently yields such a radius, and the game would + * become slower in some situations if it did. * ! * Rad=0 Rad=1 Rad=2 Rad=3 ! * No-Lite Torch,etc Lantern Artifacts ! * ! * 333 ! * 333 43334 ! * 212 32123 3321233 ! * @ 1@1 31@13 331@133 ! * 212 32123 3321233 ! * 333 43334 ! * 333 * * ! * Here is an illustration of the two different "update_view()" algorithms, ! * in which the grids marked "%" are pillars, and the grids marked "?" are ! * not in line of sight of the player. ! * ! * ! * Sample situation * ! * ##################### ! * ############.%.%.%.%# ! * #...@..#####........# ! * #............%.%.%.%# ! * #......#####........# ! * ############........# ! * ##################### * * ! * New Algorithm Old Algorithm * ! * ########????????????? ########????????????? ! * #...@..#????????????? #...@..#????????????? ! * #...........????????? #.........??????????? ! * #......#####.....???? #......####?????????? ! * ########?????????...# ########????????????? * ! * ########????????????? ########????????????? ! * #.@....#????????????? #.@....#????????????? ! * #............%??????? #...........????????? ! * #......#####........? #......#####????????? ! * ########??????????..# ########????????????? * ! * ########????????????? ########?????%??????? ! * #......#####........# #......#####..??????? ! * #.@..........%??????? #.@..........%??????? ! * #......#####........# #......#####..??????? ! * ########????????????? ########????????????? ! * ! * ########??????????..# ########????????????? ! * #......#####........? #......#####????????? ! * #............%??????? #...........????????? ! * #.@....#????????????? #.@....#????????????? ! * ########????????????? ########????????????? ! * ! * ########?????????%??? ########????????????? ! * #......#####.....???? #......####?????????? ! * #...........????????? #.........??????????? ! * #...@..#????????????? #...@..#????????????? ! * ########????????????? ########????????????? */ + /* ! * Maximum number of grids in a single octant */ ! #define VINFO_MAX_GRIDS 161 ! /* ! * Maximum number of slopes in a single octant ! */ ! #define VINFO_MAX_SLOPES 126 ! /* ! * Mask of bits used in a single octant ! */ ! #define VINFO_BITS_3 0x3FFFFFFF ! #define VINFO_BITS_2 0xFFFFFFFF ! #define VINFO_BITS_1 0xFFFFFFFF ! #define VINFO_BITS_0 0xFFFFFFFF /* ! * Forward declare */ ! typedef struct vinfo_type vinfo_type; /* ! * The 'vinfo_type' structure */ ! struct vinfo_type { ! s16b grid_0; ! s16b grid_1; ! s16b grid_2; ! s16b grid_3; ! s16b grid_4; ! s16b grid_5; ! s16b grid_6; ! s16b grid_7; ! u32b bits_3; ! u32b bits_2; ! u32b bits_1; ! u32b bits_0; ! vinfo_type *next_0; ! vinfo_type *next_1; + byte y; + byte x; + byte d; + byte r; + }; ! /* ! * The array of "vinfo" objects, initialized by "vinfo_init()" ! */ ! static vinfo_type vinfo[VINFO_MAX_GRIDS]; ! /* ! * Slope scale factor ! */ ! #define SCALE 100000L ! ! ! /* ! * The actual slopes (for reference) ! */ ! ! /* Bit : Slope Grids */ ! /* --- : ----- ----- */ ! /* 0 : 2439 21 */ ! /* 1 : 2564 21 */ ! /* 2 : 2702 21 */ ! /* 3 : 2857 21 */ ! /* 4 : 3030 21 */ ! /* 5 : 3225 21 */ ! /* 6 : 3448 21 */ ! /* 7 : 3703 21 */ ! /* 8 : 4000 21 */ ! /* 9 : 4347 21 */ ! /* 10 : 4761 21 */ ! /* 11 : 5263 21 */ ! /* 12 : 5882 21 */ ! /* 13 : 6666 21 */ ! /* 14 : 7317 22 */ ! /* 15 : 7692 20 */ ! /* 16 : 8108 21 */ ! /* 17 : 8571 21 */ ! /* 18 : 9090 20 */ ! /* 19 : 9677 21 */ ! /* 20 : 10344 21 */ ! /* 21 : 11111 20 */ ! /* 22 : 12000 21 */ ! /* 23 : 12820 22 */ ! /* 24 : 13043 22 */ ! /* 25 : 13513 22 */ ! /* 26 : 14285 20 */ ! /* 27 : 15151 22 */ ! /* 28 : 15789 22 */ ! /* 29 : 16129 22 */ ! /* 30 : 17241 22 */ ! /* 31 : 17647 22 */ ! /* 32 : 17948 23 */ ! /* 33 : 18518 22 */ ! /* 34 : 18918 22 */ ! /* 35 : 20000 19 */ ! /* 36 : 21212 22 */ ! /* 37 : 21739 22 */ ! /* 38 : 22580 22 */ ! /* 39 : 23076 22 */ ! /* 40 : 23809 22 */ ! /* 41 : 24137 22 */ ! /* 42 : 24324 23 */ ! /* 43 : 25714 23 */ ! /* 44 : 25925 23 */ ! /* 45 : 26315 23 */ ! /* 46 : 27272 22 */ ! /* 47 : 28000 23 */ ! /* 48 : 29032 23 */ ! /* 49 : 29411 23 */ ! /* 50 : 29729 24 */ ! /* 51 : 30434 23 */ ! /* 52 : 31034 23 */ ! /* 53 : 31428 23 */ ! /* 54 : 33333 18 */ ! /* 55 : 35483 23 */ ! /* 56 : 36000 23 */ ! /* 57 : 36842 23 */ ! /* 58 : 37142 24 */ ! /* 59 : 37931 24 */ ! /* 60 : 38461 24 */ ! /* 61 : 39130 24 */ ! /* 62 : 39393 24 */ ! /* 63 : 40740 24 */ ! /* 64 : 41176 24 */ ! /* 65 : 41935 24 */ ! /* 66 : 42857 23 */ ! /* 67 : 44000 24 */ ! /* 68 : 44827 24 */ ! /* 69 : 45454 23 */ ! /* 70 : 46666 24 */ ! /* 71 : 47368 24 */ ! /* 72 : 47826 24 */ ! /* 73 : 48148 24 */ ! /* 74 : 48387 24 */ ! /* 75 : 51515 25 */ ! /* 76 : 51724 25 */ ! /* 77 : 52000 25 */ ! /* 78 : 52380 25 */ ! /* 79 : 52941 25 */ ! /* 80 : 53846 25 */ ! /* 81 : 54838 25 */ ! /* 82 : 55555 24 */ ! /* 83 : 56521 25 */ ! /* 84 : 57575 26 */ ! /* 85 : 57894 25 */ ! /* 86 : 58620 25 */ ! /* 87 : 60000 23 */ ! /* 88 : 61290 25 */ ! /* 89 : 61904 25 */ ! /* 90 : 62962 25 */ ! /* 91 : 63636 25 */ ! /* 92 : 64705 25 */ ! /* 93 : 65217 25 */ ! /* 94 : 65517 25 */ ! /* 95 : 67741 26 */ ! /* 96 : 68000 26 */ ! /* 97 : 68421 26 */ ! /* 98 : 69230 26 */ ! /* 99 : 70370 26 */ ! /* 100 : 71428 25 */ ! /* 101 : 72413 26 */ ! /* 102 : 73333 26 */ ! /* 103 : 73913 26 */ ! /* 104 : 74193 27 */ ! /* 105 : 76000 26 */ ! /* 106 : 76470 26 */ ! /* 107 : 77777 25 */ ! /* 108 : 78947 26 */ ! /* 109 : 79310 26 */ ! /* 110 : 80952 26 */ ! /* 111 : 81818 26 */ ! /* 112 : 82608 26 */ ! /* 113 : 84000 26 */ ! /* 114 : 84615 26 */ ! /* 115 : 85185 26 */ ! /* 116 : 86206 27 */ ! /* 117 : 86666 27 */ ! /* 118 : 88235 27 */ ! /* 119 : 89473 27 */ ! /* 120 : 90476 27 */ ! /* 121 : 91304 27 */ ! /* 122 : 92000 27 */ ! /* 123 : 92592 27 */ ! /* 124 : 93103 28 */ ! /* 125 : 100000 13 */ ! ! ! ! /* ! * Forward declare ! */ ! typedef struct vinfo_hack vinfo_hack; ! ! ! /* ! * Temporary data used by "vinfo_init()" ! * ! * - Number of grids ! * ! * - Number of slopes ! * ! * - Slope values ! * ! * - Slope range per grid ! */ ! struct vinfo_hack { ! int num_slopes; ! long slopes[VINFO_MAX_SLOPES]; ! long slopes_min[MAX_SIGHT+1][MAX_SIGHT+1]; ! long slopes_max[MAX_SIGHT+1][MAX_SIGHT+1]; ! }; ! /* ! * Sorting hook -- comp function -- array of long's (see below) ! * ! * We use "u" to point to an array of long integers. ! */ ! static bool ang_sort_comp_hook_longs(vptr u, vptr v, int a, int b) ! { ! long *x = (long*)(u); ! return (x[a] <= x[b]); ! } ! /* ! * Sorting hook -- comp function -- array of long's (see below) ! * ! * We use "u" to point to an array of long integers. ! */ ! static void ang_sort_swap_hook_longs(vptr u, vptr v, int a, int b) ! { ! long *x = (long*)(u); ! long temp; ! /* Swap */ ! temp = x[a]; ! x[a] = x[b]; ! x[b] = temp; ! } ! ! ! ! /* ! * Save a slope ! */ ! static void vinfo_init_aux(vinfo_hack *hack, int y, int x, long m) ! { ! int i; ! /* Handle "legal" slopes */ ! if ((m > 0) && (m <= SCALE)) ! { ! /* Look for that slope */ ! for (i = 0; i < hack->num_slopes; i++) { ! if (hack->slopes[i] == m) break; } ! /* New slope */ ! if (i == hack->num_slopes) { ! /* Paranoia */ ! if (hack->num_slopes >= VINFO_MAX_SLOPES) ! { ! quit_fmt("Too many slopes (%d)!", ! VINFO_MAX_SLOPES); ! } ! ! /* Save the slope, and advance */ ! hack->slopes[hack->num_slopes++] = m; } } ! /* Track slope range */ ! if (hack->slopes_min[y][x] > m) hack->slopes_min[y][x] = m; ! if (hack->slopes_max[y][x] < m) hack->slopes_max[y][x] = m; ! } ! /* ! * Initialize the "vinfo" array ! * ! * Full Octagon (radius 20), Grids=1149 ! * ! * Quadrant (south east), Grids=308, Slopes=251 ! * ! * Octant (east then south), Grids=161, Slopes=126 ! * ! * This function assumes that VINFO_MAX_GRIDS and VINFO_MAX_SLOPES ! * have the correct values, which can be derived by setting them to ! * a number which is too high, running this function, and using the ! * error messages to obtain the correct values. ! */ ! errr vinfo_init(void) ! { ! int i, g; ! int y, x; ! long m; ! vinfo_hack *hack; ! int num_grids = 0; ! int queue_head = 0; ! int queue_tail = 0; ! vinfo_type *queue[VINFO_MAX_GRIDS*2]; ! /* Make hack */ ! MAKE(hack, vinfo_hack); ! ! /* Analyze grids */ ! for (y = 0; y <= MAX_SIGHT; ++y) ! { ! for (x = y; x <= MAX_SIGHT; ++x) { ! /* Skip grids which are out of sight range */ ! if (distance(0, 0, y, x) > MAX_SIGHT) continue; ! ! /* Default slope range */ ! hack->slopes_min[y][x] = 999999999; ! hack->slopes_max[y][x] = 0; ! /* Paranoia */ ! if (num_grids >= VINFO_MAX_GRIDS) ! { ! quit_fmt("Too many grids (%d >= %d)!", ! num_grids, VINFO_MAX_GRIDS); ! } ! /* Count grids */ ! num_grids++; ! /* Slope to the top right corner */ ! m = SCALE * (1000L * y - 500) / (1000L * x + 500); ! /* Handle "legal" slopes */ ! vinfo_init_aux(hack, y, x, m); ! /* Slope to top left corner */ ! m = SCALE * (1000L * y - 500) / (1000L * x - 500); + /* Handle "legal" slopes */ + vinfo_init_aux(hack, y, x, m); ! /* Slope to bottom right corner */ ! m = SCALE * (1000L * y + 500) / (1000L * x + 500); ! /* Handle "legal" slopes */ ! vinfo_init_aux(hack, y, x, m); ! /* Slope to bottom left corner */ ! m = SCALE * (1000L * y + 500) / (1000L * x - 500); ! /* Handle "legal" slopes */ ! vinfo_init_aux(hack, y, x, m); } } ! /* Enforce maximal efficiency */ ! if (num_grids < VINFO_MAX_GRIDS) ! { ! quit_fmt("Too few grids (%d < %d)!", ! num_grids, VINFO_MAX_GRIDS); ! } ! /* Enforce maximal efficiency */ ! if (hack->num_slopes < VINFO_MAX_SLOPES) ! { ! quit_fmt("Too few slopes (%d < %d)!", ! hack->num_slopes, VINFO_MAX_SLOPES); } + /* Sort slopes numerically */ + ang_sort_comp = ang_sort_comp_hook_longs; + /* Sort slopes numerically */ + ang_sort_swap = ang_sort_swap_hook_longs; + /* Sort the (unique) slopes */ + ang_sort(hack->slopes, NULL, hack->num_slopes); + /* Enqueue player grid */ + queue[queue_tail++] = &vinfo[0]; ! /* Process queue */ ! while (queue_head < queue_tail) ! { ! int e; + vinfo_type *p; ! /* Index */ ! e = queue_head; ! /* Dequeue next grid */ ! p = queue[queue_head++]; ! /* Main Grid */ ! g = vinfo[e].grid_0; ! /* Location */ ! y = GRID_Y(g); ! x = GRID_X(g); ! /* Compute grid offsets */ ! vinfo[e].grid_0 = GRID(+y,+x); ! vinfo[e].grid_1 = GRID(+x,+y); ! vinfo[e].grid_2 = GRID(+x,-y); ! vinfo[e].grid_3 = GRID(+y,-x); ! vinfo[e].grid_4 = GRID(-y,-x); ! vinfo[e].grid_5 = GRID(-x,-y); ! vinfo[e].grid_6 = GRID(-x,+y); ! vinfo[e].grid_7 = GRID(-y,+x); ! /* Analyze slopes */ ! for (i = 0; i < hack->num_slopes; ++i) ! { ! m = hack->slopes[i]; + /* Memorize intersection slopes (for non-player-grids) */ + if ((e > 0) && + (hack->slopes_min[y][x] < m) && + (m < hack->slopes_max[y][x])) + { + switch (i / 32) + { + case 3: vinfo[e].bits_3 |= (1L << (i % 32)); break; + case 2: vinfo[e].bits_2 |= (1L << (i % 32)); break; + case 1: vinfo[e].bits_1 |= (1L << (i % 32)); break; + case 0: vinfo[e].bits_0 |= (1L << (i % 32)); break; + } + } + } + /* Default */ + vinfo[e].next_0 = &vinfo[0]; ! /* Grid next child */ ! if (distance(0, 0, y, x+1) <= MAX_SIGHT) ! { ! g = GRID(y,x+1); ! if (queue[queue_tail-1]->grid_0 != g) ! { ! vinfo[queue_tail].grid_0 = g; ! queue[queue_tail] = &vinfo[queue_tail]; ! queue_tail++; ! } + vinfo[e].next_0 = &vinfo[queue_tail - 1]; + } ! /* Default */ ! vinfo[e].next_1 = &vinfo[0]; + /* Grid diag child */ + if (distance(0, 0, y+1, x+1) <= MAX_SIGHT) + { + g = GRID(y+1,x+1); ! if (queue[queue_tail-1]->grid_0 != g) ! { ! vinfo[queue_tail].grid_0 = g; ! queue[queue_tail] = &vinfo[queue_tail]; ! queue_tail++; ! } + vinfo[e].next_1 = &vinfo[queue_tail - 1]; + } ! /* Hack -- main diagonal has special children */ ! if (y == x) vinfo[e].next_0 = vinfo[e].next_1; ! /* Extra values */ ! vinfo[e].y = y; ! vinfo[e].x = x; ! vinfo[e].d = ((y > x) ? (y + x/2) : (x + y/2)); ! vinfo[e].r = ((!y) ? x : (!x) ? y : (y == x) ? y : 0); } ! /* Verify maximal bits XXX XXX XXX */ ! if (((vinfo[1].bits_3 | vinfo[2].bits_3) != VINFO_BITS_3) || ! ((vinfo[1].bits_2 | vinfo[2].bits_2) != VINFO_BITS_2) || ! ((vinfo[1].bits_1 | vinfo[2].bits_1) != VINFO_BITS_1) || ! ((vinfo[1].bits_0 | vinfo[2].bits_0) != VINFO_BITS_0)) ! { ! quit("Incorrect bit masks!"); } ! /* Kill hack */ ! KILL(hack, vinfo_hack); ! /* Success */ ! return (0); ! } ! /* ! * Forget the "CAVE_VIEW" grids, redrawing as needed ! */ ! void forget_view(void) ! { ! int i, g; + int fast_view_n = view_n; + u16b *fast_view_g = view_g; + + byte *fast_cave_info = &cave_info[0][0]; + + + /* None to forget */ + if (!fast_view_n) return; ! /* Clear them all */ ! for (i = 0; i < fast_view_n; i++) { ! int y, x; ! /* Grid */ ! g = fast_view_g[i]; ! /* Location */ ! y = GRID_Y(g); ! x = GRID_X(g); ! ! /* Clear "CAVE_VIEW" and "CAVE_SEEN" flags */ ! fast_cave_info[g] &= ~(CAVE_VIEW | CAVE_SEEN); ! ! /* Clear "CAVE_LITE" flag */ ! /* fast_cave_info[g] &= ~(CAVE_LITE); */ ! ! /* Redraw */ ! lite_spot(y, x); } + /* None left */ + fast_view_n = 0; + ! /* Save 'view_n' */ ! view_n = fast_view_n; } /* ! * Calculate the complete field of view using a new algorithm ! * ! * If "view_g" and "temp_g" were global pointers to arrays of grids, as ! * opposed to actual arrays of grids, then we could be more efficient by ! * using "pointer swapping". ! * ! * Note the following idiom, which is used in the function below. ! * This idiom processes each "octant" of the field of view, in a ! * clockwise manner, starting with the east strip, south side, ! * and for each octant, allows a simple calculation to set "g" ! * equal to the proper grids, relative to "pg", in the octant. ! * ! * for (o2 = 0; o2 < 16; o2 += 2) ! * ... ! * g = pg + *((s16b*)(((byte*)(p))+o2)); ! * ... ! * ! * ! * Normally, vision along the major axes is more likely than vision ! * along the diagonal axes, so we check the bits corresponding to ! * the lines of sight near the major axes first. ! * ! * We use the "temp_g" array (and the "CAVE_TEMP" flag) to keep track of ! * which grids were previously marked "CAVE_SEEN", since only those grids ! * whose "CAVE_SEEN" value changes during this routine must be redrawn. ! * ! * This function is now responsible for maintaining the "CAVE_SEEN" ! * flags as well as the "CAVE_VIEW" flags, which is good, because ! * the only grids which normally need to be memorized and/or redrawn ! * are the ones whose "CAVE_SEEN" flag changes during this routine. ! * ! * Basically, this function divides the "octagon of view" into octants of ! * grids (where grids on the main axes and diagonal axes are "shared" by ! * two octants), and processes each octant one at a time, processing each ! * octant one grid at a time, processing only those grids which "might" be ! * viewable, and setting the "CAVE_VIEW" flag for each grid for which there ! * is an (unobstructed) line of sight from the center of the player grid to ! * any internal point in the grid (and collecting these "CAVE_VIEW" grids ! * into the "view_g" array), and setting the "CAVE_SEEN" flag for the grid ! * if, in addition, the grid is "illuminated" in some way. ! * ! * This function relies on a theorem (suggested and proven by Mat Hostetter) ! * which states that in each octant of a field of view, a given grid will ! * be "intersected" by one or more unobstructed "lines of sight" from the ! * center of the player grid if and only if it is "intersected" by at least ! * one such unobstructed "line of sight" which passes directly through some ! * corner of some grid in the octant which is not shared by any other octant. ! * The proof is based on the fact that there are at least three significant ! * lines of sight involving any non-shared grid in any octant, one which ! * intersects the grid and passes though the corner of the grid closest to ! * the player, and two which "brush" the grid, passing through the "outer" ! * corners of the grid, and that any line of sight which intersects a grid ! * without passing through the corner of a grid in the octant can be "slid" ! * slowly towards the corner of the grid closest to the player, until it ! * either reaches it or until it brushes the corner of another grid which ! * is closer to the player, and in either case, the existanc of a suitable ! * line of sight is thus demonstrated. ! * ! * It turns out that in each octant of the radius 20 "octagon of view", ! * there are 161 grids (with 128 not shared by any other octant), and there ! * are exactly 126 distinct "lines of sight" passing from the center of the ! * player grid through any corner of any non-shared grid in the octant. To ! * determine if a grid is "viewable" by the player, therefore, you need to ! * simply show that one of these 126 lines of sight intersects the grid but ! * does not intersect any wall grid closer to the player. So we simply use ! * a bit vector with 126 bits to represent the set of interesting lines of ! * sight which have not yet been obstructed by wall grids, and then we scan ! * all the grids in the octant, moving outwards from the player grid. For ! * each grid, if any of the lines of sight which intersect that grid have not ! * yet been obstructed, then the grid is viewable. Furthermore, if the grid ! * is a wall grid, then all of the lines of sight which intersect the grid ! * should be marked as obstructed for future reference. Also, we only need ! * to check those grids for whom at least one of the "parents" was a viewable ! * non-wall grid, where the parents include the two grids touching the grid ! * but closer to the player grid (one adjacent, and one diagonal). For the ! * bit vector, we simply use 4 32-bit integers. All of the static values ! * which are needed by this function are stored in the large "vinfo" array ! * (above), which is machine generated by another program. XXX XXX XXX ! * ! * Hack -- The queue must be able to hold more than VINFO_MAX_GRIDS grids ! * because the grids at the edge of the field of view use "grid zero" as ! * their children, and the queue must be able to hold several of these ! * special grids. Because the actual number of required grids is bizarre, ! * we simply allocate twice as many as we would normally need. XXX XXX XXX */ void update_view(void) { int py = p_ptr->py; int px = p_ptr->px; ! int pg = GRID(py,px); ! int i, g, o2; ! int radius; + int fast_view_n = view_n; + u16b *fast_view_g = view_g; ! int fast_temp_n = 0; ! u16b *fast_temp_g = temp_g; ! byte *fast_cave_info = &cave_info[0][0]; ! byte info; /*** Step 0 -- Begin ***/ /* Save the old "view" grids for later */ ! for (i = 0; i < fast_view_n; i++) { ! /* Grid */ ! g = fast_view_g[i]; ! /* Get grid info */ ! info = fast_cave_info[g]; ! /* Save "CAVE_SEEN" grids */ ! if (info & (CAVE_SEEN)) ! { ! /* Set "CAVE_TEMP" flag */ ! info |= (CAVE_TEMP); ! /* Save grid for later */ ! fast_temp_g[fast_temp_n++] = g; ! } ! /* Clear "CAVE_VIEW" and "CAVE_SEEN" flags */ ! info &= ~(CAVE_VIEW | CAVE_SEEN); ! /* Clear "CAVE_LITE" flag */ ! /* info &= ~(CAVE_LITE); */ + /* Save cave info */ + fast_cave_info[g] = info; + } ! /* Reset the "view" array */ ! fast_view_n = 0; ! /* Extract "radius" value */ ! radius = p_ptr->cur_lite; ! /* Handle real light */ ! if (radius > 0) ++radius; ! /*** Step 1 -- player grid ***/ ! /* Player grid */ ! g = pg; + /* Get grid info */ + info = fast_cave_info[g]; ! /* Assume viewable */ ! info |= (CAVE_VIEW); ! /* Torch-lit grid */ ! if (0 < radius) { ! /* Mark as "CAVE_SEEN" */ ! info |= (CAVE_SEEN); ! /* Mark as "CAVE_LITE" */ ! /* info |= (CAVE_LITE); */ } ! /* Perma-lit grid */ ! else if (info & (CAVE_GLOW)) { ! /* Mark as "CAVE_SEEN" */ ! info |= (CAVE_SEEN); } ! /* Save cave info */ ! fast_cave_info[g] = info; ! /* Save in array */ ! fast_view_g[fast_view_n++] = g; ! /*** Step 2 -- octants ***/ ! /* Scan each octant */ ! for (o2 = 0; o2 < 16; o2 += 2) { ! vinfo_type *p; + /* Last added */ + vinfo_type *last = &vinfo[0]; ! /* Grid queue */ ! int queue_head = 0; ! int queue_tail = 0; ! vinfo_type *queue[VINFO_MAX_GRIDS*2]; + /* Slope bit vector */ + u32b bits0 = VINFO_BITS_0; + u32b bits1 = VINFO_BITS_1; + u32b bits2 = VINFO_BITS_2; + u32b bits3 = VINFO_BITS_3; ! /* Reset queue */ ! queue_head = queue_tail = 0; + /* Initial grids */ + queue[queue_tail++] = &vinfo[1]; + queue[queue_tail++] = &vinfo[2]; ! /* Process queue */ ! while (queue_head < queue_tail) { ! /* Dequeue next grid */ ! p = queue[queue_head++]; ! /* Check bits */ ! if ((bits0 & (p->bits_0)) || ! (bits1 & (p->bits_1)) || ! (bits2 & (p->bits_2)) || ! (bits3 & (p->bits_3))) { ! /* Extract grid value XXX XXX XXX */ ! g = pg + *((s16b*)(((byte*)(p))+o2)); ! /* Get grid info */ ! info = fast_cave_info[g]; ! /* Handle wall */ ! if (info & (CAVE_WALL)) { ! /* Clear bits */ ! bits0 &= ~(p->bits_0); ! bits1 &= ~(p->bits_1); ! bits2 &= ~(p->bits_2); ! bits3 &= ~(p->bits_3); ! /* Newly viewable wall */ ! if (!(info & (CAVE_VIEW))) { ! /* Mark as viewable */ ! info |= (CAVE_VIEW); ! /* Torch-lit grids */ ! if (p->d < radius) ! { ! /* Mark as "CAVE_SEEN" */ ! info |= (CAVE_SEEN); ! /* Mark as "CAVE_LITE" */ ! /* info |= (CAVE_LITE); */ ! } ! /* Perma-lit grids */ ! else if (info & (CAVE_GLOW)) ! { ! int y = GRID_Y(g); ! int x = GRID_X(g); ! /* Hack -- move towards player */ ! int yy = (y < py) ? (y + 1) : (y > py) ? (y - 1) : y; ! int xx = (x < px) ? (x + 1) : (x > px) ? (x - 1) : x; ! ! #ifdef UPDATE_VIEW_COMPLEX_WALL_ILLUMINATION ! ! /* Check for "complex" illumination */ ! if ((!(cave_info[yy][xx] & (CAVE_WALL)) && ! (cave_info[yy][xx] & (CAVE_GLOW))) || ! (!(cave_info[y][xx] & (CAVE_WALL)) && ! (cave_info[y][xx] & (CAVE_GLOW))) || ! (!(cave_info[yy][x] & (CAVE_WALL)) && ! (cave_info[yy][x] & (CAVE_GLOW)))) ! { ! /* Mark as seen */ ! info |= (CAVE_SEEN); ! } ! ! #else /* UPDATE_VIEW_COMPLEX_WALL_ILLUMINATION */ ! ! /* Check for "simple" illumination */ ! if (cave_info[yy][xx] & (CAVE_GLOW)) ! { ! /* Mark as seen */ ! info |= (CAVE_SEEN); ! } + #endif /* UPDATE_VIEW_COMPLEX_WALL_ILLUMINATION */ ! } ! /* Save cave info */ ! fast_cave_info[g] = info; ! /* Save in array */ ! fast_view_g[fast_view_n++] = g; } } ! /* Handle non-wall */ ! else { ! /* Enqueue child */ ! if (last != p->next_0) { ! queue[queue_tail++] = last = p->next_0; } ! /* Enqueue child */ ! if (last != p->next_1) { ! queue[queue_tail++] = last = p->next_1; } ! /* Newly viewable non-wall */ ! if (!(info & (CAVE_VIEW))) { ! /* Mark as "viewable" */ ! info |= (CAVE_VIEW); ! /* Torch-lit grids */ ! if (p->d < radius) ! { ! /* Mark as "CAVE_SEEN" */ ! info |= (CAVE_SEEN); ! /* Mark as "CAVE_LITE" */ ! /* info |= (CAVE_LITE); */ ! } ! /* Perma-lit grids */ ! else if (info & (CAVE_GLOW)) ! { ! /* Mark as "CAVE_SEEN" */ ! info |= (CAVE_SEEN); ! } ! /* Save cave info */ ! fast_cave_info[g] = info; ! ! /* Save in array */ ! fast_view_g[fast_view_n++] = g; } } } } } ! /*** Step 3 -- Complete the algorithm ***/ ! ! /* Handle blindness */ ! if (p_ptr->blind) ! { ! /* Process "new" grids */ ! for (i = 0; i < fast_view_n; i++) ! { ! /* Grid */ ! g = fast_view_g[i]; ! ! /* Grid cannot be "CAVE_SEEN" */ ! fast_cave_info[g] &= ~(CAVE_SEEN); ! } ! } /* Process "new" grids */ ! for (i = 0; i < fast_view_n; i++) { ! /* Grid */ ! g = fast_view_g[i]; ! /* Get grid info */ ! info = fast_cave_info[g]; ! /* Was not "CAVE_SEEN", is now "CAVE_SEEN" */ ! if ((info & (CAVE_SEEN)) && !(info & (CAVE_TEMP))) { ! int y, x; ! /* Location */ ! y = GRID_Y(g); ! x = GRID_X(g); /* Note */ note_spot(y, x); *************** *** 2710,2746 **** } /* Process "old" grids */ ! for (n = 0; n < temp_n; n++) { ! y = temp_y[n]; ! x = temp_x[n]; ! /* No longer in the array */ ! cave_info[y][x] &= ~(CAVE_TEMP); ! /* Redraw "old" grids */ ! if (!(cave_info[y][x] & (CAVE_VIEW))) { /* Redraw */ lite_spot(y, x); } } ! /* None left */ ! temp_n = 0; } - /* - * Hack -- keep the code above simple - */ - #undef DY1 - #undef DY2 - #undef DX1 - #undef DX2 /* * Hack -- provide some "speed" for the "flow" code --- 2725,2772 ---- } /* Process "old" grids */ ! for (i = 0; i < fast_temp_n; i++) { ! /* Grid */ ! g = fast_temp_g[i]; ! ! /* Get grid info */ ! info = fast_cave_info[g]; ! ! /* Clear "CAVE_TEMP" flag */ ! info &= ~(CAVE_TEMP); ! /* Save cave info */ ! fast_cave_info[g] = info; ! /* Was "CAVE_SEEN", is now not "CAVE_SEEN" */ ! if (!(info & (CAVE_SEEN))) { + int y, x; + + /* Location */ + y = GRID_Y(g); + x = GRID_X(g); + /* Redraw */ lite_spot(y, x); } } ! ! /* Save 'view_n' */ ! view_n = fast_view_n; } + #ifdef MONSTER_FLOW + /* + * Size of the circular queue used by "update_flow()" + */ + #define FLOW_MAX 2048 /* * Hack -- provide some "speed" for the "flow" code *************** *** 2756,2762 **** * able to track down either the player or a position recently * occupied by the player. */ ! static int flow_n = 0; /* --- 2782,2791 ---- * able to track down either the player or a position recently * occupied by the player. */ ! static int flow_save = 0; ! ! #endif /* MONSTER_FLOW */ ! /* *************** *** 2770,2776 **** int x, y; /* Nothing to forget */ ! if (!flow_n) return; /* Check the entire dungeon */ for (y = 0; y < DUNGEON_HGT; y++) --- 2799,2805 ---- int x, y; /* Nothing to forget */ ! if (!flow_save) return; /* Check the entire dungeon */ for (y = 0; y < DUNGEON_HGT; y++) *************** *** 2784,2854 **** } /* Start over */ ! flow_n = 0; #endif } - #ifdef MONSTER_FLOW - - /* - * Hack -- Allow us to treat the "seen" array as a queue - */ - static int flow_head = 0; - static int flow_tail = 0; - - - /* - * Take note of a reachable grid. Assume grid is legal. - */ - static void update_flow_aux(int y, int x, int n) - { - int old_head = flow_head; - - - /* Ignore "pre-stamped" entries */ - if (cave_when[y][x] == flow_n) return; - - /* Ignore "walls" and "rubble" */ - if (cave_feat[y][x] >= FEAT_RUBBLE) return; - - /* Save the time-stamp */ - cave_when[y][x] = flow_n; - - /* Save the flow cost */ - cave_cost[y][x] = n; - - /* Hack -- limit flow depth */ - if (n == MONSTER_FLOW_DEPTH) return; - - /* Enqueue that entry */ - temp_y[flow_head] = y; - temp_x[flow_head] = x; - - /* Advance the queue */ - if (++flow_head == TEMP_MAX) flow_head = 0; - - /* Hack -- notice overflow by forgetting new entry */ - if (flow_head == flow_tail) flow_head = old_head; - } - - #endif - - /* ! * Hack -- fill in the "cost" field of every grid that the player ! * can "reach" with the number of steps needed to reach that grid. ! * This also yields the "distance" of the player from every grid. * ! * In addition, mark the "when" of the grids that can reach ! * the player with the incremented value of "flow_n". * ! * Hack -- use the "seen" array as a "circular queue". * ! * We do not need a priority queue because the cost from grid ! * to grid is always "one" and we process them in order. */ void update_flow(void) { --- 2813,2838 ---- } /* Start over */ ! flow_save = 0; #endif } /* ! * Hack -- fill in the "cost" field of every grid that the player can ! * "reach" with the number of steps needed to reach that grid. This ! * also yields the "distance" of the player from every grid. * ! * In addition, mark the "when" of the grids that can reach the player ! * with the incremented value of "flow_save". * ! * Hack -- use the local "flow_y" and "flow_x" arrays as a "circular ! * queue" of cave grids. * ! * We do not need a priority queue because the cost from grid to grid ! * is always "one" (even along diagonals) and we process them in order. */ void update_flow(void) { *************** *** 2858,2926 **** int py = p_ptr->py; int px = p_ptr->px; ! int x, y, d; /* Hack -- disabled */ if (!flow_by_sound) return; - /* Paranoia -- make sure the array is empty */ - if (temp_n) return; ! /* Cycle the old entries (once per 128 updates) */ ! if (flow_n == 255) { ! /* Rotate the time-stamps */ for (y = 0; y < DUNGEON_HGT; y++) { for (x = 0; x < DUNGEON_WID; x++) { ! int w; ! w = cave_when[y][x]; ! cave_when[y][x] = (w > 128) ? (w - 128) : 0; } } /* Restart */ ! flow_n = 127; } ! /* Start a new flow (never use "zero") */ ! flow_n++; - /* Reset the "queue" */ - flow_head = flow_tail = 0; ! /* Queue the player grid */ ! update_flow_aux(py, px, 0); /* Now process the queue */ while (flow_head != flow_tail) { /* Extract the next entry */ ! y = temp_y[flow_tail]; ! x = temp_x[flow_tail]; ! /* Forget that entry */ ! if (++flow_tail == TEMP_MAX) flow_tail = 0; /* Add the "children" */ for (d = 0; d < 8; d++) { ! /* Add that child if "legal" */ ! update_flow_aux(y+ddy_ddd[d], x+ddx_ddd[d], cave_cost[y][x]+1); ! } ! } ! /* Forget the flow info */ ! flow_head = flow_tail = 0; ! #endif ! } --- 2842,2959 ---- int py = p_ptr->py; int px = p_ptr->px; ! int ty, tx; ! ! int y, x; ! ! int n, d; ! ! int flow_n; ! ! int flow_tail = 0; ! int flow_head = 0; ! ! byte flow_y[FLOW_MAX]; ! byte flow_x[FLOW_MAX]; ! /* Hack -- disabled */ if (!flow_by_sound) return; ! /*** Cycle the flow ***/ ! ! /* Cycle the flow */ ! if (flow_save++ == 255) { ! /* Cycle the flow */ for (y = 0; y < DUNGEON_HGT; y++) { for (x = 0; x < DUNGEON_WID; x++) { ! int w = cave_when[y][x]; ! cave_when[y][x] = (w >= 128) ? (w - 128) : 0; } } /* Restart */ ! flow_save = 128; } ! /* Local variable */ ! flow_n = flow_save; ! ! ! /*** Player Grid ***/ ! ! /* Save the time-stamp */ ! cave_when[py][px] = flow_n; ! ! /* Save the flow cost */ ! cave_cost[py][px] = 0; ! ! /* Enqueue that entry */ ! flow_y[flow_head] = py; ! flow_x[flow_head] = px; + /* Advance the queue */ + ++flow_tail; ! /*** Process Queue ***/ /* Now process the queue */ while (flow_head != flow_tail) { /* Extract the next entry */ ! ty = flow_y[flow_head]; ! tx = flow_x[flow_head]; ! ! /* Forget that entry (with wrap) */ ! if (++flow_head == TEMP_MAX) flow_head = 0; ! /* Child cost */ ! n = cave_cost[ty][tx] + 1; ! ! /* Hack -- Limit flow depth */ ! if (n == MONSTER_FLOW_DEPTH) continue; /* Add the "children" */ for (d = 0; d < 8; d++) { ! int old_head = flow_tail; ! /* Child location */ ! y = ty + ddy_ddd[d]; ! x = tx + ddx_ddd[d]; ! /* Ignore "pre-stamped" entries */ ! if (cave_when[y][x] == flow_n) continue; ! /* Ignore "walls" and "rubble" */ ! if (cave_feat[y][x] >= FEAT_RUBBLE) continue; ! ! /* Save the time-stamp */ ! cave_when[y][x] = flow_n; + /* Save the flow cost */ + cave_cost[y][x] = n; + + /* Enqueue that entry */ + flow_y[flow_tail] = y; + flow_x[flow_tail] = x; + + /* Advance the queue */ + if (++flow_tail == FLOW_MAX) flow_tail = 0; + + /* Hack -- Overflow by forgetting new entry */ + if (flow_tail == flow_head) flow_tail = old_head; + } + } + #endif + } *************** *** 3061,3068 **** } } ! /* Update the monsters */ ! p_ptr->update |= (PU_MONSTERS); /* Redraw map */ p_ptr->redraw |= (PR_MAP); --- 3094,3101 ---- } } ! /* Fully update the visuals */ ! p_ptr->update |= (PU_FORGET_VIEW | PU_UPDATE_VIEW | PU_MONSTERS); /* Redraw map */ p_ptr->redraw |= (PR_MAP); *************** *** 3079,3085 **** { int i, y, x; ! /* Forget every grid */ for (y = 0; y < DUNGEON_HGT; y++) { --- 3112,3118 ---- { int i, y, x; ! /* Forget every grid */ for (y = 0; y < DUNGEON_HGT; y++) { *************** *** 3105,3118 **** o_ptr->marked = FALSE; } ! /* Mega-Hack -- Forget the view and lite */ ! p_ptr->update |= (PU_UN_VIEW | PU_UN_LITE); ! ! /* Update the view and lite */ ! p_ptr->update |= (PU_VIEW | PU_LITE); ! ! /* Update the monsters */ ! p_ptr->update |= (PU_MONSTERS); /* Redraw map */ p_ptr->redraw |= (PR_MAP); --- 3138,3145 ---- o_ptr->marked = FALSE; } ! /* Fully update the visuals */ ! p_ptr->update |= (PU_FORGET_VIEW | PU_UPDATE_VIEW | PU_MONSTERS); /* Redraw map */ p_ptr->redraw |= (PR_MAP); *************** *** 3123,3128 **** --- 3150,3245 ---- + /* + * Light or Darken the town + */ + void town_illuminate(bool daytime) + { + int y, x, i; + + + /* Apply light or darkness */ + for (y = 0; y < DUNGEON_HGT; y++) + { + for (x = 0; x < DUNGEON_WID; x++) + { + /* Interesting grids */ + if (cave_feat[y][x] > FEAT_INVIS) + { + /* Illuminate the grid */ + cave_info[y][x] |= (CAVE_GLOW); + + /* Memorize the grid */ + cave_info[y][x] |= (CAVE_MARK); + } + + /* Boring grids (light) */ + else if (daytime) + { + /* Illuminate the grid */ + cave_info[y][x] |= (CAVE_GLOW); + + /* Hack -- Memorize grids */ + if (view_perma_grids) + { + cave_info[y][x] |= (CAVE_MARK); + } + } + + /* Boring grids (dark) */ + else + { + /* Darken the grid */ + cave_info[y][x] &= ~(CAVE_GLOW); + + /* Hack -- Forget grids */ + if (view_perma_grids) + { + cave_info[y][x] &= ~(CAVE_MARK); + } + } + } + } + + + /* Handle shop doorways */ + for (y = 0; y < DUNGEON_HGT; y++) + { + for (x = 0; x < DUNGEON_WID; x++) + { + /* Track shop doorways */ + if ((cave_feat[y][x] >= FEAT_SHOP_HEAD) && + (cave_feat[y][x] <= FEAT_SHOP_TAIL)) + { + for (i = 0; i < 8; i++) + { + int yy = y + ddy_ddd[i]; + int xx = x + ddx_ddd[i]; + + /* Illuminate the grid */ + cave_info[yy][xx] |= (CAVE_GLOW); + + /* Hack -- Memorize grids */ + if (view_perma_grids) + { + cave_info[yy][xx] |= (CAVE_MARK); + } + } + } + } + } + + + /* Fully update the visuals */ + p_ptr->update |= (PU_FORGET_VIEW | PU_UPDATE_VIEW | PU_MONSTERS); + + /* Redraw map */ + p_ptr->redraw |= (PR_MAP); + + /* Window stuff */ + p_ptr->window |= (PW_OVERHEAD); + } + /* *************** *** 3133,3277 **** /* Change the feature */ cave_feat[y][x] = feat; ! /* Notice */ ! note_spot(y, x); ! /* Redraw */ ! lite_spot(y, x); } /* ! * Calculate "incremental motion". Used by project() and shoot(). ! * Assumes that (*y,*x) lies on the path from (y1,x1) to (y2,x2). */ ! void mmove2(int *y, int *x, int y1, int x1, int y2, int x2) { ! int dy, dx, dist, shift; ! /* Extract the distance travelled */ ! dy = (*y < y1) ? y1 - *y : *y - y1; ! dx = (*x < x1) ? x1 - *x : *x - x1; ! /* Number of steps */ ! dist = (dy > dx) ? dy : dx; ! /* We are calculating the next location */ ! dist++; ! /* Calculate the total distance along each axis */ ! dy = (y2 < y1) ? (y1 - y2) : (y2 - y1); ! dx = (x2 < x1) ? (x1 - x2) : (x2 - x1); - /* Paranoia -- Hack -- no motion */ - if (!dy && !dx) return; ! /* Move mostly vertically */ ! if (dy > dx) { - #if 0 ! int k; ! /* Starting shift factor */ ! shift = dy >> 1; ! /* Extract a shift factor */ ! for (k = 0; k < dist; k++) { ! if (shift <= 0) shift += dy; ! shift -= dx; ! } ! /* Sometimes move along minor axis */ ! if (shift <= 0) (*x) = (x2 < x1) ? (*x - 1) : (*x + 1); ! /* Always move along major axis */ ! (*y) = (y2 < y1) ? (*y - 1) : (*y + 1); ! #endif ! /* Extract a shift factor */ ! shift = (dist * dx + (dy-1) / 2) / dy; ! /* Sometimes move along the minor axis */ ! (*x) = (x2 < x1) ? (x1 - shift) : (x1 + shift); ! /* Always move along major axis */ ! (*y) = (y2 < y1) ? (y1 - dist) : (y1 + dist); } ! /* Move mostly horizontally */ ! else { ! #if 0 ! int k; ! /* Starting shift factor */ ! shift = dx >> 1; ! ! /* Extract a shift factor */ ! for (k = 0; k < dist; k++) { ! if (shift <= 0) shift += dx; ! shift -= dy; } ! /* Sometimes move along minor axis */ ! if (shift <= 0) (*y) = (y2 < y1) ? (*y - 1) : (*y + 1); ! /* Always move along major axis */ ! (*x) = (x2 < x1) ? (*x - 1) : (*x + 1); ! #endif ! /* Extract a shift factor */ ! shift = (dist * dy + (dx-1) / 2) / dx; ! /* Sometimes move along the minor axis */ ! (*y) = (y2 < y1) ? (y1 - shift) : (y1 + shift); ! /* Always move along major axis */ ! (*x) = (x2 < x1) ? (x1 - dist) : (x1 + dist); } } /* * Determine if a bolt spell cast from (y1,x1) to (y2,x2) will arrive ! * at the final destination, assuming no monster gets in the way. * ! * This is slightly (but significantly) different from "los(y1,x1,y2,x2)". */ bool projectable(int y1, int x1, int y2, int x2) { ! int dist, y, x; ! /* Start at the initial location */ ! y = y1, x = x1; ! /* See "project()" */ ! for (dist = 0; dist <= MAX_RANGE; dist++) ! { ! /* Never pass through walls */ ! if (dist && !cave_floor_bold(y, x)) break; ! /* Check for arrival at "final target" */ ! if ((x == x2) && (y == y2)) return (TRUE); ! /* Calculate the new location */ ! mmove2(&y, &x, y1, x1, y2, x2); ! } ! /* Assume obstruction */ ! return (FALSE); } --- 3250,3583 ---- /* Change the feature */ cave_feat[y][x] = feat; ! /* Handle "wall/door" grids */ ! if (feat >= FEAT_DOOR_HEAD) ! { ! cave_info[y][x] |= (CAVE_WALL); ! } ! ! /* Handle "floor"/etc grids */ ! else ! { ! cave_info[y][x] &= ~(CAVE_WALL); ! } ! ! /* Notice/Redraw */ ! if (character_dungeon) ! { ! /* Notice */ ! note_spot(y, x); ! /* Redraw */ ! lite_spot(y, x); ! } } /* ! * Determine the path taken by a projection. ! * ! * The projection will always start from the grid (y1,x1), and will travel ! * towards the grid (y2,x2), touching one grid per unit of distance along ! * the major axis, and stopping when it enters the destination grid or a ! * wall grid, or has travelled the maximum legal distance of "range". ! * ! * Note that "distance" in this function (as in the "update_view()" code) ! * is defined as "MAX(dy,dx) + MIN(dy,dx)/2", which means that the player ! * actually has an "octagon of projection" not a "circle of projection". ! * ! * The path grids are saved into the grid array pointed to by "gp", and ! * there should be room for at least "range" grids in "gp". Note that ! * due to the way in which distance is calculated, this function normally ! * uses fewer than "range" grids for the projection path, so the result ! * of this function should never be compared directly to "range". Note ! * that the initial grid (y1,x1) is never saved into the grid array, not ! * even if the initial grid is also the final grid. XXX XXX XXX ! * ! * The "flg" flags can be used to modify the behavior of this function. ! * ! * In particular, the "PROJECT_STOP" and "PROJECT_THRU" flags have the same ! * semantics as they do for the "project" function, namely, that the path ! * will stop as soon as it hits a monster, or that the path will continue ! * through the destination grid, respectively. ! * ! * The "PROJECT_JUMP" flag, which for the "project()" function means to ! * start at a special grid (which makes no sense in this function), means ! * that the path should be "angled" slightly if needed to avoid any wall ! * grids, allowing the player to "target" any grid which is in "view". ! * This flag is non-trivial and has not yet been implemented, but could ! * perhaps make use of the "vinfo" array (above). XXX XXX XXX ! * ! * This function returns the number of grids (if any) in the path. This ! * function will return zero if and only if (y1,x1) and (y2,x2) are equal. ! * ! * This algorithm is similar to, but slightly different from, the one used ! * by "update_view_los()", and very different from the one used by "los()". */ ! sint project_path(u16b *gp, int range, int y1, int x1, int y2, int x2, int flg) { ! int y, x; ! int n = 0; ! int k = 0; ! /* Absolute */ ! int ay, ax; ! ! /* Offsets */ ! int sy, sx; ! ! /* Fractions */ ! int frac; ! /* Scale factors */ ! int full, half; ! ! /* Slope */ ! int m; ! /* No path necessary (or allowed) */ ! if ((x1 == x2) && (y1 == y2)) return (0); + /* Analyze "dy" */ + if (y2 < y1) + { + ay = (y1 - y2); + sy = -1; + } + else + { + ay = (y2 - y1); + sy = 1; + } ! /* Analyze "dx" */ ! if (x2 < x1) { + ax = (x1 - x2); + sx = -1; + } + else + { + ax = (x2 - x1); + sx = 1; + } ! /* Number of "units" in one "half" grid */ ! half = (ay * ax); ! /* Number of "units" in one "full" grid */ ! full = half << 1; ! ! /* Vertical */ ! if (ay > ax) ! { ! /* Start at tile edge */ ! frac = ax * ax; ! ! /* Let m = ((dx/dy) * full) = (dx * dx * 2) = (frac * 2) */ ! m = frac << 1; ! ! /* Start */ ! y = y1 + sy; ! x = x1; ! ! /* Create the projection path */ ! while (1) { ! /* Save grid */ ! gp[n++] = GRID(y,x); ! ! /* Hack -- Check maximum range */ ! if ((n + (k >> 1)) >= range) break; ! ! /* Sometimes stop at destination grid */ ! if (!(flg & (PROJECT_THRU))) ! { ! if ((x == x2) && (y == y2)) break; ! } ! /* Always stop at non-initial wall grids */ ! if ((n > 0) && !cave_floor_bold(y, x)) break; ! ! /* Sometimes stop at non-initial monsters/players */ ! if (flg & (PROJECT_STOP)) ! { ! if ((n > 0) && (cave_m_idx[y][x] != 0)) break; ! } ! /* Slant */ ! if (m) ! { ! /* Advance (X) part 1 */ ! frac += m; ! /* Horizontal change */ ! if (frac >= half) ! { ! /* Advance (X) part 2 */ ! x += sx; ! /* Advance (X) part 3 */ ! frac -= full; ! /* Track distance */ ! k++; ! } ! } ! /* Advance (Y) */ ! y += sy; ! } } ! /* Horizontal */ ! else if (ax > ay) { + /* Start at tile edge */ + frac = ay * ay; ! /* Let m = ((dy/dx) * full) = (dy * dy * 2) = (frac * 2) */ ! m = frac << 1; ! /* Start */ ! y = y1; ! x = x1 + sx; ! /* Create the projection path */ ! while (1) { ! /* Save grid */ ! gp[n++] = GRID(y,x); ! ! /* Hack -- Check maximum range */ ! if ((n + (k >> 1)) >= range) break; ! ! /* Sometimes stop at destination grid */ ! if (!(flg & (PROJECT_THRU))) ! { ! if ((x == x2) && (y == y2)) break; ! } ! ! /* Always stop at non-initial wall grids */ ! if ((n > 0) && !cave_floor_bold(y, x)) break; ! ! /* Sometimes stop at non-initial monsters/players */ ! if (flg & (PROJECT_STOP)) ! { ! if ((n > 0) && (cave_m_idx[y][x] != 0)) break; ! } ! ! /* Slant */ ! if (m) ! { ! /* Advance (Y) part 1 */ ! frac += m; ! ! /* Vertical change */ ! if (frac >= half) ! { ! /* Advance (Y) part 2 */ ! y += sy; ! ! /* Advance (Y) part 3 */ ! frac -= full; ! ! /* Track distance */ ! k++; ! } ! } ! ! /* Advance (X) */ ! x += sx; } + } + + /* Diagonal */ + else + { + /* Start */ + y = y1 + sy; + x = x1 + sx; ! /* Create the projection path */ ! while (1) ! { ! /* Save grid */ ! gp[n++] = GRID(y,x); ! /* Hack -- Check maximum range */ ! if ((n + (n >> 1)) >= range) break; ! /* Sometimes stop at destination grid */ ! if (!(flg & (PROJECT_THRU))) ! { ! if ((x == x2) && (y == y2)) break; ! } ! /* Always stop at non-initial wall grids */ ! if ((n > 0) && !cave_floor_bold(y, x)) break; ! ! /* Sometimes stop at non-initial monsters/players */ ! if (flg & (PROJECT_STOP)) ! { ! if ((n > 0) && (cave_m_idx[y][x] != 0)) break; ! } ! /* Advance (Y) */ ! y += sy; ! /* Advance (X) */ ! x += sx; ! } } + + + /* Length */ + return (n); } /* * Determine if a bolt spell cast from (y1,x1) to (y2,x2) will arrive ! * at the final destination, assuming that no monster gets in the way, ! * using the "project_path()" function to check the projection path. * ! * Note that no grid is ever "projectable()" from itself. ! * ! * This function is used to determine if the player can (easily) target ! * a given grid, and if a monster can target the player. */ bool projectable(int y1, int x1, int y2, int x2) { ! int y, x; ! int grid_n = 0; ! u16b grid_g[512]; ! /* Check the projection path */ ! grid_n = project_path(grid_g, MAX_RANGE, y1, x1, y2, x2, 0); ! /* No grid is ever projectable from itself */ ! if (!grid_n) return (FALSE); ! /* Final grid */ ! y = GRID_Y(grid_g[grid_n-1]); ! x = GRID_X(grid_g[grid_n-1]); + /* May not end in a wall grid */ + if (!cave_floor_bold(y, x)) return (FALSE); ! /* May not end in an unrequested grid */ ! if ((y != y2) || (x != x2)) return (FALSE); ! ! /* Assume okay */ ! return (TRUE); } *************** *** 3319,3324 **** --- 3625,3632 ---- + + /* * Track a new monster */ *************** *** 3372,3380 **** */ void disturb(int stop_search, int unused_flag) { - /* Unused */ - unused_flag = unused_flag; - /* Cancel auto-commands */ /* p_ptr->command_new = 0; */ --- 3680,3685 ---- *************** *** 3406,3411 **** --- 3711,3726 ---- /* Calculate torch radius */ p_ptr->update |= (PU_TORCH); + + /* Redraw the player */ + if (hidden_player) + { + int py = p_ptr->py; + int px = p_ptr->px; + + /* Redraw player */ + lite_spot(py, px); + } } /* Cancel searching if requested */ *************** *** 3428,3434 **** - /* * Hack -- Check if a level is a "quest" level */ --- 3743,3748 ---- *************** *** 3449,3454 **** --- 3763,3770 ---- /* Nope */ return (FALSE); } + + diff -c -r angband-282/src/cmd1.c angband-283/src/cmd1.c *** angband-282/src/cmd1.c Fri Sep 5 13:30:15 1997 --- angband-283/src/cmd1.c Wed Feb 11 06:30:28 1998 *************** *** 14,19 **** --- 14,20 ---- /* * Determine if the player "hits" a monster (normal combat). + * * Note -- Always miss 5%, always hit 5%, otherwise random. */ bool test_hit_fire(int chance, int ac, int vis) *************** *** 26,42 **** /* Hack -- Instant miss or hit */ if (k < 10) return (k < 5); - /* Never hit */ - if (chance <= 0) return (FALSE); - /* Invisible monsters are harder to hit */ ! if (!vis) chance = (chance + 1) / 2; /* Power competes against armor */ ! if (rand_int(chance) < (ac * 3 / 4)) return (FALSE); ! /* Assume hit */ ! return (TRUE); } --- 27,40 ---- /* Hack -- Instant miss or hit */ if (k < 10) return (k < 5); /* Invisible monsters are harder to hit */ ! if (!vis) chance = chance / 2; /* Power competes against armor */ ! if ((chance > 0) && (rand_int(chance) >= (ac * 3 / 4))) return (TRUE); ! /* Assume miss */ ! return (FALSE); } *************** *** 56,72 **** /* Hack -- Instant miss or hit */ if (k < 10) return (k < 5); - /* Wimpy attack never hits */ - if (chance <= 0) return (FALSE); - /* Penalize invisible targets */ ! if (!vis) chance = (chance + 1) / 2; ! /* Power must defeat armor */ ! if (rand_int(chance) < (ac * 3 / 4)) return (FALSE); ! /* Assume hit */ ! return (TRUE); } --- 54,67 ---- /* Hack -- Instant miss or hit */ if (k < 10) return (k < 5); /* Penalize invisible targets */ ! if (!vis) chance = chance / 2; ! /* Power competes against armor */ ! if ((chance > 0) && (rand_int(chance) >= (ac * 3 / 4))) return (TRUE); ! /* Assume miss */ ! return (FALSE); } *************** *** 75,81 **** * Critical hits (from objects thrown by player) * Factor in item weight, total plusses, and player level. */ ! s16b critical_shot(int weight, int plus, int dam) { int i, k; --- 70,76 ---- * Critical hits (from objects thrown by player) * Factor in item weight, total plusses, and player level. */ ! sint critical_shot(int weight, int plus, int dam) { int i, k; *************** *** 114,120 **** * * Factor in weapon weight, total plusses, player level. */ ! s16b critical_norm(int weight, int plus, int dam) { int i, k; --- 109,115 ---- * * Factor in weapon weight, total plusses, player level. */ ! sint critical_norm(int weight, int plus, int dam) { int i, k; *************** *** 167,173 **** * Note that most brands and slays are x3, except Slay Animal (x2), * Slay Evil (x2), and Kill dragon (x5). */ ! s16b tot_dam_aux(object_type *o_ptr, int tdam, monster_type *m_ptr) { int mult = 1; --- 162,168 ---- * Note that most brands and slays are x3, except Slay Animal (x2), * Slay Evil (x2), and Kill dragon (x5). */ ! sint tot_dam_aux(object_type *o_ptr, int tdam, monster_type *m_ptr) { int mult = 1; *************** *** 522,528 **** p_ptr->redraw |= (PR_GOLD); /* Window stuff */ ! p_ptr->window |= (PW_SPELL | PW_PLAYER); /* Delete the gold */ delete_object_idx(this_o_idx); --- 517,523 ---- p_ptr->redraw |= (PR_GOLD); /* Window stuff */ ! p_ptr->window |= (PW_PLAYER_0 | PW_PLAYER_1); /* Delete the gold */ delete_object_idx(this_o_idx); *************** *** 600,613 **** /* Hack -- 5% hit, 5% miss */ if (k < 10) return (k < 5); - /* Paranoia -- No power */ - if (power <= 0) return (FALSE); - /* Total armor */ ac = p_ptr->ac + p_ptr->to_a; /* Power competes against Armor */ ! if (randint(power) > ((ac * 3) / 4)) return (TRUE); /* Assume miss */ return (FALSE); --- 595,605 ---- /* Hack -- 5% hit, 5% miss */ if (k < 10) return (k < 5); /* Total armor */ ac = p_ptr->ac + p_ptr->to_a; /* Power competes against Armor */ ! if ((power > 0) && (randint(power) >= (ac * 3 / 4))) return (TRUE); /* Assume miss */ return (FALSE); *************** *** 1756,1762 **** row = py + ddy[new_dir]; col = px + ddx[new_dir]; ! /* Unknown grid or non-wall XXX XXX XXX cave_floor_bold(row, col)) */ if (!(cave_info[row][col] & (CAVE_MARK)) || (cave_feat[row][col] < FEAT_SECRET)) { --- 1748,1755 ---- row = py + ddy[new_dir]; col = px + ddx[new_dir]; ! /* Unknown grid or non-wall */ ! /* Was: cave_floor_bold(row, col) */ if (!(cave_info[row][col] & (CAVE_MARK)) || (cave_feat[row][col] < FEAT_SECRET)) { *************** *** 1786,1792 **** row = py + ddy[new_dir]; col = px + ddx[new_dir]; ! /* Unknown grid or non-wall XXX XXX XXX cave_floor_bold(row, col)) */ if (!(cave_info[row][col] & (CAVE_MARK)) || (cave_feat[row][col] < FEAT_SECRET)) { --- 1779,1786 ---- row = py + ddy[new_dir]; col = px + ddx[new_dir]; ! /* Unknown grid or non-wall */ ! /* Was: cave_floor_bold(row, col) */ if (!(cave_info[row][col] & (CAVE_MARK)) || (cave_feat[row][col] < FEAT_SECRET)) { diff -c -r angband-282/src/cmd2.c angband-283/src/cmd2.c *** angband-282/src/cmd2.c Fri Sep 5 13:30:31 1997 --- angband-283/src/cmd2.c Fri Feb 6 04:10:31 1998 *************** *** 556,563 **** /* Open the door */ cave_set_feat(y, x, FEAT_OPEN); ! /* Update some things */ ! p_ptr->update |= (PU_VIEW | PU_LITE | PU_MONSTERS); /* Sound */ sound(SOUND_OPENDOOR); --- 556,563 ---- /* Open the door */ cave_set_feat(y, x, FEAT_OPEN); ! /* Update the visuals */ ! p_ptr->update |= (PU_UPDATE_VIEW | PU_MONSTERS); /* Sound */ sound(SOUND_OPENDOOR); *************** *** 586,593 **** /* Open the door */ cave_set_feat(y, x, FEAT_OPEN); ! /* Update some things */ ! p_ptr->update |= (PU_VIEW | PU_LITE | PU_MONSTERS); /* Sound */ sound(SOUND_OPENDOOR); --- 586,593 ---- /* Open the door */ cave_set_feat(y, x, FEAT_OPEN); ! /* Update the visuals */ ! p_ptr->update |= (PU_UPDATE_VIEW | PU_MONSTERS); /* Sound */ sound(SOUND_OPENDOOR); *************** *** 748,755 **** /* Close the door */ cave_set_feat(y, x, FEAT_DOOR_HEAD + 0x00); ! /* Update some things */ ! p_ptr->update |= (PU_VIEW | PU_LITE | PU_MONSTERS); /* Sound */ sound(SOUND_SHUTDOOR); --- 748,755 ---- /* Close the door */ cave_set_feat(y, x, FEAT_DOOR_HEAD + 0x00); ! /* Update the visuals */ ! p_ptr->update |= (PU_UPDATE_VIEW | PU_MONSTERS); /* Sound */ sound(SOUND_SHUTDOOR); *************** *** 887,894 **** /* Remove the feature */ cave_set_feat(y, x, FEAT_FLOOR); ! /* Update some things */ ! p_ptr->update |= (PU_VIEW | PU_LITE | PU_FLOW | PU_MONSTERS); /* Result */ return (TRUE); --- 887,897 ---- /* Remove the feature */ cave_set_feat(y, x, FEAT_FLOOR); ! /* Update the visuals */ ! p_ptr->update |= (PU_UPDATE_VIEW | PU_MONSTERS); ! ! /* Fully update the flow */ ! p_ptr->update |= (PU_FORGET_FLOW | PU_UPDATE_FLOW); /* Result */ return (TRUE); *************** *** 900,905 **** --- 903,910 ---- * * Assumes that no monster is blocking the destination * + * Uses "twall" (above) to do all "terrain feature changing". + * * Returns TRUE if repeated commands may continue */ static bool do_cmd_tunnel_aux(int y, int x) *************** *** 946,955 **** bool hard = FALSE; /* Found gold */ ! if (cave_feat[y][x] >= FEAT_MAGMA_H) gold = TRUE; /* Extract "quartz" flag XXX XXX XXX */ ! if ((cave_feat[y][x] - FEAT_MAGMA) & 0x01) hard = TRUE; /* Quartz */ if (hard) --- 951,966 ---- bool hard = FALSE; /* Found gold */ ! if (cave_feat[y][x] >= FEAT_MAGMA_H) ! { ! gold = TRUE; ! } /* Extract "quartz" flag XXX XXX XXX */ ! if ((cave_feat[y][x] - FEAT_MAGMA) & 0x01) ! { ! hard = TRUE; ! } /* Quartz */ if (hard) *************** *** 1071,1083 **** } } - /* Notice new floor grids */ - if (!cave_floor_bold(y, x)) - { - /* Update some things */ - p_ptr->update |= (PU_VIEW | PU_LITE | PU_FLOW | PU_MONSTERS); - } - /* Result */ return (more); } --- 1082,1087 ---- *************** *** 1447,1455 **** /* Sound */ sound(SOUND_OPENDOOR); ! /* Update some things */ ! p_ptr->update |= (PU_VIEW | PU_LITE); ! p_ptr->update |= (PU_DISTANCE); } /* Saving throw against stun */ --- 1451,1458 ---- /* Sound */ sound(SOUND_OPENDOOR); ! /* Update the visuals */ ! p_ptr->update |= (PU_UPDATE_VIEW | PU_MONSTERS); } /* Saving throw against stun */ *************** *** 1570,1576 **** * * Attack monsters, tunnel through walls, disarm traps, open doors. * ! * This command must always take a turn, to prevent free detection * of invisible monsters. * * The "semantics" of this command must be chosen before the player --- 1573,1579 ---- * * Attack monsters, tunnel through walls, disarm traps, open doors. * ! * This command must always take energy, to prevent free detection * of invisible monsters. * * The "semantics" of this command must be chosen before the player *************** *** 1807,1816 **** msg_print("You jam the door with a spike."); /* Convert "locked" to "stuck" XXX XXX XXX */ ! if (cave_feat[y][x] < FEAT_DOOR_HEAD + 0x08) cave_feat[y][x] += 0x08; /* Add one spike to the door */ ! if (cave_feat[y][x] < FEAT_DOOR_TAIL) cave_feat[y][x]++; /* Use up, and describe, a single spike, from the bottom */ inven_item_increase(item, -1); --- 1810,1825 ---- msg_print("You jam the door with a spike."); /* Convert "locked" to "stuck" XXX XXX XXX */ ! if (cave_feat[y][x] < FEAT_DOOR_HEAD + 0x08) ! { ! cave_feat[y][x] += 0x08; ! } /* Add one spike to the door */ ! if (cave_feat[y][x] < FEAT_DOOR_TAIL) ! { ! cave_feat[y][x] += 0x01; ! } /* Use up, and describe, a single spike, from the bottom */ inven_item_increase(item, -1); *************** *** 2101,2106 **** --- 2110,2118 ---- /* Save the rest code */ p_ptr->resting = p_ptr->command_arg; + /* Cancel the arg */ + p_ptr->command_arg = 0; + /* Cancel searching */ p_ptr->searching = FALSE; *************** *** 2113,2120 **** /* Handle stuff */ handle_stuff(); ! /* Refresh */ ! Term_fresh(); } --- 2125,2132 ---- /* Handle stuff */ handle_stuff(); ! /* Refresh XXX XXX XXX */ ! if (fresh_before) Term_fresh(); } *************** *** 2200,2209 **** int px = p_ptr->px; int dir, item; ! int j, y, x, ny, nx, ty, tx; int tdam, tdis, thits, tmul; int bonus, chance; - int cur_dis, visible; object_type *o_ptr; object_type *j_ptr; --- 2212,2220 ---- int px = p_ptr->px; int dir, item; ! int i, j, y, x, ty, tx; int tdam, tdis, thits, tmul; int bonus, chance; object_type *o_ptr; object_type *j_ptr; *************** *** 2218,2223 **** --- 2229,2237 ---- char o_name[80]; + int path_n = 0; + u16b path_g[256]; + cptr q, s; int msec = op_ptr->delay_factor * op_ptr->delay_factor; *************** *** 2313,2319 **** /* Boost the damage */ tdam *= tmul; ! /* Base range */ tdis = 10 + 5 * tmul; --- 2327,2333 ---- /* Boost the damage */ tdam *= tmul; ! /* Base range XXX XXX */ tdis = 10 + 5 * tmul; *************** *** 2336,2402 **** ty = p_ptr->target_row; } /* Hack -- Handle stuff */ handle_stuff(); ! ! /* Travel until stopped */ ! for (cur_dis = 0; cur_dis <= tdis; ) { ! /* Hack -- Stop at the target */ ! if ((y == ty) && (x == tx)) break; ! ! /* Calculate the new location (see "project()") */ ! ny = y; ! nx = x; ! mmove2(&ny, &nx, py, px, ty, tx); ! /* Stopped by walls/doors */ if (!cave_floor_bold(ny, nx)) break; ! /* Advance the distance */ ! cur_dis++; ! ! /* Save the new location */ x = nx; y = ny; ! ! /* The player can see the (on screen) missile */ if (panel_contains(y, x) && player_can_see_bold(y, x)) { ! /* Draw, Hilite, Fresh, Pause, Erase */ print_rel(missile_char, missile_attr, y, x); move_cursor_relative(y, x); ! Term_fresh(); Term_xtra(TERM_XTRA_DELAY, msec); lite_spot(y, x); ! Term_fresh(); } ! /* The player cannot see the missile */ else { /* Pause anyway, for consistancy */ Term_xtra(TERM_XTRA_DELAY, msec); } - /* Handle monster */ if (cave_m_idx[y][x] > 0) { monster_type *m_ptr = &m_list[cave_m_idx[y][x]]; monster_race *r_ptr = &r_info[m_ptr->r_idx]; ! /* Check the visibility */ ! visible = m_ptr->ml; /* Note the collision */ hit_body = TRUE; ! /* Did we hit it (penalize range) */ ! if (test_hit_fire(chance - cur_dis, r_ptr->ac, m_ptr->ml)) { bool fear = FALSE; --- 2350,2409 ---- ty = p_ptr->target_row; } + /* Calculate the path */ + path_n = project_path(path_g, tdis, py, px, ty, tx, 0); + /* Hack -- Handle stuff */ handle_stuff(); ! /* Project along the path */ ! for (i = 0; i < path_n; ++i) { ! int ny = GRID_Y(path_g[i]); ! int nx = GRID_X(path_g[i]); ! /* Hack -- Stop before hitting walls */ if (!cave_floor_bold(ny, nx)) break; ! /* Advance */ x = nx; y = ny; ! /* Only do visuals if the player can "see" the missile */ if (panel_contains(y, x) && player_can_see_bold(y, x)) { ! /* Visual effects */ print_rel(missile_char, missile_attr, y, x); move_cursor_relative(y, x); ! if (fresh_before) Term_fresh(); Term_xtra(TERM_XTRA_DELAY, msec); lite_spot(y, x); ! if (fresh_before) Term_fresh(); } ! /* Delay anyway for consistency */ else { /* Pause anyway, for consistancy */ Term_xtra(TERM_XTRA_DELAY, msec); } /* Handle monster */ if (cave_m_idx[y][x] > 0) { monster_type *m_ptr = &m_list[cave_m_idx[y][x]]; monster_race *r_ptr = &r_info[m_ptr->r_idx]; ! int chance2 = chance - distance(py, px, y, x); ! ! int visible = m_ptr->ml; /* Note the collision */ hit_body = TRUE; ! /* Did we hit it (penalize distance travelled) */ ! if (test_hit_fire(chance2, r_ptr->ac, m_ptr->ml)) { bool fear = FALSE; *************** *** 2511,2520 **** int px = p_ptr->px; int dir, item; ! int j, y, x, ny, nx, ty, tx; int chance, tdam, tdis; int mul, div; - int cur_dis, visible; object_type *o_ptr; --- 2518,2526 ---- int px = p_ptr->px; int dir, item; ! int i, j, y, x, ty, tx; int chance, tdam, tdis; int mul, div; object_type *o_ptr; *************** *** 2528,2533 **** --- 2534,2542 ---- char o_name[80]; + int path_n = 0; + u16b path_g[256]; + cptr q, s; int msec = op_ptr->delay_factor * op_ptr->delay_factor; *************** *** 2614,2621 **** x = px; /* Predict the "target" location */ - tx = px + 99 * ddx[dir]; ty = py + 99 * ddy[dir]; /* Check for "target request" */ if ((dir == 5) && target_okay()) --- 2623,2630 ---- x = px; /* Predict the "target" location */ ty = py + 99 * ddy[dir]; + tx = px + 99 * ddx[dir]; /* Check for "target request" */ if ((dir == 5) && target_okay()) *************** *** 2624,2690 **** ty = p_ptr->target_row; } /* Hack -- Handle stuff */ handle_stuff(); ! ! /* Travel until stopped */ ! for (cur_dis = 0; cur_dis <= tdis; ) { ! /* Hack -- Stop at the target */ ! if ((y == ty) && (x == tx)) break; ! ! /* Calculate the new location (see "project()") */ ! ny = y; ! nx = x; ! mmove2(&ny, &nx, py, px, ty, tx); ! /* Stopped by walls/doors */ if (!cave_floor_bold(ny, nx)) break; ! /* Advance the distance */ ! cur_dis++; ! ! /* Save the new location */ x = nx; y = ny; ! ! /* The player can see the (on screen) missile */ if (panel_contains(y, x) && player_can_see_bold(y, x)) { ! /* Draw, Hilite, Fresh, Pause, Erase */ print_rel(missile_char, missile_attr, y, x); move_cursor_relative(y, x); ! Term_fresh(); Term_xtra(TERM_XTRA_DELAY, msec); lite_spot(y, x); ! Term_fresh(); } ! /* The player cannot see the missile */ else { /* Pause anyway, for consistancy */ Term_xtra(TERM_XTRA_DELAY, msec); } - /* Handle monster */ if (cave_m_idx[y][x] > 0) { monster_type *m_ptr = &m_list[cave_m_idx[y][x]]; monster_race *r_ptr = &r_info[m_ptr->r_idx]; ! /* Check the visibility */ ! visible = m_ptr->ml; /* Note the collision */ hit_body = TRUE; /* Did we hit it (penalize range) */ ! if (test_hit_fire(chance - cur_dis, r_ptr->ac, m_ptr->ml)) { bool fear = FALSE; --- 2633,2692 ---- ty = p_ptr->target_row; } + /* Calculate the path */ + path_n = project_path(path_g, tdis, py, px, ty, tx, 0); + /* Hack -- Handle stuff */ handle_stuff(); ! /* Project along the path */ ! for (i = 0; i < path_n; ++i) { ! int ny = GRID_Y(path_g[i]); ! int nx = GRID_X(path_g[i]); ! /* Hack -- Stop before hitting walls */ if (!cave_floor_bold(ny, nx)) break; ! /* Advance */ x = nx; y = ny; ! /* Only do visuals if the player can "see" the missile */ if (panel_contains(y, x) && player_can_see_bold(y, x)) { ! /* Visual effects */ print_rel(missile_char, missile_attr, y, x); move_cursor_relative(y, x); ! if (fresh_before) Term_fresh(); Term_xtra(TERM_XTRA_DELAY, msec); lite_spot(y, x); ! if (fresh_before) Term_fresh(); } ! /* Delay anyway for consistency */ else { /* Pause anyway, for consistancy */ Term_xtra(TERM_XTRA_DELAY, msec); } /* Handle monster */ if (cave_m_idx[y][x] > 0) { monster_type *m_ptr = &m_list[cave_m_idx[y][x]]; monster_race *r_ptr = &r_info[m_ptr->r_idx]; ! int chance2 = chance - distance(py, px, y, x); ! ! int visible = m_ptr->ml; /* Note the collision */ hit_body = TRUE; /* Did we hit it (penalize range) */ ! if (test_hit_fire(chance2, r_ptr->ac, m_ptr->ml)) { bool fear = FALSE; diff -c -r angband-282/src/cmd3.c angband-283/src/cmd3.c *** angband-282/src/cmd3.c Thu Sep 4 10:17:51 1997 --- angband-283/src/cmd3.c Wed Feb 11 06:30:28 1998 *************** *** 20,34 **** */ void do_cmd_inven(void) { - char out_val[160]; - - /* Note that we are in "inventory" mode */ p_ptr->command_wrk = FALSE; ! /* Save the screen */ ! Term_save(); /* Hack -- show empty slots */ item_tester_full = TRUE; --- 20,31 ---- */ void do_cmd_inven(void) { /* Note that we are in "inventory" mode */ p_ptr->command_wrk = FALSE; ! /* Save screen */ ! screen_save(); /* Hack -- show empty slots */ item_tester_full = TRUE; *************** *** 39,66 **** /* Hack -- hide empty slots */ item_tester_full = FALSE; ! /* Build a prompt */ ! sprintf(out_val, "Inventory (carrying %d.%d pounds). Command: ", ! p_ptr->total_weight / 10, p_ptr->total_weight % 10); ! ! /* Get a command */ ! prt(out_val, 0, 0); ! /* Get a new command */ p_ptr->command_new = inkey(); ! /* Restore the screen */ ! Term_load(); ! /* Process "Escape" */ if (p_ptr->command_new == ESCAPE) { /* Reset stuff */ p_ptr->command_new = 0; } ! /* Process normal keys */ else { /* Hack -- Use "display" mode */ --- 36,59 ---- /* Hack -- hide empty slots */ item_tester_full = FALSE; ! /* Prompt for a command */ ! prt("(Inventory) Command: ", 0, 0); ! /* Hack -- Get a new command */ p_ptr->command_new = inkey(); ! /* Load screen */ ! screen_load(); ! /* Hack -- Process "Escape" */ if (p_ptr->command_new == ESCAPE) { /* Reset stuff */ p_ptr->command_new = 0; } ! /* Hack -- Process normal keys */ else { /* Hack -- Use "display" mode */ *************** *** 74,88 **** */ void do_cmd_equip(void) { - char out_val[160]; - - /* Note that we are in "equipment" mode */ p_ptr->command_wrk = TRUE; ! /* Save the screen */ ! Term_save(); /* Hack -- show empty slots */ item_tester_full = TRUE; --- 67,78 ---- */ void do_cmd_equip(void) { /* Note that we are in "equipment" mode */ p_ptr->command_wrk = TRUE; ! /* Save screen */ ! screen_save(); /* Hack -- show empty slots */ item_tester_full = TRUE; *************** *** 93,120 **** /* Hack -- undo the hack above */ item_tester_full = FALSE; ! /* Build a prompt */ ! sprintf(out_val, "Equipment (carrying %d.%d pounds). Command: ", ! p_ptr->total_weight / 10, p_ptr->total_weight % 10); ! /* Get a command */ ! prt(out_val, 0, 0); ! ! /* Get a new command */ p_ptr->command_new = inkey(); ! /* Restore the screen */ ! Term_load(); ! /* Process "Escape" */ if (p_ptr->command_new == ESCAPE) { /* Reset stuff */ p_ptr->command_new = 0; } ! /* Process normal keys */ else { /* Enter "display" mode */ --- 83,106 ---- /* Hack -- undo the hack above */ item_tester_full = FALSE; ! /* Prompt for a command */ ! prt("(Equipment) Command: ", 0, 0); ! /* Hack -- Get a new command */ p_ptr->command_new = inkey(); ! /* Load screen */ ! screen_load(); ! /* Hack -- Process "Escape" */ if (p_ptr->command_new == ESCAPE) { /* Reset stuff */ p_ptr->command_new = 0; } ! /* Hack -- Process normal keys */ else { /* Enter "display" mode */ *************** *** 283,289 **** p_ptr->update |= (PU_MANA); /* Window stuff */ ! p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER); } --- 269,275 ---- p_ptr->update |= (PU_MANA); /* Window stuff */ ! p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER_0 | PW_PLAYER_1); } *************** *** 366,386 **** o_ptr = &o_list[0 - item]; } ! /* Assume one item */ ! amt = 1; ! ! /* Use "p_ptr->command_arg" */ ! if (p_ptr->command_arg) ! { ! /* Extract a number */ ! amt = p_ptr->command_arg; ! ! /* Clear "p_ptr->command_arg" */ ! p_ptr->command_arg = 0; ! /* Enforce the maximum */ ! if (amt > o_ptr->number) amt = o_ptr->number; ! } /* Hack -- Cannot remove cursed items */ if ((item >= INVEN_WIELD) && cursed_p(o_ptr)) --- 352,362 ---- o_ptr = &o_list[0 - item]; } ! /* Get a quantity */ ! amt = get_quantity(NULL, o_ptr->number); ! /* Allow user abort */ ! if (amt <= 0) return; /* Hack -- Cannot remove cursed items */ if ((item >= INVEN_WIELD) && cursed_p(o_ptr)) *************** *** 417,424 **** cptr q, s; - bool force = FALSE; - /* Get an item */ q = "Destroy which item? "; --- 393,398 ---- *************** *** 437,460 **** o_ptr = &o_list[0 - item]; } ! /* Assume one item */ ! amt = 1; ! /* Use "p_ptr->command_arg" */ ! if (p_ptr->command_arg) ! { ! /* Hack XXX XXX */ ! force = TRUE; ! ! /* Extract a number */ ! amt = p_ptr->command_arg; ! ! /* Clear "p_ptr->command_arg" */ ! p_ptr->command_arg = 0; ! ! /* Enforce the maximum */ ! if (amt > o_ptr->number) amt = o_ptr->number; ! } /* Describe the object */ old_number = o_ptr->number; --- 411,421 ---- o_ptr = &o_list[0 - item]; } ! /* Get a quantity */ ! amt = get_quantity(NULL, o_ptr->number); ! /* Allow user abort */ ! if (amt <= 0) return; /* Describe the object */ old_number = o_ptr->number; *************** *** 462,469 **** object_desc(o_name, o_ptr, TRUE, 3); o_ptr->number = old_number; ! /* Hack -- Verify destruction XXX XXX XXX */ ! if (!force) { sprintf(out_val, "Really destroy %s? ", o_name); if (!get_check(out_val)) return; --- 423,430 ---- object_desc(o_name, o_ptr, TRUE, 3); o_ptr->number = old_number; ! /* Verify destruction */ ! if (verify_destroy) { sprintf(out_val, "Really destroy %s? ", o_name); if (!get_check(out_val)) return; *************** *** 634,640 **** char o_name[80]; ! char out_val[80]; cptr q, s; --- 595,601 ---- char o_name[80]; ! char tmp[81]; cptr q, s; *************** *** 664,683 **** msg_print(NULL); /* Start with nothing */ ! strcpy(out_val, ""); /* Use old inscription */ if (o_ptr->note) { /* Start with the old inscription */ ! strcpy(out_val, quark_str(o_ptr->note)); } /* Get a new inscription (possibly empty) */ ! if (get_string("Inscription: ", out_val, 80)) { /* Save the inscription */ ! o_ptr->note = quark_add(out_val); /* Combine the pack */ p_ptr->notice |= (PN_COMBINE); --- 625,644 ---- msg_print(NULL); /* Start with nothing */ ! strcpy(tmp, ""); /* Use old inscription */ if (o_ptr->note) { /* Start with the old inscription */ ! strcpy(tmp, quark_str(o_ptr->note)); } /* Get a new inscription (possibly empty) */ ! if (get_string("Inscription: ", tmp, 80)) { /* Save the inscription */ ! o_ptr->note = quark_add(tmp); /* Combine the pack */ p_ptr->notice |= (PN_COMBINE); *************** *** 923,929 **** void do_cmd_target(void) { /* Target set */ ! if (target_set(TARGET_KILL)) { msg_print("Target Selected."); } --- 884,890 ---- void do_cmd_target(void) { /* Target set */ ! if (target_set_interactive(TARGET_KILL)) { msg_print("Target Selected."); } *************** *** 943,949 **** void do_cmd_look(void) { /* Look around */ ! if (target_set(TARGET_LOOK)) { msg_print("Target Selected."); } --- 904,910 ---- void do_cmd_look(void) { /* Look around */ ! if (target_set_interactive(TARGET_LOOK)) { msg_print("Target Selected."); } *************** *** 999,1008 **** if (!get_com(out_val, &command)) break; /* Extract direction */ ! dir = keymap_dirs[command & 0x7F]; /* Error */ ! if (!dir) bell(); } /* No direction */ --- 960,969 ---- if (!get_com(out_val, &command)) break; /* Extract direction */ ! dir = target_dir(command); /* Error */ ! if (!dir) bell("Illegal direction for locate!"); } /* No direction */ *************** *** 1027,1054 **** p_ptr->wy = y2; p_ptr->wx = x2; - /* Update stuff */ - p_ptr->update |= (PU_MONSTERS); - /* Redraw map */ p_ptr->redraw |= (PR_MAP); /* Handle stuff */ handle_stuff(); } } ! /* Recenter the map around the player */ ! verify_panel(); ! ! /* Update stuff */ ! p_ptr->update |= (PU_MONSTERS); ! ! /* Redraw map */ ! p_ptr->redraw |= (PR_MAP); ! ! /* Window stuff */ ! p_ptr->window |= (PW_OVERHEAD); /* Handle stuff */ handle_stuff(); --- 988,1006 ---- p_ptr->wy = y2; p_ptr->wx = x2; /* Redraw map */ p_ptr->redraw |= (PR_MAP); + /* Window stuff */ + p_ptr->window |= (PW_OVERHEAD); + /* Handle stuff */ handle_stuff(); } } ! /* Verify panel */ ! p_ptr->update |= (PU_PANEL); /* Handle stuff */ handle_stuff(); *************** *** 1252,1260 **** u16b holder; - /* XXX XXX */ - v = v ? v : 0; - /* Swap */ holder = who[a]; who[a] = who[b]; --- 1204,1209 ---- *************** *** 1320,1326 **** * * The responses may be sorted in several ways, see below. * ! * Note that the player ghosts are ignored. XXX XXX XXX */ void do_cmd_query_symbol(void) { --- 1269,1275 ---- * * The responses may be sorted in several ways, see below. * ! * Note that the player ghosts are ignored, since they do not exist. */ void do_cmd_query_symbol(void) { *************** *** 1398,1404 **** if (!n) return; ! /* Prompt XXX XXX XXX */ put_str("Recall details? (k/p/y/n): ", 0, 40); /* Query */ --- 1347,1353 ---- if (!n) return; ! /* Prompt */ put_str("Recall details? (k/p/y/n): ", 0, 40); /* Query */ *************** *** 1465,1472 **** /* Recall */ if (recall) { ! /* Save the screen */ ! Term_save(); /* Recall on screen */ screen_roff(who[i]); --- 1414,1421 ---- /* Recall */ if (recall) { ! /* Save screen */ ! screen_save(); /* Recall on screen */ screen_roff(who[i]); *************** *** 1481,1488 **** /* Unrecall */ if (recall) { ! /* Restore */ ! Term_load(); } /* Normal commands */ --- 1430,1437 ---- /* Unrecall */ if (recall) { ! /* Load screen */ ! screen_load(); } /* Normal commands */ diff -c -r angband-282/src/cmd4.c angband-283/src/cmd4.c *** angband-282/src/cmd4.c Fri Sep 5 13:30:48 1997 --- angband-283/src/cmd4.c Wed Feb 11 06:30:28 1998 *************** *** 30,41 **** term *old = Term; ! /* Hack -- react to changes */ ! Term_xtra(TERM_XTRA_REACT, 0); ! /* Verify the keymap */ ! keymap_init(); /* Combine and Reorder the pack (later) */ --- 30,44 ---- term *old = Term; ! /* Low level flush */ ! Term_flush(); + /* Reset "inkey()" */ + flush(); ! ! /* Hack -- React to changes */ ! Term_xtra(TERM_XTRA_REACT, 0); /* Combine and Reorder the pack (later) */ *************** *** 48,71 **** /* Update stuff */ p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS); ! /* Forget lite/view */ ! p_ptr->update |= (PU_UN_VIEW | PU_UN_LITE); ! ! /* Update lite/view */ ! p_ptr->update |= (PU_VIEW | PU_LITE); ! ! /* Update monsters */ ! p_ptr->update |= (PU_MONSTERS); /* Redraw everything */ ! p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP); /* Window stuff */ ! p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER); /* Window stuff */ p_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_MONSTER | PW_OBJECT); /* Hack -- update */ handle_stuff(); --- 51,71 ---- /* Update stuff */ p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS); ! /* Fully update the visuals */ ! p_ptr->update |= (PU_FORGET_VIEW | PU_UPDATE_VIEW | PU_MONSTERS); /* Redraw everything */ ! p_ptr->redraw |= (PR_BASIC | PR_EXTRA | PR_MAP); /* Window stuff */ ! p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER_0 | PW_PLAYER_1); /* Window stuff */ p_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_MONSTER | PW_OBJECT); + /* Clear screen */ + Term_clear(); + /* Hack -- update */ handle_stuff(); *************** *** 100,113 **** int mode = 0; ! char tmp[160]; ! ! /* Enter "icky" mode */ ! character_icky = TRUE; ! /* Save the screen */ ! Term_save(); /* Forever */ while (1) --- 100,112 ---- int mode = 0; ! cptr p; ! /* Prompt */ ! p = "['c' to change name, 'f' to file, 'h' to change mode, or ESC]"; ! /* Save screen */ ! screen_save(); /* Forever */ while (1) *************** *** 116,123 **** display_player(mode); /* Prompt */ ! Term_putstr(2, 23, -1, TERM_WHITE, ! "['c' to change name, 'f' to file, 'h' to change mode, or ESC]"); /* Query */ c = inkey(); --- 115,121 ---- display_player(mode); /* Prompt */ ! Term_putstr(2, 23, -1, TERM_WHITE, p); /* Query */ c = inkey(); *************** *** 134,140 **** --- 132,141 ---- /* File dump */ else if (c == 'f') { + char tmp[81]; + sprintf(tmp, "%s.txt", op_ptr->base_name); + if (get_string("File name: ", tmp, 80)) { if (tmp[0] && (tmp[0] != ' ')) *************** *** 147,170 **** /* Toggle mode */ else if (c == 'h') { ! mode++; } /* Oops */ else { ! bell(); } /* Flush messages */ msg_print(NULL); } ! /* Restore the screen */ ! Term_load(); ! ! /* Leave "icky" mode */ ! character_icky = FALSE; } --- 148,168 ---- /* Toggle mode */ else if (c == 'h') { ! mode = !mode; } /* Oops */ else { ! bell("Illegal command for change name!"); } /* Flush messages */ msg_print(NULL); } ! /* Load screen */ ! screen_load(); } *************** *** 197,204 **** { int i, j, k, n, q; ! char shower[80]; ! char finder[80]; /* Wipe finder */ --- 195,202 ---- { int i, j, k, n, q; ! char shower[81]; ! char finder[81]; /* Wipe finder */ *************** *** 218,228 **** q = 0; ! /* Enter "icky" mode */ ! character_icky = TRUE; ! ! /* Save the screen */ ! Term_save(); /* Process requests until done */ while (1) --- 216,223 ---- q = 0; ! /* Save screen */ ! screen_save(); /* Process requests until done */ while (1) *************** *** 383,396 **** } /* Hack -- Error of some kind */ ! if (i == j) bell(); } ! /* Restore the screen */ ! Term_load(); ! ! /* Leave "icky" mode */ ! character_icky = FALSE; } --- 378,388 ---- } /* Hack -- Error of some kind */ ! if (i == j) bell(NULL); } ! /* Load screen */ ! screen_load(); } *************** *** 529,535 **** default: { ! bell(); break; } } --- 521,527 ---- default: { ! bell("Illegal command for cheat options!"); break; } } *************** *** 643,649 **** default: { ! bell(); break; } } --- 635,641 ---- default: { ! bell("Illegal command for normal options!"); break; } } *************** *** 656,670 **** */ static void do_cmd_options_win(void) { ! int i, j; int y = 0; int x = 0; char ch; - bool go = TRUE; - u32b old_flag[8]; --- 648,660 ---- */ static void do_cmd_options_win(void) { ! int i, j, d; int y = 0; int x = 0; char ch; u32b old_flag[8]; *************** *** 680,686 **** Term_clear(); /* Interact */ ! while (go) { /* Prompt */ prt("Window flags ( to move, 't' to toggle, or ESC)", 0, 0); --- 670,676 ---- Term_clear(); /* Interact */ ! while (1) { /* Prompt */ prt("Window flags ( to move, 't' to toggle, or ESC)", 0, 0); *************** *** 739,790 **** /* Get key */ ch = inkey(); ! /* Analyze */ ! switch (ch) { ! case ESCAPE: ! case 'q': { ! go = FALSE; ! break; } ! case 't': ! case '.': ! case '5': ! case '0': { ! /* Hack -- ignore the main window */ ! if (x == 0) ! { ! bell(); ! break; ! } ! ! /* Toggle flag */ ! if (op_ptr->window_flag[x] & (1L << y)) ! { ! op_ptr->window_flag[x] &= ~(1L << y); ! } ! else ! { ! op_ptr->window_flag[x] |= (1L << y); ! } ! ! break; } ! default: { ! int d = keymap_dirs[ch & 0x7F]; ! x = (x + ddx[d] + 8) % 8; ! y = (y + ddy[d] + 16) % 16; ! if (!d) bell(); ! ! break; ! } } } --- 729,776 ---- /* Get key */ ch = inkey(); ! /* Allow escape */ ! if ((ch == ESCAPE) || (ch == 'q')) break; ! ! /* Toggle */ ! if ((ch == '5') || (ch == 't')) { ! /* Hack -- ignore the main window */ ! if (x == 0) { ! bell("Cannot set main window flags!"); } ! /* Toggle flag (off) */ ! else if (op_ptr->window_flag[x] & (1L << y)) { ! op_ptr->window_flag[x] &= ~(1L << y); } ! /* Toggle flag (on) */ ! else { ! op_ptr->window_flag[x] |= (1L << y); ! } ! /* Continue */ ! continue; ! } ! /* Extract direction */ ! d = target_dir(ch); ! ! /* Move */ ! if (d != 0) ! { ! x = (x + ddx[d] + 8) % 8; ! y = (y + ddy[d] + 16) % 16; ! } ! ! /* Oops */ ! else ! { ! bell("Illegal command for window options!"); } } *************** *** 827,837 **** int k; ! /* Enter "icky" mode */ ! character_icky = TRUE; ! ! /* Save the screen */ ! Term_save(); /* Interact */ --- 813,820 ---- int k; ! /* Save screen */ ! screen_save(); /* Interact */ *************** *** 937,943 **** k = inkey(); if (k == ESCAPE) break; if (isdigit(k)) op_ptr->delay_factor = D2I(k); ! else bell(); } break; --- 920,926 ---- k = inkey(); if (k == ESCAPE) break; if (isdigit(k)) op_ptr->delay_factor = D2I(k); ! else bell("Illegal delay factor!"); } break; *************** *** 959,965 **** k = inkey(); if (k == ESCAPE) break; if (isdigit(k)) op_ptr->hitpoint_warn = D2I(k); ! else bell(); } break; --- 942,948 ---- k = inkey(); if (k == ESCAPE) break; if (isdigit(k)) op_ptr->hitpoint_warn = D2I(k); ! else bell("Illegal hitpoint warning!"); } break; *************** *** 969,975 **** default: { /* Oops */ ! bell(); break; } } --- 952,958 ---- default: { /* Oops */ ! bell("Illegal command for options!"); break; } } *************** *** 979,989 **** } ! /* Restore the screen */ ! Term_load(); ! ! /* Leave "icky" mode */ ! character_icky = FALSE; } --- 962,969 ---- } ! /* Load screen */ ! screen_load(); } *************** *** 995,1010 **** */ void do_cmd_pref(void) { ! char buf[80]; /* Default */ ! strcpy(buf, ""); /* Ask for a "user pref command" */ ! if (!get_string("Pref: ", buf, 80)) return; /* Process that pref command */ ! (void)process_pref_file_aux(buf); } --- 975,990 ---- */ void do_cmd_pref(void) { ! char tmp[81]; /* Default */ ! strcpy(tmp, ""); /* Ask for a "user pref command" */ ! if (!get_string("Pref: ", tmp, 80)) return; /* Process that pref command */ ! (void)process_pref_file_aux(tmp); } *************** *** 1056,1066 **** /* Extract the action */ ascii_to_text(buf, macro__pat[i]); - /* Dump command macros */ - if (macro__cmd[i]) fprintf(fff, "C:%s\n", buf); - /* Dump normal macros */ ! else fprintf(fff, "P:%s\n", buf); /* End the macro */ fprintf(fff, "\n\n"); --- 1036,1043 ---- /* Extract the action */ ascii_to_text(buf, macro__pat[i]); /* Dump normal macros */ ! fprintf(fff, "P:%s\n", buf); /* End the macro */ fprintf(fff, "\n\n"); *************** *** 1083,1089 **** * * Note the complex use of the "inkey()" function from "util.c". * ! * Note that both "flush()" calls are extremely important. */ static void do_cmd_macro_aux(char *buf) { --- 1060,1067 ---- * * Note the complex use of the "inkey()" function from "util.c". * ! * Note that both "flush()" calls are extremely important. This may ! * no longer be true, since "util.c" is much simpler now. XXX XXX XXX */ static void do_cmd_macro_aux(char *buf) { *************** *** 1131,1136 **** --- 1109,1229 ---- Term_addstr(-1, TERM_WHITE, tmp); } + + /* + * Hack -- ask for a keymap "trigger" (see below) + * + * Note that both "flush()" calls are extremely important. This may + * no longer be true, since "util.c" is much simpler now. XXX XXX XXX + */ + static void do_cmd_macro_aux_keymap(char *buf) + { + char tmp[1024]; + + + /* Flush */ + flush(); + + + /* Get a key */ + buf[0] = inkey(); + buf[1] = '\0'; + + + /* Convert to ascii */ + ascii_to_text(tmp, buf); + + /* Hack -- display the trigger */ + Term_addstr(-1, TERM_WHITE, tmp); + + + /* Flush */ + flush(); + } + + + /* + * Hack -- append all keymaps to the given file + */ + static errr keymap_dump(cptr fname) + { + int i; + + FILE *fff; + + char key[1024]; + char buf[1024]; + + int mode; + + + /* Roguelike */ + if (rogue_like_commands) + { + mode = KEYMAP_MODE_ROGUE; + } + + /* Original */ + else + { + mode = KEYMAP_MODE_ORIG; + } + + + /* Build the filename */ + path_build(buf, 1024, ANGBAND_DIR_USER, fname); + + /* File type is "TEXT" */ + FILE_TYPE(FILE_TYPE_TEXT); + + /* Append to the file */ + fff = my_fopen(buf, "a"); + + /* Failure */ + if (!fff) return (-1); + + + /* Skip space */ + fprintf(fff, "\n\n"); + + /* Start dumping */ + fprintf(fff, "# Automatic keymap dump\n\n"); + + /* Dump them */ + for (i = 0; i < 256; i++) + { + cptr act; + + /* Loop up the keymap */ + act = keymap_act[mode][i]; + + /* Skip empty keymaps */ + if (!act) continue; + + /* Encode the key */ + buf[0] = i; + buf[1] = '\0'; + ascii_to_text(key, buf); + + /* Encode the action */ + ascii_to_text(buf, act); + + /* Dump the macro */ + fprintf(fff, "M:%d %2s %s\n", mode, key, buf); + } + + /* Start dumping */ + fprintf(fff, "\n\n\n"); + + + /* Close */ + my_fclose(fff); + + /* Success */ + return (0); + } + + #endif *************** *** 1139,1164 **** * * Note that the macro "action" must be defined before the trigger. * ! * XXX XXX XXX Need messages for success, plus "helpful" info */ void do_cmd_macros(void) { int i; ! char tmp[160]; char buf[1024]; /* File type is "TEXT" */ FILE_TYPE(FILE_TYPE_TEXT); ! /* Enter "icky" mode */ ! character_icky = TRUE; - /* Save the screen */ - Term_save(); /* Process requests until done */ while (1) --- 1232,1270 ---- * * Note that the macro "action" must be defined before the trigger. * ! * Could use some helpful instructions on this page. XXX XXX XXX */ void do_cmd_macros(void) { int i; ! char tmp[1024]; char buf[1024]; + int mode; + + + /* Roguelike */ + if (rogue_like_commands) + { + mode = KEYMAP_MODE_ROGUE; + } + + /* Original */ + else + { + mode = KEYMAP_MODE_ORIG; + } + /* File type is "TEXT" */ FILE_TYPE(FILE_TYPE_TEXT); ! /* Save screen */ ! screen_save(); /* Process requests until done */ while (1) *************** *** 1171,1200 **** /* Describe that action */ ! prt("Current action (if any) shown below:", 18, 0); /* Analyze the current action */ ! ascii_to_text(buf, macro__buf); /* Display the current action */ ! prt(buf, 20, 0); /* Selections */ prt("(1) Load a user pref file", 4, 5); #ifdef ALLOW_MACROS ! prt("(2) Dump macros", 5, 5); ! prt("(3) Enter a new action", 6, 5); ! prt("(4) Query a macro action", 7, 5); ! prt("(5) Create a command macro", 8, 5); ! prt("(6) Create a normal macro", 9, 5); ! prt("(7) Create an identity macro", 10, 5); ! prt("(8) Create an empty macro", 11, 5); ! prt("(9) Define a special keymap", 12, 5); #endif /* ALLOW_MACROS */ /* Prompt */ ! prt("Command: ", 14, 0); /* Get a command */ i = inkey(); --- 1277,1307 ---- /* Describe that action */ ! prt("Current action (if any) shown below:", 20, 0); /* Analyze the current action */ ! ascii_to_text(buf, macro_buffer); /* Display the current action */ ! prt(buf, 22, 0); /* Selections */ prt("(1) Load a user pref file", 4, 5); #ifdef ALLOW_MACROS ! prt("(2) Append macros to a file", 5, 5); ! prt("(3) Query a macro", 6, 5); ! prt("(4) Create a macro", 7, 5); ! prt("(5) Remove a macro", 8, 5); ! prt("(6) Append keymaps to a file", 9, 5); ! prt("(7) Query a keymap", 10, 5); ! prt("(8) Create a keymap", 11, 5); ! prt("(9) Remove a keymap", 12, 5); ! prt("(0) Enter a new action", 13, 5); #endif /* ALLOW_MACROS */ /* Prompt */ ! prt("Command: ", 16, 0); /* Get a command */ i = inkey(); *************** *** 1206,1242 **** else if (i == '1') { /* Prompt */ ! prt("Command: Load a user pref file", 14, 0); /* Prompt */ ! prt("File: ", 16, 0); /* Default filename */ ! sprintf(tmp, "user.prf"); /* Ask for a file */ ! if (!askfor_aux(tmp, 70)) continue; /* Process the given filename */ ! (void)process_pref_file(tmp); } #ifdef ALLOW_MACROS ! /* Save a 'macro' file */ else if (i == '2') { /* Prompt */ ! prt("Command: Save a macro file", 14, 0); /* Prompt */ ! prt("File: ", 16, 0); /* Default filename */ ! sprintf(tmp, "user.prf"); /* Ask for a file */ ! if (!askfor_aux(tmp, 70)) continue; /* Drop priv's */ safe_setuid_drop(); --- 1313,1353 ---- else if (i == '1') { /* Prompt */ ! prt("Command: Load a user pref file", 16, 0); /* Prompt */ ! prt("File: ", 18, 0); /* Default filename */ ! sprintf(tmp, "%s.prf", op_ptr->base_name); /* Ask for a file */ ! if (!askfor_aux(tmp, 80)) continue; /* Process the given filename */ ! if (0 != process_pref_file(tmp)) ! { ! /* Prompt */ ! msg_print("Could not load file!"); ! } } #ifdef ALLOW_MACROS ! /* Save macros */ else if (i == '2') { /* Prompt */ ! prt("Command: Append macros to a file", 16, 0); /* Prompt */ ! prt("File: ", 18, 0); /* Default filename */ ! sprintf(tmp, "%s.prf", op_ptr->base_name); /* Ask for a file */ ! if (!askfor_aux(tmp, 80)) continue; /* Drop priv's */ safe_setuid_drop(); *************** *** 1246,1395 **** /* Grab priv's */ safe_setuid_grab(); } ! /* Enter a new action */ else if (i == '3') { /* Prompt */ ! prt("Command: Enter a new action", 14, 0); ! /* Go to the correct location */ ! Term_gotoxy(0, 20); ! /* Hack -- limit the value */ ! tmp[80] = '\0'; ! /* Get an encoded action */ ! if (!askfor_aux(buf, 80)) continue; ! /* Extract an action */ ! text_to_ascii(macro__buf, buf); } ! /* Query a macro action */ else if (i == '4') { - - #if 0 /* Prompt */ ! prt("Command: Query a macro action", 14, 0); /* Prompt */ ! prt("Enter a macro trigger: ", 16, 0); /* Get a macro trigger */ do_cmd_macro_aux(buf); - #endif ! /* XXX XXX XXX */ ! msg_print("Command not ready."); } ! /* Create a command macro */ else if (i == '5') { /* Prompt */ ! prt("Command: Create a command macro", 14, 0); /* Prompt */ ! prt("Trigger: ", 16, 0); /* Get a macro trigger */ do_cmd_macro_aux(buf); /* Link the macro */ ! macro_add(buf, macro__buf, TRUE); ! /* Message */ ! msg_print("Created a new command macro."); } ! /* Create a normal macro */ else if (i == '6') { /* Prompt */ ! prt("Command: Create a normal macro", 14, 0); /* Prompt */ ! prt("Trigger: ", 16, 0); ! /* Get a macro trigger */ ! do_cmd_macro_aux(buf); ! /* Link the macro */ ! macro_add(buf, macro__buf, FALSE); ! /* Message */ ! msg_print("Created a new normal macro."); } ! /* Create an identity macro */ else if (i == '7') { /* Prompt */ ! prt("Command: Create an identity macro", 14, 0); /* Prompt */ ! prt("Trigger: ", 16, 0); ! /* Get a macro trigger */ ! do_cmd_macro_aux(buf); ! /* Link the macro */ ! macro_add(buf, buf, FALSE); ! /* Message */ ! msg_print("Created a new identity macro."); } ! /* Create an empty macro */ else if (i == '8') { /* Prompt */ ! prt("Command: Create an empty macro", 14, 0); /* Prompt */ ! prt("Trigger: ", 16, 0); ! /* Get a macro trigger */ ! do_cmd_macro_aux(buf); ! /* Link the macro */ ! macro_add(buf, "", FALSE); ! /* Message */ ! msg_print("Created a new empty macro."); } ! /* Define a keymap */ else if (i == '9') { ! char i1, i2, i3; ! /* Flush the input */ ! flush(); ! /* Get the trigger */ ! if (get_com("Type the trigger keypress: ", &i1) && ! get_com("Type the resulting keypress: ", &i2) && ! get_com("Type a direction (or zero): ", &i3)) ! { ! /* Acquire the array index */ ! int k = (i1 & 0x7F); ! int r = (i2 & 0x7F); ! int d = (i3 & 0x7F); ! ! /* Analyze the result key */ ! keymap_cmds[k] = r; ! ! /* Hack -- Analyze the "direction" (always allow numbers) */ ! keymap_dirs[k] = (isdigit(d) ? (d - '0') : keymap_dirs[d]); ! ! /* Success */ ! msg_format("Keypress 0x%02x mapped to 0x%02x (direction %d)", ! k, keymap_cmds[k], keymap_dirs[k]); ! } } #endif /* ALLOW_MACROS */ --- 1357,1608 ---- /* Grab priv's */ safe_setuid_grab(); + + /* Prompt */ + msg_print("Appended macros."); } ! /* Query a macro */ else if (i == '3') { + int k; + /* Prompt */ ! prt("Command: Query a macro", 16, 0); ! /* Prompt */ ! prt("Trigger: ", 18, 0); ! /* Get a macro trigger */ ! do_cmd_macro_aux(buf); ! /* Acquire action */ ! k = macro_find_exact(buf); ! /* Nothing found */ ! if (k < 0) ! { ! /* Prompt */ ! msg_print("Found no macro."); ! } ! ! /* Found one */ ! else ! { ! /* Obtain the action */ ! strcpy(macro_buffer, macro__act[k]); ! ! /* Analyze the current action */ ! ascii_to_text(buf, macro_buffer); ! ! /* Display the current action */ ! prt(buf, 22, 0); ! ! /* Prompt */ ! msg_print("Found a macro."); ! } } ! /* Create a macro */ else if (i == '4') { /* Prompt */ ! prt("Command: Create a macro", 16, 0); /* Prompt */ ! prt("Trigger: ", 18, 0); /* Get a macro trigger */ do_cmd_macro_aux(buf); ! /* Clear */ ! clear_from(20); ! ! /* Prompt */ ! prt("Action: ", 20, 0); ! ! /* Convert to text */ ! ascii_to_text(tmp, macro_buffer); ! ! /* Get an encoded action */ ! if (askfor_aux(tmp, 80)) ! { ! /* Convert to ascii */ ! text_to_ascii(macro_buffer, tmp); ! ! /* Link the macro */ ! macro_add(buf, macro_buffer); ! ! /* Prompt */ ! msg_print("Added a macro."); ! } } ! /* Remove a macro */ else if (i == '5') { /* Prompt */ ! prt("Command: Remove a macro", 16, 0); /* Prompt */ ! prt("Trigger: ", 18, 0); /* Get a macro trigger */ do_cmd_macro_aux(buf); /* Link the macro */ ! macro_add(buf, buf); ! /* Prompt */ ! msg_print("Removed a macro."); } ! /* Save keymaps */ else if (i == '6') { /* Prompt */ ! prt("Command: Append keymaps to a file", 16, 0); /* Prompt */ ! prt("File: ", 18, 0); ! /* Default filename */ ! sprintf(tmp, "%s.prf", op_ptr->base_name); ! /* Ask for a file */ ! if (!askfor_aux(tmp, 80)) continue; ! /* Drop priv's */ ! safe_setuid_drop(); ! ! /* Dump the macros */ ! (void)keymap_dump(tmp); ! ! /* Grab priv's */ ! safe_setuid_grab(); ! ! /* Prompt */ ! msg_print("Appended keymaps."); } ! /* Query a keymap */ else if (i == '7') { + cptr act; + /* Prompt */ ! prt("Command: Query a keymap", 16, 0); /* Prompt */ ! prt("Keypress: ", 18, 0); ! /* Get a keymap trigger */ ! do_cmd_macro_aux_keymap(buf); ! /* Look up the keymap */ ! act = keymap_act[mode][(byte)(buf[0])]; ! /* Nothing found */ ! if (!act) ! { ! /* Prompt */ ! msg_print("Found no keymap."); ! } ! ! /* Found one */ ! else ! { ! /* Obtain the action */ ! strcpy(macro_buffer, act); ! ! /* Analyze the current action */ ! ascii_to_text(buf, macro_buffer); ! ! /* Display the current action */ ! prt(buf, 22, 0); ! ! /* Prompt */ ! msg_print("Found a keymap."); ! } } ! /* Create a keymap */ else if (i == '8') { /* Prompt */ ! prt("Command: Create a keymap", 16, 0); /* Prompt */ ! prt("Keypress: ", 18, 0); ! /* Get a keymap trigger */ ! do_cmd_macro_aux_keymap(buf); ! /* Clear */ ! clear_from(20); ! /* Prompt */ ! prt("Action: ", 20, 0); ! ! /* Convert to text */ ! ascii_to_text(tmp, macro_buffer); ! ! /* Get an encoded action */ ! if (askfor_aux(tmp, 80)) ! { ! /* Convert to ascii */ ! text_to_ascii(macro_buffer, tmp); ! ! /* Free old keymap */ ! string_free(keymap_act[mode][(byte)(buf[0])]); ! ! /* Make new keymap */ ! keymap_act[mode][(byte)(buf[0])] = string_make(macro_buffer); ! ! /* Prompt */ ! msg_print("Added a keymap."); ! } } ! /* Remove a keymap */ else if (i == '9') { ! /* Prompt */ ! prt("Command: Remove a keymap", 16, 0); ! ! /* Prompt */ ! prt("Keypress: ", 18, 0); ! /* Get a keymap trigger */ ! do_cmd_macro_aux_keymap(buf); ! /* Free old keymap */ ! string_free(keymap_act[mode][(byte)(buf[0])]); ! ! /* Make new keymap */ ! keymap_act[mode][(byte)(buf[0])] = NULL; ! ! /* Prompt */ ! msg_print("Removed a keymap."); ! } ! ! /* Enter a new action */ ! else if (i == '0') ! { ! /* Prompt */ ! prt("Command: Enter a new action", 16, 0); ! ! /* Go to the correct location */ ! Term_gotoxy(0, 22); ! ! /* Hack -- limit the value */ ! tmp[80] = '\0'; ! ! /* Get an encoded action */ ! if (!askfor_aux(buf, 80)) continue; ! ! /* Extract an action */ ! text_to_ascii(macro_buffer, buf); } #endif /* ALLOW_MACROS */ *************** *** 1398,1404 **** else { /* Oops */ ! bell(); } /* Flush messages */ --- 1611,1617 ---- else { /* Oops */ ! bell("Illegal command for macros!"); } /* Flush messages */ *************** *** 1406,1416 **** } ! /* Load the screen */ ! Term_load(); ! ! /* Leave "icky" mode */ ! character_icky = FALSE; } --- 1619,1626 ---- } ! /* Load screen */ ! screen_load(); } *************** *** 1433,1443 **** FILE_TYPE(FILE_TYPE_TEXT); ! /* Enter "icky" mode */ ! character_icky = TRUE; ! ! /* Save the screen */ ! Term_save(); /* Interact until done */ --- 1643,1650 ---- FILE_TYPE(FILE_TYPE_TEXT); ! /* Save screen */ ! screen_save(); /* Interact until done */ *************** *** 1482,1491 **** prt("File: ", 17, 0); /* Default filename */ ! sprintf(tmp, "user.prf"); /* Query */ ! if (!askfor_aux(tmp, 70)) continue; /* Process the given filename */ (void)process_pref_file(tmp); --- 1689,1698 ---- prt("File: ", 17, 0); /* Default filename */ ! sprintf(tmp, "%s.prf", op_ptr->base_name); /* Query */ ! if (!askfor_aux(tmp, 80)) continue; /* Process the given filename */ (void)process_pref_file(tmp); *************** *** 1503,1512 **** prt("File: ", 17, 0); /* Default filename */ ! sprintf(tmp, "user.prf"); /* Get a filename */ ! if (!askfor_aux(tmp, 70)) continue; /* Build the filename */ path_build(buf, 1024, ANGBAND_DIR_USER, tmp); --- 1710,1719 ---- prt("File: ", 17, 0); /* Default filename */ ! sprintf(tmp, "%s.prf", op_ptr->base_name); /* Get a filename */ ! if (!askfor_aux(tmp, 80)) continue; /* Build the filename */ path_build(buf, 1024, ANGBAND_DIR_USER, tmp); *************** *** 1563,1572 **** prt("File: ", 17, 0); /* Default filename */ ! sprintf(tmp, "user.prf"); /* Get a filename */ ! if (!askfor_aux(tmp, 70)) continue; /* Build the filename */ path_build(buf, 1024, ANGBAND_DIR_USER, tmp); --- 1770,1779 ---- prt("File: ", 17, 0); /* Default filename */ ! sprintf(tmp, "%s.prf", op_ptr->base_name); /* Get a filename */ ! if (!askfor_aux(tmp, 80)) continue; /* Build the filename */ path_build(buf, 1024, ANGBAND_DIR_USER, tmp); *************** *** 1623,1632 **** prt("File: ", 17, 0); /* Default filename */ ! sprintf(tmp, "user.prf"); /* Get a filename */ ! if (!askfor_aux(tmp, 70)) continue; /* Build the filename */ path_build(buf, 1024, ANGBAND_DIR_USER, tmp); --- 1830,1839 ---- prt("File: ", 17, 0); /* Default filename */ ! sprintf(tmp, "%s.prf", op_ptr->base_name); /* Get a filename */ ! if (!askfor_aux(tmp, 80)) continue; /* Build the filename */ path_build(buf, 1024, ANGBAND_DIR_USER, tmp); *************** *** 1660,1666 **** /* Dump the feature attr/char info */ fprintf(fff, "F:%d:0x%02X:0x%02X\n\n", i, ! (byte)(f_ptr->z_attr), (byte)(f_ptr->z_char)); } /* All done */ --- 1867,1873 ---- /* Dump the feature attr/char info */ fprintf(fff, "F:%d:0x%02X:0x%02X\n\n", i, ! (byte)(f_ptr->x_attr), (byte)(f_ptr->x_char)); } /* All done */ *************** *** 1741,1748 **** { object_kind *k_ptr = &k_info[k]; ! int da = (byte)k_ptr->k_attr; ! int dc = (byte)k_ptr->k_char; int ca = (byte)k_ptr->x_attr; int cc = (byte)k_ptr->x_char; --- 1948,1955 ---- { object_kind *k_ptr = &k_info[k]; ! int da = (byte)k_ptr->d_attr; ! int dc = (byte)k_ptr->d_char; int ca = (byte)k_ptr->x_attr; int cc = (byte)k_ptr->x_char; *************** *** 1796,1805 **** { feature_type *f_ptr = &f_info[f]; ! int da = (byte)f_ptr->f_attr; ! int dc = (byte)f_ptr->f_char; ! int ca = (byte)f_ptr->z_attr; ! int cc = (byte)f_ptr->z_char; /* Label the object */ Term_putstr(5, 17, -1, TERM_WHITE, --- 2003,2012 ---- { feature_type *f_ptr = &f_info[f]; ! int da = (byte)f_ptr->d_attr; ! int dc = (byte)f_ptr->d_char; ! int ca = (byte)f_ptr->x_attr; ! int cc = (byte)f_ptr->x_char; /* Label the object */ Term_putstr(5, 17, -1, TERM_WHITE, *************** *** 1831,1840 **** /* Analyze */ if (i == 'n') f = (f + MAX_F_IDX + 1) % MAX_F_IDX; if (i == 'N') f = (f + MAX_F_IDX - 1) % MAX_F_IDX; ! if (i == 'a') f_info[f].z_attr = (byte)(ca + 1); ! if (i == 'A') f_info[f].z_attr = (byte)(ca - 1); ! if (i == 'c') f_info[f].z_char = (byte)(cc + 1); ! if (i == 'C') f_info[f].z_char = (byte)(cc - 1); } } --- 2038,2047 ---- /* Analyze */ if (i == 'n') f = (f + MAX_F_IDX + 1) % MAX_F_IDX; if (i == 'N') f = (f + MAX_F_IDX - 1) % MAX_F_IDX; ! if (i == 'a') f_info[f].x_attr = (byte)(ca + 1); ! if (i == 'A') f_info[f].x_attr = (byte)(ca - 1); ! if (i == 'c') f_info[f].x_char = (byte)(cc + 1); ! if (i == 'C') f_info[f].x_char = (byte)(cc - 1); } } *************** *** 1853,1859 **** /* Unknown option */ else { ! bell(); } /* Flush messages */ --- 2060,2066 ---- /* Unknown option */ else { ! bell("Illegal command for visuals!"); } /* Flush messages */ *************** *** 1861,1871 **** } ! /* Restore the screen */ ! Term_load(); ! ! /* Leave "icky" mode */ ! character_icky = FALSE; } --- 2068,2075 ---- } ! /* Load screen */ ! screen_load(); } *************** *** 1887,1897 **** FILE_TYPE(FILE_TYPE_TEXT); ! /* Enter "icky" mode */ ! character_icky = TRUE; ! ! /* Save the screen */ ! Term_save(); /* Interact until done */ --- 2091,2098 ---- FILE_TYPE(FILE_TYPE_TEXT); ! /* Save screen */ ! screen_save(); /* Interact until done */ *************** *** 1929,1938 **** prt("File: ", 10, 0); /* Default file */ ! sprintf(tmp, "user.prf"); /* Query */ ! if (!askfor_aux(tmp, 70)) continue; /* Process the given filename */ (void)process_pref_file(tmp); --- 2130,2139 ---- prt("File: ", 10, 0); /* Default file */ ! sprintf(tmp, "%s.prf", op_ptr->base_name); /* Query */ ! if (!askfor_aux(tmp, 80)) continue; /* Process the given filename */ (void)process_pref_file(tmp); *************** *** 1956,1965 **** prt("File: ", 10, 0); /* Default filename */ ! sprintf(tmp, "user.prf"); /* Get a filename */ ! if (!askfor_aux(tmp, 70)) continue; /* Build the filename */ path_build(buf, 1024, ANGBAND_DIR_USER, tmp); --- 2157,2166 ---- prt("File: ", 10, 0); /* Default filename */ ! sprintf(tmp, "%s.prf", op_ptr->base_name); /* Get a filename */ ! if (!askfor_aux(tmp, 80)) continue; /* Build the filename */ path_build(buf, 1024, ANGBAND_DIR_USER, tmp); *************** *** 2090,2096 **** /* Unknown option */ else { ! bell(); } /* Flush messages */ --- 2291,2297 ---- /* Unknown option */ else { ! bell("Illegal command for colors!"); } /* Flush messages */ *************** *** 2098,2108 **** } ! /* Restore the screen */ ! Term_load(); ! ! /* Leave "icky" mode */ ! character_icky = FALSE; } --- 2299,2306 ---- } ! /* Load screen */ ! screen_load(); } *************** *** 2111,2129 **** */ void do_cmd_note(void) { ! char buf[80]; /* Default */ ! strcpy(buf, ""); /* Input */ ! if (!get_string("Note: ", buf, 60)) return; /* Ignore empty notes */ ! if (!buf[0] || (buf[0] == ' ')) return; /* Add the note to the message recall */ ! msg_format("Note: %s", buf); } --- 2309,2327 ---- */ void do_cmd_note(void) { ! char tmp[81]; /* Default */ ! strcpy(tmp, ""); /* Input */ ! if (!get_string("Note: ", tmp, 80)) return; /* Ignore empty notes */ ! if (!tmp[0] || (tmp[0] == ' ')) return; /* Add the note to the message recall */ ! msg_format("Note: %s", tmp); } *************** *** 2216,2226 **** if (!fff) return; ! /* Enter "icky" mode */ ! character_icky = TRUE; - /* Save the screen */ - Term_save(); /* Clear the screen */ Term_clear(); --- 2414,2422 ---- if (!fff) return; ! /* Save screen */ ! screen_save(); /* Clear the screen */ Term_clear(); *************** *** 2285,2295 **** msg_print(NULL); ! /* Restore the screen */ ! Term_load(); ! ! /* Leave "icky" mode */ ! character_icky = FALSE; } --- 2481,2488 ---- msg_print(NULL); ! /* Load screen */ ! screen_load(); } *************** *** 2327,2337 **** if (!fff) return; ! /* Enter "icky" mode */ ! character_icky = TRUE; ! ! /* Save the screen */ ! Term_save(); /* Dump the screen */ --- 2520,2527 ---- if (!fff) return; ! /* Save screen */ ! screen_save(); /* Dump the screen */ *************** *** 2391,2401 **** msg_print(NULL); ! /* Restore the screen */ ! Term_load(); ! ! /* Leave "icky" mode */ ! character_icky = FALSE; } --- 2581,2588 ---- msg_print(NULL); ! /* Load screen */ ! screen_load(); } *************** *** 2412,2418 **** char file_name[1024]; ! char base_name[80]; bool okay[MAX_A_IDX]; --- 2599,2605 ---- char file_name[1024]; ! char o_name[80]; bool okay[MAX_A_IDX]; *************** *** 2498,2504 **** if (!okay[k]) continue; /* Paranoia */ ! strcpy(base_name, "Unknown Artifact"); /* Obtain the base object type */ z = lookup_kind(a_ptr->tval, a_ptr->sval); --- 2685,2691 ---- if (!okay[k]) continue; /* Paranoia */ ! strcpy(o_name, "Unknown Artifact"); /* Obtain the base object type */ z = lookup_kind(a_ptr->tval, a_ptr->sval); *************** *** 2519,2529 **** i_ptr->name1 = k; /* Describe the artifact */ ! object_desc_store(base_name, i_ptr, FALSE, 0); } /* Hack -- Build the artifact name */ ! fprintf(fff, " The %s\n", base_name); } /* Close the file */ --- 2706,2716 ---- i_ptr->name1 = k; /* Describe the artifact */ ! object_desc_store(o_name, i_ptr, FALSE, 0); } /* Hack -- Build the artifact name */ ! fprintf(fff, " The %s\n", o_name); } /* Close the file */ *************** *** 2618,2624 **** if (k_ptr->flags3 & (TR3_INSTA_ART)) continue; /* List known flavored objects */ ! if (k_ptr->has_flavor && k_ptr->aware) { object_type *i_ptr; object_type object_type_body; --- 2805,2811 ---- if (k_ptr->flags3 & (TR3_INSTA_ART)) continue; /* List known flavored objects */ ! if (k_ptr->flavor && k_ptr->aware) { object_type *i_ptr; object_type object_type_body; *************** *** 2660,2670 **** FILE_TYPE(FILE_TYPE_TEXT); ! /* Enter "icky" mode */ ! character_icky = TRUE; ! ! /* Save the screen */ ! Term_save(); /* Interact until done */ --- 2847,2854 ---- FILE_TYPE(FILE_TYPE_TEXT); ! /* Save screen */ ! screen_save(); /* Interact until done */ *************** *** 2714,2720 **** /* Unknown option */ else { ! bell(); } /* Flush messages */ --- 2898,2904 ---- /* Unknown option */ else { ! bell("Illegal command for knowledge!"); } /* Flush messages */ *************** *** 2722,2732 **** } ! /* Restore the screen */ ! Term_load(); ! ! /* Leave "icky" mode */ ! character_icky = FALSE; } --- 2906,2913 ---- } ! /* Load screen */ ! screen_load(); } diff -c -r angband-282/src/cmd5.c angband-283/src/cmd5.c *** angband-282/src/cmd5.c Thu Sep 4 10:17:51 1997 --- angband-283/src/cmd5.c Wed Feb 11 06:30:28 1998 *************** *** 31,37 **** byte spells[64]; ! bool flag, redraw, okay, ask; char choice; magic_type *s_ptr; --- 31,39 ---- byte spells[64]; ! int ver; ! ! bool flag, redraw, okay; char choice; magic_type *s_ptr; *************** *** 81,86 **** --- 83,101 ---- /* No redraw yet */ redraw = FALSE; + #if 0 + /* Show the list */ + if (redraw) + { + /* Save screen */ + screen_save(); + + /* Display a list of spells */ + print_spells(spells, num, 1, 20); + } + + #endif + /* Build a prompt (accept all spells) */ strnfmt(out_val, 78, "(%^ss %c-%c, *=List, ESC=exit) %^s which %s? ", *************** *** 92,130 **** /* Request redraw */ if ((choice == ' ') || (choice == '*') || (choice == '?')) { /* Show the list */ ! if (!redraw) { /* Show list */ redraw = TRUE; ! /* Save the screen */ ! Term_save(); /* Display a list of spells */ print_spells(spells, num, 1, 20); } - /* Hide the list */ - else - { - /* Hide list */ - redraw = FALSE; - - /* Restore the screen */ - Term_load(); - } - /* Ask again */ continue; } /* Note verify */ ! ask = (isupper(choice)); /* Lowercase */ ! if (ask) choice = tolower(choice); /* Extract request */ i = (islower(choice) ? A2I(choice) : -1); --- 107,145 ---- /* Request redraw */ if ((choice == ' ') || (choice == '*') || (choice == '?')) { + /* Hide the list */ + if (redraw) + { + /* Load screen */ + screen_load(); + + /* Hide list */ + redraw = FALSE; + } + /* Show the list */ ! else { /* Show list */ redraw = TRUE; ! /* Save screen */ ! screen_save(); /* Display a list of spells */ print_spells(spells, num, 1, 20); } /* Ask again */ continue; } /* Note verify */ ! ver = (isupper(choice)); /* Lowercase */ ! choice = tolower(choice); /* Extract request */ i = (islower(choice) ? A2I(choice) : -1); *************** *** 132,138 **** /* Totally Illegal */ if ((i < 0) || (i >= num)) { ! bell(); continue; } --- 147,153 ---- /* Totally Illegal */ if ((i < 0) || (i >= num)) { ! bell("Illegal spell choice!"); continue; } *************** *** 142,154 **** /* Require "okay" spells */ if (!spell_okay(spell, known)) { ! bell(); msg_format("You may not %s that %s.", prompt, p); continue; } /* Verify it */ ! if (ask) { char tmp_val[160]; --- 157,169 ---- /* Require "okay" spells */ if (!spell_okay(spell, known)) { ! bell("Illegal spell choice!"); msg_format("You may not %s that %s.", prompt, p); continue; } /* Verify it */ ! if (ver) { char tmp_val[160]; *************** *** 170,176 **** /* Restore the screen */ ! if (redraw) Term_load(); /* Abort if needed */ --- 185,198 ---- /* Restore the screen */ ! if (redraw) ! { ! /* Load screen */ ! screen_load(); ! ! /* Hack -- forget redraw */ ! /* redraw = FALSE; */ ! } /* Abort if needed */ *************** *** 278,300 **** } ! /* Save the screen */ ! Term_save(); /* Display the spells */ print_spells(spells, num, 1, 20); ! /* Clear the top line */ ! prt("", 0, 0); ! /* Prompt user */ ! put_str("[Press any key to continue]", 0, 23); ! /* Wait for key */ ! (void)inkey(); ! /* Restore the screen */ ! Term_load(); } --- 300,327 ---- } ! /* Save screen */ ! screen_save(); /* Display the spells */ print_spells(spells, num, 1, 20); ! /* Prompt for a command */ ! put_str("(Browsing) Command: ", 0, 0); ! /* Hack -- Get a new command */ ! p_ptr->command_new = inkey(); ! /* Load screen */ ! screen_load(); ! ! /* Hack -- Process "Escape" */ ! if (p_ptr->command_new == ESCAPE) ! { ! /* Reset stuff */ ! p_ptr->command_new = 0; ! } } *************** *** 397,407 **** /* Skip non "okay" prayers */ if (!spell_okay(spell, FALSE)) continue; ! /* Hack -- Prepare the randomizer */ ! k++; ! /* Hack -- Apply the randomizer */ ! if (rand_int(k) == 0) gift = spell; } } --- 424,434 ---- /* Skip non "okay" prayers */ if (!spell_okay(spell, FALSE)) continue; ! /* Apply the randomizer */ ! if ((++k > 1) && (rand_int(k) != 0)) continue; ! /* Track it */ ! gift = spell; } } *************** *** 1074,1080 **** p_ptr->redraw |= (PR_MANA); /* Window stuff */ ! p_ptr->window |= (PW_SPELL | PW_PLAYER); } --- 1101,1107 ---- p_ptr->redraw |= (PR_MANA); /* Window stuff */ ! p_ptr->window |= (PW_PLAYER_0 | PW_PLAYER_1); } *************** *** 1404,1410 **** case 26: { ! (void)dispel_undead(plev * 3); break; } --- 1431,1437 ---- case 26: { ! (void)dispel_undead(randint(plev * 3)); break; } *************** *** 1418,1424 **** case 28: { ! (void)dispel_evil(plev * 3); break; } --- 1445,1451 ---- case 28: { ! (void)dispel_evil(randint(plev * 3)); break; } *************** *** 1430,1436 **** case 30: { ! (void)dispel_evil(plev * 4); (void)hp_player(1000); (void)set_afraid(0); (void)set_poisoned(0); --- 1457,1463 ---- case 30: { ! (void)dispel_evil(randint(plev * 4)); (void)hp_player(1000); (void)set_afraid(0); (void)set_poisoned(0); *************** *** 1511,1523 **** case 41: { ! (void)dispel_undead(plev * 4); break; } case 42: { ! (void)dispel_evil(plev * 4); break; } --- 1538,1550 ---- case 41: { ! (void)dispel_undead(randint(plev * 4)); break; } case 42: { ! (void)dispel_evil(randint(plev * 4)); break; } *************** *** 1694,1699 **** p_ptr->redraw |= (PR_MANA); /* Window stuff */ ! p_ptr->window |= (PW_SPELL | PW_PLAYER); } --- 1721,1726 ---- p_ptr->redraw |= (PR_MANA); /* Window stuff */ ! p_ptr->window |= (PW_PLAYER_0 | PW_PLAYER_1); } diff -c -r angband-282/src/cmd6.c angband-283/src/cmd6.c *** angband-282/src/cmd6.c Thu Sep 4 10:17:51 1997 --- angband-283/src/cmd6.c Wed Feb 11 06:30:28 1998 *************** *** 713,719 **** p_ptr->csp_frac = 0; msg_print("Your feel your head clear."); p_ptr->redraw |= (PR_MANA); ! p_ptr->window |= (PW_SPELL | PW_PLAYER); ident = TRUE; } break; --- 713,719 ---- p_ptr->csp_frac = 0; msg_print("Your feel your head clear."); p_ptr->redraw |= (PR_MANA); ! p_ptr->window |= (PW_PLAYER_0 | PW_PLAYER_1); ident = TRUE; } break; *************** *** 955,961 **** p_ptr->update |= (PU_MANA); /* Window stuff */ ! p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER); } return (TRUE); --- 955,961 ---- p_ptr->update |= (PU_MANA); /* Window stuff */ ! p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER_0 | PW_PLAYER_1); } return (TRUE); *************** *** 1019,1025 **** p_ptr->update |= (PU_MANA); /* Window stuff */ ! p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER); } /* Notice */ --- 1019,1025 ---- p_ptr->update |= (PU_MANA); /* Window stuff */ ! p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER_0 | PW_PLAYER_1); } /* Notice */ *************** *** 1714,1720 **** ident = TRUE; msg_print("Your feel your head clear."); p_ptr->redraw |= (PR_MANA); ! p_ptr->window |= (PW_SPELL | PW_PLAYER); } break; } --- 1714,1720 ---- ident = TRUE; msg_print("Your feel your head clear."); p_ptr->redraw |= (PR_MANA); ! p_ptr->window |= (PW_PLAYER_0 | PW_PLAYER_1); } break; } diff -c -r angband-282/src/config.h angband-283/src/config.h *** angband-282/src/config.h Wed Sep 3 11:57:33 1997 --- angband-283/src/config.h Wed Feb 11 06:30:28 1998 *************** *** 169,182 **** /* ! * OPTION: Hack -- Compile in support for "Cyborg" mode */ /* #define ALLOW_BORG */ /* ! * OPTION: Hack -- Compile in support for "Wizard Commands" */ ! /* #define ALLOW_WIZARD */ /* * OPTION: Hack -- Compile in support for "Spoiler Generation" --- 169,182 ---- /* ! * OPTION: Hack -- Compile in support for "Borg mode" */ /* #define ALLOW_BORG */ /* ! * OPTION: Hack -- Compile in support for "Debug Commands" */ ! /* #define ALLOW_DEBUG */ /* * OPTION: Hack -- Compile in support for "Spoiler Generation" *************** *** 305,310 **** --- 305,326 ---- #define MONSTER_FLOW_DEPTH 32 + /* + * OPTION: Support multiple "player" grids in "map_info()" + */ + /* #define MAP_INFO_MULTIPLE_PLAYERS */ + + + /* + * OPTION: Use the new "update_view()" algorithm + */ + #define UPDATE_VIEW_NEW + + /* + * OPTION: Use the "complex" wall illumination code + */ + /* #define UPDATE_VIEW_COMPLEX_WALL_ILLUMINATION */ + /* * OPTION: Enable the "smart_learn" and "smart_cheat" options. *************** *** 420,441 **** /* - * OPTION: For some brain-dead computers with no command line interface, - * namely Macintosh, there has to be some way of "naming" your savefiles. - * The current "Macintosh" hack is to make it so whenever the character - * name changes, the savefile is renamed accordingly. But on normal - * machines, once you manage to "load" a savefile, it stays that way. - * Macintosh is particularly weird because you can load savefiles that - * are not contained in the "lib:save:" folder, and if you change the - * player's name, it will then save the savefile elsewhere. Note that - * this also gives a method of "bypassing" the "VERIFY_TIMESTAMP" code. - */ - #if defined(MACINTOSH) || defined(WINDOWS) || defined(AMIGA) - # define SAVEFILE_MUTABLE - #endif - - - /* * OPTION: Capitalize the "user_name" (for "default" player name) * This option is only relevant on SET_UID machines. */ --- 436,441 ---- *************** *** 446,452 **** /* * OPTION: Person to bother if something goes wrong. */ ! #define MAINTAINER "benh@voicenet.com" /* --- 446,452 ---- /* * OPTION: Person to bother if something goes wrong. */ ! #define MAINTAINER "benh@phial.com" /* *************** *** 492,498 **** # undef DRS_SMART_OPTIONS # undef ALLOW_OLD_SAVEFILES # undef ALLOW_BORG ! # undef ALLOW_WIZARD # undef ALLOW_SPOILERS # undef ALLOW_TEMPLATES # undef DELAY_LOAD_R_TEXT --- 492,498 ---- # undef DRS_SMART_OPTIONS # undef ALLOW_OLD_SAVEFILES # undef ALLOW_BORG ! # undef ALLOW_DEBUG # undef ALLOW_SPOILERS # undef ALLOW_TEMPLATES # undef DELAY_LOAD_R_TEXT diff -c -r angband-282/src/defines.h angband-283/src/defines.h *** angband-282/src/defines.h Wed Sep 3 11:57:33 1997 --- angband-283/src/defines.h Wed Feb 11 06:30:28 1998 *************** *** 39,49 **** /* ! * Current version number of Angband: 2.8.2 */ #define VERSION_MAJOR 2 #define VERSION_MINOR 8 ! #define VERSION_PATCH 2 /* * This value is not currently used --- 39,54 ---- /* ! * Current version string ! */ ! #define VERSION_STRING "2.8.3" ! ! /* ! * Current version numbers */ #define VERSION_MAJOR 2 #define VERSION_MINOR 8 ! #define VERSION_PATCH 3 /* * This value is not currently used *************** *** 170,182 **** /* - * Maximum size of the "lite" array (see "cave.c") - * Note that the "lite radius" will NEVER exceed 5, and even if the "lite" - * was rectangular, we would never require more than 128 entries in the array. - */ - #define LITE_MAX 128 - - /* * Maximum size of the "view" array (see "cave.c") * Note that the "view radius" will NEVER exceed 20, and even if the "view" * was octagonal, we would never require more than 1520 entries in the array. --- 175,180 ---- *************** *** 185,192 **** /* * Maximum size of the "temp" array (see "cave.c") ! * We must be as large as "VIEW_MAX" and "LITE_MAX" for proper functioning ! * of "update_view()" and "update_lite()". We must also be as large as the * largest illuminatable room, but no room is larger than 800 grids. We * must also be large enough to allow "good enough" use as a circular queue, * to calculate monster flow, but note that the flow code is "paranoid". --- 183,190 ---- /* * Maximum size of the "temp" array (see "cave.c") ! * Note that we must be as large as "VIEW_MAX" for proper functioning ! * of the "update_view()" function, and we must also be as large as the * largest illuminatable room, but no room is larger than 800 grids. We * must also be large enough to allow "good enough" use as a circular queue, * to calculate monster flow, but note that the flow code is "paranoid". *************** *** 618,623 **** --- 616,636 ---- #define DRS_RES_DISEN 31 + /* + * Number of keymap modes + */ + #define KEYMAP_MODES 2 + + /* + * Mode for original keyset commands + */ + #define KEYMAP_MODE_ORIG 0 + + /* + * Mode for roguelike keyset commands + */ + #define KEYMAP_MODE_ROGUE 1 + /*** Feature Indexes (see "lib/edit/f_info.txt") ***/ *************** *** 1653,1670 **** #define PU_MANA 0x00000020L /* Calculate csp and msp */ #define PU_SPELLS 0x00000040L /* Calculate spells */ /* xxx (many) */ /* xxx (many) */ ! #define PU_UN_VIEW 0x00010000L /* Forget view */ ! #define PU_UN_LITE 0x00020000L /* Forget lite */ /* xxx (many) */ ! #define PU_VIEW 0x00100000L /* Update view */ ! #define PU_LITE 0x00200000L /* Update lite */ ! /* xxx */ ! #define PU_MONSTERS 0x01000000L /* Update monsters */ ! #define PU_DISTANCE 0x02000000L /* Update distances */ /* xxx */ ! #define PU_FLOW 0x10000000L /* Update flow */ ! /* xxx (many) */ /* --- 1666,1681 ---- #define PU_MANA 0x00000020L /* Calculate csp and msp */ #define PU_SPELLS 0x00000040L /* Calculate spells */ /* xxx (many) */ + #define PU_FORGET_VIEW 0x00010000L /* Forget field of view */ + #define PU_UPDATE_VIEW 0x00020000L /* Update field of view */ /* xxx (many) */ ! #define PU_FORGET_FLOW 0x00100000L /* Forget flow data */ ! #define PU_UPDATE_FLOW 0x00200000L /* Update flow data */ /* xxx (many) */ ! #define PU_MONSTERS 0x10000000L /* Update monsters */ ! #define PU_DISTANCE 0x20000000L /* Update distances */ /* xxx */ ! #define PU_PANEL 0x80000000L /* Update panel */ /* *************** *** 1696,1715 **** /* xxx */ #define PR_EXTRA 0x01000000L /* Display Extra Info */ #define PR_BASIC 0x02000000L /* Display Basic Info */ - #define PR_MAP 0x04000000L /* Display Map */ - #define PR_WIPE 0x08000000L /* Hack -- Total Redraw */ - /* xxx */ - /* xxx */ - /* xxx */ /* xxx */ /* * Bit flags for the "p_ptr->window" variable (etc) */ #define PW_INVEN 0x00000001L /* Display inven/equip */ #define PW_EQUIP 0x00000002L /* Display equip/inven */ ! #define PW_SPELL 0x00000004L /* Display spell list */ ! #define PW_PLAYER 0x00000008L /* Display character */ /* xxx */ /* xxx */ #define PW_MESSAGE 0x00000040L /* Display messages */ --- 1707,1723 ---- /* xxx */ #define PR_EXTRA 0x01000000L /* Display Extra Info */ #define PR_BASIC 0x02000000L /* Display Basic Info */ /* xxx */ + #define PR_MAP 0x08000000L /* Display Map */ + /* xxx (many) */ /* * Bit flags for the "p_ptr->window" variable (etc) */ #define PW_INVEN 0x00000001L /* Display inven/equip */ #define PW_EQUIP 0x00000002L /* Display equip/inven */ ! #define PW_PLAYER_0 0x00000004L /* Display player (basic) */ ! #define PW_PLAYER_1 0x00000008L /* Display player (extra) */ /* xxx */ /* xxx */ #define PW_MESSAGE 0x00000040L /* Display messages */ *************** *** 1735,1744 **** #define CAVE_GLOW 0x02 /* self-illuminating */ #define CAVE_ICKY 0x04 /* part of a vault */ #define CAVE_ROOM 0x08 /* part of a room */ ! #define CAVE_LITE 0x10 /* lite flag */ #define CAVE_VIEW 0x20 /* view flag */ #define CAVE_TEMP 0x40 /* temp flag */ ! #define CAVE_XTRA 0x80 /* misc flag */ --- 1743,1752 ---- #define CAVE_GLOW 0x02 /* self-illuminating */ #define CAVE_ICKY 0x04 /* part of a vault */ #define CAVE_ROOM 0x08 /* part of a room */ ! #define CAVE_SEEN 0x10 /* seen flag */ #define CAVE_VIEW 0x20 /* view flag */ #define CAVE_TEMP 0x40 /* temp flag */ ! #define CAVE_WALL 0x80 /* wall flag */ *************** *** 2252,2258 **** */ #define OPT_rogue_like_commands 0 #define OPT_quick_messages 1 ! #define OPT_other_query_flag 2 #define OPT_carry_query_flag 3 #define OPT_use_old_target 4 #define OPT_always_pickup 5 --- 2260,2266 ---- */ #define OPT_rogue_like_commands 0 #define OPT_quick_messages 1 ! #define OPT_floor_query_flag 2 #define OPT_carry_query_flag 3 #define OPT_use_old_target 4 #define OPT_always_pickup 5 *************** *** 2265,2271 **** #define OPT_show_choices 12 #define OPT_show_details 13 #define OPT_ring_bell 14 ! #define OPT_inventory_colors 15 #define OPT_run_ignore_stairs 16 #define OPT_run_ignore_doors 17 #define OPT_run_cut_corners 18 --- 2273,2279 ---- #define OPT_show_choices 12 #define OPT_show_details 13 #define OPT_ring_bell 14 ! #define OPT_show_flavors 15 #define OPT_run_ignore_stairs 16 #define OPT_run_ignore_doors 17 #define OPT_run_cut_corners 18 *************** *** 2278,2286 **** #define OPT_disturb_other 25 #define OPT_alert_hitpoint 26 #define OPT_alert_failure 27 ! /* xxx */ ! /* xxx */ ! /* xxx */ /* xxx */ #define OPT_auto_haggle 32 #define OPT_auto_scum 33 --- 2286,2294 ---- #define OPT_disturb_other 25 #define OPT_alert_hitpoint 26 #define OPT_alert_failure 27 ! #define OPT_verify_destroy 28 ! #define OPT_verify_special 29 ! #define OPT_allow_quantity 30 /* xxx */ #define OPT_auto_haggle 32 #define OPT_auto_scum 33 *************** *** 2294,2313 **** #define OPT_dungeon_stair 41 #define OPT_flow_by_sound 42 #define OPT_flow_by_smell 43 ! #define OPT_track_follow 44 ! #define OPT_track_target 45 #define OPT_smart_learn 46 #define OPT_smart_cheat 47 #define OPT_view_reduce_lite 48 ! #define OPT_view_reduce_view 49 #define OPT_avoid_abort 50 #define OPT_avoid_other 51 #define OPT_flush_failure 52 #define OPT_flush_disturb 53 ! #define OPT_flush_command 54 #define OPT_fresh_before 55 #define OPT_fresh_after 56 ! #define OPT_fresh_message 57 #define OPT_compress_savefile 58 #define OPT_hilite_player 59 #define OPT_view_yellow_lite 60 --- 2302,2321 ---- #define OPT_dungeon_stair 41 #define OPT_flow_by_sound 42 #define OPT_flow_by_smell 43 ! /* xxx */ ! /* xxx */ #define OPT_smart_learn 46 #define OPT_smart_cheat 47 #define OPT_view_reduce_lite 48 ! #define OPT_hidden_player 49 #define OPT_avoid_abort 50 #define OPT_avoid_other 51 #define OPT_flush_failure 52 #define OPT_flush_disturb 53 ! /* xxx */ #define OPT_fresh_before 55 #define OPT_fresh_after 56 ! /* xxx */ #define OPT_compress_savefile 58 #define OPT_hilite_player 59 #define OPT_view_yellow_lite 60 *************** *** 2322,2328 **** */ #define rogue_like_commands op_ptr->opt[OPT_rogue_like_commands] #define quick_messages op_ptr->opt[OPT_quick_messages] ! #define other_query_flag op_ptr->opt[OPT_other_query_flag] #define carry_query_flag op_ptr->opt[OPT_carry_query_flag] #define use_old_target op_ptr->opt[OPT_use_old_target] #define always_pickup op_ptr->opt[OPT_always_pickup] --- 2330,2336 ---- */ #define rogue_like_commands op_ptr->opt[OPT_rogue_like_commands] #define quick_messages op_ptr->opt[OPT_quick_messages] ! #define floor_query_flag op_ptr->opt[OPT_floor_query_flag] #define carry_query_flag op_ptr->opt[OPT_carry_query_flag] #define use_old_target op_ptr->opt[OPT_use_old_target] #define always_pickup op_ptr->opt[OPT_always_pickup] *************** *** 2335,2341 **** #define show_choices op_ptr->opt[OPT_show_choices] #define show_details op_ptr->opt[OPT_show_details] #define ring_bell op_ptr->opt[OPT_ring_bell] ! #define inventory_colors op_ptr->opt[OPT_inventory_colors] #define run_ignore_stairs op_ptr->opt[OPT_run_ignore_stairs] #define run_ignore_doors op_ptr->opt[OPT_run_ignore_doors] #define run_cut_corners op_ptr->opt[OPT_run_cut_corners] --- 2343,2349 ---- #define show_choices op_ptr->opt[OPT_show_choices] #define show_details op_ptr->opt[OPT_show_details] #define ring_bell op_ptr->opt[OPT_ring_bell] ! #define show_flavors op_ptr->opt[OPT_show_flavors] #define run_ignore_stairs op_ptr->opt[OPT_run_ignore_stairs] #define run_ignore_doors op_ptr->opt[OPT_run_ignore_doors] #define run_cut_corners op_ptr->opt[OPT_run_cut_corners] *************** *** 2348,2356 **** #define disturb_other op_ptr->opt[OPT_disturb_other] #define alert_hitpoint op_ptr->opt[OPT_alert_hitpoint] #define alert_failure op_ptr->opt[OPT_alert_failure] ! /* xxx */ ! /* xxx */ ! /* xxx */ /* xxx */ #define auto_haggle op_ptr->opt[OPT_auto_haggle] #define auto_scum op_ptr->opt[OPT_auto_scum] --- 2356,2364 ---- #define disturb_other op_ptr->opt[OPT_disturb_other] #define alert_hitpoint op_ptr->opt[OPT_alert_hitpoint] #define alert_failure op_ptr->opt[OPT_alert_failure] ! #define verify_destroy op_ptr->opt[OPT_verify_destroy] ! #define verify_special op_ptr->opt[OPT_verify_special] ! #define allow_quantity op_ptr->opt[OPT_allow_quantity] /* xxx */ #define auto_haggle op_ptr->opt[OPT_auto_haggle] #define auto_scum op_ptr->opt[OPT_auto_scum] *************** *** 2364,2383 **** #define dungeon_stair op_ptr->opt[OPT_dungeon_stair] #define flow_by_sound op_ptr->opt[OPT_flow_by_sound] #define flow_by_smell op_ptr->opt[OPT_flow_by_smell] ! #define track_follow op_ptr->opt[OPT_track_follow] ! #define track_target op_ptr->opt[OPT_track_target] #define smart_learn op_ptr->opt[OPT_smart_learn] #define smart_cheat op_ptr->opt[OPT_smart_cheat] #define view_reduce_lite op_ptr->opt[OPT_view_reduce_lite] ! #define view_reduce_view op_ptr->opt[OPT_view_reduce_view] #define avoid_abort op_ptr->opt[OPT_avoid_abort] #define avoid_other op_ptr->opt[OPT_avoid_other] #define flush_failure op_ptr->opt[OPT_flush_failure] #define flush_disturb op_ptr->opt[OPT_flush_disturb] ! #define flush_command op_ptr->opt[OPT_flush_command] #define fresh_before op_ptr->opt[OPT_fresh_before] #define fresh_after op_ptr->opt[OPT_fresh_after] ! #define fresh_message op_ptr->opt[OPT_fresh_message] #define compress_savefile op_ptr->opt[OPT_compress_savefile] #define hilite_player op_ptr->opt[OPT_hilite_player] #define view_yellow_lite op_ptr->opt[OPT_view_yellow_lite] --- 2372,2391 ---- #define dungeon_stair op_ptr->opt[OPT_dungeon_stair] #define flow_by_sound op_ptr->opt[OPT_flow_by_sound] #define flow_by_smell op_ptr->opt[OPT_flow_by_smell] ! /* xxx */ ! /* xxx */ #define smart_learn op_ptr->opt[OPT_smart_learn] #define smart_cheat op_ptr->opt[OPT_smart_cheat] #define view_reduce_lite op_ptr->opt[OPT_view_reduce_lite] ! #define hidden_player op_ptr->opt[OPT_hidden_player] #define avoid_abort op_ptr->opt[OPT_avoid_abort] #define avoid_other op_ptr->opt[OPT_avoid_other] #define flush_failure op_ptr->opt[OPT_flush_failure] #define flush_disturb op_ptr->opt[OPT_flush_disturb] ! /* xxx */ #define fresh_before op_ptr->opt[OPT_fresh_before] #define fresh_after op_ptr->opt[OPT_fresh_after] ! /* xxx */ #define compress_savefile op_ptr->opt[OPT_compress_savefile] #define hilite_player op_ptr->opt[OPT_hilite_player] #define view_yellow_lite op_ptr->opt[OPT_view_yellow_lite] *************** *** 2395,2412 **** */ #define term_screen (angband_term[0]) /* * Determine if a given inventory item is "aware" */ #define object_aware_p(T) \ ! (k_info[(T)->k_idx].aware) /* * Determine if a given inventory item is "tried" */ #define object_tried_p(T) \ ! (k_info[(T)->k_idx].tried) /* --- 2403,2426 ---- */ #define term_screen (angband_term[0]) + /* + * Hack -- random number generation + */ + #define randint(M) \ + (rand_int(M) + 1) + /* * Determine if a given inventory item is "aware" */ #define object_aware_p(T) \ ! (k_info[(T)->k_idx].aware) /* * Determine if a given inventory item is "tried" */ #define object_tried_p(T) \ ! (k_info[(T)->k_idx].tried) /* *************** *** 2415,2443 **** * Test Two -- Check for "Easy Know" + "Aware" */ #define object_known_p(T) \ ! (((T)->ident & (IDENT_KNOWN)) || \ ! (k_info[(T)->k_idx].easy_know && k_info[(T)->k_idx].aware)) /* * Return the "attr" for a given item. ! * Allow user redefinition of "aware" items. ! * Default to the "base" attr for unaware items */ #define object_attr(T) \ ! ((k_info[(T)->k_idx].aware) ? \ ! (k_info[(T)->k_idx].x_attr) : \ ! (k_info[(T)->k_idx].d_attr)) /* * Return the "char" for a given item. ! * Allow user redefinition of "aware" items. ! * Default to the "base" char for unaware items */ #define object_char(T) \ ! ((k_info[(T)->k_idx].aware) ? \ ! (k_info[(T)->k_idx].x_char) : \ ! (k_info[(T)->k_idx].d_char)) --- 2429,2457 ---- * Test Two -- Check for "Easy Know" + "Aware" */ #define object_known_p(T) \ ! (((T)->ident & (IDENT_KNOWN)) || \ ! (k_info[(T)->k_idx].easy_know && k_info[(T)->k_idx].aware)) /* * Return the "attr" for a given item. ! * Use "flavor" if available. ! * Default to user definitions. */ #define object_attr(T) \ ! ((k_info[(T)->k_idx].flavor) ? \ ! (misc_to_attr[k_info[(T)->k_idx].flavor]) : \ ! (k_info[(T)->k_idx].x_attr)) /* * Return the "char" for a given item. ! * Use "flavor" if available. ! * Default to user definitions. */ #define object_char(T) \ ! ((k_info[(T)->k_idx].flavor) ? \ ! (misc_to_char[k_info[(T)->k_idx].flavor]) : \ ! (k_info[(T)->k_idx].x_char)) *************** *** 2446,2481 **** * Artifacts use the "name1" field */ #define artifact_p(T) \ ! ((T)->name1 ? TRUE : FALSE) /* * Ego-Items use the "name2" field */ #define ego_item_p(T) \ ! ((T)->name2 ? TRUE : FALSE) /* * Broken items. */ #define broken_p(T) \ ! ((T)->ident & (IDENT_BROKEN)) /* * Cursed items. */ #define cursed_p(T) \ ! ((T)->ident & (IDENT_CURSED)) /* ! * Determines if a map location is defined ! * Note the hack involving casting the args to unsigned */ #define in_bounds(Y,X) \ ! (((unsigned)(Y) < (unsigned)(DUNGEON_HGT)) && \ ! ((unsigned)(X) < (unsigned)(DUNGEON_WID))) /* * Determines if a map location is fully inside the outer walls --- 2460,2531 ---- * Artifacts use the "name1" field */ #define artifact_p(T) \ ! ((T)->name1 ? TRUE : FALSE) /* * Ego-Items use the "name2" field */ #define ego_item_p(T) \ ! ((T)->name2 ? TRUE : FALSE) /* * Broken items. */ #define broken_p(T) \ ! ((T)->ident & (IDENT_BROKEN)) /* * Cursed items. */ #define cursed_p(T) \ ! ((T)->ident & (IDENT_CURSED)) ! ! ! /* ! * Convert an "attr"/"char" pair into a "pict" (P) ! */ ! #define PICT(A,C) \ ! ((((u16b)(A)) << 8) | ((byte)(C))) ! ! /* ! * Convert a "pict" (P) into an "attr" (A) ! */ ! #define PICT_A(P) \ ! ((byte)((P) >> 8)) ! ! /* ! * Convert a "pict" (P) into an "char" (C) ! */ ! #define PICT_C(P) \ ! ((char)((byte)(P))) + /* + * Convert a "location" (Y,X) into a "grid" (G) + */ + #define GRID(Y,X) \ + (256 * (Y) + (X)) + + /* + * Convert a "grid" (G) into a "location" (Y) + */ + #define GRID_Y(G) \ + ((int)((G) / 256U)) + + /* + * Convert a "grid" (G) into a "location" (X) + */ + #define GRID_X(G) \ + ((int)((G) % 256U)) + /* ! * Determines if a map location is "meaningful" */ #define in_bounds(Y,X) \ ! (((unsigned)(Y) < (unsigned)(DUNGEON_HGT)) && \ ! ((unsigned)(X) < (unsigned)(DUNGEON_WID))) /* * Determines if a map location is fully inside the outer walls *************** *** 2483,2499 **** * often we need to exclude the outer walls from calculations. */ #define in_bounds_fully(Y,X) \ ! (((Y) > 0) && ((Y) < DUNGEON_HGT-1) && \ ! ((X) > 0) && ((X) < DUNGEON_WID-1)) /* * Determines if a map location is currently "on screen" * Note that "panel_contains(Y,X)" always implies "in_bounds(Y,X)". */ #define panel_contains(Y,X) \ ! (((unsigned)((Y) - p_ptr->wy) < (unsigned)(SCREEN_HGT)) && \ ! ((unsigned)((X) - p_ptr->wx) < (unsigned)(SCREEN_WID))) --- 2533,2550 ---- * often we need to exclude the outer walls from calculations. */ #define in_bounds_fully(Y,X) \ ! (((Y) > 0) && ((Y) < DUNGEON_HGT-1) && \ ! ((X) > 0) && ((X) < DUNGEON_WID-1)) /* * Determines if a map location is currently "on screen" * Note that "panel_contains(Y,X)" always implies "in_bounds(Y,X)". + * Pre-storing this into a cave_info flag would be nice. XXX XXX */ #define panel_contains(Y,X) \ ! (((unsigned)((Y) - p_ptr->wy) < (unsigned)(SCREEN_HGT)) && \ ! ((unsigned)((X) - p_ptr->wx) < (unsigned)(SCREEN_WID))) *************** *** 2502,2513 **** * * Line 1 -- forbid doors, rubble, seams, walls * ! * Note that the terrain features are split by a one bit test ! * into those features which block line of sight and those that ! * do not, allowing an extremely fast single bit check below. */ #define cave_floor_bold(Y,X) \ ! (!(cave_feat[Y][X] & 0x20)) /* * Determine if a "legal" grid is a "clean" floor grid --- 2553,2562 ---- * * Line 1 -- forbid doors, rubble, seams, walls * ! * Note the use of the new "CAVE_WALL" flag. */ #define cave_floor_bold(Y,X) \ ! (!(cave_info[Y][X] & (CAVE_WALL))) /* * Determine if a "legal" grid is a "clean" floor grid *************** *** 2516,2523 **** * Line 2 -- forbid normal objects */ #define cave_clean_bold(Y,X) \ ! ((cave_feat[Y][X] == FEAT_FLOOR) && \ ! (cave_o_idx[Y][X] == 0)) /* * Determine if a "legal" grid is an "empty" floor grid --- 2565,2572 ---- * Line 2 -- forbid normal objects */ #define cave_clean_bold(Y,X) \ ! ((cave_feat[Y][X] == FEAT_FLOOR) && \ ! (cave_o_idx[Y][X] == 0)) /* * Determine if a "legal" grid is an "empty" floor grid *************** *** 2526,2533 **** * Line 2 -- forbid player/monsters */ #define cave_empty_bold(Y,X) \ ! (cave_floor_bold(Y,X) && \ ! (cave_m_idx[Y][X] == 0)) /* * Determine if a "legal" grid is an "naked" floor grid --- 2575,2582 ---- * Line 2 -- forbid player/monsters */ #define cave_empty_bold(Y,X) \ ! (cave_floor_bold(Y,X) && \ ! (cave_m_idx[Y][X] == 0)) /* * Determine if a "legal" grid is an "naked" floor grid *************** *** 2537,2545 **** * Line 3 -- forbid player/monsters */ #define cave_naked_bold(Y,X) \ ! ((cave_feat[Y][X] == FEAT_FLOOR) && \ ! (cave_o_idx[Y][X] == 0) && \ ! (cave_m_idx[Y][X] == 0)) /* --- 2586,2594 ---- * Line 3 -- forbid player/monsters */ #define cave_naked_bold(Y,X) \ ! ((cave_feat[Y][X] == FEAT_FLOOR) && \ ! (cave_o_idx[Y][X] == 0) && \ ! (cave_m_idx[Y][X] == 0)) /* *************** *** 2550,2560 **** * Line 4-5 -- shop doors */ #define cave_perma_bold(Y,X) \ ! ((cave_feat[Y][X] >= FEAT_PERM_EXTRA) || \ ! ((cave_feat[Y][X] == FEAT_LESS) || \ ! (cave_feat[Y][X] == FEAT_MORE)) || \ ! ((cave_feat[Y][X] >= FEAT_SHOP_HEAD) && \ ! (cave_feat[Y][X] <= FEAT_SHOP_TAIL))) /* --- 2599,2609 ---- * Line 4-5 -- shop doors */ #define cave_perma_bold(Y,X) \ ! ((cave_feat[Y][X] >= FEAT_PERM_EXTRA) || \ ! ((cave_feat[Y][X] == FEAT_LESS) || \ ! (cave_feat[Y][X] == FEAT_MORE)) || \ ! ((cave_feat[Y][X] >= FEAT_SHOP_HEAD) && \ ! (cave_feat[Y][X] <= FEAT_SHOP_TAIL))) /* *************** *** 2563,2569 **** * Note the use of comparison to zero to force a "boolean" result */ #define player_has_los_bold(Y,X) \ ! ((cave_info[Y][X] & (CAVE_VIEW)) != 0) --- 2612,2627 ---- * Note the use of comparison to zero to force a "boolean" result */ #define player_has_los_bold(Y,X) \ ! ((cave_info[Y][X] & (CAVE_VIEW)) != 0) ! ! ! /* ! * Determine if a "legal" grid can be "seen" by the player ! * ! * Note the use of comparison to zero to force a "boolean" result ! */ ! #define player_can_see_bold(Y,X) \ ! ((cave_info[Y][X] & (CAVE_SEEN)) != 0) *************** *** 2661,2664 **** --- 2719,2723 ---- # undef MESSAGE_BUF # define MESSAGE_BUF 4096 #endif + diff -c -r angband-282/src/dungeon.c angband-283/src/dungeon.c *** angband-282/src/dungeon.c Thu Sep 4 10:17:51 1997 --- angband-283/src/dungeon.c Wed Feb 11 06:30:28 1998 *************** *** 319,325 **** p_ptr->redraw |= (PR_HP); /* Window stuff */ ! p_ptr->window |= (PW_SPELL | PW_PLAYER); } } --- 319,325 ---- p_ptr->redraw |= (PR_HP); /* Window stuff */ ! p_ptr->window |= (PW_PLAYER_0 | PW_PLAYER_1); } } *************** *** 365,371 **** p_ptr->redraw |= (PR_MANA); /* Window stuff */ ! p_ptr->window |= (PW_SPELL | PW_PLAYER); } } --- 365,371 ---- p_ptr->redraw |= (PR_MANA); /* Window stuff */ ! p_ptr->window |= (PW_PLAYER_0 | PW_PLAYER_1); } } *************** *** 424,430 **** */ static void process_world(void) { ! int x, y, i, j; int regen_amount; --- 424,430 ---- */ static void process_world(void) { ! int i, j; int regen_amount; *************** *** 491,512 **** { /* Message */ msg_print("The sun has risen."); - - /* Hack -- Scan the town */ - for (y = 0; y < DUNGEON_HGT; y++) - { - for (x = 0; x < DUNGEON_WID; x++) - { - /* Assume lit */ - cave_info[y][x] |= (CAVE_GLOW); - - /* Hack -- Memorize lit grids if allowed */ - if (view_perma_grids) cave_info[y][x] |= (CAVE_MARK); - - /* Hack -- Notice spot */ - note_spot(y, x); - } - } } /* Night falls */ --- 491,496 ---- *************** *** 514,546 **** { /* Message */ msg_print("The sun has fallen."); - - /* Hack -- Scan the town */ - for (y = 0; y < DUNGEON_HGT; y++) - { - for (x = 0; x < DUNGEON_WID; x++) - { - /* Darken "boring" features */ - if (cave_feat[y][x] <= FEAT_INVIS) - { - /* Forget the grid */ - cave_info[y][x] &= ~(CAVE_GLOW | CAVE_MARK); - - /* Hack -- Notice spot */ - note_spot(y, x); - } - } - } } ! /* Update the monsters */ ! p_ptr->update |= (PU_MONSTERS); ! ! /* Redraw map */ ! p_ptr->redraw |= (PR_MAP); ! ! /* Window stuff */ ! p_ptr->window |= (PW_OVERHEAD); } } --- 498,507 ---- { /* Message */ msg_print("The sun has fallen."); } ! /* Illuminate */ ! town_illuminate(dawn); } } *************** *** 1093,1100 **** if (!(p_ptr->noscore & 0x0002)) { /* Mention effects */ ! msg_print("Wizard mode is for debugging and experimenting."); ! msg_print("The game will not be scored if you enter wizard mode."); msg_print(NULL); /* Verify request */ --- 1054,1061 ---- if (!(p_ptr->noscore & 0x0002)) { /* Mention effects */ ! msg_print("You are about to enter 'wizard' mode for the very first time!"); ! msg_print("This is a form of cheating, and your game will not be scored!"); msg_print(NULL); /* Verify request */ *************** *** 1112,1146 **** } ! #ifdef ALLOW_WIZARD /* ! * Verify use of "debug" commands */ ! static bool enter_debug_mode(void) { /* Ask first time */ ! if (!(p_ptr->noscore & 0x0008)) { /* Mention effects */ ! msg_print("The debug commands are for debugging and experimenting."); ! msg_print("The game will not be scored if you use debug commands."); msg_print(NULL); /* Verify request */ ! if (!get_check("Are you sure you want to use debug commands? ")) { return (FALSE); } - - /* Mark savefile */ - p_ptr->noscore |= 0x0008; } ! /* Success */ return (TRUE); } /* * Hack -- Declare the Debug Routines */ --- 1073,1114 ---- } ! ! #ifdef ALLOW_DEBUG /* ! * Verify use of "debug" mode */ ! static bool verify_debug_mode(void) { + static int verify = 1; + /* Ask first time */ ! if (verify && verify_special) { /* Mention effects */ ! msg_print("You are about to use the dangerous, unsupported, debug commands!"); ! msg_print("Your machine may crash, and your savefile may become corrupted!"); msg_print(NULL); /* Verify request */ ! if (!get_check("Are you sure you want to use the debug commands? ")) { return (FALSE); } } ! /* Verified */ ! verify = 0; ! ! /* Mark savefile */ ! p_ptr->noscore |= 0x0008; ! ! /* Okay */ return (TRUE); } + /* * Hack -- Declare the Debug Routines */ *************** *** 1149,1185 **** #endif #ifdef ALLOW_BORG /* ! * Verify use of "borg" commands */ ! static bool enter_borg_mode(void) { /* Ask first time */ ! if (!(p_ptr->noscore & 0x0010)) { /* Mention effects */ ! msg_print("The borg commands are for debugging and experimenting."); ! msg_print("The game will not be scored if you use borg commands."); msg_print(NULL); /* Verify request */ ! if (!get_check("Are you sure you want to use borg commands? ")) { return (FALSE); } - - /* Mark savefile */ - p_ptr->noscore |= 0x0010; } ! /* Success */ return (TRUE); } /* ! * Hack -- Declare the Ben Borg */ extern void do_cmd_borg(void); --- 1117,1160 ---- #endif + #ifdef ALLOW_BORG /* ! * Verify use of "borg" mode */ ! static bool verify_borg_mode(void) { + static int verify = 1; + /* Ask first time */ ! if (verify && verify_special) { /* Mention effects */ ! msg_print("You are about to use the dangerous, unsupported, borg commands!"); ! msg_print("Your machine may crash, and your savefile may become corrupted!"); msg_print(NULL); /* Verify request */ ! if (!get_check("Are you sure you want to use the borg commands? ")) { return (FALSE); } } ! /* Verified */ ! verify = 0; ! ! /* Mark savefile */ ! p_ptr->noscore |= 0x0010; ! ! /* Okay */ return (TRUE); } + /* ! * Hack -- Declare the Borg Routines */ extern void do_cmd_borg(void); *************** *** 1190,1221 **** /* * Parse and execute the current command * Give "Warning" on illegal commands. - * - * XXX XXX XXX Make some "blocks" */ static void process_command(void) { /* Parse the command */ switch (p_ptr->command_cmd) { ! /* Ignore */ case ESCAPE: case ' ': - { - break; - } ! /* Ignore return */ case '\r': { break; } ! /*** Wizard Commands ***/ ! ! /* Toggle Wizard Mode */ case KTRL('W'): { if (p_ptr->wizard) --- 1165,1190 ---- /* * Parse and execute the current command * Give "Warning" on illegal commands. */ static void process_command(void) { /* Parse the command */ switch (p_ptr->command_cmd) { ! /* Ignore */ case ESCAPE: case ' ': ! /* Ignore */ case '\r': { break; } + /*** Cheating Commands ***/ ! /* Toggle Wizard Mode */ case KTRL('W'): { if (p_ptr->wizard) *************** *** 1239,1254 **** } ! #ifdef ALLOW_WIZARD ! /* Special "debug" commands */ case KTRL('A'): { ! /* Enter debug mode */ ! if (enter_debug_mode()) ! { ! do_cmd_debug(); ! } break; } --- 1208,1219 ---- } ! #ifdef ALLOW_DEBUG ! /* Special "debug" commands */ case KTRL('A'): { ! if (verify_debug_mode()) do_cmd_debug(); break; } *************** *** 1257,1271 **** #ifdef ALLOW_BORG ! /* Special "borg" commands */ case KTRL('Z'): { ! /* Enter borg mode */ ! if (enter_borg_mode()) ! { ! do_cmd_borg(); ! } ! break; } --- 1222,1231 ---- #ifdef ALLOW_BORG ! /* Special "borg" commands */ case KTRL('Z'): { ! if (verify_borg_mode()) do_cmd_borg(); break; } *************** *** 1273,1316 **** ! /*** Inventory Commands ***/ ! /* Wear/wield equipment */ case 'w': { do_cmd_wield(); break; } ! /* Take off equipment */ case 't': { do_cmd_takeoff(); break; } ! /* Drop an item */ case 'd': { do_cmd_drop(); break; } ! /* Destroy an item */ case 'k': { do_cmd_destroy(); break; } ! /* Equipment list */ case 'e': { do_cmd_equip(); break; } ! /* Inventory list */ case 'i': { do_cmd_inven(); --- 1233,1276 ---- ! /*** Inventory Commands ***/ ! /* Wear/wield equipment */ case 'w': { do_cmd_wield(); break; } ! /* Take off equipment */ case 't': { do_cmd_takeoff(); break; } ! /* Drop an item */ case 'd': { do_cmd_drop(); break; } ! /* Destroy an item */ case 'k': { do_cmd_destroy(); break; } ! /* Equipment list */ case 'e': { do_cmd_equip(); break; } ! /* Inventory list */ case 'i': { do_cmd_inven(); *************** *** 1318,1333 **** } ! /*** Various commands ***/ ! /* Identify an object */ case 'I': { do_cmd_observe(); break; } ! /* Hack -- toggle windows */ case KTRL('E'): { toggle_inven_equip(); --- 1278,1293 ---- } ! /*** Various commands ***/ ! /* Identify an object */ case 'I': { do_cmd_observe(); break; } ! /* Hack -- toggle windows */ case KTRL('E'): { toggle_inven_equip(); *************** *** 1335,1364 **** } ! /*** Standard "Movement" Commands ***/ ! /* Alter a grid */ case '+': { do_cmd_alter(); break; } ! /* Dig a tunnel */ case 'T': { do_cmd_tunnel(); break; } ! /* Walk */ case ';': { do_cmd_walk(); break; } ! /* Jump */ case '-': { do_cmd_jump(); --- 1295,1324 ---- } ! /*** Standard "Movement" Commands ***/ ! /* Alter a grid */ case '+': { do_cmd_alter(); break; } ! /* Dig a tunnel */ case 'T': { do_cmd_tunnel(); break; } ! /* Walk */ case ';': { do_cmd_walk(); break; } ! /* Jump */ case '-': { do_cmd_jump(); *************** *** 1366,1409 **** } ! /*** Running, Resting, Searching, Staying */ ! /* Begin Running -- Arg is Max Distance */ case '.': { do_cmd_run(); break; } ! /* Hold still */ case ',': { do_cmd_hold(); break; } ! /* Stay still */ case 'g': { do_cmd_stay(); break; } ! /* Rest -- Arg is time */ case 'R': { do_cmd_rest(); break; } ! /* Search for traps/doors */ case 's': { do_cmd_search(); break; } ! /* Toggle search mode */ case 'S': { do_cmd_toggle_search(); --- 1326,1369 ---- } ! /*** Running, Resting, Searching, Staying */ ! /* Begin Running -- Arg is Max Distance */ case '.': { do_cmd_run(); break; } ! /* Hold still */ case ',': { do_cmd_hold(); break; } ! /* Stay still */ case 'g': { do_cmd_stay(); break; } ! /* Rest -- Arg is time */ case 'R': { do_cmd_rest(); break; } ! /* Search for traps/doors */ case 's': { do_cmd_search(); break; } ! /* Toggle search mode */ case 'S': { do_cmd_toggle_search(); *************** *** 1411,1468 **** } ! /*** Stairs and Doors and Chests and Traps ***/ ! /* Enter store */ case '_': { do_cmd_store(); break; } ! /* Go up staircase */ case '<': { do_cmd_go_up(); break; } ! /* Go down staircase */ case '>': { do_cmd_go_down(); break; } ! /* Open a door or chest */ case 'o': { do_cmd_open(); break; } ! /* Close a door */ case 'c': { do_cmd_close(); break; } ! /* Jam a door with spikes */ case 'j': { do_cmd_spike(); break; } ! /* Bash a door */ case 'B': { do_cmd_bash(); break; } ! /* Disarm a trap or chest */ case 'D': { do_cmd_disarm(); --- 1371,1428 ---- } ! /*** Stairs and Doors and Chests and Traps ***/ ! /* Enter store */ case '_': { do_cmd_store(); break; } ! /* Go up staircase */ case '<': { do_cmd_go_up(); break; } ! /* Go down staircase */ case '>': { do_cmd_go_down(); break; } ! /* Open a door or chest */ case 'o': { do_cmd_open(); break; } ! /* Close a door */ case 'c': { do_cmd_close(); break; } ! /* Jam a door with spikes */ case 'j': { do_cmd_spike(); break; } ! /* Bash a door */ case 'B': { do_cmd_bash(); break; } ! /* Disarm a trap or chest */ case 'D': { do_cmd_disarm(); *************** *** 1470,1499 **** } ! /*** Magic and Prayers ***/ ! /* Gain new spells/prayers */ case 'G': { do_cmd_study(); break; } ! /* Browse a book */ case 'b': { do_cmd_browse(); break; } ! /* Cast a spell */ case 'm': { do_cmd_cast(); break; } ! /* Pray a prayer */ case 'p': { do_cmd_pray(); --- 1430,1459 ---- } ! /*** Magic and Prayers ***/ ! /* Gain new spells/prayers */ case 'G': { do_cmd_study(); break; } ! /* Browse a book */ case 'b': { do_cmd_browse(); break; } ! /* Cast a spell */ case 'm': { do_cmd_cast(); break; } ! /* Pray a prayer */ case 'p': { do_cmd_pray(); *************** *** 1501,1586 **** } ! /*** Use various objects ***/ ! /* Inscribe an object */ case '{': { do_cmd_inscribe(); break; } ! /* Uninscribe an object */ case '}': { do_cmd_uninscribe(); break; } ! /* Activate an artifact */ case 'A': { do_cmd_activate(); break; } ! /* Eat some food */ case 'E': { do_cmd_eat_food(); break; } ! /* Fuel your lantern/torch */ case 'F': { do_cmd_refill(); break; } ! /* Fire an item */ case 'f': { do_cmd_fire(); break; } ! /* Throw an item */ case 'v': { do_cmd_throw(); break; } ! /* Aim a wand */ case 'a': { do_cmd_aim_wand(); break; } ! /* Zap a rod */ case 'z': { do_cmd_zap_rod(); break; } ! /* Quaff a potion */ case 'q': { do_cmd_quaff_potion(); break; } ! /* Read a scroll */ case 'r': { do_cmd_read_scroll(); break; } ! /* Use a staff */ case 'u': { do_cmd_use_staff(); --- 1461,1546 ---- } ! /*** Use various objects ***/ ! /* Inscribe an object */ case '{': { do_cmd_inscribe(); break; } ! /* Uninscribe an object */ case '}': { do_cmd_uninscribe(); break; } ! /* Activate an artifact */ case 'A': { do_cmd_activate(); break; } ! /* Eat some food */ case 'E': { do_cmd_eat_food(); break; } ! /* Fuel your lantern/torch */ case 'F': { do_cmd_refill(); break; } ! /* Fire an item */ case 'f': { do_cmd_fire(); break; } ! /* Throw an item */ case 'v': { do_cmd_throw(); break; } ! /* Aim a wand */ case 'a': { do_cmd_aim_wand(); break; } ! /* Zap a rod */ case 'z': { do_cmd_zap_rod(); break; } ! /* Quaff a potion */ case 'q': { do_cmd_quaff_potion(); break; } ! /* Read a scroll */ case 'r': { do_cmd_read_scroll(); break; } ! /* Use a staff */ case 'u': { do_cmd_use_staff(); *************** *** 1588,1617 **** } ! /*** Looking at Things (nearby or on map) ***/ ! /* Full dungeon map */ case 'M': { do_cmd_view_map(); break; } ! /* Locate player on map */ case 'L': { do_cmd_locate(); break; } ! /* Look around */ case 'l': { do_cmd_look(); break; } ! /* Target monster or location */ case '*': { do_cmd_target(); --- 1548,1577 ---- } ! /*** Looking at Things (nearby or on map) ***/ ! /* Full dungeon map */ case 'M': { do_cmd_view_map(); break; } ! /* Locate player on map */ case 'L': { do_cmd_locate(); break; } ! /* Look around */ case 'l': { do_cmd_look(); break; } ! /* Target monster or location */ case '*': { do_cmd_target(); *************** *** 1620,1642 **** ! /*** Help and Such ***/ ! /* Help */ case '?': { do_cmd_help(); break; } ! /* Identify symbol */ case '/': { do_cmd_query_symbol(); break; } ! /* Character description */ case 'C': { do_cmd_change_name(); --- 1580,1602 ---- ! /*** Help and Such ***/ ! /* Help */ case '?': { do_cmd_help(); break; } ! /* Identify symbol */ case '/': { do_cmd_query_symbol(); break; } ! /* Character description */ case 'C': { do_cmd_change_name(); *************** *** 1644,1687 **** } ! /*** System Commands ***/ ! /* Hack -- User interface */ case '!': { (void)Term_user(0); break; } ! /* Single line from a pref file */ case '"': { do_cmd_pref(); break; } ! /* Interact with macros */ case '@': { do_cmd_macros(); break; } ! /* Interact with visuals */ case '%': { do_cmd_visuals(); break; } ! /* Interact with colors */ case '&': { do_cmd_colors(); break; } ! /* Interact with options */ case '=': { do_cmd_options(); --- 1604,1647 ---- } ! /*** System Commands ***/ ! /* Hack -- User interface */ case '!': { (void)Term_user(0); break; } ! /* Single line from a pref file */ case '"': { do_cmd_pref(); break; } ! /* Interact with macros */ case '@': { do_cmd_macros(); break; } ! /* Interact with visuals */ case '%': { do_cmd_visuals(); break; } ! /* Interact with colors */ case '&': { do_cmd_colors(); break; } ! /* Interact with options */ case '=': { do_cmd_options(); *************** *** 1690,1733 **** } ! /*** Misc Commands ***/ ! /* Take notes */ case ':': { do_cmd_note(); break; } ! /* Version info */ case 'V': { do_cmd_version(); break; } ! /* Repeat level feeling */ case KTRL('F'): { do_cmd_feeling(); break; } ! /* Show previous message */ case KTRL('O'): { do_cmd_message_one(); break; } ! /* Show previous messages */ case KTRL('P'): { do_cmd_messages(); break; } ! /* Redraw the screen */ case KTRL('R'): { do_cmd_redraw(); --- 1650,1693 ---- } ! /*** Misc Commands ***/ ! /* Take notes */ case ':': { do_cmd_note(); break; } ! /* Version info */ case 'V': { do_cmd_version(); break; } ! /* Repeat level feeling */ case KTRL('F'): { do_cmd_feeling(); break; } ! /* Show previous message */ case KTRL('O'): { do_cmd_message_one(); break; } ! /* Show previous messages */ case KTRL('P'): { do_cmd_messages(); break; } ! /* Redraw the screen */ case KTRL('R'): { do_cmd_redraw(); *************** *** 1736,1742 **** #ifndef VERIFY_SAVEFILE ! /* Hack -- Save and don't quit */ case KTRL('S'): { do_cmd_save_game(); --- 1696,1702 ---- #ifndef VERIFY_SAVEFILE ! /* Hack -- Save and don't quit */ case KTRL('S'): { do_cmd_save_game(); *************** *** 1745,1751 **** #endif ! /* Save and quit */ case KTRL('X'): { /* Stop playing */ --- 1705,1711 ---- #endif ! /* Save and quit */ case KTRL('X'): { /* Stop playing */ *************** *** 1757,1770 **** break; } ! /* Quit (commit suicide) */ case 'Q': { do_cmd_suicide(); break; } ! /* Check knowledge */ case '~': case '|': { --- 1717,1730 ---- break; } ! /* Quit (commit suicide) */ case 'Q': { do_cmd_suicide(); break; } ! /* Check knowledge */ case '~': case '|': { *************** *** 1772,1792 **** break; } ! /* Load "screen dump" */ case '(': { do_cmd_load_screen(); break; } ! /* Save "screen dump" */ case ')': { do_cmd_save_screen(); break; } ! /* Hack -- Unknown command */ default: { prt("Type '?' for help.", 0, 0); --- 1732,1752 ---- break; } ! /* Load "screen dump" */ case '(': { do_cmd_load_screen(); break; } ! /* Save "screen dump" */ case ')': { do_cmd_save_screen(); break; } ! /* Hack -- Unknown command */ default: { prt("Type '?' for help.", 0, 0); *************** *** 1888,1893 **** --- 1848,1859 ---- * every time we change any internal monster memory field, and * also reduces the number of times that the recall window must * be redrawn. + * + * Note that the code to check for user abort during repeated commands + * and running and resting can be disabled entirely with an option, and + * even if not disabled, it will never check during "special" resting + * (codes -1 and -2), and it will only check during every 16th player + * turn of "normal" resting. */ static void process_player(void) { *************** *** 1939,1946 **** /* Handle "abort" */ if (!avoid_abort) { ! /* Check for "player abort" (semi-efficiently for resting) */ ! if (p_ptr->running || p_ptr->command_rep || (p_ptr->resting && !(p_ptr->resting & 0x0F))) { /* Do not wait */ inkey_scan = TRUE; --- 1905,1914 ---- /* Handle "abort" */ if (!avoid_abort) { ! /* Check for "player abort" */ ! if (p_ptr->running || ! p_ptr->command_rep || ! (p_ptr->resting && !(p_ptr->resting & 0x0F))) { /* Do not wait */ inkey_scan = TRUE; *************** *** 2277,2283 **** /* Cancel the target */ ! p_ptr->target_who = 0; /* Cancel the health bar */ health_track(0); --- 2245,2251 ---- /* Cancel the target */ ! target_set_monster(0); /* Cancel the health bar */ health_track(0); *************** *** 2357,2379 **** msg_print(NULL); ! /* Enter "xtra" mode */ ! character_xtra = TRUE; - /* Window stuff */ - p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER); ! /* Window stuff */ ! p_ptr->window |= (PW_MONSTER); ! ! /* Redraw dungeon */ ! p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA); ! ! /* Redraw map */ ! p_ptr->redraw |= (PR_MAP); - /* Window stuff */ - p_ptr->window |= (PW_OVERHEAD); /* Update stuff */ p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS); --- 2325,2337 ---- msg_print(NULL); ! /* Hack -- Increase "xtra" depth */ ! character_xtra++; ! /* Clear */ ! Term_clear(); /* Update stuff */ p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS); *************** *** 2384,2397 **** /* Update stuff */ update_stuff(); - /* Redraw stuff */ - redraw_stuff(); ! /* Redraw stuff */ ! window_stuff(); ! /* Update stuff */ ! p_ptr->update |= (PU_VIEW | PU_LITE | PU_FLOW | PU_DISTANCE); /* Update stuff */ update_stuff(); --- 2342,2365 ---- /* Update stuff */ update_stuff(); ! /* Fully update the visuals (and monster distances) */ ! p_ptr->update |= (PU_FORGET_VIEW | PU_UPDATE_VIEW | PU_DISTANCE); ! /* Fully update the flow */ ! p_ptr->update |= (PU_FORGET_FLOW | PU_UPDATE_FLOW); ! ! /* Redraw dungeon */ ! p_ptr->redraw |= (PR_BASIC | PR_EXTRA | PR_MAP); ! ! /* Window stuff */ ! p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER_0 | PW_PLAYER_1); ! ! /* Window stuff */ ! p_ptr->window |= (PW_MONSTER); ! ! /* Window stuff */ ! p_ptr->window |= (PW_OVERHEAD); /* Update stuff */ update_stuff(); *************** *** 2399,2406 **** /* Redraw stuff */ redraw_stuff(); ! /* Leave "xtra" mode */ ! character_xtra = FALSE; /* Update stuff */ p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS); --- 2367,2379 ---- /* Redraw stuff */ redraw_stuff(); ! /* Redraw stuff */ ! window_stuff(); ! ! ! /* Hack -- Decrease "xtra" depth */ ! character_xtra--; ! /* Update stuff */ p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS); *************** *** 2549,2558 **** /* Process the "user.prf" file */ (void)process_pref_file("user.prf"); ! /* Process the "PLAYER" file */ sprintf(buf, "%s.prf", op_ptr->base_name); ! /* Process the "user.prf" file */ (void)process_pref_file(buf); } --- 2522,2531 ---- /* Process the "user.prf" file */ (void)process_pref_file("user.prf"); ! /* Process the "PLAYER.prf" file */ sprintf(buf, "%s.prf", op_ptr->base_name); ! /* Process the "PLAYER.prf" file */ (void)process_pref_file(buf); } *************** *** 2571,2578 **** */ void play_game(bool new_game) { ! /* Hack -- Character is "icky" */ ! character_icky = TRUE; /* Hack -- turn off the cursor */ --- 2544,2570 ---- */ void play_game(bool new_game) { ! /* Hack -- Increase "icky" depth */ ! character_icky++; ! ! ! /* Verify main term */ ! if (!angband_term[0]) ! { ! quit("main window does not exist"); ! } ! ! /* Make sure main term is active */ ! Term_activate(angband_term[0]); ! ! /* Verify minimum size */ ! if ((Term->hgt < 24) || (Term->wid < 80)) ! { ! quit("main window is too small"); ! } ! ! /* Forbid resizing */ ! Term->fixed_shape = TRUE; /* Hack -- turn off the cursor */ *************** *** 2599,2606 **** /* Process old character */ if (!new_game) { - /* Process the player name */ - process_player_name(FALSE); } /* Init RNG */ --- 2591,2596 ---- *************** *** 2647,2652 **** --- 2637,2653 ---- turn = 1; } + /* Normal machine (process player name) */ + if (savefile[0]) + { + process_player_name(FALSE); + } + + /* Weird machine (process player name, pick savefile name) */ + else + { + process_player_name(TRUE); + } /* Flash a message */ prt("Please wait...", 0, 0); *************** *** 2667,2673 **** /* Window stuff */ ! p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER); /* Window stuff */ p_ptr->window |= (PW_MONSTER); --- 2668,2674 ---- /* Window stuff */ ! p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER_0 | PW_PLAYER_1); /* Window stuff */ p_ptr->window |= (PW_MONSTER); *************** *** 2684,2691 **** if (arg_force_original) rogue_like_commands = FALSE; if (arg_force_roguelike) rogue_like_commands = TRUE; - /* Verify the keymap */ - keymap_init(); /* React to changes */ Term_xtra(TERM_XTRA_REACT, 0); --- 2685,2690 ---- *************** *** 2699,2706 **** character_generated = TRUE; ! /* Hack -- Character is no longer "icky" */ ! character_icky = FALSE; /* Start playing */ --- 2698,2705 ---- character_generated = TRUE; ! /* Hack -- Decrease "icky" depth */ ! character_icky--; /* Start playing */ *************** *** 2730,2743 **** /* Cancel the target */ ! p_ptr->target_who = 0; /* Cancel the health bar */ health_track(0); - - /* Forget the lite */ - forget_lite(); /* Forget the view */ forget_view(); --- 2729,2739 ---- /* Cancel the target */ ! target_set_monster(0); /* Cancel the health bar */ health_track(0); /* Forget the view */ forget_view(); diff -c -r angband-282/src/externs.h angband-283/src/externs.h *** angband-282/src/externs.h Wed Sep 3 11:57:33 1997 --- angband-283/src/externs.h Mon Feb 9 01:49:44 1998 *************** *** 92,99 **** extern bool character_dungeon; extern bool character_loaded; extern bool character_saved; ! extern bool character_icky; ! extern bool character_xtra; extern u32b seed_flavor; extern u32b seed_town; extern s16b num_repro; --- 92,99 ---- extern bool character_dungeon; extern bool character_loaded; extern bool character_saved; ! extern s16b character_icky; ! extern s16b character_xtra; extern u32b seed_flavor; extern u32b seed_town; extern s16b num_repro; *************** *** 129,148 **** extern int player_euid; extern int player_egid; extern char savefile[1024]; - extern s16b lite_n; - extern byte lite_y[LITE_MAX]; - extern byte lite_x[LITE_MAX]; - extern s16b view_n; - extern byte view_y[VIEW_MAX]; - extern byte view_x[VIEW_MAX]; - extern s16b temp_n; - extern byte temp_y[TEMP_MAX]; - extern byte temp_x[TEMP_MAX]; extern s16b macro__num; extern cptr *macro__pat; extern cptr *macro__act; - extern bool *macro__cmd; - extern char *macro__buf; extern s16b quark__num; extern cptr *quark__str; extern u16b message__next; --- 129,137 ---- *************** *** 155,174 **** extern char angband_term_name[8][16]; extern byte angband_color_table[256][4]; extern char angband_sound_name[SOUND_MAX][16]; ! extern object_type o_list[MAX_O_IDX]; ! extern monster_type m_list[MAX_M_IDX]; ! extern quest q_list[MAX_Q_IDX]; extern store_type *store; extern object_type *inventory; extern s16b alloc_kind_size; extern alloc_entry *alloc_kind_table; extern s16b alloc_race_size; extern alloc_entry *alloc_race_table; ! extern byte misc_to_attr[128]; ! extern char misc_to_char[128]; extern byte tval_to_attr[128]; ! extern byte keymap_cmds[128]; ! extern byte keymap_dirs[128]; extern player_sex *sp_ptr; extern player_race *rp_ptr; extern player_class *cp_ptr; --- 144,175 ---- extern char angband_term_name[8][16]; extern byte angband_color_table[256][4]; extern char angband_sound_name[SOUND_MAX][16]; ! extern sint view_n; ! extern u16b *view_g; ! extern sint temp_n; ! extern u16b *temp_g; ! extern byte *temp_y; ! extern byte *temp_x; ! extern byte (*cave_info)[256]; ! extern byte (*cave_feat)[DUNGEON_WID]; ! extern s16b (*cave_o_idx)[DUNGEON_WID]; ! extern s16b (*cave_m_idx)[DUNGEON_WID]; ! extern byte (*cave_cost)[DUNGEON_WID]; ! extern byte (*cave_when)[DUNGEON_WID]; ! extern object_type *o_list; ! extern monster_type *m_list; ! extern quest *q_list; extern store_type *store; extern object_type *inventory; extern s16b alloc_kind_size; extern alloc_entry *alloc_kind_table; extern s16b alloc_race_size; extern alloc_entry *alloc_race_table; ! extern byte misc_to_attr[256]; ! extern char misc_to_char[256]; extern byte tval_to_attr[128]; ! extern char macro_buffer[1024]; ! extern cptr keymap_act[KEYMAP_MODES][256]; extern player_sex *sp_ptr; extern player_race *rp_ptr; extern player_class *cp_ptr; *************** *** 218,229 **** extern void (*ang_sort_swap)(vptr u, vptr v, int a, int b); extern bool (*get_mon_num_hook)(int r_idx); extern bool (*get_obj_num_hook)(int k_idx); - extern byte cave_cost[DUNGEON_HGT][DUNGEON_WID]; - extern byte cave_when[DUNGEON_HGT][DUNGEON_WID]; - extern byte cave_info[DUNGEON_HGT][DUNGEON_WID]; - extern byte cave_feat[DUNGEON_HGT][DUNGEON_WID]; - extern s16b cave_o_idx[DUNGEON_HGT][DUNGEON_WID]; - extern s16b cave_m_idx[DUNGEON_HGT][DUNGEON_WID]; /* --- 219,224 ---- *************** *** 234,242 **** extern void player_birth(void); /* cave.c */ ! extern int distance(int y1, int x1, int y2, int x2); extern bool los(int y1, int x1, int y2, int x2); - extern bool player_can_see_bold(int y, int x); extern bool no_lite(void); extern bool cave_valid_bold(int y, int x); extern void map_info(int y, int x, byte *ap, char *cp); --- 229,236 ---- extern void player_birth(void); /* cave.c */ ! extern sint distance(int y1, int x1, int y2, int x2); extern bool los(int y1, int x1, int y2, int x2); extern bool no_lite(void); extern bool cave_valid_bold(int y, int x); extern void map_info(int y, int x, byte *ap, char *cp); *************** *** 247,254 **** extern void prt_map(void); extern void display_map(int *cy, int *cx); extern void do_cmd_view_map(void); ! extern void forget_lite(void); ! extern void update_lite(void); extern void forget_view(void); extern void update_view(void); extern void forget_flow(void); --- 241,247 ---- extern void prt_map(void); extern void display_map(int *cy, int *cx); extern void do_cmd_view_map(void); ! extern errr vinfo_init(void); extern void forget_view(void); extern void update_view(void); extern void forget_flow(void); *************** *** 256,263 **** extern void map_area(void); extern void wiz_lite(void); extern void wiz_dark(void); extern void cave_set_feat(int y, int x, int feat); ! extern void mmove2(int *y, int *x, int y1, int x1, int y2, int x2); extern bool projectable(int y1, int x1, int y2, int x2); extern void scatter(int *yp, int *xp, int y, int x, int d, int m); extern void health_track(int m_idx); --- 249,258 ---- extern void map_area(void); extern void wiz_lite(void); extern void wiz_dark(void); + extern void town_illuminate(bool daytime); extern void cave_set_feat(int y, int x, int feat); ! extern sint project_path(u16b *gp, int range, \ ! int y1, int x1, int y2, int x2, int flg); extern bool projectable(int y1, int x1, int y2, int x2); extern void scatter(int *yp, int *xp, int y, int x, int d, int m); extern void health_track(int m_idx); *************** *** 269,277 **** /* cmd1.c */ extern bool test_hit_fire(int chance, int ac, int vis); extern bool test_hit_norm(int chance, int ac, int vis); ! extern s16b critical_shot(int weight, int plus, int dam); ! extern s16b critical_norm(int weight, int plus, int dam); ! extern s16b tot_dam_aux(object_type *o_ptr, int tdam, monster_type *m_ptr); extern void search(void); extern void py_pickup(int pickup); extern void hit_trap(int y, int x); --- 264,272 ---- /* cmd1.c */ extern bool test_hit_fire(int chance, int ac, int vis); extern bool test_hit_norm(int chance, int ac, int vis); ! extern sint critical_shot(int weight, int plus, int dam); ! extern sint critical_norm(int weight, int plus, int dam); ! extern sint tot_dam_aux(object_type *o_ptr, int tdam, monster_type *m_ptr); extern void search(void); extern void py_pickup(int pickup); extern void hit_trap(int y, int x); *************** *** 623,644 **** extern errr fd_read(int fd, char *buf, huge n); extern errr fd_write(int fd, cptr buf, huge n); extern errr fd_close(int fd); - extern void move_cursor(int row, int col); extern void text_to_ascii(char *buf, cptr str); extern void ascii_to_text(char *buf, cptr str); ! extern void keymap_init(void); ! extern void macro_add(cptr pat, cptr act, bool cmd_flag); extern void flush(void); - extern void bell(void); - extern void sound(int val); extern char inkey(void); extern s16b quark_add(cptr str); extern cptr quark_str(s16b i); extern s16b message_num(void); extern cptr message_str(s16b age); extern void message_add(cptr str); extern void msg_print(cptr msg); extern void msg_format(cptr fmt, ...); extern void c_put_str(byte attr, cptr str, int row, int col); extern void put_str(cptr str, int row, int col); extern void c_prt(byte attr, cptr str, int row, int col); --- 618,644 ---- extern errr fd_read(int fd, char *buf, huge n); extern errr fd_write(int fd, cptr buf, huge n); extern errr fd_close(int fd); extern void text_to_ascii(char *buf, cptr str); extern void ascii_to_text(char *buf, cptr str); ! extern sint macro_find_exact(cptr pat); ! extern errr macro_add(cptr pat, cptr act); ! extern errr macro_init(void); extern void flush(void); extern char inkey(void); + extern void bell(cptr reason); + extern void sound(int val); extern s16b quark_add(cptr str); extern cptr quark_str(s16b i); + extern errr quark_init(void); extern s16b message_num(void); extern cptr message_str(s16b age); extern void message_add(cptr str); + extern errr message_init(void); + extern void move_cursor(int row, int col); extern void msg_print(cptr msg); extern void msg_format(cptr fmt, ...); + extern void screen_save(void); + extern void screen_load(void); extern void c_put_str(byte attr, cptr str, int row, int col); extern void put_str(cptr str, int row, int col); extern void c_prt(byte attr, cptr str, int row, int col); *************** *** 648,657 **** --- 648,660 ---- extern void clear_from(int row); extern bool askfor_aux(char *buf, int len); extern bool get_string(cptr prompt, char *buf, int len); + extern s16b get_quantity(cptr prompt, int max); extern bool get_check(cptr prompt); extern bool get_com(cptr prompt, char *command); extern void pause_line(int row); extern void request_command(bool shopping); + extern uint damroll(uint num, uint sides); + extern uint maxroll(uint num, uint sides); extern bool is_a_vowel(int ch); /* xtra1.c */ *************** *** 697,705 **** extern cptr look_mon_desc(int m_idx); extern void ang_sort_aux(vptr u, vptr v, int p, int q); extern void ang_sort(vptr u, vptr v, int n); extern bool target_able(int m_idx); extern bool target_okay(void); ! extern bool target_set(int mode); extern bool get_aim_dir(int *dp); extern bool get_rep_dir(int *dp); extern bool confuse_dir(int *dp); --- 700,711 ---- extern cptr look_mon_desc(int m_idx); extern void ang_sort_aux(vptr u, vptr v, int p, int q); extern void ang_sort(vptr u, vptr v, int n); + extern sint target_dir(char ch); extern bool target_able(int m_idx); extern bool target_okay(void); ! extern void target_set_monster(int m_idx); ! extern void target_set_location(int y, int x); ! extern bool target_set_interactive(int mode); extern bool get_aim_dir(int *dp); extern bool get_rep_dir(int *dp); extern bool confuse_dir(int *dp); *************** *** 739,742 **** --- 745,749 ---- /* main.c */ /* extern int main(int argc, char *argv[]); */ + diff -c -r angband-282/src/files.c angband-283/src/files.c *** angband-282/src/files.c Fri Sep 5 13:31:14 1997 --- angband-283/src/files.c Wed Feb 11 06:30:28 1998 *************** *** 100,105 **** --- 100,160 ---- } + #if 0 + + /* + * Use this (perhaps) for Angband 2.8.4 + * + * Extract "tokens" from a buffer + * + * This function uses "whitespace" as delimiters, and treats any amount of + * whitespace as a single delimiter. We will never return any empty tokens. + * When given an empty buffer, or a buffer containing only "whitespace", we + * will return no tokens. We will never extract more than "num" tokens. + * + * By running a token through the "text_to_ascii()" function, you can allow + * that token to include (encoded) whitespace, using "\s" to encode spaces. + * + * We save pointers to the tokens in "tokens", and return the number found. + */ + static s16b tokenize_whitespace(char *buf, s16b num, char **tokens) + { + int k = 0; + + char *s = buf; + + + /* Process */ + while (k < num) + { + char *t; + + /* Skip leading whitespace */ + for ( ; *s && isspace(*s); ++s) /* loop */; + + /* All done */ + if (!*s) break; + + /* Find next whitespace, if any */ + for (t = s; *t && !isspace(*t); ++t) /* loop */; + + /* Nuke and advance (if necessary) */ + if (*t) *t++ = '\0'; + + /* Save the token */ + tokens[k++] = s; + + /* Advance */ + s = t; + } + + /* Count */ + return (k); + } + + #endif + + /* * Extract the first few "tokens" from a buffer * *************** *** 201,216 **** * used for the "nothing" attr/char. * * Specify the attr/char values for "monsters" by race index ! * R::: * * Specify the attr/char values for "objects" by kind index ! * K::: * * Specify the attr/char values for "features" by feature index ! * F::: * * Specify the attr/char values for unaware "objects" by kind tval ! * U::: * * Specify the attribute values for inventory "objects" by kind tval * E:: --- 256,274 ---- * used for the "nothing" attr/char. * * Specify the attr/char values for "monsters" by race index ! * R::/ * * Specify the attr/char values for "objects" by kind index ! * K::/ * * Specify the attr/char values for "features" by feature index ! * F::/ ! * ! * Specify the attr/char values for "special" things ! * S::/ * * Specify the attr/char values for unaware "objects" by kind tval ! * U::/ * * Specify the attribute values for inventory "objects" by kind tval * E:: *************** *** 218,231 **** * Define a macro action, given an encoded macro action * A: * ! * Create a normal macro, given an encoded macro trigger * P: * ! * Create a command macro, given an encoded macro trigger ! * C: ! * ! * Create a keyset mapping ! * S::: * * Turn an option off, given its name * X: --- 276,286 ---- * Define a macro action, given an encoded macro action * A: * ! * Create a macro, given an encoded macro trigger * P: * ! * Create a keymap, given an encoded keymap trigger ! * C:: * * Turn an option off, given its name * X: *************** *** 238,244 **** */ errr process_pref_file_aux(char *buf) { ! int i, j, k, n1, n2; char *zz[16]; --- 293,299 ---- */ errr process_pref_file_aux(char *buf) { ! int i, j, n1, n2; char *zz[16]; *************** *** 253,258 **** --- 308,317 ---- if (buf[0] == '#') return (0); + /* Paranoia */ + /* if (strlen(buf) >= 1024) return (1); */ + + /* Require "?:*" format */ if (buf[1] != ':') return (1); *************** *** 304,311 **** n2 = strtol(zz[2], NULL, 0); if (i >= MAX_F_IDX) return (1); f_ptr = &f_info[i]; ! if (n1) f_ptr->z_attr = n1; ! if (n2) f_ptr->z_char = n2; return (0); } } --- 363,385 ---- n2 = strtol(zz[2], NULL, 0); if (i >= MAX_F_IDX) return (1); f_ptr = &f_info[i]; ! if (n1) f_ptr->x_attr = n1; ! if (n2) f_ptr->x_char = n2; ! return (0); ! } ! } ! ! ! /* Process "S::/" -- attr/char for special things */ ! else if (buf[0] == 'S') ! { ! if (tokenize(buf+2, 3, zz) == 3) ! { ! j = (byte)strtol(zz[0], NULL, 0); ! n1 = strtol(zz[1], NULL, 0); ! n2 = strtol(zz[2], NULL, 0); ! misc_to_attr[j] = n1; ! misc_to_char[j] = n2; return (0); } } *************** *** 349,390 **** /* Process "A:" -- save an "action" for later */ else if (buf[0] == 'A') { ! text_to_ascii(macro__buf, buf+2); return (0); } ! /* Process "P:" -- create normal macro */ else if (buf[0] == 'P') { char tmp[1024]; text_to_ascii(tmp, buf+2); ! macro_add(tmp, macro__buf, FALSE); return (0); } ! /* Process "C:" -- create command macro */ else if (buf[0] == 'C') { char tmp[1024]; - text_to_ascii(tmp, buf+2); - macro_add(tmp, macro__buf, TRUE); - return (0); - } ! /* Process "S:::" -- keymap */ ! else if (buf[0] == 'S') ! { ! if (tokenize(buf+2, 3, zz) == 3) ! { ! i = strtol(zz[0], NULL, 0) & 0x7F; ! j = strtol(zz[0], NULL, 0) & 0x7F; ! k = strtol(zz[0], NULL, 0) & 0x7F; ! if ((k > 9) || (k == 5)) k = 0; ! keymap_cmds[i] = j; ! keymap_dirs[i] = k; ! return (0); ! } } --- 423,462 ---- /* Process "A:" -- save an "action" for later */ else if (buf[0] == 'A') { ! text_to_ascii(macro_buffer, buf+2); return (0); } ! /* Process "P:" -- create macro */ else if (buf[0] == 'P') { char tmp[1024]; text_to_ascii(tmp, buf+2); ! macro_add(tmp, macro_buffer); return (0); } ! /* Process "C::" -- create keymap */ else if (buf[0] == 'C') { + int mode; + char tmp[1024]; + if (tokenize(buf+2, 2, zz) != 2) return (1); ! mode = strtol(zz[0], NULL, 0); ! if ((mode < 0) || (mode >= KEYMAP_MODES)) return (1); ! ! text_to_ascii(tmp, zz[1]); ! if (!tmp[0] || tmp[1]) return (1); ! i = (byte)(tmp[0]); ! ! string_free(keymap_act[mode][i]); ! ! keymap_act[mode][i] = string_make(macro_buffer); ! ! return (0); } *************** *** 516,522 **** while (*s && (f != b2)) { t = process_pref_file_expr(&s, &f); ! if (*t && streq(t, "0")) v = "0"; } } --- 588,594 ---- while (*s && (f != b2)) { t = process_pref_file_expr(&s, &f); ! if (*t && !streq(t, "0")) v = "0"; } } *************** *** 587,594 **** /* Other */ else { ! /* Scan (accept identifiers and dollar signs) */ ! while (isalnum(*s) || (*s == '_') || (*s == '$')) s++; /* Extract final and Terminate */ if ((f = *s) != '\0') *s++ = '\0'; --- 659,666 ---- /* Other */ else { ! /* Accept all printables except spaces and brackets */ ! while (isprint(*s) && !strchr(" []", *s)) ++s; /* Extract final and Terminate */ if ((f = *s) != '\0') *s++ = '\0'; *************** *** 653,658 **** --- 725,732 ---- char buf[1024]; + char old[1024]; + int num = -1; errr err = 0; *************** *** 687,692 **** --- 761,770 ---- if (buf[0] == '#') continue; + /* Save a copy */ + strcpy(old, buf); + + /* Process "?:" */ if ((buf[0] == '?') && (buf[1] == ':')) { *************** *** 735,741 **** { /* Useful error message */ msg_format("Error %d in line %d of file '%s'.", err, num, name); ! msg_format("Parsing '%s'", buf); } /* Close the file */ --- 813,820 ---- { /* Useful error message */ msg_format("Error %d in line %d of file '%s'.", err, num, name); ! msg_format("Parsing '%s'", old); ! msg_print(NULL); } /* Close the file */ *************** *** 989,1111 **** - - /* - * Print long number with header at given row, column - * Use the color for the number, not the header - */ - static void prt_lnum(cptr header, s32b num, int row, int col, byte color) - { - int len = strlen(header); - char out_val[32]; - put_str(header, row, col); - sprintf(out_val, "%9ld", (long)num); - c_put_str(color, out_val, row, col + len); - } - - /* - * Print number with header at given row, column - */ - static void prt_num(cptr header, int num, int row, int col, byte color) - { - int len = strlen(header); - char out_val[32]; - put_str(header, row, col); - put_str(" ", row, col + len); - sprintf(out_val, "%6ld", (long)num); - c_put_str(color, out_val, row, col + len + 3); - } - - - - /* - * Prints the following information on the screen. - * - * For this to look right, the following should be spaced the - * same as in the prt_lnum code... -CFT - */ - static void display_player_middle(void) - { - int show_tohit = p_ptr->dis_to_h; - int show_todam = p_ptr->dis_to_d; - - object_type *o_ptr = &inventory[INVEN_WIELD]; - - /* Hack -- add in weapon info if known */ - if (object_known_p(o_ptr)) show_tohit += o_ptr->to_h; - if (object_known_p(o_ptr)) show_todam += o_ptr->to_d; - - /* Dump the bonuses to hit/dam */ - prt_num("+ To Hit ", show_tohit, 9, 1, TERM_L_BLUE); - prt_num("+ To Damage ", show_todam, 10, 1, TERM_L_BLUE); - - /* Dump the armor class bonus */ - prt_num("+ To AC ", p_ptr->dis_to_a, 11, 1, TERM_L_BLUE); - - /* Dump the total armor class */ - prt_num(" Base AC ", p_ptr->dis_ac, 12, 1, TERM_L_BLUE); - - prt_num("Level ", (int)p_ptr->lev, 9, 28, TERM_L_GREEN); - - if (p_ptr->exp >= p_ptr->max_exp) - { - prt_lnum("Experience ", p_ptr->exp, 10, 28, TERM_L_GREEN); - } - else - { - prt_lnum("Experience ", p_ptr->exp, 10, 28, TERM_YELLOW); - } - - prt_lnum("Max Exp ", p_ptr->max_exp, 11, 28, TERM_L_GREEN); - - if (p_ptr->lev >= PY_MAX_LEVEL) - { - put_str("Exp to Adv.", 12, 28); - c_put_str(TERM_L_GREEN, " *****", 12, 28+11); - } - else - { - prt_lnum("Exp to Adv.", - (s32b)(player_exp[p_ptr->lev - 1] * p_ptr->expfact / 100L), - 12, 28, TERM_L_GREEN); - } - - prt_lnum("Gold ", p_ptr->au, 13, 28, TERM_L_GREEN); - - prt_num("Max Hit Points ", p_ptr->mhp, 9, 52, TERM_L_GREEN); - - if (p_ptr->chp >= p_ptr->mhp) - { - prt_num("Cur Hit Points ", p_ptr->chp, 10, 52, TERM_L_GREEN); - } - else if (p_ptr->chp > (p_ptr->mhp * op_ptr->hitpoint_warn) / 10) - { - prt_num("Cur Hit Points ", p_ptr->chp, 10, 52, TERM_YELLOW); - } - else - { - prt_num("Cur Hit Points ", p_ptr->chp, 10, 52, TERM_RED); - } - - prt_num("Max SP (Mana) ", p_ptr->msp, 11, 52, TERM_L_GREEN); - - if (p_ptr->csp >= p_ptr->msp) - { - prt_num("Cur SP (Mana) ", p_ptr->csp, 12, 52, TERM_L_GREEN); - } - else if (p_ptr->csp > (p_ptr->msp * op_ptr->hitpoint_warn) / 10) - { - prt_num("Cur SP (Mana) ", p_ptr->csp, 12, 52, TERM_YELLOW); - } - else - { - prt_num("Cur SP (Mana) ", p_ptr->csp, 12, 52, TERM_RED); - } - } - - - - /* * Hack -- pass color info around this file */ --- 1068,1073 ---- *************** *** 1190,1215 **** /* ! * Prints ratings on certain abilities * ! * This code is "imitated" elsewhere to "dump" a character sheet. ! */ ! static void display_player_various(void) ! { ! int tmp; int xthn, xthb, xfos, xsrh; int xdis, xdev, xsav, xstl; - cptr desc; object_type *o_ptr; /* Fighting Skill (with current weapon) */ o_ptr = &inventory[INVEN_WIELD]; tmp = p_ptr->to_h + o_ptr->to_h; xthn = p_ptr->skill_thn + (tmp * BTH_PLUS_ADJ); ! /* Shooting Skill (with current bow and normal missile) */ o_ptr = &inventory[INVEN_BOW]; tmp = p_ptr->to_h + o_ptr->to_h; xthb = p_ptr->skill_thb + (tmp * BTH_PLUS_ADJ); --- 1152,1363 ---- /* ! * Prints some "extra" information on the screen. * ! * Space includes rows 3-9 cols 24-79 ! * Space includes rows 10-17 cols 1-79 ! * Space includes rows 19-22 cols 1-79 ! */ ! static void display_player_xtra_info(void) ! { ! int col; ! int hit, dam; ! int base, plus; ! int i, tmp; int xthn, xthb, xfos, xsrh; int xdis, xdev, xsav, xstl; object_type *o_ptr; + cptr desc; + + char buf[160]; + + + /* Upper middle */ + col = 26; + + + /* Age */ + Term_putstr(col, 3, -1, TERM_WHITE, "Age"); + Term_putstr(col+9, 3, -1, TERM_L_BLUE, format("%4d", (int)p_ptr->age)); + + /* Height */ + Term_putstr(col, 4, -1, TERM_WHITE, "Height"); + Term_putstr(col+9, 4, -1, TERM_L_BLUE, format("%4d", (int)p_ptr->ht)); + + /* Weight */ + Term_putstr(col, 5, -1, TERM_WHITE, "Weight"); + Term_putstr(col+9, 5, -1, TERM_L_BLUE, format("%4d", (int)p_ptr->wt)); + + /* Status */ + Term_putstr(col, 6, -1, TERM_WHITE, "Status"); + Term_putstr(col+9, 6, -1, TERM_L_BLUE, format("%4d", (int)p_ptr->sc)); + + /* Maximize */ + Term_putstr(col, 7, -1, TERM_WHITE, "Maximize"); + Term_putstr(col+12, 7, -1, TERM_L_BLUE, p_ptr->maximize ? "Y" : "N"); + + /* Preserve */ + Term_putstr(col, 8, -1, TERM_WHITE, "Preserve"); + Term_putstr(col+12, 8, -1, TERM_L_BLUE, p_ptr->preserve ? "Y" : "N"); + + + /* Left */ + col = 1; + + + /* Level */ + Term_putstr(col, 10, -1, TERM_WHITE, "Level"); + if (p_ptr->lev >= p_ptr->max_lev) + { + Term_putstr(col+8, 10, -1, TERM_L_GREEN, + format("%10d", p_ptr->lev)); + } + else + { + Term_putstr(col+8, 10, -1, TERM_YELLOW, + format("%10d", p_ptr->lev)); + } + + + /* Current Experience */ + Term_putstr(col, 11, -1, TERM_WHITE, "Cur Exp"); + if (p_ptr->exp >= p_ptr->max_exp) + { + Term_putstr(col+8, 11, -1, TERM_L_GREEN, + format("%10ld", p_ptr->exp)); + } + else + { + Term_putstr(col+8, 11, -1, TERM_YELLOW, + format("%10ld", p_ptr->exp)); + } + + + /* Maximum Experience */ + Term_putstr(col, 12, -1, TERM_WHITE, "Max Exp"); + Term_putstr(col+8, 12, -1, TERM_L_GREEN, + format("%10ld", p_ptr->max_exp)); + + + /* Advance Experience */ + Term_putstr(col, 13, -1, TERM_WHITE, "Adv Exp"); + if (p_ptr->lev < PY_MAX_LEVEL) + { + s32b advance = (player_exp[p_ptr->lev - 1] * + p_ptr->expfact / 100L); + Term_putstr(col+8, 13, -1, TERM_L_GREEN, + format("%10ld", advance)); + } + else + { + Term_putstr(col+8, 13, -1, TERM_L_GREEN, + format("%10s", "********")); + } + + + /* Gold */ + Term_putstr(col, 15, -1, TERM_WHITE, "Gold"); + Term_putstr(col+8, 15, -1, TERM_L_GREEN, + format("%10ld", p_ptr->au)); + + + /* Burden */ + sprintf(buf, "%d.%d lbs", + p_ptr->total_weight / 10, + p_ptr->total_weight % 10); + Term_putstr(col, 17, -1, TERM_WHITE, "Burden"); + Term_putstr(col+8, 17, -1, TERM_L_GREEN, + format("%10s", buf)); + + + /* Middle */ + col = 26; + + + /* Armor */ + base = p_ptr->dis_ac; + plus = p_ptr->dis_to_a; + + /* Total Armor */ + sprintf(buf, "[%d,%+d]", base, plus); + Term_putstr(col, 10, -1, TERM_WHITE, "Armor"); + Term_putstr(col+5, 10, -1, TERM_L_BLUE, format("%13s", buf)); + + + /* Base skill */ + hit = p_ptr->dis_to_h; + dam = p_ptr->dis_to_d; + + /* Basic fighting */ + sprintf(buf, "(%+d,%+d)", hit, dam); + Term_putstr(col, 11, -1, TERM_WHITE, "Fight"); + Term_putstr(col+5, 11, -1, TERM_L_BLUE, format("%13s", buf)); + + + /* Melee weapon */ + o_ptr = &inventory[INVEN_WIELD]; + + /* Base skill */ + hit = p_ptr->dis_to_h; + dam = p_ptr->dis_to_d; + + /* Apply weapon bonuses */ + if (object_known_p(o_ptr)) hit += o_ptr->to_h; + if (object_known_p(o_ptr)) dam += o_ptr->to_d; + + /* Melee attacks */ + sprintf(buf, "(%+d,%+d)", hit, dam); + Term_putstr(col, 12, -1, TERM_WHITE, "Melee"); + Term_putstr(col+5, 12, -1, TERM_L_BLUE, format("%13s", buf)); + + + /* Range weapon */ + o_ptr = &inventory[INVEN_BOW]; + + /* Base skill */ + hit = p_ptr->dis_to_h; + dam = 0; + + /* Apply weapon bonuses */ + if (object_known_p(o_ptr)) hit += o_ptr->to_h; + if (object_known_p(o_ptr)) dam += o_ptr->to_d; + + /* Range attacks */ + sprintf(buf, "(%+d,%+d)", hit, dam); + Term_putstr(col, 13, -1, TERM_WHITE, "Shoot"); + Term_putstr(col+5, 13, -1, TERM_L_BLUE, format("%13s", buf)); + + + /* Blows */ + sprintf(buf, "%d/turn", p_ptr->num_blow); + Term_putstr(col, 14, -1, TERM_WHITE, "Blows"); + Term_putstr(col+5, 14, -1, TERM_L_BLUE, format("%13s", buf)); + + + /* Shots */ + sprintf(buf, "%d/turn", p_ptr->num_fire); + Term_putstr(col, 15, -1, TERM_WHITE, "Shots"); + Term_putstr(col+5, 15, -1, TERM_L_BLUE, format("%13s", buf)); + + + /* Infra */ + sprintf(buf, "%d ft", p_ptr->see_infra * 10); + Term_putstr(col, 17, -1, TERM_WHITE, "Infra"); + Term_putstr(col+5, 17, -1, TERM_L_BLUE, format("%13s", buf)); + + + /* Right */ + col = 49; + /* Fighting Skill (with current weapon) */ o_ptr = &inventory[INVEN_WIELD]; tmp = p_ptr->to_h + o_ptr->to_h; xthn = p_ptr->skill_thn + (tmp * BTH_PLUS_ADJ); ! /* Shooting Skill (with current bow) */ o_ptr = &inventory[INVEN_BOW]; tmp = p_ptr->to_h + o_ptr->to_h; xthb = p_ptr->skill_thb + (tmp * BTH_PLUS_ADJ); *************** *** 1223,1270 **** xfos = p_ptr->skill_fos; ! put_str("Fighting :", 16, 1); ! desc = likert(xthn, 12); ! c_put_str(likert_color, desc, 16, 15); ! ! put_str("Bows/Throw :", 17, 1); ! desc = likert(xthb, 12); ! c_put_str(likert_color, desc, 17, 15); ! ! put_str("Saving Throw:", 18, 1); desc = likert(xsav, 6); ! c_put_str(likert_color, desc, 18, 15); ! put_str("Stealth :", 19, 1); desc = likert(xstl, 1); ! c_put_str(likert_color, desc, 19, 15); ! ! put_str("Perception :", 16, 28); ! desc = likert(xfos, 6); ! c_put_str(likert_color, desc, 16, 42); ! put_str("Searching :", 17, 28); ! desc = likert(xsrh, 6); ! c_put_str(likert_color, desc, 17, 42); ! put_str("Disarming :", 18, 28); desc = likert(xdis, 8); ! c_put_str(likert_color, desc, 18, 42); ! put_str("Magic Device:", 19, 28); desc = likert(xdev, 6); ! c_put_str(likert_color, desc, 19, 42); - put_str("Blows/Round:", 16, 55); - put_str(format("%d", p_ptr->num_blow), 16, 69); ! put_str("Shots/Round:", 17, 55); ! put_str(format("%d", p_ptr->num_fire), 17, 69); ! put_str("Infra-Vision:", 19, 55); ! put_str(format("%d feet", p_ptr->see_infra * 10), 19, 69); } --- 1371,1417 ---- xfos = p_ptr->skill_fos; ! put_str("Saving Throw", 10, col); desc = likert(xsav, 6); ! c_put_str(likert_color, format("%9s", desc), 10, col+14); ! put_str("Stealth", 11, col); desc = likert(xstl, 1); ! c_put_str(likert_color, format("%9s", desc), 11, col+14); ! put_str("Fighting", 12, col); ! desc = likert(xthn, 12); ! c_put_str(likert_color, format("%9s", desc), 12, col+14); ! put_str("Shooting", 13, col); ! desc = likert(xthb, 12); ! c_put_str(likert_color, format("%9s", desc), 13, col+14); ! put_str("Disarming", 14, col); desc = likert(xdis, 8); ! c_put_str(likert_color, format("%9s", desc), 14, col+14); ! put_str("Magic Device", 15, col); desc = likert(xdev, 6); ! c_put_str(likert_color, format("%9s", desc), 15, col+14); ! ! put_str("Perception", 16, col); ! desc = likert(xfos, 6); ! c_put_str(likert_color, format("%9s", desc), 16, col+14); + put_str("Searching", 17, col); + desc = likert(xsrh, 6); + c_put_str(likert_color, format("%9s", desc), 17, col+14); ! /* Bottom */ ! col = 5; ! /* History */ ! for (i = 0; i < 4; i++) ! { ! put_str(p_ptr->history[i], i + 19, col); ! } } *************** *** 1430,1436 **** for (x = 0; x < 4; x++) { /* Reset */ ! row = 10; col = 20 * x; /* Extract set */ --- 1577,1583 ---- for (x = 0; x < 4; x++) { /* Reset */ ! row = 11; col = 20 * x; /* Extract set */ *************** *** 1440,1446 **** head = display_player_flag_head[x]; /* Header */ - display_player_equippy(row++, col+6); c_put_str(TERM_WHITE, "abcdefghijkl@", row++, col+6); /* Eight rows */ --- 1587,1592 ---- *************** *** 1496,1501 **** --- 1642,1649 ---- /* Footer */ c_put_str(TERM_WHITE, "abcdefghijkl@", row++, col+6); + + /* Equippy */ display_player_equippy(row++, col+6); } } *************** *** 1506,1533 **** */ static void display_player_misc_info(void) { char buf[80]; - /* Display basics */ - put_str("Name :", 2, 1); - put_str("Sex :", 3, 1); - put_str("Race :", 4, 1); - put_str("Class:", 5, 1); c_put_str(TERM_L_BLUE, op_ptr->full_name, 2, 8); c_put_str(TERM_L_BLUE, sp_ptr->title, 3, 8); c_put_str(TERM_L_BLUE, rp_ptr->title, 4, 8); c_put_str(TERM_L_BLUE, cp_ptr->title, 5, 8); - /* Display extras */ - put_str("Level:", 6, 1); - put_str("HP :", 7, 1); - put_str("SP :", 8, 1); ! sprintf(buf, "%d", p_ptr->lev); ! c_put_str(TERM_L_BLUE, buf, 6, 8); sprintf(buf, "%d/%d", p_ptr->chp, p_ptr->mhp); c_put_str(TERM_L_BLUE, buf, 7, 8); sprintf(buf, "%d/%d", p_ptr->csp, p_ptr->msp); c_put_str(TERM_L_BLUE, buf, 8, 8); } --- 1654,1717 ---- */ static void display_player_misc_info(void) { + cptr p; + char buf[80]; + /* Name */ + put_str("Name", 2, 1); c_put_str(TERM_L_BLUE, op_ptr->full_name, 2, 8); + + + /* Sex */ + put_str("Sex", 3, 1); c_put_str(TERM_L_BLUE, sp_ptr->title, 3, 8); + + + /* Race */ + put_str("Race", 4, 1); c_put_str(TERM_L_BLUE, rp_ptr->title, 4, 8); + + + /* Class */ + put_str("Class", 5, 1); c_put_str(TERM_L_BLUE, cp_ptr->title, 5, 8); ! /* Title */ ! put_str("Title", 6, 1); ! ! /* Wizard */ ! if (p_ptr->wizard) ! { ! p = "[=-WIZARD-=]"; ! } ! ! /* Winner */ ! else if (p_ptr->total_winner || (p_ptr->lev > PY_MAX_LEVEL)) ! { ! p = "***WINNER***"; ! } ! ! /* Normal */ ! else ! { ! p = player_title[p_ptr->pclass][(p_ptr->lev-1)/5]; ! } ! ! /* Dump it */ ! c_put_str(TERM_L_BLUE, p, 6, 8); ! ! ! /* Hit Points */ ! put_str("HP", 7, 1); sprintf(buf, "%d/%d", p_ptr->chp, p_ptr->mhp); c_put_str(TERM_L_BLUE, buf, 7, 8); + + + /* Spell Points */ + put_str("SP", 8, 1); sprintf(buf, "%d/%d", p_ptr->csp, p_ptr->msp); c_put_str(TERM_L_BLUE, buf, 8, 8); } *************** *** 1535,1612 **** /* * Special display, part 2b - * - * How to print out the modifications and sustains. - * Positive mods with no sustain will be light green. - * Positive mods with a sustain will be dark green. - * Sustains (with no modification) will be a dark green 's'. - * Negative mods (from a curse) will be red. - * Huge mods (>9), like from MICoMorgoth, will be a '*' - * No mod, no sustain, will be a slate '.' */ static void display_player_stat_info(void) { int i, row, col; - int stat_col, stat; - - object_type *o_ptr; - u32b f1, f2, f3; - u32b ignore_f2, ignore_f3; - s16b k_idx; - - byte a; - char c; char buf[80]; - /* Column */ - stat_col = 24; - /* Row */ row = 3; /* Print out the labels for the columns */ ! c_put_str(TERM_WHITE, "Stat", row-1, stat_col); ! c_put_str(TERM_BLUE, "Intrnl", row-1, stat_col+5); ! c_put_str(TERM_L_BLUE, "Rce Cls Eqp", row-1, stat_col+12); ! c_put_str(TERM_L_GREEN, "Actual", row-1, stat_col+24); ! c_put_str(TERM_YELLOW, "Currnt", row-1, stat_col+31); /* Display the stats */ for (i = 0; i < 6; i++) { ! /* Reduced name of stat */ ! c_put_str(TERM_WHITE, stat_names_reduced[i], row+i, stat_col); /* Internal "natural" maximum value */ cnv_stat(p_ptr->stat_max[i], buf); ! c_put_str(TERM_BLUE, buf, row+i, stat_col+5); ! /* Race, class, and equipment modifiers */ ! sprintf(buf, "%3d", rp_ptr->r_adj[i]); ! c_put_str(TERM_L_BLUE, buf, row+i, stat_col+12); ! sprintf(buf, "%3d", cp_ptr->c_adj[i]); ! c_put_str(TERM_L_BLUE, buf, row+i, stat_col+16); ! sprintf(buf, "%3d", p_ptr->stat_add[i]); ! c_put_str(TERM_L_BLUE, buf, row+i, stat_col+20); /* Resulting "modified" maximum value */ cnv_stat(p_ptr->stat_top[i], buf); ! c_put_str(TERM_L_GREEN, buf, row+i, stat_col+24); /* Only display stat_use if not maximal */ if (p_ptr->stat_use[i] < p_ptr->stat_top[i]) { cnv_stat(p_ptr->stat_use[i], buf); ! c_put_str(TERM_YELLOW, buf, row+i, stat_col+31); } } /* Column */ ! col = 60+6; ! /* Header and Footer */ c_put_str(TERM_WHITE, "abcdefghijkl@", row-1, col); /* Process equipment */ --- 1719,1829 ---- /* * Special display, part 2b */ static void display_player_stat_info(void) { int i, row, col; char buf[80]; /* Row */ row = 3; + /* Column */ + col = 42; + /* Print out the labels for the columns */ ! c_put_str(TERM_WHITE, " Self", row-1, col+5); ! c_put_str(TERM_WHITE, " RB", row-1, col+12); ! c_put_str(TERM_WHITE, " CB", row-1, col+16); ! c_put_str(TERM_WHITE, " EB", row-1, col+20); ! c_put_str(TERM_WHITE, " Best", row-1, col+24); /* Display the stats */ for (i = 0; i < 6; i++) { ! /* Reduced */ ! if (p_ptr->stat_use[i] < p_ptr->stat_top[i]) ! { ! /* Use lowercase stat name */ ! put_str(stat_names_reduced[i], row+i, col); ! } ! ! /* Normal */ ! else ! { ! /* Assume uppercase stat name */ ! put_str(stat_names[i], row+i, col); ! } ! ! /* Indicate natural maximum */ ! if (p_ptr->stat_max[i] == 18+100) ! { ! put_str("!", row+i, col+3); ! } /* Internal "natural" maximum value */ cnv_stat(p_ptr->stat_max[i], buf); ! c_put_str(TERM_L_GREEN, buf, row+i, col+5); ! /* Race Bonus */ ! sprintf(buf, "%+3d", rp_ptr->r_adj[i]); ! c_put_str(TERM_L_BLUE, buf, row+i, col+12); ! ! /* Class Bonus */ ! sprintf(buf, "%+3d", cp_ptr->c_adj[i]); ! c_put_str(TERM_L_BLUE, buf, row+i, col+16); ! ! /* Equipment Bonus */ ! sprintf(buf, "%+3d", p_ptr->stat_add[i]); ! c_put_str(TERM_L_BLUE, buf, row+i, col+20); /* Resulting "modified" maximum value */ cnv_stat(p_ptr->stat_top[i], buf); ! c_put_str(TERM_L_GREEN, buf, row+i, col+24); /* Only display stat_use if not maximal */ if (p_ptr->stat_use[i] < p_ptr->stat_top[i]) { cnv_stat(p_ptr->stat_use[i], buf); ! c_put_str(TERM_YELLOW, buf, row+i, col+31); } } + } + + + /* + * Special display, part 2c + * + * How to print out the modifications and sustains. + * Positive mods with no sustain will be light green. + * Positive mods with a sustain will be dark green. + * Sustains (with no modification) will be a dark green 's'. + * Negative mods (from a curse) will be red. + * Huge mods (>9), like from MICoMorgoth, will be a '*' + * No mod, no sustain, will be a slate '.' + */ + static void display_player_sust_info(void) + { + int i, row, col, stat; + + object_type *o_ptr; + u32b f1, f2, f3; + u32b ignore_f2, ignore_f3; + s16b k_idx; + + byte a; + char c; + + + /* Row */ + row = 3; /* Column */ ! col = 26; ! /* Header */ c_put_str(TERM_WHITE, "abcdefghijkl@", row-1, col); /* Process equipment */ *************** *** 1644,1650 **** a = TERM_L_GREEN; /* Label boost */ ! if (o_ptr->pval < 10) c = '0' + o_ptr->pval; } /* Bad */ --- 1861,1867 ---- a = TERM_L_GREEN; /* Label boost */ ! if (o_ptr->pval < 10) c = I2D(o_ptr->pval); } /* Bad */ *************** *** 1654,1660 **** a = TERM_RED; /* Label boost */ ! if (o_ptr->pval < 10) c = '0' - o_ptr->pval; } } --- 1871,1877 ---- a = TERM_RED; /* Label boost */ ! if (o_ptr->pval > -10) c = I2D(-(o_ptr->pval)); } } *************** *** 1672,1678 **** /* Advance */ col++; ! } /* Player flags */ player_flags(&f1, &f2, &f3); --- 1889,1895 ---- /* Advance */ col++; ! } /* Player flags */ player_flags(&f1, &f2, &f3); *************** *** 1694,1822 **** /* Dump */ Term_putch(col, row+stat, a, c); ! } } /* ! * Display the character on the screen (various modes) * ! * The top two and bottom two lines are left blank. * ! * Mode 0 = standard display with skills ! * Mode 1 = standard display with history ! * Mode 2 = special display with flags */ void display_player(int mode) { - int i; - - char buf[80]; - - - /* XXX XXX XXX */ - mode = (mode % 3); - - /* Erase screen */ clear_from(0); ! /* Standard */ ! if ((mode == 0) || (mode == 1)) ! { ! /* Name, Sex, Race, Class */ ! put_str("Name :", 2, 1); ! put_str("Sex :", 3, 1); ! put_str("Race :", 4, 1); ! put_str("Class :", 5, 1); ! ! c_put_str(TERM_L_BLUE, op_ptr->full_name, 2, 15); ! c_put_str(TERM_L_BLUE, sp_ptr->title, 3, 15); ! c_put_str(TERM_L_BLUE, rp_ptr->title, 4, 15); ! c_put_str(TERM_L_BLUE, cp_ptr->title, 5, 15); ! ! /* Age, Height, Weight, Social */ ! prt_num("Age ", (int)p_ptr->age, 2, 32, TERM_L_BLUE); ! prt_num("Height ", (int)p_ptr->ht, 3, 32, TERM_L_BLUE); ! prt_num("Weight ", (int)p_ptr->wt, 4, 32, TERM_L_BLUE); ! prt_num("Social Class ", (int)p_ptr->sc, 5, 32, TERM_L_BLUE); ! ! /* Display the stats */ ! for (i = 0; i < 6; i++) ! { ! /* Special treatment of "injured" stats */ ! if (p_ptr->stat_cur[i] < p_ptr->stat_max[i]) ! { ! int value; ! ! /* Use lowercase stat name */ ! put_str(stat_names_reduced[i], 2 + i, 61); ! ! /* Get the current stat */ ! value = p_ptr->stat_use[i]; ! ! /* Obtain the current stat (modified) */ ! cnv_stat(value, buf); ! ! /* Display the current stat (modified) */ ! c_put_str(TERM_YELLOW, buf, 2 + i, 66); ! ! /* Acquire the max stat */ ! value = p_ptr->stat_top[i]; ! /* Obtain the maximum stat (modified) */ ! cnv_stat(value, buf); ! /* Display the maximum stat (modified) */ ! c_put_str(TERM_L_GREEN, buf, 2 + i, 73); ! } ! ! /* Normal treatment of "normal" stats */ ! else ! { ! /* Assume uppercase stat name */ ! put_str(stat_names[i], 2 + i, 61); ! ! /* Obtain the current stat (modified) */ ! cnv_stat(p_ptr->stat_use[i], buf); ! ! /* Display the current stat (modified) */ ! c_put_str(TERM_L_GREEN, buf, 2 + i, 66); ! } ! } ! ! /* Extra info */ ! display_player_middle(); ! ! /* Display "history" info */ ! if (mode == 1) ! { ! put_str("(Character Background)", 15, 25); ! ! for (i = 0; i < 4; i++) ! { ! put_str(p_ptr->history[i], i + 16, 10); ! } ! } ! /* Display "various" info */ ! else ! { ! put_str("(Miscellaneous Abilities)", 15, 25); ! display_player_various(); ! } } ! /* Special */ ! else if (mode == 2) { ! /* See "http://www.cs.berkeley.edu/~davidb/angband.html" */ ! ! /* Dump the info */ ! display_player_misc_info(); ! display_player_stat_info(); ! display_player_flag_info(); } } --- 1911,1967 ---- /* Dump */ Term_putch(col, row+stat, a, c); ! } ! ! /* Column */ ! col = 26; ! ! /* Footer */ ! c_put_str(TERM_WHITE, "abcdefghijkl@", row+6, col); ! ! /* Equippy */ ! display_player_equippy(row+7, col); } /* ! * Display the character on the screen (two different modes) * ! * The top two lines, and the bottom line (or two) are left blank. * ! * Mode 0 = standard display with skills/history ! * Mode 1 = special display with equipment flags */ void display_player(int mode) { /* Erase screen */ clear_from(0); ! /* Misc info */ ! display_player_misc_info(); ! /* Stat info */ ! display_player_stat_info(); ! /* Special */ ! if (mode) ! { ! /* Hack -- Level */ ! put_str("Level", 9, 1); ! c_put_str(TERM_L_BLUE, format("%d", p_ptr->lev), 9, 8); ! /* Stat/Sustain flags */ ! display_player_sust_info(); ! /* Other flags */ ! display_player_flag_info(); } ! /* Standard */ ! else { ! /* Extra info */ ! display_player_xtra_info(); } } *************** *** 1907,1913 **** display_player(0); /* Dump part of the screen */ ! for (y = 2; y < 22; y++) { /* Dump each row */ for (x = 0; x < 79; x++) --- 2052,2058 ---- display_player(0); /* Dump part of the screen */ ! for (y = 2; y < 23; y++) { /* Dump each row */ for (x = 0; x < 79; x++) *************** *** 1919,1946 **** buf[x] = c; } ! /* Terminate */ ! buf[x] = '\0'; ! ! /* End the row */ ! fprintf(fff, "%s\n", buf); ! } ! ! /* Display history */ ! display_player(1); ! ! /* Dump part of the screen */ ! for (y = 15; y < 20; y++) ! { ! /* Dump each row */ ! for (x = 0; x < 79; x++) ! { ! /* Get the attr/char */ ! (void)(Term_what(x, y, &a, &c)); ! ! /* Dump it */ ! buf[x] = c; ! } /* Terminate */ buf[x] = '\0'; --- 2064,2071 ---- buf[x] = c; } ! /* Back up over spaces */ ! while ((x > 0) && (buf[x-1] == ' ')) --x; /* Terminate */ buf[x] = '\0'; *************** *** 2045,2054 **** cptr find = NULL; /* Hold a string to find */ ! char finder[128]; /* Hold a string to show */ ! char shower[128]; /* Describe this thing */ char caption[128]; --- 2170,2179 ---- cptr find = NULL; /* Hold a string to find */ ! char finder[81]; /* Hold a string to show */ ! char shower[81]; /* Describe this thing */ char caption[128]; *************** *** 2146,2152 **** menu = TRUE; /* Extract the menu item */ ! k = buf[7] - '0'; /* Extract the menu item */ strcpy(hook[k], buf + 10); --- 2271,2277 ---- menu = TRUE; /* Extract the menu item */ ! k = D2I(buf[7]); /* Extract the menu item */ strcpy(hook[k], buf + 10); *************** *** 2249,2255 **** /* Hack -- failed search */ if (find) { ! bell(); line = back; find = NULL; continue; --- 2374,2380 ---- /* Hack -- failed search */ if (find) { ! bell("Search string not found!"); line = back; find = NULL; continue; *************** *** 2317,2323 **** /* Hack -- go to a specific line */ if (k == '#') { ! char tmp[80]; prt("Goto Line: ", 23, 0); strcpy(tmp, "0"); if (askfor_aux(tmp, 80)) --- 2442,2448 ---- /* Hack -- go to a specific line */ if (k == '#') { ! char tmp[81]; prt("Goto Line: ", 23, 0); strcpy(tmp, "0"); if (askfor_aux(tmp, 80)) *************** *** 2329,2335 **** /* Hack -- go to a specific file */ if (k == '%') { ! char tmp[80]; prt("Goto File: ", 23, 0); strcpy(tmp, "help.hlp"); if (askfor_aux(tmp, 80)) --- 2454,2460 ---- /* Hack -- go to a specific file */ if (k == '%') { ! char tmp[81]; prt("Goto File: ", 23, 0); strcpy(tmp, "help.hlp"); if (askfor_aux(tmp, 80)) *************** *** 2358,2367 **** } /* Recurse on numbers */ ! if (menu && isdigit(k) && hook[k-'0'][0]) { /* Recurse on that file */ ! if (!show_file(hook[k-'0'], NULL, 0, mode)) k = ESCAPE; } /* Exit on escape */ --- 2483,2492 ---- } /* Recurse on numbers */ ! if (menu && isdigit(k) && hook[D2I(k)][0]) { /* Recurse on that file */ ! if (!show_file(hook[D2I(k)], NULL, 0, mode)) k = ESCAPE; } /* Exit on escape */ *************** *** 2384,2415 **** */ void do_cmd_help(void) { ! /* Enter "icky" mode */ ! character_icky = TRUE; ! ! /* Save the screen */ ! Term_save(); /* Peruse the main help file */ (void)show_file("help.hlp", NULL, 0, 0); ! /* Restore the screen */ ! Term_load(); ! ! /* Leave "icky" mode */ ! character_icky = FALSE; } /* ! * Process the player name. ! * Extract a clean "base name". ! * Build the savefile name if needed. */ void process_player_name(bool sf) { ! int i, k = 0; /* Cannot be too long */ --- 2509,2538 ---- */ void do_cmd_help(void) { ! /* Save screen */ ! screen_save(); /* Peruse the main help file */ (void)show_file("help.hlp", NULL, 0, 0); ! /* Load screen */ ! screen_load(); } /* ! * Process the player name and extract a clean "base name". ! * ! * If "sf" is TRUE, then we initialize "savefile" based on player name. ! * ! * Some platforms (Windows, Macintosh, Amiga) leave the "savefile" empty ! * when a new character is created, and then when the character is done ! * being created, they call this function to choose a new savefile name. */ void process_player_name(bool sf) { ! int i; /* Cannot be too long */ *************** *** 2419,2489 **** quit_fmt("The name '%s' is too long!", op_ptr->full_name); } ! /* Cannot contain "icky" characters */ for (i = 0; op_ptr->full_name[i]; i++) { /* No control characters */ ! if (iscntrl(op_ptr->full_name[i])) { /* Illegal characters */ ! quit_fmt("The name '%s' contains control chars!", op_ptr->full_name); } - } - - - #ifdef MACINTOSH ! /* Extract "useful" letters */ ! for (i = 0; op_ptr->full_name[i]; i++) ! { ! char c = op_ptr->full_name[i]; ! /* Convert "colon" and "period" */ ! if ((c == ':') || (c == '.')) c = '_'; ! ! /* Accept all the letters */ ! op_ptr->base_name[k++] = c; } - #else - - /* Extract "useful" letters */ - for (i = 0; op_ptr->full_name[i]; i++) - { - char c = op_ptr->full_name[i]; - - /* Accept some letters */ - if (isalpha(c) || isdigit(c)) op_ptr->base_name[k++] = c; - - /* Convert space, dot, and underscore to underscore */ - else if (strchr(". _", c)) op_ptr->base_name[k++] = '_'; - } - - #endif - - #if defined(WINDOWS) || defined(MSDOS) ! /* Hack -- max length */ ! if (k > 8) k = 8; #endif /* Terminate */ ! op_ptr->base_name[k] = '\0'; /* Require a "base" name */ ! if (!op_ptr->base_name[0]) strcpy(op_ptr->base_name, "PLAYER"); ! ! ! #ifdef SAVEFILE_MUTABLE ! ! /* Accept */ ! sf = TRUE; - #endif ! /* Change the savefile name */ if (sf) { char temp[128]; --- 2542,2584 ---- quit_fmt("The name '%s' is too long!", op_ptr->full_name); } ! /* Process the player name */ for (i = 0; op_ptr->full_name[i]; i++) { + char c = op_ptr->full_name[i]; + /* No control characters */ ! if (iscntrl(c)) { /* Illegal characters */ ! quit_fmt("Illegal control char (0x%02X) in player name", c); } ! /* Convert all non-alphanumeric symbols */ ! if (!isalpha(c) && !isdigit(c)) c = '_'; ! /* Build "base_name" */ ! op_ptr->base_name[i] = c; } #if defined(WINDOWS) || defined(MSDOS) ! /* Max length */ ! if (i > 8) i = 8; #endif /* Terminate */ ! op_ptr->base_name[i] = '\0'; /* Require a "base" name */ ! if (!op_ptr->base_name[0]) ! { ! strcpy(op_ptr->base_name, "PLAYER"); ! } ! /* Pick savefile name if needed */ if (sf) { char temp[128]; *************** *** 2510,2559 **** /* * Gets a name for the character, reacting to name changes. * - * Assumes that "display_player(0)" has just been called - * * Perhaps we should NOT ask for a name (at "birth()") on ! * Unix machines? XXX XXX * * What a horrible name for a global function. XXX XXX XXX */ void get_name(void) { ! char tmp[32]; ! /* Clear last line */ ! clear_from(22); ! /* Prompt and ask */ ! prt("[Enter your player's name above, or hit ESCAPE]", 23, 2); ! ! /* Ask until happy */ ! while (1) { ! /* Go to the "name" field */ ! move_cursor(2, 15); ! ! /* Save the player name */ ! strcpy(tmp, op_ptr->full_name); ! ! /* Get an input, ignore "Escape" */ ! if (askfor_aux(tmp, 15)) strcpy(op_ptr->full_name, tmp); /* Process the player name */ process_player_name(FALSE); - - /* All done */ - break; } - - /* Pad the name (to clear junk) */ - sprintf(tmp, "%-15.15s", op_ptr->full_name); - - /* Re-Draw the name (in light blue) */ - c_put_str(TERM_L_BLUE, tmp, 2, 15); - - /* Erase the prompt, etc */ - clear_from(22); } --- 2605,2631 ---- /* * Gets a name for the character, reacting to name changes. * * Perhaps we should NOT ask for a name (at "birth()") on ! * Unix machines? XXX XXX XXX * * What a horrible name for a global function. XXX XXX XXX */ void get_name(void) { ! char tmp[16]; ! /* Save the player name */ ! strcpy(tmp, op_ptr->full_name); ! /* Prompt for a new name */ ! if (get_string("Enter a name for your character: ", tmp, 15)) { ! /* Use the name */ ! strcpy(op_ptr->full_name, tmp); /* Process the player name */ process_player_name(FALSE); } } *************** *** 2900,2927 **** /* Dump character records as requested */ while (TRUE) { ! char out_val[160]; /* Prompt */ put_str("Filename: ", 23, 0); /* Default */ ! strcpy(out_val, ""); /* Ask for filename (or abort) */ ! if (!askfor_aux(out_val, 60)) return; /* Return means "show on screen" */ ! if (!out_val[0]) break; /* Save screen */ ! Term_save(); /* Dump a character file */ ! (void)file_character(out_val, FALSE); /* Load screen */ ! Term_load(); } --- 2972,2999 ---- /* Dump character records as requested */ while (TRUE) { ! char tmp[81]; /* Prompt */ put_str("Filename: ", 23, 0); /* Default */ ! strcpy(tmp, ""); /* Ask for filename (or abort) */ ! if (!askfor_aux(tmp, 80)) return; /* Return means "show on screen" */ ! if (!tmp[0]) break; /* Save screen */ ! screen_save(); /* Dump a character file */ ! (void)file_character(tmp, FALSE); /* Load screen */ ! screen_load(); } *************** *** 2989,2997 **** /* Acquire inventory color */ attr = tval_to_attr[o_ptr->tval & 0x7F]; - /* Disable inventory colors */ - if (!inventory_colors) attr = TERM_WHITE; - /* Display the object */ c_put_str(attr, o_name, j+2, 7); } --- 3061,3066 ---- *************** *** 3176,3182 **** high_score the_score; ! char out_val[256]; char tmp_val[160]; --- 3245,3251 ---- high_score the_score; ! char out_val[160]; char tmp_val[160]; *************** *** 3332,3343 **** /* Open the binary high score file, for reading */ highscore_fd = fd_open(buf, O_RDONLY); - /* Paranoia -- No score file */ - if (highscore_fd < 0) quit("Score file unavailable."); - /* Clear screen */ Term_clear(); /* Display the scores */ display_scores_aux(from, to, -1, NULL); --- 3401,3412 ---- /* Open the binary high score file, for reading */ highscore_fd = fd_open(buf, O_RDONLY); /* Clear screen */ Term_clear(); + /* Title */ + put_str(" Angband Hall of Fame", 0, 0); + /* Display the scores */ display_scores_aux(from, to, -1, NULL); *************** *** 3347,3352 **** --- 3416,3426 ---- /* Forget the high score fd */ highscore_fd = -1; + /* Wait for response */ + prt("[Press any key to quit.]", 23, 17); + (void)inkey(); + prt("", 23, 0); + /* Quit */ quit(NULL); } *************** *** 3668,3675 **** signals_ignore_tstp(); ! /* Hack -- Character is now "icky" */ ! character_icky = TRUE; /* Build the filename */ --- 3742,3749 ---- signals_ignore_tstp(); ! /* Hack -- Increase "icky" depth */ ! character_icky++; /* Build the filename */ *************** *** 3691,3698 **** /* Show more info */ show_info(); ! /* Save memories (and mark savefile as "dead") */ ! if (!save_player()) msg_print("death save failed!"); #if 0 /* Dump bones file */ --- 3765,3776 ---- /* Show more info */ show_info(); ! /* Save dead player */ ! if (!save_player()) ! { ! msg_print("death save failed!"); ! msg_print(NULL); ! } #if 0 /* Dump bones file */ *************** *** 3722,3727 **** --- 3800,3809 ---- /* Forget the high score fd */ highscore_fd = -1; + + + /* Hack -- Decrease "icky" depth */ + /* character_icky--; */ /* Allow suspending now */ diff -c -r angband-282/src/generate.c angband-283/src/generate.c *** angband-282/src/generate.c Wed Sep 3 11:57:33 1997 --- angband-283/src/generate.c Fri Feb 6 04:10:31 1998 *************** *** 358,364 **** static void place_rubble(int y, int x) { /* Create rubble */ ! cave_feat[y][x] = FEAT_RUBBLE; } --- 358,364 ---- static void place_rubble(int y, int x) { /* Create rubble */ ! cave_set_feat(y, x, FEAT_RUBBLE); } *************** *** 369,375 **** static void place_up_stairs(int y, int x) { /* Create up stairs */ ! cave_feat[y][x] = FEAT_LESS; } --- 369,375 ---- static void place_up_stairs(int y, int x) { /* Create up stairs */ ! cave_set_feat(y, x, FEAT_LESS); } *************** *** 379,385 **** static void place_down_stairs(int y, int x) { /* Create down stairs */ ! cave_feat[y][x] = FEAT_MORE; } --- 379,385 ---- static void place_down_stairs(int y, int x) { /* Create down stairs */ ! cave_set_feat(y, x, FEAT_MORE); } *************** *** 415,436 **** /* - * Place a locked door at the given location - */ - static void place_locked_door(int y, int x) - { - /* Create locked door */ - cave_feat[y][x] = FEAT_DOOR_HEAD + randint(7); - } - - - /* * Place a secret door at the given location */ static void place_secret_door(int y, int x) { /* Create secret door */ ! cave_feat[y][x] = FEAT_SECRET; } --- 415,426 ---- /* * Place a secret door at the given location */ static void place_secret_door(int y, int x) { /* Create secret door */ ! cave_set_feat(y, x, FEAT_SECRET); } *************** *** 448,489 **** if (tmp < 300) { /* Create open door */ ! cave_feat[y][x] = FEAT_OPEN; } /* Broken doors (100/1000) */ else if (tmp < 400) { /* Create broken door */ ! cave_feat[y][x] = FEAT_BROKEN; } /* Secret doors (200/1000) */ else if (tmp < 600) { /* Create secret door */ ! cave_feat[y][x] = FEAT_SECRET; } /* Closed doors (300/1000) */ else if (tmp < 900) { /* Create closed door */ ! cave_feat[y][x] = FEAT_DOOR_HEAD + 0x00; } /* Locked doors (99/1000) */ else if (tmp < 999) { /* Create locked door */ ! cave_feat[y][x] = FEAT_DOOR_HEAD + randint(7); } /* Stuck doors (1/1000) */ else { /* Create jammed door */ ! cave_feat[y][x] = FEAT_DOOR_HEAD + 0x08 + rand_int(8); } } --- 438,479 ---- if (tmp < 300) { /* Create open door */ ! cave_set_feat(y, x, FEAT_OPEN); } /* Broken doors (100/1000) */ else if (tmp < 400) { /* Create broken door */ ! cave_set_feat(y, x, FEAT_BROKEN); } /* Secret doors (200/1000) */ else if (tmp < 600) { /* Create secret door */ ! cave_set_feat(y, x, FEAT_SECRET); } /* Closed doors (300/1000) */ else if (tmp < 900) { /* Create closed door */ ! cave_set_feat(y, x, FEAT_DOOR_HEAD + 0x00); } /* Locked doors (99/1000) */ else if (tmp < 999) { /* Create locked door */ ! cave_set_feat(y, x, FEAT_DOOR_HEAD + randint(7)); } /* Stuck doors (1/1000) */ else { /* Create jammed door */ ! cave_set_feat(y, x, FEAT_DOOR_HEAD + 0x08 + rand_int(8)); } } *************** *** 520,540 **** if (!p_ptr->depth) { /* Clear previous contents, add down stairs */ ! cave_feat[y][x] = FEAT_MORE; } /* Quest -- must go up */ else if (is_quest(p_ptr->depth) || (p_ptr->depth >= MAX_DEPTH-1)) { /* Clear previous contents, add up stairs */ ! cave_feat[y][x] = FEAT_LESS; } /* Requested type */ else { /* Clear previous contents, add stairs */ ! cave_feat[y][x] = feat; } /* All done */ --- 510,530 ---- if (!p_ptr->depth) { /* Clear previous contents, add down stairs */ ! cave_set_feat(y, x, FEAT_MORE); } /* Quest -- must go up */ else if (is_quest(p_ptr->depth) || (p_ptr->depth >= MAX_DEPTH-1)) { /* Clear previous contents, add up stairs */ ! cave_set_feat(y, x, FEAT_LESS); } /* Requested type */ else { /* Clear previous contents, add stairs */ ! cave_set_feat(y, x, feat); } /* All done */ *************** *** 660,666 **** if (cave_feat[ty][tx] > FEAT_WALL_SOLID) continue; /* Clear previous contents, add proper vein type */ ! cave_feat[ty][tx] = feat; /* Hack -- Add some (known) treasure */ if (rand_int(chance) == 0) cave_feat[ty][tx] += 0x04; --- 650,656 ---- if (cave_feat[ty][tx] > FEAT_WALL_SOLID) continue; /* Clear previous contents, add proper vein type */ ! cave_set_feat(ty, tx, feat); /* Hack -- Add some (known) treasure */ if (rand_int(chance) == 0) cave_feat[ty][tx] += 0x04; *************** *** 724,758 **** if (t < 20) { /* Create granite wall */ ! cave_feat[y][x] = FEAT_WALL_EXTRA; } /* Quartz */ else if (t < 70) { /* Create quartz vein */ ! cave_feat[y][x] = FEAT_QUARTZ; } /* Magma */ else if (t < 100) { /* Create magma vein */ ! cave_feat[y][x] = FEAT_MAGMA; } /* Floor */ else { /* Create floor */ ! cave_feat[y][x] = FEAT_FLOOR; } /* No longer part of a room or vault */ cave_info[y][x] &= ~(CAVE_ROOM | CAVE_ICKY); ! /* No longer illuminated or known */ ! cave_info[y][x] &= ~(CAVE_MARK | CAVE_GLOW); } } } --- 714,748 ---- if (t < 20) { /* Create granite wall */ ! cave_set_feat(y, x, FEAT_WALL_EXTRA); } /* Quartz */ else if (t < 70) { /* Create quartz vein */ ! cave_set_feat(y, x, FEAT_QUARTZ); } /* Magma */ else if (t < 100) { /* Create magma vein */ ! cave_set_feat(y, x, FEAT_MAGMA); } /* Floor */ else { /* Create floor */ ! cave_set_feat(y, x, FEAT_FLOOR); } /* No longer part of a room or vault */ cave_info[y][x] &= ~(CAVE_ROOM | CAVE_ICKY); ! /* No longer illuminated */ ! cave_info[y][x] &= ~(CAVE_GLOW); } } } *************** *** 882,887 **** --- 872,1013 ---- + /* + * Generate helper -- create a new room with optional light + */ + static void generate_room(int y1, int x1, int y2, int x2, int light) + { + int y, x; + + for (y = y1; y <= y2; y++) + { + for (x = x1; x <= x2; x++) + { + cave_info[y][x] |= (CAVE_ROOM); + if (light) cave_info[y][x] |= (CAVE_GLOW); + } + } + } + + + /* + * Generate helper -- fill a rectangle with a feature + */ + static void generate_fill(int y1, int x1, int y2, int x2, int feat) + { + int y, x; + + for (y = y1; y <= y2; y++) + { + for (x = x1; x <= x2; x++) + { + cave_set_feat(y, x, feat); + } + } + } + + + /* + * Generate helper -- draw a rectangle with a feature + */ + static void generate_draw(int y1, int x1, int y2, int x2, int feat) + { + int y, x; + + for (y = y1; y <= y2; y++) + { + cave_set_feat(y, x1, feat); + cave_set_feat(y, x2, feat); + } + + for (x = x1; x <= x2; x++) + { + cave_set_feat(y1, x, feat); + cave_set_feat(y2, x, feat); + } + } + + + /* + * Generate helper -- split a rectangle with a feature + */ + static void generate_plus(int y1, int x1, int y2, int x2, int feat) + { + int y, x; + int y0, x0; + + /* Center */ + y0 = (y1 + y2) / 2; + x0 = (x1 + x2) / 2; + + for (y = y1; y <= y2; y++) + { + cave_set_feat(y, x0, feat); + } + + for (x = x1; x <= x2; x++) + { + cave_set_feat(y0, x, feat); + } + } + + + /* + * Generate helper -- open all sides of a rectangle with a feature + */ + static void generate_open(int y1, int x1, int y2, int x2, int feat) + { + int y0, x0; + + /* Center */ + y0 = (y1 + y2) / 2; + x0 = (x1 + x2) / 2; + + /* Open all sides */ + cave_set_feat(y1, x0, feat); + cave_set_feat(y0, x1, feat); + cave_set_feat(y2, x0, feat); + cave_set_feat(y0, x2, feat); + } + + + /* + * Generate helper -- open one side of a rectangle with a feature + */ + static void generate_hole(int y1, int x1, int y2, int x2, int feat) + { + int y0, x0; + + /* Center */ + y0 = (y1 + y2) / 2; + x0 = (x1 + x2) / 2; + + /* Open random side */ + switch (rand_int(4)) + { + case 0: + { + cave_set_feat(y1, x0, feat); + break; + } + case 1: + { + cave_set_feat(y0, x1, feat); + break; + } + case 2: + { + cave_set_feat(y2, x0, feat); + break; + } + case 3: + { + cave_set_feat(y0, x2, feat); + break; + } + } + } + /* * Room building routines. *************** *** 901,947 **** /* * Type 1 -- normal rectangular rooms */ ! static void build_type1(int yval, int xval) { ! int y, x, y2, x2; ! int y1, x1; ! bool light; ! /* Choose lite or dark */ ! light = (p_ptr->depth <= randint(25)); /* Pick a room size */ ! y1 = yval - randint(4); ! y2 = yval + randint(3); ! x1 = xval - randint(11); ! x2 = xval + randint(11); ! /* Place a full floor under the room */ ! for (y = y1 - 1; y <= y2 + 1; y++) ! { ! for (x = x1 - 1; x <= x2 + 1; x++) ! { ! cave_feat[y][x] = FEAT_FLOOR; ! cave_info[y][x] |= (CAVE_ROOM); ! if (light) cave_info[y][x] |= (CAVE_GLOW); ! } ! } ! /* Walls around the room */ ! for (y = y1 - 1; y <= y2 + 1; y++) ! { ! cave_feat[y][x1-1] = FEAT_WALL_OUTER; ! cave_feat[y][x2+1] = FEAT_WALL_OUTER; ! } ! for (x = x1 - 1; x <= x2 + 1; x++) ! { ! cave_feat[y1-1][x] = FEAT_WALL_OUTER; ! cave_feat[y2+1][x] = FEAT_WALL_OUTER; ! } /* Hack -- Occasional pillar room */ --- 1027,1060 ---- /* * Type 1 -- normal rectangular rooms */ ! static void build_type1(int y0, int x0) { ! int y, x; ! ! int y1, x1, y2, x2; ! int light = FALSE; ! /* Occasional light */ ! if (p_ptr->depth <= randint(25)) light = TRUE; /* Pick a room size */ ! y1 = y0 - randint(4); ! x1 = x0 - randint(11); ! y2 = y0 + randint(3); ! x2 = x0 + randint(11); ! /* Generate new room */ ! generate_room(y1-1, x1-1, y2+1, x2+1, light); ! /* Generate outer walls */ ! generate_draw(y1-1, x1-1, y2+1, x2+1, FEAT_WALL_OUTER); ! ! /* Generate inner floors */ ! generate_fill(y1, x1, y2, x2, FEAT_FLOOR); /* Hack -- Occasional pillar room */ *************** *** 951,957 **** { for (x = x1; x <= x2; x += 2) { ! cave_feat[y][x] = FEAT_WALL_INNER; } } } --- 1064,1070 ---- { for (x = x1; x <= x2; x += 2) { ! cave_set_feat(y, x, FEAT_WALL_INNER); } } } *************** *** 961,973 **** { for (y = y1 + 2; y <= y2 - 2; y += 2) { ! cave_feat[y][x1] = FEAT_WALL_INNER; ! cave_feat[y][x2] = FEAT_WALL_INNER; } for (x = x1 + 2; x <= x2 - 2; x += 2) { ! cave_feat[y1][x] = FEAT_WALL_INNER; ! cave_feat[y2][x] = FEAT_WALL_INNER; } } } --- 1074,1087 ---- { for (y = y1 + 2; y <= y2 - 2; y += 2) { ! cave_set_feat(y, x1, FEAT_WALL_INNER); ! cave_set_feat(y, x2, FEAT_WALL_INNER); } + for (x = x1 + 2; x <= x2 - 2; x += 2) { ! cave_set_feat(y1, x, FEAT_WALL_INNER); ! cave_set_feat(y2, x, FEAT_WALL_INNER); } } } *************** *** 976,1074 **** /* * Type 2 -- Overlapping rectangular rooms */ ! static void build_type2(int yval, int xval) { - int y, x; int y1a, x1a, y2a, x2a; int y1b, x1b, y2b, x2b; ! bool light; - /* Choose lite or dark */ - light = (p_ptr->depth <= randint(25)); - /* Determine extents of the first room */ - y1a = yval - randint(4); - y2a = yval + randint(3); - x1a = xval - randint(11); - x2a = xval + randint(10); - - /* Determine extents of the second room */ - y1b = yval - randint(3); - y2b = yval + randint(4); - x1b = xval - randint(10); - x2b = xval + randint(11); - - - /* Place a full floor for room "a" */ - for (y = y1a - 1; y <= y2a + 1; y++) - { - for (x = x1a - 1; x <= x2a + 1; x++) - { - cave_feat[y][x] = FEAT_FLOOR; - cave_info[y][x] |= (CAVE_ROOM); - if (light) cave_info[y][x] |= (CAVE_GLOW); - } - } ! /* Place a full floor for room "b" */ ! for (y = y1b - 1; y <= y2b + 1; y++) ! { ! for (x = x1b - 1; x <= x2b + 1; x++) ! { ! cave_feat[y][x] = FEAT_FLOOR; ! cave_info[y][x] |= (CAVE_ROOM); ! if (light) cave_info[y][x] |= (CAVE_GLOW); ! } ! } ! /* Place the walls around room "a" */ ! for (y = y1a - 1; y <= y2a + 1; y++) ! { ! cave_feat[y][x1a-1] = FEAT_WALL_OUTER; ! cave_feat[y][x2a+1] = FEAT_WALL_OUTER; ! } ! for (x = x1a - 1; x <= x2a + 1; x++) ! { ! cave_feat[y1a-1][x] = FEAT_WALL_OUTER; ! cave_feat[y2a+1][x] = FEAT_WALL_OUTER; ! } ! /* Place the walls around room "b" */ ! for (y = y1b - 1; y <= y2b + 1; y++) ! { ! cave_feat[y][x1b-1] = FEAT_WALL_OUTER; ! cave_feat[y][x2b+1] = FEAT_WALL_OUTER; ! } ! for (x = x1b - 1; x <= x2b + 1; x++) ! { ! cave_feat[y1b-1][x] = FEAT_WALL_OUTER; ! cave_feat[y2b+1][x] = FEAT_WALL_OUTER; ! } ! /* Replace the floor for room "a" */ ! for (y = y1a; y <= y2a; y++) ! { ! for (x = x1a; x <= x2a; x++) ! { ! cave_feat[y][x] = FEAT_FLOOR; ! } ! } ! /* Replace the floor for room "b" */ ! for (y = y1b; y <= y2b; y++) ! { ! for (x = x1b; x <= x2b; x++) ! { ! cave_feat[y][x] = FEAT_FLOOR; ! } ! } } --- 1090,1138 ---- /* * Type 2 -- Overlapping rectangular rooms */ ! static void build_type2(int y0, int x0) { int y1a, x1a, y2a, x2a; int y1b, x1b, y2b, x2b; ! int light = FALSE; + /* Occasional light */ + if (p_ptr->depth <= randint(25)) light = TRUE; + /* Determine extents of room (a) */ + y1a = y0 - randint(4); + x1a = x0 - randint(11); + y2a = y0 + randint(3); + x2a = x0 + randint(10); ! /* Determine extents of room (b) */ ! y1b = y0 - randint(3); ! x1b = x0 - randint(10); ! y2b = y0 + randint(4); ! x2b = x0 + randint(11); ! /* Generate new room (a) */ ! generate_room(y1a-1, x1a-1, y2a+1, x2a+1, light); ! /* Generate new room (b) */ ! generate_room(y1b-1, x1b-1, y2b+1, x2b+1, light); + /* Generate outer walls (a) */ + generate_draw(y1a-1, x1a-1, y2a+1, x2a+1, FEAT_WALL_OUTER); + /* Generate outer walls (b) */ + generate_draw(y1b-1, x1b-1, y2b+1, x2b+1, FEAT_WALL_OUTER); ! /* Generate inner floors (a) */ ! generate_fill(y1a, x1a, y2a, x2a, FEAT_FLOOR); ! /* Generate inner floors (b) */ ! generate_fill(y1b, x1b, y2b, x2b, FEAT_FLOOR); } *************** *** 1076,1249 **** /* * Type 3 -- Cross shaped rooms * - * Builds a room at a row, column coordinate - * * Room "a" runs north/south, and Room "b" runs east/east ! * So the "central pillar" runs from x1a,y1b to x2a,y2b. * * Note that currently, the "center" is always 3x3, but I think that ! * the code below will work (with "bounds checking") for 5x5, or even ! * for unsymetric values like 4x3 or 5x3 or 3x4 or 3x5, or even larger. */ ! static void build_type3(int yval, int xval) { ! int y, x, dy, dx, wy, wx; int y1a, x1a, y2a, x2a; int y1b, x1b, y2b, x2b; ! bool light; ! /* Choose lite or dark */ ! light = (p_ptr->depth <= randint(25)); ! /* For now, always 3x3 */ ! wx = wy = 1; ! /* Pick max vertical size (at most 4) */ dy = rand_range(3, 4); - - /* Pick max horizontal size (at most 15) */ dx = rand_range(3, 11); ! /* Determine extents of the north/south room */ ! y1a = yval - dy; ! y2a = yval + dy; ! x1a = xval - wx; ! x2a = xval + wx; ! /* Determine extents of the east/west room */ ! y1b = yval - wy; ! y2b = yval + wy; ! x1b = xval - dx; ! x2b = xval + dx; ! /* Place a full floor for room "a" */ ! for (y = y1a - 1; y <= y2a + 1; y++) ! { ! for (x = x1a - 1; x <= x2a + 1; x++) ! { ! cave_feat[y][x] = FEAT_FLOOR; ! cave_info[y][x] |= (CAVE_ROOM); ! if (light) cave_info[y][x] |= (CAVE_GLOW); ! } ! } ! /* Place a full floor for room "b" */ ! for (y = y1b - 1; y <= y2b + 1; y++) ! { ! for (x = x1b - 1; x <= x2b + 1; x++) ! { ! cave_feat[y][x] = FEAT_FLOOR; ! cave_info[y][x] |= (CAVE_ROOM); ! if (light) cave_info[y][x] |= (CAVE_GLOW); ! } ! } ! /* Place the walls around room "a" */ ! for (y = y1a - 1; y <= y2a + 1; y++) ! { ! cave_feat[y][x1a-1] = FEAT_WALL_OUTER; ! cave_feat[y][x2a+1] = FEAT_WALL_OUTER; ! } ! for (x = x1a - 1; x <= x2a + 1; x++) ! { ! cave_feat[y1a-1][x] = FEAT_WALL_OUTER; ! cave_feat[y2a+1][x] = FEAT_WALL_OUTER; ! } ! /* Place the walls around room "b" */ ! for (y = y1b - 1; y <= y2b + 1; y++) ! { ! cave_feat[y][x1b-1] = FEAT_WALL_OUTER; ! cave_feat[y][x2b+1] = FEAT_WALL_OUTER; ! } ! for (x = x1b - 1; x <= x2b + 1; x++) ! { ! cave_feat[y1b-1][x] = FEAT_WALL_OUTER; ! cave_feat[y2b+1][x] = FEAT_WALL_OUTER; ! } - /* Replace the floor for room "a" */ - for (y = y1a; y <= y2a; y++) - { - for (x = x1a; x <= x2a; x++) - { - cave_feat[y][x] = FEAT_FLOOR; - } - } ! /* Replace the floor for room "b" */ ! for (y = y1b; y <= y2b; y++) { ! for (x = x1b; x <= x2b; x++) { ! cave_feat[y][x] = FEAT_FLOOR; } - } - - - /* Special features (3/4) */ - switch (rand_int(4)) - { /* Large solid middle pillar */ ! case 1: { ! for (y = y1b; y <= y2b; y++) ! { ! for (x = x1a; x <= x2a; x++) ! { ! cave_feat[y][x] = FEAT_WALL_INNER; ! } ! } break; } /* Inner treasure vault */ ! case 2: { ! /* Build the vault */ ! for (y = y1b; y <= y2b; y++) ! { ! cave_feat[y][x1a] = FEAT_WALL_INNER; ! cave_feat[y][x2a] = FEAT_WALL_INNER; ! } ! for (x = x1a; x <= x2a; x++) ! { ! cave_feat[y1b][x] = FEAT_WALL_INNER; ! cave_feat[y2b][x] = FEAT_WALL_INNER; ! } ! /* Place a secret door on the inner room */ ! switch (rand_int(4)) ! { ! case 0: place_secret_door(y1b, xval); break; ! case 1: place_secret_door(y2b, xval); break; ! case 2: place_secret_door(yval, x1a); break; ! case 3: place_secret_door(yval, x2a); break; ! } /* Place a treasure in the vault */ ! place_object(yval, xval, FALSE, FALSE); /* Let's guard the treasure well */ ! vault_monsters(yval, xval, rand_int(2) + 3); /* Traps naturally */ ! vault_traps(yval, xval, 4, 4, rand_int(3) + 2); break; } /* Something else */ ! case 3: { /* Occasionally pinch the center shut */ if (rand_int(3) == 0) --- 1140,1250 ---- /* * Type 3 -- Cross shaped rooms * * Room "a" runs north/south, and Room "b" runs east/east ! * So a "central pillar" would run from x1a,y1b to x2a,y2b. * * Note that currently, the "center" is always 3x3, but I think that ! * the code below will work for 5x5 (and perhaps even for unsymetric ! * values like 4x3 or 5x3 or 3x4 or 3x5). */ ! static void build_type3(int y0, int x0) { ! int y, x; ! int y1a, x1a, y2a, x2a; int y1b, x1b, y2b, x2b; ! int dy, dx, wy, wx; + int light = FALSE; ! /* Occasional light */ ! if (p_ptr->depth <= randint(25)) light = TRUE; ! /* Pick inner dimension */ ! wy = 1; ! wx = 1; ! /* Pick outer dimension */ dy = rand_range(3, 4); dx = rand_range(3, 11); ! /* Determine extents of room (a) */ ! y1a = y0 - dy; ! x1a = x0 - wx; ! y2a = y0 + dy; ! x2a = x0 + wx; ! /* Determine extents of room (b) */ ! y1b = y0 - wy; ! x1b = x0 - dx; ! y2b = y0 + wy; ! x2b = x0 + dx; ! /* Generate new room (a) */ ! generate_room(y1a-1, x1a-1, y2a+1, x2a+1, light); ! /* Generate new room (b) */ ! generate_room(y1b-1, x1b-1, y2b+1, x2b+1, light); + /* Generate outer walls (a) */ + generate_draw(y1a-1, x1a-1, y2a+1, x2a+1, FEAT_WALL_OUTER); ! /* Generate outer walls (b) */ ! generate_draw(y1b-1, x1b-1, y2b+1, x2b+1, FEAT_WALL_OUTER); ! /* Generate inner floors (a) */ ! generate_fill(y1a, x1a, y2a, x2a, FEAT_FLOOR); + /* Generate inner floors (b) */ + generate_fill(y1b, x1b, y2b, x2b, FEAT_FLOOR); ! /* Special features */ ! switch (rand_int(4)) { ! /* Nothing */ ! case 1: { ! break; } /* Large solid middle pillar */ ! case 2: { ! /* Generate a small inner solid pillar */ ! generate_fill(y1b, x1a, y2b, x2a, FEAT_WALL_INNER); ! break; } /* Inner treasure vault */ ! case 3: { ! /* Generate a small inner vault */ ! generate_draw(y1b, x1a, y2b, x2a, FEAT_WALL_INNER); ! /* Open the inner vault with a secret door */ ! generate_hole(y1b, x1a, y2b, x2a, FEAT_SECRET); /* Place a treasure in the vault */ ! place_object(y0, x0, FALSE, FALSE); /* Let's guard the treasure well */ ! vault_monsters(y0, x0, rand_int(2) + 3); /* Traps naturally */ ! vault_traps(y0, x0, 4, 4, rand_int(3) + 2); break; } /* Something else */ ! case 4: { /* Occasionally pinch the center shut */ if (rand_int(3) == 0) *************** *** 1251,1293 **** /* Pinch the east/west sides */ for (y = y1b; y <= y2b; y++) { ! if (y == yval) continue; ! cave_feat[y][x1a - 1] = FEAT_WALL_INNER; ! cave_feat[y][x2a + 1] = FEAT_WALL_INNER; } /* Pinch the north/south sides */ for (x = x1a; x <= x2a; x++) { ! if (x == xval) continue; ! cave_feat[y1b - 1][x] = FEAT_WALL_INNER; ! cave_feat[y2b + 1][x] = FEAT_WALL_INNER; } ! /* Sometimes shut using secret doors */ if (rand_int(3) == 0) { ! place_secret_door(yval, x1a - 1); ! place_secret_door(yval, x2a + 1); ! place_secret_door(y1b - 1, xval); ! place_secret_door(y2b + 1, xval); } } /* Occasionally put a "plus" in the center */ else if (rand_int(3) == 0) { ! cave_feat[yval][xval] = FEAT_WALL_INNER; ! cave_feat[y1b][xval] = FEAT_WALL_INNER; ! cave_feat[y2b][xval] = FEAT_WALL_INNER; ! cave_feat[yval][x1a] = FEAT_WALL_INNER; ! cave_feat[yval][x2a] = FEAT_WALL_INNER; } ! /* Occasionally put a pillar in the center */ else if (rand_int(3) == 0) { ! cave_feat[yval][xval] = FEAT_WALL_INNER; } break; --- 1252,1287 ---- /* Pinch the east/west sides */ for (y = y1b; y <= y2b; y++) { ! if (y == y0) continue; ! cave_set_feat(y, x1a - 1, FEAT_WALL_INNER); ! cave_set_feat(y, x2a + 1, FEAT_WALL_INNER); } /* Pinch the north/south sides */ for (x = x1a; x <= x2a; x++) { ! if (x == x0) continue; ! cave_set_feat(y1b - 1, x, FEAT_WALL_INNER); ! cave_set_feat(y2b + 1, x, FEAT_WALL_INNER); } ! /* Open sides with secret doors */ if (rand_int(3) == 0) { ! generate_open(y1b-1, x1a-1, y2b+1, x2a+1, FEAT_SECRET); } } /* Occasionally put a "plus" in the center */ else if (rand_int(3) == 0) { ! generate_plus(y1b, x1a, y2b, x2a, FEAT_WALL_INNER); } ! /* Occasionally put a "pillar" in the center */ else if (rand_int(3) == 0) { ! cave_set_feat(y0, x0, FEAT_WALL_INNER); } break; *************** *** 1297,1353 **** /* ! * Type 4 -- Large room with inner features * * Possible sub-types: ! * 1 - Just an inner room with one door ! * 2 - An inner room within an inner room ! * 3 - An inner room with pillar(s) ! * 4 - Inner room has a maze ! * 5 - A set of four inner rooms */ ! static void build_type4(int yval, int xval) { ! int y, x, y1, x1; ! int y2, x2, tmp; ! ! bool light; ! /* Choose lite or dark */ ! light = (p_ptr->depth <= randint(25)); /* Large room */ ! y1 = yval - 4; ! y2 = yval + 4; ! x1 = xval - 11; ! x2 = xval + 11; ! /* Place a full floor under the room */ ! for (y = y1 - 1; y <= y2 + 1; y++) ! { ! for (x = x1 - 1; x <= x2 + 1; x++) ! { ! cave_feat[y][x] = FEAT_FLOOR; ! cave_info[y][x] |= (CAVE_ROOM); ! if (light) cave_info[y][x] |= (CAVE_GLOW); ! } ! } ! /* Outer Walls */ ! for (y = y1 - 1; y <= y2 + 1; y++) ! { ! cave_feat[y][x1-1] = FEAT_WALL_OUTER; ! cave_feat[y][x2+1] = FEAT_WALL_OUTER; ! } ! for (x = x1 - 1; x <= x2 + 1; x++) ! { ! cave_feat[y1-1][x] = FEAT_WALL_OUTER; ! cave_feat[y2+1][x] = FEAT_WALL_OUTER; ! } /* The inner room */ --- 1291,1331 ---- /* ! * Type 4 -- Large room with an inner room * * Possible sub-types: ! * 1 - An inner room ! * 2 - An inner room with a small inner room ! * 3 - An inner room with a pillar or pillars ! * 4 - An inner room with a checkerboard ! * 5 - An inner room with four compartments */ ! static void build_type4(int y0, int x0) { ! int y, x, y1, x1, y2, x2; + int light = FALSE; ! /* Occasional light */ ! if (p_ptr->depth <= randint(25)) light = TRUE; /* Large room */ ! y1 = y0 - 4; ! y2 = y0 + 4; ! x1 = x0 - 11; ! x2 = x0 + 11; ! /* Generate new room */ ! generate_room(y1-1, x1-1, y2+1, x2+1, light); ! /* Generate outer walls */ ! generate_draw(y1-1, x1-1, y2+1, x2+1, FEAT_WALL_OUTER); ! ! /* Generate inner floors */ ! generate_fill(y1, x1, y2, x2, FEAT_FLOOR); /* The inner room */ *************** *** 1356,1594 **** x1 = x1 + 2; x2 = x2 - 2; ! /* The inner walls */ ! for (y = y1 - 1; y <= y2 + 1; y++) ! { ! cave_feat[y][x1-1] = FEAT_WALL_INNER; ! cave_feat[y][x2+1] = FEAT_WALL_INNER; ! } ! for (x = x1 - 1; x <= x2 + 1; x++) ! { ! cave_feat[y1-1][x] = FEAT_WALL_INNER; ! cave_feat[y2+1][x] = FEAT_WALL_INNER; ! } /* Inner room variations */ switch (randint(5)) { ! /* Just an inner room with a monster */ case 1: - - /* Place a secret door */ - switch (randint(4)) { ! case 1: place_secret_door(y1 - 1, xval); break; ! case 2: place_secret_door(y2 + 1, xval); break; ! case 3: place_secret_door(yval, x1 - 1); break; ! case 4: place_secret_door(yval, x2 + 1); break; ! } ! /* Place a monster in the room */ ! vault_monsters(yval, xval, 1); ! break; ! /* Treasure Vault (with a door) */ case 2: - - /* Place a secret door */ - switch (randint(4)) { ! case 1: place_secret_door(y1 - 1, xval); break; ! case 2: place_secret_door(y2 + 1, xval); break; ! case 3: place_secret_door(yval, x1 - 1); break; ! case 4: place_secret_door(yval, x2 + 1); break; ! } ! /* Place another inner room */ ! for (y = yval - 1; y <= yval + 1; y++) ! { ! for (x = xval - 1; x <= xval + 1; x++) ! { ! if ((x == xval) && (y == yval)) continue; ! cave_feat[y][x] = FEAT_WALL_INNER; ! } ! } ! /* Place a locked door on the inner room */ ! switch (randint(4)) ! { ! case 1: place_locked_door(yval - 1, xval); break; ! case 2: place_locked_door(yval + 1, xval); break; ! case 3: place_locked_door(yval, xval - 1); break; ! case 4: place_locked_door(yval, xval + 1); break; ! } ! /* Monsters to guard the "treasure" */ ! vault_monsters(yval, xval, randint(3) + 2); ! /* Object (80%) */ ! if (rand_int(100) < 80) ! { ! place_object(yval, xval, FALSE, FALSE); ! } ! /* Stairs (20%) */ ! else ! { ! place_random_stairs(yval, xval); ! } ! /* Traps to protect the treasure */ ! vault_traps(yval, xval, 4, 10, 2 + randint(3)); ! break; ! /* Inner pillar(s). */ case 3: - - /* Place a secret door */ - switch (randint(4)) { ! case 1: place_secret_door(y1 - 1, xval); break; ! case 2: place_secret_door(y2 + 1, xval); break; ! case 3: place_secret_door(yval, x1 - 1); break; ! case 4: place_secret_door(yval, x2 + 1); break; ! } ! /* Large Inner Pillar */ ! for (y = yval - 1; y <= yval + 1; y++) ! { ! for (x = xval - 1; x <= xval + 1; x++) ! { ! cave_feat[y][x] = FEAT_WALL_INNER; ! } ! } ! /* Occasionally, two more Large Inner Pillars */ ! if (rand_int(2) == 0) ! { ! tmp = randint(2); ! for (y = yval - 1; y <= yval + 1; y++) { ! for (x = xval - 5 - tmp; x <= xval - 3 - tmp; x++) { ! cave_feat[y][x] = FEAT_WALL_INNER; } ! for (x = xval + 3 + tmp; x <= xval + 5 + tmp; x++) { ! cave_feat[y][x] = FEAT_WALL_INNER; } } - } ! /* Occasionally, some Inner rooms */ ! if (rand_int(3) == 0) ! { ! /* Long horizontal walls */ ! for (x = xval - 5; x <= xval + 5; x++) { ! cave_feat[yval-1][x] = FEAT_WALL_INNER; ! cave_feat[yval+1][x] = FEAT_WALL_INNER; ! } ! ! /* Close off the left/right edges */ ! cave_feat[yval][xval-5] = FEAT_WALL_INNER; ! cave_feat[yval][xval+5] = FEAT_WALL_INNER; ! /* Secret doors (random top/bottom) */ ! place_secret_door(yval - 3 + (randint(2) * 2), xval - 3); ! place_secret_door(yval - 3 + (randint(2) * 2), xval + 3); ! ! /* Monsters */ ! vault_monsters(yval, xval - 2, randint(2)); ! vault_monsters(yval, xval + 2, randint(2)); ! /* Objects */ ! if (rand_int(3) == 0) place_object(yval, xval - 2, FALSE, FALSE); ! if (rand_int(3) == 0) place_object(yval, xval + 2, FALSE, FALSE); } - break; - ! /* Maze inside. */ case 4: - - /* Place a secret door */ - switch (randint(4)) { ! case 1: place_secret_door(y1 - 1, xval); break; ! case 2: place_secret_door(y2 + 1, xval); break; ! case 3: place_secret_door(yval, x1 - 1); break; ! case 4: place_secret_door(yval, x2 + 1); break; ! } ! /* Maze (really a checkerboard) */ ! for (y = y1; y <= y2; y++) ! { ! for (x = x1; x <= x2; x++) { ! if (0x1 & (x + y)) { ! cave_feat[y][x] = FEAT_WALL_INNER; } } - } - - /* Monsters just love mazes. */ - vault_monsters(yval, xval - 5, randint(3)); - vault_monsters(yval, xval + 5, randint(3)); ! /* Traps make them entertaining. */ ! vault_traps(yval, xval - 3, 2, 8, randint(3)); ! vault_traps(yval, xval + 3, 2, 8, randint(3)); ! /* Mazes should have some treasure too. */ ! vault_objects(yval, xval, 3); ! break; /* Four small rooms. */ case 5: - - /* Inner "cross" */ - for (y = y1; y <= y2; y++) - { - cave_feat[y][xval] = FEAT_WALL_INNER; - } - for (x = x1; x <= x2; x++) { ! cave_feat[yval][x] = FEAT_WALL_INNER; ! } ! /* Doors into the rooms */ ! if (rand_int(100) < 50) ! { ! int i = randint(10); ! place_secret_door(y1 - 1, xval - i); ! place_secret_door(y1 - 1, xval + i); ! place_secret_door(y2 + 1, xval - i); ! place_secret_door(y2 + 1, xval + i); ! } ! else ! { ! int i = randint(3); ! place_secret_door(yval + i, x1 - 1); ! place_secret_door(yval - i, x1 - 1); ! place_secret_door(yval + i, x2 + 1); ! place_secret_door(yval - i, x2 + 1); ! } ! /* Treasure, centered at the center of the cross */ ! vault_objects(yval, xval, 2 + randint(2)); ! ! /* Gotta have some monsters. */ ! vault_monsters(yval + 1, xval - 4, randint(4)); ! vault_monsters(yval + 1, xval + 4, randint(4)); ! vault_monsters(yval - 1, xval - 4, randint(4)); ! vault_monsters(yval - 1, xval + 4, randint(4)); ! break; } } --- 1334,1517 ---- x1 = x1 + 2; x2 = x2 - 2; ! /* Generate inner walls */ ! generate_draw(y1-1, x1-1, y2+1, x2+1, FEAT_WALL_INNER); /* Inner room variations */ switch (randint(5)) { ! /* An inner room */ case 1: { ! /* Open the inner room with a secret door */ ! generate_hole(y1-1, x1-1, y2+1, x2+1, FEAT_SECRET); ! /* Place a monster in the room */ ! vault_monsters(y0, x0, 1); ! break; ! } ! /* An inner room with a small inner room */ case 2: { ! /* Open the inner room with a secret door */ ! generate_hole(y1-1, x1-1, y2+1, x2+1, FEAT_SECRET); ! /* Place another inner room */ ! generate_draw(y0-1, x0-1, y0+1, x0+1, FEAT_WALL_INNER); ! /* Open the inner room with a locked door */ ! generate_hole(y0-1, x0-1, y0+1, x0+1, FEAT_DOOR_HEAD + randint(7)); ! /* Monsters to guard the treasure */ ! vault_monsters(y0, x0, randint(3) + 2); ! /* Object (80%) */ ! if (rand_int(100) < 80) ! { ! place_object(y0, x0, FALSE, FALSE); ! } ! /* Stairs (20%) */ ! else ! { ! place_random_stairs(y0, x0); ! } ! /* Traps to protect the treasure */ ! vault_traps(y0, x0, 4, 10, 2 + randint(3)); ! break; ! } ! /* An inner room with an inner pillar or pillars */ case 3: { ! /* Open the inner room with a secret door */ ! generate_hole(y1-1, x1-1, y2+1, x2+1, FEAT_SECRET); ! /* Inner pillar */ ! generate_fill(y0-1, x0-1, y0+1, x0+1, FEAT_WALL_INNER); ! /* Occasionally, two more Large Inner Pillars */ ! if (rand_int(2) == 0) { ! /* Three spaces */ ! if (rand_int(100) < 50) { ! /* Inner pillar */ ! generate_fill(y0-1, x0-7, y0+1, x0-5, FEAT_WALL_INNER); ! ! /* Inner pillar */ ! generate_fill(y0-1, x0+5, y0+1, x0+7, FEAT_WALL_INNER); } ! ! /* Two spaces */ ! else { ! /* Inner pillar */ ! generate_fill(y0-1, x0-6, y0+1, x0-4, FEAT_WALL_INNER); ! ! /* Inner pillar */ ! generate_fill(y0-1, x0+4, y0+1, x0+6, FEAT_WALL_INNER); } } ! /* Occasionally, some Inner rooms */ ! if (rand_int(3) == 0) { ! /* Inner rectangle */ ! generate_draw(y0-1, x0-5, y0+1, x0+5, FEAT_WALL_INNER); ! /* Secret doors (random top/bottom) */ ! place_secret_door(y0 - 3 + (randint(2) * 2), x0 - 3); ! place_secret_door(y0 - 3 + (randint(2) * 2), x0 + 3); ! ! /* Monsters */ ! vault_monsters(y0, x0 - 2, randint(2)); ! vault_monsters(y0, x0 + 2, randint(2)); ! ! /* Objects */ ! if (rand_int(3) == 0) place_object(y0, x0 - 2, FALSE, FALSE); ! if (rand_int(3) == 0) place_object(y0, x0 + 2, FALSE, FALSE); ! } ! break; } ! /* An inner room with a checkerboard */ case 4: { ! /* Open the inner room with a secret door */ ! generate_hole(y1-1, x1-1, y2+1, x2+1, FEAT_SECRET); ! /* Checkerboard */ ! for (y = y1; y <= y2; y++) { ! for (x = x1; x <= x2; x++) { ! if ((x + y) & 0x01) ! { ! cave_set_feat(y, x, FEAT_WALL_INNER); ! } } } ! /* Monsters just love mazes. */ ! vault_monsters(y0, x0 - 5, randint(3)); ! vault_monsters(y0, x0 + 5, randint(3)); ! ! /* Traps make them entertaining. */ ! vault_traps(y0, x0 - 3, 2, 8, randint(3)); ! vault_traps(y0, x0 + 3, 2, 8, randint(3)); ! /* Mazes should have some treasure too. */ ! vault_objects(y0, x0, 3); ! break; ! } /* Four small rooms. */ case 5: { ! /* Inner "cross" */ ! generate_plus(y1, x1, y2, x2, FEAT_WALL_INNER); ! /* Doors into the rooms */ ! if (rand_int(100) < 50) ! { ! int i = randint(10); ! place_secret_door(y1 - 1, x0 - i); ! place_secret_door(y1 - 1, x0 + i); ! place_secret_door(y2 + 1, x0 - i); ! place_secret_door(y2 + 1, x0 + i); ! } ! else ! { ! int i = randint(3); ! place_secret_door(y0 + i, x1 - 1); ! place_secret_door(y0 - i, x1 - 1); ! place_secret_door(y0 + i, x2 + 1); ! place_secret_door(y0 - i, x2 + 1); ! } ! /* Treasure, centered at the center of the cross */ ! vault_objects(y0, x0, 2 + randint(2)); ! ! /* Gotta have some monsters */ ! vault_monsters(y0 + 1, x0 - 4, randint(4)); ! vault_monsters(y0 + 1, x0 + 4, randint(4)); ! vault_monsters(y0 - 1, x0 - 4, randint(4)); ! vault_monsters(y0 - 1, x0 + 4, randint(4)); ! break; ! } } } *************** *** 1604,1612 **** * Some of the pits/nests are asked to avoid monsters which can blink * away or which are invisible. This is probably a hack. * ! * The old method made direct use of monster "names", which is bad. ! * ! * Note the use of Angband 2.7.9 monster race pictures in various places. */ --- 1527,1534 ---- * Some of the pits/nests are asked to avoid monsters which can blink * away or which are invisible. This is probably a hack. * ! * The old method used monster "names", which was bad, but the new ! * method uses monster race characters, which is also bad. XXX XXX XXX */ *************** *** 1788,1794 **** * * Note that "monster nests" will never contain "unique" monsters. */ ! static void build_type5(int yval, int xval) { int y, x, y1, x1, y2, x2; --- 1710,1716 ---- * * Note that "monster nests" will never contain "unique" monsters. */ ! static void build_type5(int y0, int x0) { int y, x, y1, x1, y2, x2; *************** *** 1800,1834 **** bool empty = FALSE; /* Large room */ ! y1 = yval - 4; ! y2 = yval + 4; ! x1 = xval - 11; ! x2 = xval + 11; ! /* Place the floor area */ ! for (y = y1 - 1; y <= y2 + 1; y++) ! { ! for (x = x1 - 1; x <= x2 + 1; x++) ! { ! cave_feat[y][x] = FEAT_FLOOR; ! cave_info[y][x] |= (CAVE_ROOM); ! } ! } ! /* Place the outer walls */ ! for (y = y1 - 1; y <= y2 + 1; y++) ! { ! cave_feat[y][x1-1] = FEAT_WALL_OUTER; ! cave_feat[y][x2+1] = FEAT_WALL_OUTER; ! } ! for (x = x1 - 1; x <= x2 + 1; x++) ! { ! cave_feat[y1-1][x] = FEAT_WALL_OUTER; ! cave_feat[y2+1][x] = FEAT_WALL_OUTER; ! } /* Advance to the center room */ --- 1722,1745 ---- bool empty = FALSE; + int light = FALSE; + /* Large room */ ! y1 = y0 - 4; ! y2 = y0 + 4; ! x1 = x0 - 11; ! x2 = x0 + 11; ! /* Generate new room */ ! generate_room(y1-1, x1-1, y2+1, x2+1, light); ! /* Generate outer walls */ ! generate_draw(y1-1, x1-1, y2+1, x2+1, FEAT_WALL_OUTER); ! ! /* Generate inner floors */ ! generate_fill(y1, x1, y2, x2, FEAT_FLOOR); /* Advance to the center room */ *************** *** 1837,1863 **** x1 = x1 + 2; x2 = x2 - 2; ! /* The inner walls */ ! for (y = y1 - 1; y <= y2 + 1; y++) ! { ! cave_feat[y][x1-1] = FEAT_WALL_INNER; ! cave_feat[y][x2+1] = FEAT_WALL_INNER; ! } ! for (x = x1 - 1; x <= x2 + 1; x++) ! { ! cave_feat[y1-1][x] = FEAT_WALL_INNER; ! cave_feat[y2+1][x] = FEAT_WALL_INNER; ! } ! ! /* Place a secret door */ ! switch (randint(4)) ! { ! case 1: place_secret_door(y1 - 1, xval); break; ! case 2: place_secret_door(y2 + 1, xval); break; ! case 3: place_secret_door(yval, x1 - 1); break; ! case 4: place_secret_door(yval, x2 + 1); break; ! } /* Hack -- Choose a nest type */ --- 1748,1758 ---- x1 = x1 + 2; x2 = x2 - 2; ! /* Generate inner walls */ ! generate_draw(y1-1, x1-1, y2+1, x2+1, FEAT_WALL_INNER); ! /* Open the inner room with a secret door */ ! generate_hole(y1-1, x1-1, y2+1, x2+1, FEAT_SECRET); /* Hack -- Choose a nest type */ *************** *** 1931,1946 **** rating += 10; /* (Sometimes) Cause a "special feeling" (for "Monster Nests") */ ! if ((p_ptr->depth <= 40) && (randint(p_ptr->depth*p_ptr->depth + 1) < 300)) { good_item_flag = TRUE; } /* Place some monsters */ ! for (y = yval - 2; y <= yval + 2; y++) { ! for (x = xval - 9; x <= xval + 9; x++) { int r_idx = what[rand_int(64)]; --- 1826,1842 ---- rating += 10; /* (Sometimes) Cause a "special feeling" (for "Monster Nests") */ ! if ((p_ptr->depth <= 40) && ! (randint(p_ptr->depth * p_ptr->depth + 1) < 300)) { good_item_flag = TRUE; } /* Place some monsters */ ! for (y = y0 - 2; y <= y0 + 2; y++) { ! for (x = x0 - 9; x <= x0 + 9; x++) { int r_idx = what[rand_int(64)]; *************** *** 1995,2001 **** * * Note that "monster pits" will never contain "unique" monsters. */ ! static void build_type6(int yval, int xval) { int tmp, what[16]; --- 1891,1897 ---- * * Note that "monster pits" will never contain "unique" monsters. */ ! static void build_type6(int y0, int x0) { int tmp, what[16]; *************** *** 2003,2039 **** bool empty = FALSE; cptr name; /* Large room */ ! y1 = yval - 4; ! y2 = yval + 4; ! x1 = xval - 11; ! x2 = xval + 11; ! /* Place the floor area */ ! for (y = y1 - 1; y <= y2 + 1; y++) ! { ! for (x = x1 - 1; x <= x2 + 1; x++) ! { ! cave_feat[y][x] = FEAT_FLOOR; ! cave_info[y][x] |= (CAVE_ROOM); ! } ! } ! /* Place the outer walls */ ! for (y = y1 - 1; y <= y2 + 1; y++) ! { ! cave_feat[y][x1-1] = FEAT_WALL_OUTER; ! cave_feat[y][x2+1] = FEAT_WALL_OUTER; ! } ! for (x = x1 - 1; x <= x2 + 1; x++) ! { ! cave_feat[y1-1][x] = FEAT_WALL_OUTER; ! cave_feat[y2+1][x] = FEAT_WALL_OUTER; ! } /* Advance to the center room */ --- 1899,1924 ---- bool empty = FALSE; + int light = FALSE; + cptr name; /* Large room */ ! y1 = y0 - 4; ! y2 = y0 + 4; ! x1 = x0 - 11; ! x2 = x0 + 11; ! /* Generate new room */ ! generate_room(y1-1, x1-1, y2+1, x2+1, light); ! /* Generate outer walls */ ! generate_draw(y1-1, x1-1, y2+1, x2+1, FEAT_WALL_OUTER); ! ! /* Generate inner floors */ ! generate_fill(y1, x1, y2, x2, FEAT_FLOOR); /* Advance to the center room */ *************** *** 2042,2068 **** x1 = x1 + 2; x2 = x2 - 2; ! /* The inner walls */ ! for (y = y1 - 1; y <= y2 + 1; y++) ! { ! cave_feat[y][x1-1] = FEAT_WALL_INNER; ! cave_feat[y][x2+1] = FEAT_WALL_INNER; ! } ! for (x = x1 - 1; x <= x2 + 1; x++) ! { ! cave_feat[y1-1][x] = FEAT_WALL_INNER; ! cave_feat[y2+1][x] = FEAT_WALL_INNER; ! } ! ! /* Place a secret door */ ! switch (randint(4)) ! { ! case 1: place_secret_door(y1 - 1, xval); break; ! case 2: place_secret_door(y2 + 1, xval); break; ! case 3: place_secret_door(yval, x1 - 1); break; ! case 4: place_secret_door(yval, x2 + 1); break; ! } /* Choose a pit type */ --- 1927,1937 ---- x1 = x1 + 2; x2 = x2 - 2; ! /* Generate inner walls */ ! generate_draw(y1-1, x1-1, y2+1, x2+1, FEAT_WALL_INNER); ! /* Open the inner room with a secret door */ ! generate_hole(y1-1, x1-1, y2+1, x2+1, FEAT_SECRET); /* Choose a pit type */ *************** *** 2226,2233 **** if (empty) return; ! /* XXX XXX XXX */ ! /* Sort the entries */ for (i = 0; i < 16 - 1; i++) { /* Sort the entries */ --- 2095,2101 ---- if (empty) return; ! /* Sort the entries XXX XXX XXX */ for (i = 0; i < 16 - 1; i++) { /* Sort the entries */ *************** *** 2262,2274 **** { /* Room type */ msg_format("Monster pit (%s)", name); - - /* Contents */ - for (i = 0; i < 8; i++) - { - /* Message */ - msg_print(r_name + r_info[what[i]].name); - } } --- 2130,2135 ---- *************** *** 2276,2335 **** rating += 10; /* (Sometimes) Cause a "special feeling" (for "Monster Pits") */ ! if ((p_ptr->depth <= 40) && (randint(p_ptr->depth*p_ptr->depth + 1) < 300)) { good_item_flag = TRUE; } /* Top and bottom rows */ ! for (x = xval - 9; x <= xval + 9; x++) { ! place_monster_aux(yval - 2, x, what[0], FALSE, FALSE); ! place_monster_aux(yval + 2, x, what[0], FALSE, FALSE); } /* Middle columns */ ! for (y = yval - 1; y <= yval + 1; y++) { ! place_monster_aux(y, xval - 9, what[0], FALSE, FALSE); ! place_monster_aux(y, xval + 9, what[0], FALSE, FALSE); ! place_monster_aux(y, xval - 8, what[1], FALSE, FALSE); ! place_monster_aux(y, xval + 8, what[1], FALSE, FALSE); ! place_monster_aux(y, xval - 7, what[1], FALSE, FALSE); ! place_monster_aux(y, xval + 7, what[1], FALSE, FALSE); ! place_monster_aux(y, xval - 6, what[2], FALSE, FALSE); ! place_monster_aux(y, xval + 6, what[2], FALSE, FALSE); ! place_monster_aux(y, xval - 5, what[2], FALSE, FALSE); ! place_monster_aux(y, xval + 5, what[2], FALSE, FALSE); ! place_monster_aux(y, xval - 4, what[3], FALSE, FALSE); ! place_monster_aux(y, xval + 4, what[3], FALSE, FALSE); ! place_monster_aux(y, xval - 3, what[3], FALSE, FALSE); ! place_monster_aux(y, xval + 3, what[3], FALSE, FALSE); ! place_monster_aux(y, xval - 2, what[4], FALSE, FALSE); ! place_monster_aux(y, xval + 2, what[4], FALSE, FALSE); } /* Above/Below the center monster */ ! for (x = xval - 1; x <= xval + 1; x++) { ! place_monster_aux(yval + 1, x, what[5], FALSE, FALSE); ! place_monster_aux(yval - 1, x, what[5], FALSE, FALSE); } /* Next to the center monster */ ! place_monster_aux(yval, xval + 1, what[6], FALSE, FALSE); ! place_monster_aux(yval, xval - 1, what[6], FALSE, FALSE); /* Center monster */ ! place_monster_aux(yval, xval, what[7], FALSE, FALSE); } --- 2137,2197 ---- rating += 10; /* (Sometimes) Cause a "special feeling" (for "Monster Pits") */ ! if ((p_ptr->depth <= 40) && ! (randint(p_ptr->depth * p_ptr->depth + 1) < 300)) { good_item_flag = TRUE; } /* Top and bottom rows */ ! for (x = x0 - 9; x <= x0 + 9; x++) { ! place_monster_aux(y0 - 2, x, what[0], FALSE, FALSE); ! place_monster_aux(y0 + 2, x, what[0], FALSE, FALSE); } /* Middle columns */ ! for (y = y0 - 1; y <= y0 + 1; y++) { ! place_monster_aux(y, x0 - 9, what[0], FALSE, FALSE); ! place_monster_aux(y, x0 + 9, what[0], FALSE, FALSE); ! place_monster_aux(y, x0 - 8, what[1], FALSE, FALSE); ! place_monster_aux(y, x0 + 8, what[1], FALSE, FALSE); ! place_monster_aux(y, x0 - 7, what[1], FALSE, FALSE); ! place_monster_aux(y, x0 + 7, what[1], FALSE, FALSE); ! place_monster_aux(y, x0 - 6, what[2], FALSE, FALSE); ! place_monster_aux(y, x0 + 6, what[2], FALSE, FALSE); ! place_monster_aux(y, x0 - 5, what[2], FALSE, FALSE); ! place_monster_aux(y, x0 + 5, what[2], FALSE, FALSE); ! place_monster_aux(y, x0 - 4, what[3], FALSE, FALSE); ! place_monster_aux(y, x0 + 4, what[3], FALSE, FALSE); ! place_monster_aux(y, x0 - 3, what[3], FALSE, FALSE); ! place_monster_aux(y, x0 + 3, what[3], FALSE, FALSE); ! place_monster_aux(y, x0 - 2, what[4], FALSE, FALSE); ! place_monster_aux(y, x0 + 2, what[4], FALSE, FALSE); } /* Above/Below the center monster */ ! for (x = x0 - 1; x <= x0 + 1; x++) { ! place_monster_aux(y0 + 1, x, what[5], FALSE, FALSE); ! place_monster_aux(y0 - 1, x, what[5], FALSE, FALSE); } /* Next to the center monster */ ! place_monster_aux(y0, x0 + 1, what[6], FALSE, FALSE); ! place_monster_aux(y0, x0 - 1, what[6], FALSE, FALSE); /* Center monster */ ! place_monster_aux(y0, x0, what[7], FALSE, FALSE); } *************** *** 2337,2343 **** /* * Hack -- fill in "vault" rooms */ ! static void build_vault(int yval, int xval, int ymax, int xmax, cptr data) { int dx, dy, x, y; --- 2199,2205 ---- /* * Hack -- fill in "vault" rooms */ ! static void build_vault(int y0, int x0, int ymax, int xmax, cptr data) { int dx, dy, x, y; *************** *** 2350,2363 **** for (dx = 0; dx < xmax; dx++, t++) { /* Extract the location */ ! x = xval - (xmax / 2) + dx; ! y = yval - (ymax / 2) + dy; /* Hack -- skip "non-grids" */ if (*t == ' ') continue; /* Lay down a floor */ ! cave_feat[y][x] = FEAT_FLOOR; /* Part of a vault */ cave_info[y][x] |= (CAVE_ROOM | CAVE_ICKY); --- 2212,2225 ---- for (dx = 0; dx < xmax; dx++, t++) { /* Extract the location */ ! x = x0 - (xmax / 2) + dx; ! y = y0 - (ymax / 2) + dy; /* Hack -- skip "non-grids" */ if (*t == ' ') continue; /* Lay down a floor */ ! cave_set_feat(y, x, FEAT_FLOOR); /* Part of a vault */ cave_info[y][x] |= (CAVE_ROOM | CAVE_ICKY); *************** *** 2367,2406 **** { /* Granite wall (outer) */ case '%': ! cave_feat[y][x] = FEAT_WALL_OUTER; ! break; /* Granite wall (inner) */ case '#': ! cave_feat[y][x] = FEAT_WALL_INNER; ! break; /* Permanent wall (inner) */ case 'X': ! cave_feat[y][x] = FEAT_PERM_INNER; ! break; /* Treasure/trap */ case '*': - if (rand_int(100) < 75) - { - place_object(y, x, FALSE, FALSE); - } - else { ! place_trap(y, x); } - break; /* Secret doors */ case '+': ! place_secret_door(y, x); ! break; /* Trap */ case '^': ! place_trap(y, x); ! break; } } } --- 2229,2280 ---- { /* Granite wall (outer) */ case '%': ! { ! cave_set_feat(y, x, FEAT_WALL_OUTER); ! break; ! } /* Granite wall (inner) */ case '#': ! { ! cave_set_feat(y, x, FEAT_WALL_INNER); ! break; ! } /* Permanent wall (inner) */ case 'X': ! { ! cave_set_feat(y, x, FEAT_PERM_INNER); ! break; ! } /* Treasure/trap */ case '*': { ! if (rand_int(100) < 75) ! { ! place_object(y, x, FALSE, FALSE); ! } ! else ! { ! place_trap(y, x); ! } ! break; } /* Secret doors */ case '+': ! { ! place_secret_door(y, x); ! break; ! } /* Trap */ case '^': ! { ! place_trap(y, x); ! break; ! } } } } *************** *** 2412,2419 **** for (dx = 0; dx < xmax; dx++, t++) { /* Extract the grid */ ! x = xval - (xmax/2) + dx; ! y = yval - (ymax/2) + dy; /* Hack -- skip "non-grids" */ if (*t == ' ') continue; --- 2286,2293 ---- for (dx = 0; dx < xmax; dx++, t++) { /* Extract the grid */ ! x = x0 - (xmax/2) + dx; ! y = y0 - (ymax/2) + dy; /* Hack -- skip "non-grids" */ if (*t == ' ') continue; *************** *** 2490,2496 **** /* * Type 7 -- simple vaults (see "v_info.txt") */ ! static void build_type7(int yval, int xval) { vault_type *v_ptr; --- 2364,2370 ---- /* * Type 7 -- simple vaults (see "v_info.txt") */ ! static void build_type7(int y0, int x0) { vault_type *v_ptr; *************** *** 2518,2524 **** } /* Hack -- Build the vault */ ! build_vault(yval, xval, v_ptr->hgt, v_ptr->wid, v_text + v_ptr->text); } --- 2392,2398 ---- } /* Hack -- Build the vault */ ! build_vault(y0, x0, v_ptr->hgt, v_ptr->wid, v_text + v_ptr->text); } *************** *** 2526,2532 **** /* * Type 8 -- greater vaults (see "v_info.txt") */ ! static void build_type8(int yval, int xval) { vault_type *v_ptr; --- 2400,2406 ---- /* * Type 8 -- greater vaults (see "v_info.txt") */ ! static void build_type8(int y0, int x0) { vault_type *v_ptr; *************** *** 2554,2560 **** } /* Hack -- Build the vault */ ! build_vault(yval, xval, v_ptr->hgt, v_ptr->wid, v_text + v_ptr->text); } --- 2428,2434 ---- } /* Hack -- Build the vault */ ! build_vault(y0, x0, v_ptr->hgt, v_ptr->wid, v_text + v_ptr->text); } *************** *** 2703,2709 **** if (cave_feat[y][x] == FEAT_WALL_OUTER) { /* Change the wall to a "solid" wall */ ! cave_feat[y][x] = FEAT_WALL_SOLID; } } } --- 2577,2583 ---- if (cave_feat[y][x] == FEAT_WALL_OUTER) { /* Change the wall to a "solid" wall */ ! cave_set_feat(y, x, FEAT_WALL_SOLID); } } } *************** *** 2784,2790 **** x = dun->tunn[i].x; /* Clear previous contents, add a floor */ ! cave_feat[y][x] = FEAT_FLOOR; } --- 2658,2664 ---- x = dun->tunn[i].x; /* Clear previous contents, add a floor */ ! cave_set_feat(y, x, FEAT_FLOOR); } *************** *** 2796,2802 **** x = dun->wall[i].x; /* Convert to floor grid */ ! cave_feat[y][x] = FEAT_FLOOR; /* Occasional doorway */ if (rand_int(100) < DUN_TUN_PEN) --- 2670,2676 ---- x = dun->wall[i].x; /* Convert to floor grid */ ! cave_set_feat(y, x, FEAT_FLOOR); /* Occasional doorway */ if (rand_int(100) < DUN_TUN_PEN) *************** *** 2911,2919 **** * Note that we restrict the number of "crowded" rooms to reduce * the chance of overflowing the monster list during level creation. */ ! static bool room_build(int y0, int x0, int typ) { ! int y, x, y1, x1, y2, x2; /* Restrict level */ --- 2785,2795 ---- * Note that we restrict the number of "crowded" rooms to reduce * the chance of overflowing the monster list during level creation. */ ! static bool room_build(int by0, int bx0, int typ) { ! int y, x; ! int by, bx; ! int by1, bx1, by2, bx2; /* Restrict level */ *************** *** 2923,2952 **** if (dun->crowded && ((typ == 5) || (typ == 6))) return (FALSE); /* Extract blocks */ ! y1 = y0 + room[typ].dy1; ! y2 = y0 + room[typ].dy2; ! x1 = x0 + room[typ].dx1; ! x2 = x0 + room[typ].dx2; /* Never run off the screen */ ! if ((y1 < 0) || (y2 >= dun->row_rooms)) return (FALSE); ! if ((x1 < 0) || (x2 >= dun->col_rooms)) return (FALSE); /* Verify open space */ ! for (y = y1; y <= y2; y++) { ! for (x = x1; x <= x2; x++) { ! if (dun->room_map[y][x]) return (FALSE); } } ! /* XXX XXX XXX It is *extremely* important that the following */ ! /* calculation is *exactly* correct to prevent memory errors */ /* Acquire the location of the room */ ! y = ((y1 + y2 + 1) * BLOCK_HGT) / 2; ! x = ((x1 + x2 + 1) * BLOCK_WID) / 2; /* Build a room */ switch (typ) --- 2799,2828 ---- if (dun->crowded && ((typ == 5) || (typ == 6))) return (FALSE); /* Extract blocks */ ! by1 = by0 + room[typ].dy1; ! bx1 = bx0 + room[typ].dx1; ! by2 = by0 + room[typ].dy2; ! bx2 = bx0 + room[typ].dx2; /* Never run off the screen */ ! if ((by1 < 0) || (by2 >= dun->row_rooms)) return (FALSE); ! if ((bx1 < 0) || (bx2 >= dun->col_rooms)) return (FALSE); /* Verify open space */ ! for (by = by1; by <= by2; by++) { ! for (bx = bx1; bx <= bx2; bx++) { ! if (dun->room_map[by][bx]) return (FALSE); } } ! /* It is *extremely* important that the following calculation */ ! /* be *exactly* correct to prevent memory errors XXX XXX XXX */ /* Acquire the location of the room */ ! y = ((by1 + by2 + 1) * BLOCK_HGT) / 2; ! x = ((bx1 + bx2 + 1) * BLOCK_WID) / 2; /* Build a room */ switch (typ) *************** *** 2974,2984 **** } /* Reserve some blocks */ ! for (y = y1; y <= y2; y++) { ! for (x = x1; x <= x2; x++) { ! dun->room_map[y][x] = TRUE; } } --- 2850,2860 ---- } /* Reserve some blocks */ ! for (by = by1; by <= by2; by++) { ! for (bx = bx1; bx <= bx2; bx++) { ! dun->room_map[by][bx] = TRUE; } } *************** *** 2999,3004 **** --- 2875,2882 ---- { int i, k, y, x, y1, x1; + int by, bx; + bool destroyed = FALSE; dun_data dun_body; *************** *** 3014,3020 **** for (x = 0; x < DUNGEON_WID; x++) { /* Create granite wall */ ! cave_feat[y][x] = FEAT_WALL_EXTRA; } } --- 2892,2898 ---- for (x = 0; x < DUNGEON_WID; x++) { /* Create granite wall */ ! cave_set_feat(y, x, FEAT_WALL_EXTRA); } } *************** *** 3031,3041 **** dun->col_rooms = DUNGEON_WID / BLOCK_WID; /* Initialize the room table */ ! for (y = 0; y < dun->row_rooms; y++) { ! for (x = 0; x < dun->col_rooms; x++) { ! dun->room_map[y][x] = FALSE; } } --- 2909,2919 ---- dun->col_rooms = DUNGEON_WID / BLOCK_WID; /* Initialize the room table */ ! for (by = 0; by < dun->row_rooms; by++) { ! for (bx = 0; bx < dun->col_rooms; bx++) { ! dun->room_map[by][bx] = FALSE; } } *************** *** 3051,3074 **** for (i = 0; i < DUN_ROOMS; i++) { /* Pick a block for the room */ ! y = rand_int(dun->row_rooms); ! x = rand_int(dun->col_rooms); /* Align dungeon rooms */ if (dungeon_align) { /* Slide some rooms right */ ! if ((x % 3) == 0) x++; /* Slide some rooms left */ ! if ((x % 3) == 2) x--; } /* Destroyed levels are boring */ if (destroyed) { /* Attempt a "trivial" room */ ! if (room_build(y, x, 1)) continue; /* Never mind */ continue; --- 2929,2952 ---- for (i = 0; i < DUN_ROOMS; i++) { /* Pick a block for the room */ ! by = rand_int(dun->row_rooms); ! bx = rand_int(dun->col_rooms); /* Align dungeon rooms */ if (dungeon_align) { /* Slide some rooms right */ ! if ((bx % 3) == 0) bx++; /* Slide some rooms left */ ! if ((bx % 3) == 2) bx--; } /* Destroyed levels are boring */ if (destroyed) { /* Attempt a "trivial" room */ ! if (room_build(by, bx, 1)) continue; /* Never mind */ continue; *************** *** 3084,3113 **** if (rand_int(DUN_UNUSUAL) < p_ptr->depth) { /* Type 8 -- Greater vault (10%) */ ! if ((k < 10) && room_build(y, x, 8)) continue; /* Type 7 -- Lesser vault (15%) */ ! if ((k < 25) && room_build(y, x, 7)) continue; /* Type 6 -- Monster pit (15%) */ ! if ((k < 40) && room_build(y, x, 6)) continue; /* Type 5 -- Monster nest (10%) */ ! if ((k < 50) && room_build(y, x, 5)) continue; } /* Type 4 -- Large room (25%) */ ! if ((k < 25) && room_build(y, x, 4)) continue; /* Type 3 -- Cross room (25%) */ ! if ((k < 50) && room_build(y, x, 3)) continue; /* Type 2 -- Overlapping (50%) */ ! if ((k < 100) && room_build(y, x, 2)) continue; } /* Attempt a trivial room */ ! if (room_build(y, x, 1)) continue; } --- 2962,2991 ---- if (rand_int(DUN_UNUSUAL) < p_ptr->depth) { /* Type 8 -- Greater vault (10%) */ ! if ((k < 10) && room_build(by, bx, 8)) continue; /* Type 7 -- Lesser vault (15%) */ ! if ((k < 25) && room_build(by, bx, 7)) continue; /* Type 6 -- Monster pit (15%) */ ! if ((k < 40) && room_build(by, bx, 6)) continue; /* Type 5 -- Monster nest (10%) */ ! if ((k < 50) && room_build(by, bx, 5)) continue; } /* Type 4 -- Large room (25%) */ ! if ((k < 25) && room_build(by, bx, 4)) continue; /* Type 3 -- Cross room (25%) */ ! if ((k < 50) && room_build(by, bx, 3)) continue; /* Type 2 -- Overlapping (50%) */ ! if ((k < 100) && room_build(by, bx, 2)) continue; } /* Attempt a trivial room */ ! if (room_build(by, bx, 1)) continue; } *************** *** 3117,3123 **** y = 0; /* Clear previous contents, add "solid" perma-wall */ ! cave_feat[y][x] = FEAT_PERM_SOLID; } /* Special boundary walls -- Bottom */ --- 2995,3001 ---- y = 0; /* Clear previous contents, add "solid" perma-wall */ ! cave_set_feat(y, x, FEAT_PERM_SOLID); } /* Special boundary walls -- Bottom */ *************** *** 3126,3132 **** y = DUNGEON_HGT-1; /* Clear previous contents, add "solid" perma-wall */ ! cave_feat[y][x] = FEAT_PERM_SOLID; } /* Special boundary walls -- Left */ --- 3004,3010 ---- y = DUNGEON_HGT-1; /* Clear previous contents, add "solid" perma-wall */ ! cave_set_feat(y, x, FEAT_PERM_SOLID); } /* Special boundary walls -- Left */ *************** *** 3135,3141 **** x = 0; /* Clear previous contents, add "solid" perma-wall */ ! cave_feat[y][x] = FEAT_PERM_SOLID; } /* Special boundary walls -- Right */ --- 3013,3019 ---- x = 0; /* Clear previous contents, add "solid" perma-wall */ ! cave_set_feat(y, x, FEAT_PERM_SOLID); } /* Special boundary walls -- Right */ *************** *** 3144,3150 **** x = DUNGEON_WID-1; /* Clear previous contents, add "solid" perma-wall */ ! cave_feat[y][x] = FEAT_PERM_SOLID; } --- 3022,3028 ---- x = DUNGEON_WID-1; /* Clear previous contents, add "solid" perma-wall */ ! cave_set_feat(y, x, FEAT_PERM_SOLID); } *************** *** 3245,3263 **** alloc_object(ALLOC_SET_CORR, ALLOC_TYP_RUBBLE, randint(k)); /* Put some objects in rooms */ ! alloc_object(ALLOC_SET_ROOM, ALLOC_TYP_OBJECT, randnor(DUN_AMT_ROOM, 3)); /* Put some objects/gold in the dungeon */ ! alloc_object(ALLOC_SET_BOTH, ALLOC_TYP_OBJECT, randnor(DUN_AMT_ITEM, 3)); ! alloc_object(ALLOC_SET_BOTH, ALLOC_TYP_GOLD, randnor(DUN_AMT_GOLD, 3)); } /* ! * Builds a store at a given (row, column) * ! * Note that the solid perma-walls are at x=0/65 and y=0/21 * * As of 2.7.4 (?) the stores are placed in a more "user friendly" * configuration, such that the four "center" buildings always --- 3123,3144 ---- alloc_object(ALLOC_SET_CORR, ALLOC_TYP_RUBBLE, randint(k)); /* Put some objects in rooms */ ! alloc_object(ALLOC_SET_ROOM, ALLOC_TYP_OBJECT, Rand_normal(DUN_AMT_ROOM, 3)); /* Put some objects/gold in the dungeon */ ! alloc_object(ALLOC_SET_BOTH, ALLOC_TYP_OBJECT, Rand_normal(DUN_AMT_ITEM, 3)); ! alloc_object(ALLOC_SET_BOTH, ALLOC_TYP_GOLD, Rand_normal(DUN_AMT_GOLD, 3)); } /* ! * Builds a store at a given pseudo-location * ! * As of 2.8.1 (?) the town is actually centered in the middle of a ! * complete level, and thus the top left corner of the town itself ! * is no longer at (0,0), but rather, at (qy,qx), so the constants ! * in the comments below should be mentally modified accordingly. * * As of 2.7.4 (?) the stores are placed in a more "user friendly" * configuration, such that the four "center" buildings always *************** *** 3267,3272 **** --- 3148,3156 ---- * The stores now lie inside boxes from 3-9 and 12-18 vertically, * and from 7-17, 21-31, 35-45, 49-59. Note that there are thus * always at least 2 open grids between any disconnected walls. + * + * Note the use of "town_illuminate()" to handle all "illumination" + * and "memorization" issues. */ static void build_store(int n, int yy, int xx) { *************** *** 3291,3301 **** { for (x = x1; x <= x2; x++) { ! /* Clear previous contents, add "basic" perma-wall */ ! cave_feat[y][x] = FEAT_PERM_EXTRA; ! ! /* Hack -- The buildings are illuminated and known */ ! cave_info[y][x] |= (CAVE_GLOW | CAVE_MARK); } } --- 3175,3182 ---- { for (x = x1; x <= x2; x++) { ! /* Create the building */ ! cave_set_feat(y, x, FEAT_PERM_EXTRA); } } *************** *** 3349,3355 **** } /* Clear previous contents, add a store door */ ! cave_feat[y][x] = FEAT_SHOP_HEAD + n; } --- 3230,3236 ---- } /* Clear previous contents, add a store door */ ! cave_set_feat(y, x, FEAT_SHOP_HEAD + n); } *************** *** 3389,3395 **** for (x = 0; x < 4; x++) { /* Pick a random unplaced store */ ! k = rand_int(n); /* Build that store at the proper location */ build_store(rooms[k], y, x); --- 3270,3276 ---- for (x = 0; x < 4; x++) { /* Pick a random unplaced store */ ! k = ((n <= 1) ? 0 : rand_int(n)); /* Build that store at the proper location */ build_store(rooms[k], y, x); *************** *** 3412,3421 **** } /* Clear previous contents, add down stairs */ ! cave_feat[y][x] = FEAT_MORE; ! ! /* Memorize the stairs */ ! cave_info[y][x] |= (CAVE_MARK); /* Place the player */ --- 3293,3299 ---- } /* Clear previous contents, add down stairs */ ! cave_set_feat(y, x, FEAT_MORE); /* Place the player */ *************** *** 3483,3492 **** for (x = 0; x < DUNGEON_WID; x++) { /* Create "solid" perma-wall */ ! cave_feat[y][x] = FEAT_PERM_SOLID; ! ! /* Illuminate and memorize the walls */ ! cave_info[y][x] |= (CAVE_GLOW | CAVE_MARK); } } --- 3361,3367 ---- for (x = 0; x < DUNGEON_WID; x++) { /* Create "solid" perma-wall */ ! cave_set_feat(y, x, FEAT_PERM_SOLID); } } *************** *** 3496,3522 **** for (x = qx+1; x < qx+SCREEN_WID-1; x++) { /* Create empty floor */ ! cave_feat[y][x] = FEAT_FLOOR; ! ! /* Darken and forget the floors */ ! cave_info[y][x] &= ~(CAVE_GLOW | CAVE_MARK); ! ! /* Day time */ ! if (daytime) ! { ! /* Perma-Lite */ ! cave_info[y][x] |= (CAVE_GLOW); ! ! /* Memorize */ ! if (view_perma_grids) cave_info[y][x] |= (CAVE_MARK); ! } } } ! ! /* Build the buildings/stairs (from memory) */ town_gen_hack(); /* Make some residents */ for (i = 0; i < residents; i++) --- 3371,3385 ---- for (x = qx+1; x < qx+SCREEN_WID-1; x++) { /* Create empty floor */ ! cave_set_feat(y, x, FEAT_FLOOR); } } ! /* Build stuff */ town_gen_hack(); + /* Apply illumination */ + town_illuminate(daytime); /* Make some residents */ for (i = 0; i < residents; i++) *************** *** 3533,3538 **** --- 3396,3403 ---- * Hack -- regenerate any "overflow" levels * * Hack -- allow auto-scumming via a gameplay option. + * + * Note that this function resets "cave_feat" and "cave_info" directly. */ void generate_cave(void) { *************** *** 3551,3557 **** cptr why = NULL; ! /* XXX XXX XXX XXX */ o_max = 1; m_max = 1; --- 3416,3422 ---- cptr why = NULL; ! /* Reset */ o_max = 1; m_max = 1; diff -c -r angband-282/src/h-basic.h angband-283/src/h-basic.h *** angband-282/src/h-basic.h Wed Sep 3 11:57:33 1997 --- angband-283/src/h-basic.h Fri Feb 6 04:10:31 1998 *************** *** 23,25 **** --- 23,26 ---- #endif + diff -c -r angband-282/src/h-config.h angband-283/src/h-config.h *** angband-282/src/h-config.h Wed Sep 10 18:57:05 1997 --- angband-283/src/h-config.h Fri Feb 6 04:10:31 1998 *************** *** 301,311 **** /* * OPTION: Define "HAS_USLEEP" only if "usleep()" exists. * Note that this is only relevant for "SET_UID" machines. */ #ifdef SET_UID ! # if !defined(HPUX) && !defined(ULTRIX) && !defined(SOLARIS) && \ ! !defined(SGI) && !defined(ISC) # define HAS_USLEEP # endif #endif --- 301,312 ---- /* * OPTION: Define "HAS_USLEEP" only if "usleep()" exists. + * * Note that this is only relevant for "SET_UID" machines. + * Note that new "SOLARIS" and "SGI" machines have "usleep()". */ #ifdef SET_UID ! # if !defined(HPUX) && !defined(ULTRIX) && !defined(ISC) # define HAS_USLEEP # endif #endif *************** *** 313,316 **** --- 314,318 ---- #endif + diff -c -r angband-282/src/h-define.h angband-283/src/h-define.h *** angband-282/src/h-define.h Wed Sep 3 11:57:33 1997 --- angband-283/src/h-define.h Fri Feb 6 04:10:31 1998 *************** *** 131,133 **** --- 131,134 ---- #endif + diff -c -r angband-282/src/h-system.h angband-283/src/h-system.h *** angband-282/src/h-system.h Wed Sep 3 11:57:33 1997 --- angband-283/src/h-system.h Fri Feb 6 04:10:31 1998 *************** *** 126,128 **** --- 126,129 ---- #endif + diff -c -r angband-282/src/h-type.h angband-283/src/h-type.h *** angband-282/src/h-type.h Wed Sep 3 11:57:33 1997 --- angband-283/src/h-type.h Fri Feb 6 04:10:31 1998 *************** *** 152,154 **** --- 152,155 ---- #endif + diff -c -r angband-282/src/init1.c angband-283/src/init1.c *** angband-282/src/init1.c Wed Sep 3 11:57:33 1997 --- angband-283/src/init1.c Mon Feb 9 01:12:39 1998 *************** *** 871,883 **** if (!buf[3]) return (1); if (!buf[4]) return (1); ! /* Extract the color */ tmp = color_char_to_attr(buf[4]); if (tmp < 0) return (1); /* Save the values */ ! f_ptr->f_char = buf[2]; ! f_ptr->f_attr = tmp; /* Next... */ continue; --- 871,885 ---- if (!buf[3]) return (1); if (!buf[4]) return (1); ! /* Extract the attr */ tmp = color_char_to_attr(buf[4]); + + /* Paranoia */ if (tmp < 0) return (1); /* Save the values */ ! f_ptr->d_attr = tmp; ! f_ptr->d_char = buf[2]; /* Next... */ continue; *************** *** 1113,1120 **** if (tmp < 0) return (1); /* Save the values */ ! k_ptr->k_char = sym; ! k_ptr->k_attr = tmp; /* Next... */ continue; --- 1115,1122 ---- if (tmp < 0) return (1); /* Save the values */ ! k_ptr->d_attr = tmp; ! k_ptr->d_char = sym; /* Next... */ continue; *************** *** 2087,2094 **** if (tmp < 0) return (1); /* Save the values */ - r_ptr->d_char = sym; r_ptr->d_attr = tmp; /* Next... */ continue; --- 2089,2096 ---- if (tmp < 0) return (1); /* Save the values */ r_ptr->d_attr = tmp; + r_ptr->d_char = sym; /* Next... */ continue; *************** *** 2290,2296 **** strcpy(r_name + r_ptr->name, "Nobody, the Undefined Ghost"); strcpy(r_text + r_ptr->text, "It seems strangely familiar..."); ! /* Hack -- set the char/attr info */ r_ptr->d_attr = r_ptr->x_attr = TERM_WHITE; r_ptr->d_char = r_ptr->x_char = 'G'; --- 2292,2298 ---- strcpy(r_name + r_ptr->name, "Nobody, the Undefined Ghost"); strcpy(r_text + r_ptr->text, "It seems strangely familiar..."); ! /* Hack -- set the attr/char info */ r_ptr->d_attr = r_ptr->x_attr = TERM_WHITE; r_ptr->d_char = r_ptr->x_char = 'G'; *************** *** 2323,2326 **** --- 2325,2329 ---- #endif #endif /* ALLOW_TEMPLATES */ + diff -c -r angband-282/src/init2.c angband-283/src/init2.c *** angband-282/src/init2.c Wed Sep 3 11:57:33 1997 --- angband-283/src/init2.c Fri Feb 6 04:10:31 1998 *************** *** 2019,2025 **** - /* * Initialize some other arrays */ --- 2019,2024 ---- *************** *** 2030,2061 **** /*** Prepare the various "bizarre" arrays ***/ ! /* Macro variables */ ! C_MAKE(macro__pat, MACRO_MAX, cptr); ! C_MAKE(macro__act, MACRO_MAX, cptr); ! C_MAKE(macro__cmd, MACRO_MAX, bool); ! /* Macro action buffer */ ! C_MAKE(macro__buf, 1024, char); - /* Quark variables */ - C_MAKE(quark__str, QUARK_MAX, cptr); ! /* Message variables */ ! C_MAKE(message__ptr, MESSAGE_MAX, u16b); ! C_MAKE(message__buf, MESSAGE_BUF, char); ! /* Hack -- No messages yet */ ! message__tail = MESSAGE_BUF; ! /*** Prepare the Player inventory ***/ /* Allocate it */ C_MAKE(inventory, INVEN_TOTAL, object_type); ! /*** Prepare the Stores ***/ /* Allocate the stores */ C_MAKE(store, MAX_STORES, store_type); --- 2029,2102 ---- /*** Prepare the various "bizarre" arrays ***/ ! /* Initialize the "macro" package */ ! (void)macro_init(); ! ! /* Initialize the "quark" package */ ! (void)quark_init(); ! ! /* Initialize the "message" package */ ! (void)message_init(); ! ! ! /*** Prepare grid arrays ***/ ! ! /* Array of grids */ ! C_MAKE(view_g, VIEW_MAX, u16b); ! ! /* Array of grids */ ! C_MAKE(temp_g, TEMP_MAX, u16b); ! ! /* Hack -- use some memory twice */ ! temp_y = ((byte*)(temp_g)) + 0; ! temp_x = ((byte*)(temp_g)) + TEMP_MAX; ! ! ! /*** Prepare dungeon arrays ***/ ! ! /* Padded into array */ ! C_MAKE(cave_info, DUNGEON_HGT, byte_256); ! ! /* Feature array */ ! C_MAKE(cave_feat, DUNGEON_HGT, byte_wid); ! ! /* Entity arrays */ ! C_MAKE(cave_o_idx, DUNGEON_HGT, s16b_wid); ! C_MAKE(cave_m_idx, DUNGEON_HGT, s16b_wid); ! ! /* Flow arrays */ ! C_MAKE(cave_cost, DUNGEON_HGT, byte_wid); ! C_MAKE(cave_when, DUNGEON_HGT, byte_wid); ! ! ! /*** Prepare "vinfo" array ***/ ! ! /* Used by "update_view()" */ ! (void)vinfo_init(); ! ! ! /*** Prepare entity arrays ***/ ! ! /* Objects */ ! C_MAKE(o_list, MAX_O_IDX, object_type); ! /* Monsters */ ! C_MAKE(m_list, MAX_M_IDX, monster_type); ! /*** Prepare quest array ***/ ! /* Quests */ ! C_MAKE(q_list, MAX_Q_IDX, quest); ! /*** Prepare the inventory ***/ /* Allocate it */ C_MAKE(inventory, INVEN_TOTAL, object_type); ! /*** Prepare the stores ***/ /* Allocate the stores */ C_MAKE(store, MAX_STORES, store_type); diff -c -r angband-282/src/load1.c angband-283/src/load1.c *** angband-282/src/load1.c Wed Sep 3 11:57:33 1997 --- angband-283/src/load1.c Fri Feb 6 04:10:31 1998 *************** *** 45,50 **** --- 45,53 ---- * Note that this file should not use the random number generator, the * object flavors, the visual attr/char mappings, or anything else which * is initialized *after* or *during* the "load character" function. + * + * This file assumes that many global variables, including the "dungeon" + * arrays, are initialized to all zeros. */ *************** *** 313,333 **** /* ! * Mega-Hack -- convert the old "name2" fields into the new name1/name2 ! * fields. Note that the entries below must map one-to-one onto the old ! * "SN_*" defines, shown in the comments after the new values. Also note ! * that this code relies on the fact that there are only 128 ego-items and ! * only 128 artifacts in the new system. If this changes, the array below ! * should be modified to contain "u16b" entries instead of "byte" entries. */ static byte convert_old_names[180] = { 0, /* 0 = SN_NULL */ ! EGO_RESISTANCE, /* 1 = SN_R (XXX) */ ! EGO_RESIST_ACID, /* 2 = SN_RA (XXX) */ ! EGO_RESIST_FIRE, /* 3 = SN_RF (XXX) */ ! EGO_RESIST_COLD, /* 4 = SN_RC (XXX) */ ! EGO_RESIST_ELEC, /* 5 = SN_RL (XXX) */ EGO_HA, /* 6 = SN_HA */ EGO_DF, /* 7 = SN_DF */ EGO_SLAY_ANIMAL, /* 8 = SN_SA */ --- 316,337 ---- /* ! * Hack -- convert the old "name2" fields into the new name1/name2 fields. ! * ! * Note that the entries below must map one-to-one onto the old "SN_*" ! * defines, shown in the comments after the new values. ! * ! * Note that this code relies on the fact that there are only 128 ego-items ! * and only 128 artifacts in the new system. */ static byte convert_old_names[180] = { 0, /* 0 = SN_NULL */ ! EGO_RESISTANCE, /* 1 = SN_R */ ! EGO_RESIST_ACID, /* 2 = SN_RA */ ! EGO_RESIST_FIRE, /* 3 = SN_RF */ ! EGO_RESIST_COLD, /* 4 = SN_RC */ ! EGO_RESIST_ELEC, /* 5 = SN_RL */ EGO_HA, /* 6 = SN_HA */ EGO_DF, /* 7 = SN_DF */ EGO_SLAY_ANIMAL, /* 8 = SN_SA */ *************** *** 336,357 **** EGO_SLAY_UNDEAD, /* 11 = SN_SU */ EGO_BRAND_FIRE, /* 12 = SN_FT */ EGO_BRAND_COLD, /* 13 = SN_FB */ ! EGO_FREE_ACTION, /* 14 = SN_FREE_ACTION (XXX) */ ! EGO_SLAYING, /* 15 = SN_SLAYING (XXX) */ EGO_CLUMSINESS, /* 16 = SN_CLUMSINESS */ EGO_WEAKNESS, /* 17 = SN_WEAKNESS */ EGO_SLOW_DESCENT, /* 18 = SN_SLOW_DESCENT */ EGO_SPEED, /* 19 = SN_SPEED */ ! EGO_STEALTH, /* 20 = SN_STEALTH (XXX) */ EGO_SLOWNESS, /* 21 = SN_SLOWNESS */ EGO_NOISE, /* 22 = SN_NOISE */ EGO_ANNOYANCE, /* 23 = SN_GREAT_MASS */ EGO_INTELLIGENCE, /* 24 = SN_INTELLIGENCE */ EGO_WISDOM, /* 25 = SN_WISDOM */ EGO_INFRAVISION, /* 26 = SN_INFRAVISION */ ! EGO_MIGHT, /* 27 = SN_MIGHT (XXX) */ EGO_LORDLINESS, /* 28 = SN_LORDLINESS */ ! EGO_MAGI, /* 29 = SN_MAGI (XXX) */ EGO_BEAUTY, /* 30 = SN_BEAUTY */ EGO_SEEING, /* 31 = SN_SEEING */ EGO_REGENERATION, /* 32 = SN_REGENERATION */ --- 340,361 ---- EGO_SLAY_UNDEAD, /* 11 = SN_SU */ EGO_BRAND_FIRE, /* 12 = SN_FT */ EGO_BRAND_COLD, /* 13 = SN_FB */ ! EGO_FREE_ACTION, /* 14 = SN_FREE_ACTION */ ! EGO_SLAYING, /* 15 = SN_SLAYING */ EGO_CLUMSINESS, /* 16 = SN_CLUMSINESS */ EGO_WEAKNESS, /* 17 = SN_WEAKNESS */ EGO_SLOW_DESCENT, /* 18 = SN_SLOW_DESCENT */ EGO_SPEED, /* 19 = SN_SPEED */ ! EGO_STEALTH, /* 20 = SN_STEALTH */ EGO_SLOWNESS, /* 21 = SN_SLOWNESS */ EGO_NOISE, /* 22 = SN_NOISE */ EGO_ANNOYANCE, /* 23 = SN_GREAT_MASS */ EGO_INTELLIGENCE, /* 24 = SN_INTELLIGENCE */ EGO_WISDOM, /* 25 = SN_WISDOM */ EGO_INFRAVISION, /* 26 = SN_INFRAVISION */ ! EGO_MIGHT, /* 27 = SN_MIGHT */ EGO_LORDLINESS, /* 28 = SN_LORDLINESS */ ! EGO_MAGI, /* 29 = SN_MAGI */ EGO_BEAUTY, /* 30 = SN_BEAUTY */ EGO_SEEING, /* 31 = SN_SEEING */ EGO_REGENERATION, /* 32 = SN_REGENERATION */ *************** *** 365,373 **** EGO_IRRITATION, /* 40 = SN_IRRITATION */ EGO_VULNERABILITY, /* 41 = SN_VULNERABILITY */ EGO_ENVELOPING, /* 42 = SN_ENVELOPING */ ! EGO_BRAND_FIRE, /* 43 = SN_FIRE (XXX) */ ! EGO_HURT_EVIL, /* 44 = SN_SLAY_EVIL (XXX) */ ! EGO_HURT_DRAGON, /* 45 = SN_DRAGON_SLAYING (XXX) */ 0, /* 46 = SN_EMPTY */ 0, /* 47 = SN_LOCKED */ 0, /* 48 = SN_POISON_NEEDLE */ --- 369,377 ---- EGO_IRRITATION, /* 40 = SN_IRRITATION */ EGO_VULNERABILITY, /* 41 = SN_VULNERABILITY */ EGO_ENVELOPING, /* 42 = SN_ENVELOPING */ ! EGO_BRAND_FIRE, /* 43 = SN_FIRE */ ! EGO_HURT_EVIL, /* 44 = SN_SLAY_EVIL */ ! EGO_HURT_DRAGON, /* 45 = SN_DRAGON_SLAYING */ 0, /* 46 = SN_EMPTY */ 0, /* 47 = SN_LOCKED */ 0, /* 48 = SN_POISON_NEEDLE */ *************** *** 377,383 **** 0, /* 52 = SN_MULTIPLE_TRAPS */ 0, /* 53 = SN_DISARMED */ 0, /* 54 = SN_UNLOCKED */ ! EGO_HURT_ANIMAL, /* 55 = SN_SLAY_ANIMAL (XXX) */ ART_GROND + 128, /* 56 = SN_GROND */ ART_RINGIL + 128, /* 57 = SN_RINGIL */ ART_AEGLOS + 128, /* 58 = SN_AEGLOS */ --- 381,387 ---- 0, /* 52 = SN_MULTIPLE_TRAPS */ 0, /* 53 = SN_DISARMED */ 0, /* 54 = SN_UNLOCKED */ ! EGO_HURT_ANIMAL, /* 55 = SN_SLAY_ANIMAL */ ART_GROND + 128, /* 56 = SN_GROND */ ART_RINGIL + 128, /* 57 = SN_RINGIL */ ART_AEGLOS + 128, /* 58 = SN_AEGLOS */ *************** *** 419,425 **** ART_ANARION + 128, /* 94 = SN_ANARION */ ART_ISILDUR + 128, /* 95 = SN_ISILDUR */ ART_FINGOLFIN + 128, /* 96 = SN_FINGOLFIN */ ! EGO_ELVENKIND, /* 97 = SN_ELVENKIND (XXX) */ ART_SOULKEEPER + 128, /* 98 = SN_SOULKEEPER */ ART_DOR + 128, /* 99 = SN_DOR_LOMIN */ ART_MORGOTH + 128, /* 100 = SN_MORGOTH */ --- 423,429 ---- ART_ANARION + 128, /* 94 = SN_ANARION */ ART_ISILDUR + 128, /* 95 = SN_ISILDUR */ ART_FINGOLFIN + 128, /* 96 = SN_FINGOLFIN */ ! EGO_ELVENKIND, /* 97 = SN_ELVENKIND */ ART_SOULKEEPER + 128, /* 98 = SN_SOULKEEPER */ ART_DOR + 128, /* 99 = SN_DOR_LOMIN */ ART_MORGOTH + 128, /* 100 = SN_MORGOTH */ *************** *** 508,514 **** /* * Convert old kinds into normal kinds * ! * Note hard-coded use of object kind indexes XXX XXX XXX */ static s16b convert_old_kinds_normal[501] = { --- 512,518 ---- /* * Convert old kinds into normal kinds * ! * Note the hard-coded use of the new object kind indexes. XXX XXX XXX */ static s16b convert_old_kinds_normal[501] = { *************** *** 1855,1915 **** - - - /* - * More obsolete definitions... - * - * Fval definitions: various types of dungeon floors and walls - * - * In 2.7.3 (?), the "darkness" quality was moved into the "info" flags. - * - * In 2.7.6 (?), the grid flags changed completely - */ - - #define NULL_WALL 0 /* Temp value for "generate.c" */ - - #define ROOM_FLOOR 1 /* Floor, in a room */ - #define VAULT_FLOOR 3 /* Floor, in a vault */ - #define CORR_FLOOR 5 /* Floor, in a corridor */ - - #define MIN_WALL 8 /* Hack -- minimum "wall" fval */ - - #define TMP1_WALL 8 - #define TMP2_WALL 9 - - #define GRANITE_WALL 12 /* Granite */ - #define QUARTZ_WALL 13 /* Quartz */ - #define MAGMA_WALL 14 /* Magma */ - #define BOUNDARY_WALL 15 /* Permanent */ - - - /* - * Old cave "info" flags - */ - #define OLD_CAVE_LR 0x01 /* Grid is part of a room */ - #define OLD_CAVE_FM 0x02 /* Grid is "field marked" */ - #define OLD_CAVE_PL 0x04 /* Grid is perma-lit */ - #define OLD_CAVE_TL 0x08 /* Grid is torch-lit */ - #define OLD_CAVE_INIT 0x10 /* Grid has been "initialized" */ - #define OLD_CAVE_SEEN 0x20 /* Grid is "being processed" */ - #define OLD_CAVE_VIEW 0x40 /* Grid is currently "viewable" */ - #define OLD_CAVE_XTRA 0x80 /* Grid is "easily" viewable */ - - - /* * Read a pre-2.7.0 dungeon * ! * All sorts of information is lost from pre-2.7.0 savefiles, ! * because they were not saved in a very intelligent manner. * ! * Where important, we attempt to recover lost information, or ! * at least to simulate the presence of such information. * * Old savefiles may only contain 512 objects and 1024 monsters. * ! * Prevent old "terrain" objects in inventory XXX XXX */ static errr rd_dungeon_old(void) { --- 1859,1876 ---- /* * Read a pre-2.7.0 dungeon * ! * All sorts of information is lost from pre-2.7.0 savefiles, because they ! * were not saved in a very intelligent manner. * ! * Where important, we attempt to recover lost information, or at least to ! * simulate the presence of such information. * * Old savefiles may only contain 512 objects and 1024 monsters. * ! * Old savefiles encode some "terrain" information in "fake objects". */ static errr rd_dungeon_old(void) { *************** *** 1949,1962 **** /* Ignore illegal dungeons */ if ((ymax != DUNGEON_HGT) || (xmax != DUNGEON_WID)) { - /* XXX XXX XXX */ note(format("Ignoring illegal dungeon size (%d,%d).", xmax, ymax)); return (0); } /* Ignore illegal dungeons */ ! if ((px < 0) || (px >= DUNGEON_WID) || ! (py < 0) || (py >= DUNGEON_HGT)) { note(format("Ignoring illegal player location (%d,%d).", px, py)); return (1); --- 1910,1921 ---- /* Ignore illegal dungeons */ if ((ymax != DUNGEON_HGT) || (xmax != DUNGEON_WID)) { note(format("Ignoring illegal dungeon size (%d,%d).", xmax, ymax)); return (0); } /* Ignore illegal dungeons */ ! if (!in_bounds(py, px)) { note(format("Ignoring illegal player location (%d,%d).", px, py)); return (1); *************** *** 1972,1979 **** ychar = tmp8u; rd_byte(&xchar); /* Invalid cave location */ ! if ((xchar >= DUNGEON_WID) || (ychar >= DUNGEON_HGT)) { note("Illegal monster location!"); return (71); --- 1931,1942 ---- ychar = tmp8u; rd_byte(&xchar); + /* Location */ + y = ychar; + x = xchar; + /* Invalid cave location */ ! if (!in_bounds(y, x)) { note("Illegal monster location!"); return (71); *************** *** 2006,2013 **** ychar = tmp8u; rd_byte(&xchar); /* Invalid cave location */ ! if ((xchar >= DUNGEON_WID) || (ychar >= DUNGEON_HGT)) { note("Illegal object location!"); return (72); --- 1969,1980 ---- ychar = tmp8u; rd_byte(&xchar); + /* Location */ + y = ychar; + x = xchar; + /* Invalid cave location */ ! if (!in_bounds(y, x)) { note("Illegal object location!"); return (72); *************** *** 2024,2031 **** } /* Remember the location */ ! ix[tmp16u] = xchar; ! iy[tmp16u] = ychar; } --- 1991,1998 ---- } /* Remember the location */ ! iy[tmp16u] = y; ! ix[tmp16u] = x; } *************** *** 2043,2048 **** --- 2010,2018 ---- /* Apply the RLE info */ for (i = count; i > 0; i--) { + byte info = 0x00; + byte feat = FEAT_FLOOR; + /* Invalid cave location */ if ((x >= DUNGEON_WID) || (y >= DUNGEON_HGT)) { *************** *** 2050,2076 **** return (81); } - /* Hack -- Clear all the flags */ - cave_info[y][x] = 0x00; - - /* Hack -- Clear all the flags */ - cave_feat[y][x] = FEAT_NONE; - /* Extract the old "info" flags */ ! if ((tmp8u >> 4) & 0x1) cave_info[y][x] |= (CAVE_ROOM); ! if ((tmp8u >> 5) & 0x1) cave_info[y][x] |= (CAVE_MARK); ! if ((tmp8u >> 6) & 0x1) cave_info[y][x] |= (CAVE_GLOW); /* Hack -- process old style "light" */ ! if (cave_info[y][x] & (CAVE_GLOW)) { ! cave_info[y][x] |= (CAVE_MARK); } /* Mega-Hack -- light all walls */ else if ((tmp8u & 0xF) >= 12) { ! cave_info[y][x] |= (CAVE_GLOW); } /* Process the "floor type" */ --- 2020,2040 ---- return (81); } /* Extract the old "info" flags */ ! if ((tmp8u >> 4) & 0x1) info |= (CAVE_ROOM); ! if ((tmp8u >> 5) & 0x1) info |= (CAVE_MARK); ! if ((tmp8u >> 6) & 0x1) info |= (CAVE_GLOW); /* Hack -- process old style "light" */ ! if (info & (CAVE_GLOW)) { ! info |= (CAVE_MARK); } /* Mega-Hack -- light all walls */ else if ((tmp8u & 0xF) >= 12) { ! info |= (CAVE_GLOW); } /* Process the "floor type" */ *************** *** 2079,2105 **** /* Lite Room Floor */ case 2: { ! cave_info[y][x] |= (CAVE_GLOW); } /* Dark Room Floor */ case 1: { ! cave_info[y][x] |= (CAVE_ROOM); break; } /* Lite Vault Floor */ case 4: { ! cave_info[y][x] |= (CAVE_GLOW); } /* Dark Vault Floor */ case 3: { ! cave_info[y][x] |= (CAVE_ROOM); ! cave_info[y][x] |= (CAVE_ICKY); break; } --- 2043,2069 ---- /* Lite Room Floor */ case 2: { ! info |= (CAVE_GLOW); } /* Dark Room Floor */ case 1: { ! info |= (CAVE_ROOM); break; } /* Lite Vault Floor */ case 4: { ! info |= (CAVE_GLOW); } /* Dark Vault Floor */ case 3: { ! info |= (CAVE_ROOM); ! info |= (CAVE_ICKY); break; } *************** *** 2109,2143 **** break; } ! /* Perma-wall (assume "solid") XXX */ case 15: { ! cave_feat[y][x] = FEAT_PERM_SOLID; break; } ! /* Granite wall (assume "basic") XXX */ case 12: { ! cave_feat[y][x] = FEAT_WALL_EXTRA; break; } /* Quartz vein */ case 13: { ! cave_feat[y][x] = FEAT_QUARTZ; break; } /* Magma vein */ case 14: { ! cave_feat[y][x] = FEAT_MAGMA; break; } } /* Advance the cave pointers */ x++; --- 2073,2113 ---- break; } ! /* Perma-wall */ case 15: { ! feat = FEAT_PERM_SOLID; break; } ! /* Granite wall */ case 12: { ! feat = FEAT_WALL_EXTRA; break; } /* Quartz vein */ case 13: { ! feat = FEAT_QUARTZ; break; } /* Magma vein */ case 14: { ! feat = FEAT_MAGMA; break; } } + /* Save the info */ + cave_info[y][x] = info; + + /* Save the feat */ + cave_set_feat(y, x, feat); + /* Advance the cave pointers */ x++; *************** *** 2195,2211 **** /* Read the item */ rd_item_old(i_ptr); - /* Save location */ - i_ptr->iy = iy[i]; - i_ptr->ix = ix[i]; - - /* Skip dead objects */ if (!i_ptr->k_idx) continue; /* Invalid cave location */ ! if ((i_ptr->iy >= DUNGEON_HGT) || (i_ptr->ix >= DUNGEON_WID)) { note("Illegal object location!!!"); return (72); --- 2165,2180 ---- /* Read the item */ rd_item_old(i_ptr); /* Skip dead objects */ if (!i_ptr->k_idx) continue; + /* Save location */ + i_ptr->iy = y = iy[i]; + i_ptr->ix = x = ix[i]; + /* Invalid cave location */ ! if ((y >= DUNGEON_HGT) || (x >= DUNGEON_WID)) { note("Illegal object location!!!"); return (72); *************** *** 2215,2221 **** /* Hack -- convert old "dungeon" objects */ if ((i_ptr->k_idx >= 445) && (i_ptr->k_idx <= 479)) { ! int feat = 0; /* Analyze the "dungeon objects" */ switch (i_ptr->k_idx) --- 2184,2190 ---- /* Hack -- convert old "dungeon" objects */ if ((i_ptr->k_idx >= 445) && (i_ptr->k_idx <= 479)) { ! byte feat = 0; /* Analyze the "dungeon objects" */ switch (i_ptr->k_idx) *************** *** 2327,2333 **** } /* Hack -- use the feature */ ! cave_feat[i_ptr->iy][i_ptr->ix] = feat; /* Done */ continue; --- 2296,2302 ---- } /* Hack -- use the feature */ ! cave_set_feat(y, x, feat); /* Done */ continue; *************** *** 2338,2348 **** if (i_ptr->tval == TV_GOLD) { /* Quartz or Magma with treasure */ ! if ((cave_feat[i_ptr->iy][i_ptr->ix] == FEAT_QUARTZ) || ! (cave_feat[i_ptr->iy][i_ptr->ix] == FEAT_MAGMA)) { /* Add treasure */ ! cave_feat[i_ptr->iy][i_ptr->ix] += 4; /* Done */ continue; --- 2307,2317 ---- if (i_ptr->tval == TV_GOLD) { /* Quartz or Magma with treasure */ ! if ((cave_feat[y][x] == FEAT_QUARTZ) || ! (cave_feat[y][x] == FEAT_MAGMA)) { /* Add treasure */ ! cave_set_feat(y, x, cave_feat[y][x] + 0x04); /* Done */ continue; *************** *** 2405,2410 **** --- 2374,2383 ---- rd_byte(&n_ptr->fy); rd_byte(&n_ptr->fx); + /* Extract location */ + y = n_ptr->fy; + x = n_ptr->fx; + /* Strip confusion, etc */ strip_bytes(4); *************** *** 2423,2429 **** /* Invalid cave location