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 */ ! if ((n_ptr->fx >= DUNGEON_WID) || (n_ptr->fy >= DUNGEON_HGT)) { note("Illegal monster location!!!"); return (71); --- 2396,2402 ---- /* Invalid cave location */ ! if ((x >= DUNGEON_WID) || (y >= DUNGEON_HGT)) { note("Illegal monster location!!!"); return (71); *************** *** 2452,2468 **** } - /* Hack -- clean up terrain */ - for (y = 0; y < DUNGEON_HGT; y++) - { - for (x = 0; x < DUNGEON_WID; x++) - { - /* Convert nothing-ness into floors */ - if (!cave_feat[y][x]) cave_feat[y][x] = FEAT_FLOOR; - } - } - - /* The dungeon is ready */ character_dungeon = TRUE; --- 2425,2430 ---- *************** *** 2474,2482 **** - - - /* * Read pre-2.7.0 options */ --- 2436,2441 ---- *************** *** 2637,2643 **** sf_major, sf_minor, sf_patch)); ! /* Mega-Hack XXX XXX XXX */ if (older_than(2, 5, 2)) { /* Allow use of old MacAngband 1.0 and 2.0.3 savefiles */ --- 2596,2602 ---- sf_major, sf_minor, sf_patch)); ! /* Mega-Hack */ if (older_than(2, 5, 2)) { /* Allow use of old MacAngband 1.0 and 2.0.3 savefiles */ *************** *** 2670,2678 **** xor_byte = sf_extra; - /* Fake the system info XXX XXX */ - - /* Read the artifacts */ rd_artifacts_old(); note("Loaded Artifacts"); --- 2629,2634 ---- *************** *** 2873,2902 **** r_info[MAX_R_IDX-1].max_num = 0; ! /* Hack -- reset morgoth XXX XXX */ r_info[MAX_R_IDX-2].max_num = 1; ! /* Hack -- reset sauron XXX XXX */ r_info[MAX_R_IDX-3].max_num = 1; ! /* Hack -- reset morgoth XXX XXX */ r_info[MAX_R_IDX-2].r_pkills = 0; ! /* Hack -- reset sauron XXX XXX */ r_info[MAX_R_IDX-3].r_pkills = 0; ! /* Add first quest XXX XXX */ q_list[0].level = 99; ! /* Add second quest XXX XXX */ q_list[1].level = 100; ! /* Reset third quest XXX XXX */ q_list[2].level = 0; ! /* Reset fourth quest XXX XXX */ q_list[3].level = 0; --- 2829,2858 ---- r_info[MAX_R_IDX-1].max_num = 0; ! /* Hack -- reset morgoth */ r_info[MAX_R_IDX-2].max_num = 1; ! /* Hack -- reset sauron */ r_info[MAX_R_IDX-3].max_num = 1; ! /* Hack -- reset morgoth */ r_info[MAX_R_IDX-2].r_pkills = 0; ! /* Hack -- reset sauron */ r_info[MAX_R_IDX-3].r_pkills = 0; ! /* Add first quest */ q_list[0].level = 99; ! /* Add second quest */ q_list[1].level = 100; ! /* Reset third quest */ q_list[2].level = 0; ! /* Reset fourth quest */ q_list[3].level = 0; diff -c -r angband-282/src/load2.c angband-283/src/load2.c *** angband-282/src/load2.c Wed Sep 3 11:57:33 1997 --- angband-283/src/load2.c Fri Feb 6 04:10:31 1998 *************** *** 38,46 **** * Consider changing the "globe of invulnerability" code so that it * takes some form of "maximum damage to protect from" in addition to * the existing "number of turns to protect for", and where each hit ! * by a monster will reduce the shield by that amount. ! * ! * XXX XXX XXX */ --- 38,44 ---- * Consider changing the "globe of invulnerability" code so that it * takes some form of "maximum damage to protect from" in addition to * the existing "number of turns to protect for", and where each hit ! * by a monster will reduce the shield by that amount. XXX XXX XXX */ *************** *** 1580,1588 **** /* * Read pre-2.8.0 dungeon info * ! * XXX XXX XXX Try to be more flexible about "too many monsters" * ! * Convert the old terrain objects into the new terrain features. */ static errr rd_dungeon_aux(s16b depth, s16b py, s16b px) { --- 1578,1586 ---- /* * Read pre-2.8.0 dungeon info * ! * Try to be more flexible about "too many monsters" XXX XXX * ! * Convert the old "flags" and "fake objects" into the new terrain features. */ static errr rd_dungeon_aux(s16b depth, s16b py, s16b px) { *************** *** 1603,1632 **** /* Apply the RLE info */ for (i = count; i > 0; i--) { ! /* Hack -- Clear all the flags */ ! cave_info[y][x] = 0x00; ! ! /* Hack -- Clear feature */ ! cave_feat[y][x] = FEAT_NONE; /* Old method */ if (older_than(2, 7, 5)) { /* 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 & 0x0F) >= 12) { ! cave_info[y][x] |= (CAVE_GLOW); } /* Process the "floor type" */ --- 1601,1627 ---- /* Apply the RLE info */ for (i = count; i > 0; i--) { ! byte info = 0x00; ! byte feat = FEAT_FLOOR; /* Old method */ if (older_than(2, 7, 5)) { /* 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 & 0x0F) >= 12) { ! info |= (CAVE_GLOW); } /* Process the "floor type" */ *************** *** 1635,1661 **** /* 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; } --- 1630,1656 ---- /* 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; } *************** *** 1665,1695 **** break; } ! /* Perma-wall (assume "solid") XXX XXX XXX */ case 15: { ! cave_feat[y][x] = FEAT_PERM_SOLID; break; } ! /* Granite wall (assume "basic") XXX XXX 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; } } --- 1660,1690 ---- 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; } } *************** *** 1699,1724 **** else { /* The old "vault" flag */ ! if (tmp8u & (OLD_GRID_ICKY)) cave_info[y][x] |= (CAVE_ICKY); /* The old "room" flag */ ! if (tmp8u & (OLD_GRID_ROOM)) cave_info[y][x] |= (CAVE_ROOM); /* The old "glow" flag */ ! if (tmp8u & (OLD_GRID_GLOW)) cave_info[y][x] |= (CAVE_GLOW); /* The old "mark" flag */ ! if (tmp8u & (OLD_GRID_MARK)) cave_info[y][x] |= (CAVE_MARK); /* The old "wall" flags -- granite wall */ if ((tmp8u & (OLD_GRID_WALL_MASK)) == OLD_GRID_WALL_GRANITE) { ! /* Permanent wall (assume "solid") XXX XXX XXX */ ! if (tmp8u & (OLD_GRID_PERM)) cave_feat[y][x] = FEAT_PERM_SOLID; ! /* Normal wall (assume "basic") XXX XXX XXX */ ! else cave_feat[y][x] = FEAT_WALL_EXTRA; } /* The old "wall" flags -- quartz vein */ --- 1694,1725 ---- else { /* The old "vault" flag */ ! if (tmp8u & (OLD_GRID_ICKY)) info |= (CAVE_ICKY); /* The old "room" flag */ ! if (tmp8u & (OLD_GRID_ROOM)) info |= (CAVE_ROOM); /* The old "glow" flag */ ! if (tmp8u & (OLD_GRID_GLOW)) info |= (CAVE_GLOW); /* The old "mark" flag */ ! if (tmp8u & (OLD_GRID_MARK)) info |= (CAVE_MARK); /* The old "wall" flags -- granite wall */ if ((tmp8u & (OLD_GRID_WALL_MASK)) == OLD_GRID_WALL_GRANITE) { ! /* Permanent wall */ ! if (tmp8u & (OLD_GRID_PERM)) ! { ! feat = FEAT_PERM_SOLID; ! } ! /* Normal wall */ ! else ! { ! feat = FEAT_WALL_EXTRA; ! } } /* The old "wall" flags -- quartz vein */ *************** *** 1726,1732 **** OLD_GRID_WALL_QUARTZ) { /* Assume no treasure */ ! cave_feat[y][x] = FEAT_QUARTZ; } /* The old "wall" flags -- magma vein */ --- 1727,1733 ---- OLD_GRID_WALL_QUARTZ) { /* Assume no treasure */ ! feat = FEAT_QUARTZ; } /* The old "wall" flags -- magma vein */ *************** *** 1734,1743 **** OLD_GRID_WALL_MAGMA) { /* Assume no treasure */ ! cave_feat[y][x] = FEAT_MAGMA; } } /* Advance/Wrap */ if (++x >= DUNGEON_WID) { --- 1735,1750 ---- OLD_GRID_WALL_MAGMA) { /* Assume no treasure */ ! feat = FEAT_MAGMA; } } + /* Save the info */ + cave_info[y][x] = info; + + /* Save the feat */ + cave_set_feat(y, x, feat); + /* Advance/Wrap */ if (++x >= DUNGEON_WID) { *************** *** 1792,1797 **** --- 1799,1808 ---- /* Read the item */ rd_item(i_ptr); + /* Location */ + y = i_ptr->iy; + x = i_ptr->ix; + /* Skip dead objects */ if (!i_ptr->k_idx) continue; *************** *** 1800,1806 **** /* Hack -- convert old "dungeon" objects */ if ((i_ptr->k_idx >= 445) && (i_ptr->k_idx <= 479)) { ! int k = 0; bool invis = FALSE; --- 1811,1817 ---- /* Hack -- convert old "dungeon" objects */ if ((i_ptr->k_idx >= 445) && (i_ptr->k_idx <= 479)) { ! byte feat = FEAT_FLOOR; bool invis = FALSE; *************** *** 1813,1819 **** /* Rubble */ case 445: { ! k = FEAT_RUBBLE; break; } --- 1824,1830 ---- /* Rubble */ case 445: { ! feat = FEAT_RUBBLE; break; } *************** *** 1823,1835 **** /* Broken door */ if (i_ptr->pval) { ! k = FEAT_BROKEN; } /* Open door */ else { ! k = FEAT_OPEN; } break; --- 1834,1846 ---- /* Broken door */ if (i_ptr->pval) { ! feat = FEAT_BROKEN; } /* Open door */ else { ! feat = FEAT_OPEN; } break; *************** *** 1841,1857 **** /* Jammed door */ if (i_ptr->pval < 0) { ! k = (0 - i_ptr->pval) / 2; ! if (k > 7) k = 7; ! k = FEAT_DOOR_HEAD + 0x08 + k; } /* Locked door */ else { ! k = i_ptr->pval / 2; ! if (k > 7) k = 7; ! k = FEAT_DOOR_HEAD + k; } break; --- 1852,1868 ---- /* Jammed door */ if (i_ptr->pval < 0) { ! feat = (0 - i_ptr->pval) / 2; ! if (feat > 0x07) feat = 0x07; ! feat = FEAT_DOOR_HEAD + 0x08 + feat; } /* Locked door */ else { ! feat = i_ptr->pval / 2; ! if (feat > 0x07) feat = 0x07; ! feat = FEAT_DOOR_HEAD + feat; } break; *************** *** 1860,2078 **** /* Secret Door */ case 448: { ! k = FEAT_SECRET; break; } /* Up Stairs */ case 449: { ! k = FEAT_LESS; break; } /* Down Stairs */ case 450: { ! k = FEAT_MORE; break; } /* Store '1' */ case 451: { ! k = FEAT_SHOP_HEAD + 0; break; } /* Store '2' */ case 452: { ! k = FEAT_SHOP_HEAD + 1; break; } /* Store '3' */ case 453: { ! k = FEAT_SHOP_HEAD + 2; break; } /* Store '4' */ case 454: { ! k = FEAT_SHOP_HEAD + 3; break; } /* Store '5' */ case 455: { ! k = FEAT_SHOP_HEAD + 4; break; } /* Store '6' */ case 456: { ! k = FEAT_SHOP_HEAD + 5; break; } /* Store '7' */ case 457: { ! k = FEAT_SHOP_HEAD + 6; break; } /* Store '8' */ case 458: { ! k = FEAT_SHOP_HEAD + 7; break; } /* Glyph of Warding */ case 459: { ! k = FEAT_GLYPH; break; } /* Trap -- Pit */ case 460: { ! k = FEAT_TRAP_HEAD + 0x01; break; } /* Trap -- Spiked Pit */ case 461: { ! k = FEAT_TRAP_HEAD + 0x02; break; } /* Trap -- Trap Door */ case 462: { ! k = FEAT_TRAP_HEAD + 0x00; break; } /* Trap -- Gas -- Sleep */ case 463: { ! k = FEAT_TRAP_HEAD + 0x0F; break; } /* Trap -- Loose rock */ case 464: { ! k = FEAT_TRAP_HEAD + 0x01; break; } /* Trap -- Dart -- lose str */ case 465: { ! k = FEAT_TRAP_HEAD + 0x09; break; } /* Trap -- Teleport */ case 466: { ! k = FEAT_TRAP_HEAD + 0x05; break; } /* Trap -- Falling rock */ case 467: { ! k = FEAT_TRAP_HEAD + 0x03; break; } /* Trap -- Dart -- lose dex */ case 468: { ! k = FEAT_TRAP_HEAD + 0x0A; break; } /* Trap -- Summoning */ case 469: { ! k = FEAT_TRAP_HEAD + 0x04; break; } /* Trap -- Fire */ case 470: { ! k = FEAT_TRAP_HEAD + 0x06; break; } /* Trap -- Acid */ case 471: { ! k = FEAT_TRAP_HEAD + 0x07; break; } /* Trap -- Gas -- poison */ case 472: { ! k = FEAT_TRAP_HEAD + 0x0E; break; } /* Trap -- Gas -- blind */ case 473: { ! k = FEAT_TRAP_HEAD + 0x0C; break; } /* Trap -- Gas -- confuse */ case 474: { ! k = FEAT_TRAP_HEAD + 0x0D; break; } /* Trap -- Dart -- slow */ case 475: { ! k = FEAT_TRAP_HEAD + 0x08; break; } /* Trap -- Dart -- lose con */ case 476: { ! k = FEAT_TRAP_HEAD + 0x0B; break; } /* Trap -- Arrow */ case 477: { ! k = FEAT_TRAP_HEAD + 0x08; break; } } /* Hack -- handle "invisible traps" */ ! if (invis) k = FEAT_INVIS; /* Set new bits */ ! cave_feat[i_ptr->iy][i_ptr->ix] = k; /* Skip it */ continue; --- 1871,2089 ---- /* Secret Door */ case 448: { ! feat = FEAT_SECRET; break; } /* Up Stairs */ case 449: { ! feat = FEAT_LESS; break; } /* Down Stairs */ case 450: { ! feat = FEAT_MORE; break; } /* Store '1' */ case 451: { ! feat = FEAT_SHOP_HEAD + 0x00; break; } /* Store '2' */ case 452: { ! feat = FEAT_SHOP_HEAD + 0x01; break; } /* Store '3' */ case 453: { ! feat = FEAT_SHOP_HEAD + 0x02; break; } /* Store '4' */ case 454: { ! feat = FEAT_SHOP_HEAD + 0x03; break; } /* Store '5' */ case 455: { ! feat = FEAT_SHOP_HEAD + 0x04; break; } /* Store '6' */ case 456: { ! feat = FEAT_SHOP_HEAD + 0x05; break; } /* Store '7' */ case 457: { ! feat = FEAT_SHOP_HEAD + 0x06; break; } /* Store '8' */ case 458: { ! feat = FEAT_SHOP_HEAD + 0x07; break; } /* Glyph of Warding */ case 459: { ! feat = FEAT_GLYPH; break; } /* Trap -- Pit */ case 460: { ! feat = FEAT_TRAP_HEAD + 0x01; break; } /* Trap -- Spiked Pit */ case 461: { ! feat = FEAT_TRAP_HEAD + 0x02; break; } /* Trap -- Trap Door */ case 462: { ! feat = FEAT_TRAP_HEAD + 0x00; break; } /* Trap -- Gas -- Sleep */ case 463: { ! feat = FEAT_TRAP_HEAD + 0x0F; break; } /* Trap -- Loose rock */ case 464: { ! feat = FEAT_TRAP_HEAD + 0x01; break; } /* Trap -- Dart -- lose str */ case 465: { ! feat = FEAT_TRAP_HEAD + 0x09; break; } /* Trap -- Teleport */ case 466: { ! feat = FEAT_TRAP_HEAD + 0x05; break; } /* Trap -- Falling rock */ case 467: { ! feat = FEAT_TRAP_HEAD + 0x03; break; } /* Trap -- Dart -- lose dex */ case 468: { ! feat = FEAT_TRAP_HEAD + 0x0A; break; } /* Trap -- Summoning */ case 469: { ! feat = FEAT_TRAP_HEAD + 0x04; break; } /* Trap -- Fire */ case 470: { ! feat = FEAT_TRAP_HEAD + 0x06; break; } /* Trap -- Acid */ case 471: { ! feat = FEAT_TRAP_HEAD + 0x07; break; } /* Trap -- Gas -- poison */ case 472: { ! feat = FEAT_TRAP_HEAD + 0x0E; break; } /* Trap -- Gas -- blind */ case 473: { ! feat = FEAT_TRAP_HEAD + 0x0C; break; } /* Trap -- Gas -- confuse */ case 474: { ! feat = FEAT_TRAP_HEAD + 0x0D; break; } /* Trap -- Dart -- slow */ case 475: { ! feat = FEAT_TRAP_HEAD + 0x08; break; } /* Trap -- Dart -- lose con */ case 476: { ! feat = FEAT_TRAP_HEAD + 0x0B; break; } /* Trap -- Arrow */ case 477: { ! feat = FEAT_TRAP_HEAD + 0x08; break; } } /* Hack -- handle "invisible traps" */ ! if (invis) feat = FEAT_INVIS; /* Set new bits */ ! cave_set_feat(y, x, feat); /* Skip it */ continue; *************** *** 2083,2093 **** if (i_ptr->tval == TV_GOLD) { /* Quartz + treasure */ ! if ((cave_feat[i_ptr->iy][i_ptr->ix] == FEAT_QUARTZ) || ! (cave_feat[i_ptr->iy][i_ptr->ix] == FEAT_MAGMA)) { /* Add known treasure */ ! cave_feat[i_ptr->iy][i_ptr->ix] += 0x04; /* Done */ continue; --- 2094,2104 ---- if (i_ptr->tval == TV_GOLD) { /* Quartz + treasure */ ! if ((cave_feat[y][x] == FEAT_QUARTZ) || ! (cave_feat[y][x] == FEAT_MAGMA)) { /* Add known treasure */ ! cave_set_feat(y, x, cave_feat[y][x] + 0x04); /* Done */ continue; *************** *** 2096,2102 **** /* Give the item to the floor */ ! if (!floor_carry(i_ptr->iy, i_ptr->ix, i_ptr)) { note(format("Cannot place object %d!", o_max)); return (152); --- 2107,2113 ---- /* Give the item to the floor */ ! if (!floor_carry(y, x, i_ptr)) { note(format("Cannot place object %d!", o_max)); return (152); *************** *** 2152,2167 **** } - /* Hack -- clean up the dungeon */ - for (y = 0; y < DUNGEON_HGT; y++) - { - for (x = 0; x < DUNGEON_WID; x++) - { - /* Hack -- convert nothing-ness into floors */ - if (!cave_feat[y][x]) cave_feat[y][x] = FEAT_FLOOR; - } - } - /* The dungeon is ready */ character_dungeon = TRUE; --- 2163,2168 ---- *************** *** 2282,2288 **** for (i = count; i > 0; i--) { /* Extract "feat" */ ! cave_feat[y][x] = tmp8u; /* Advance/Wrap */ if (++x >= DUNGEON_WID) --- 2283,2289 ---- for (i = count; i > 0; i--) { /* Extract "feat" */ ! cave_set_feat(y, x, tmp8u); /* Advance/Wrap */ if (++x >= DUNGEON_WID) diff -c -r angband-282/src/main-acn.c angband-283/src/main-acn.c *** angband-282/src/main-acn.c Wed Sep 3 11:57:33 1997 --- angband-283/src/main-acn.c Fri Feb 6 04:10:31 1998 *************** *** 8,24 **** * are included in all such copies. */ - /* Purpose: Support for Acorn RISC OS Angband */ /* * Author: Kevin Bracey (kbracey@art.acorn.co.uk) * ! */ ! ! /* Check compiler flag */ ! #ifdef __riscos ! ! /* * === Instructions for compiling Angband for RISC OS === * * You will require: --- 8,24 ---- * are included in all such copies. */ /* + * Purpose: Support for Acorn RISC OS Angband + * + * * Author: Kevin Bracey (kbracey@art.acorn.co.uk) * ! * ! * This file is *known* to be out of date. It needs some work. XXX XXX XXX ! * ! * * === Instructions for compiling Angband for RISC OS === * * You will require: *************** *** 33,38 **** --- 33,42 ---- * */ + + /* Check compiler flag */ + #ifdef __riscos + #define VERSION "2.7.9v6 (07-May-96)" /* Hack to prevent types clash from OSLib */ *************** *** 2350,2352 **** --- 2354,2358 ---- } #endif /* __riscos */ + + diff -c -r angband-282/src/main-ami.c angband-283/src/main-ami.c *** angband-282/src/main-ami.c Wed Sep 3 11:57:33 1997 --- angband-283/src/main-ami.c Mon Feb 9 01:13:33 1998 *************** *** 8,25 **** * are included in all such copies. */ - /* - File: main-ami.c - - Version: 2.7.9v6 (09.May.96) - - Purpose: Amiga module for Angband with graphics and sound ! Author: Lars Haugseth ! Email: larshau@ifi.uio.no ! WWW: http://www.ifi.uio.no/~larshau - */ #define VERSION "Angband 2.7.9v6" --- 8,25 ---- * are included in all such copies. */ ! /* ! * This file helps Angband run on Amiga computers. ! * ! * Author: Lars Haugseth ! * Email: larshau@ifi.uio.no ! * WWW: http://www.ifi.uio.no/~larshau ! * ! * ! * This file is *known* to be out of date. It needs some work. XXX XXX XXX ! */ #define VERSION "Angband 2.7.9v6" *************** *** 2679,2686 **** /* Get frame tile */ if ( i==0 || i == DUNGEON_WID - 1 || j == 0 || j == DUNGEON_HGT - 1 ) { ! ta = f_info[ 63 ].z_attr; ! tc = f_info[ 63 ].z_char; } /* Get tile from cave table */ --- 2679,2686 ---- /* Get frame tile */ if ( i==0 || i == DUNGEON_WID - 1 || j == 0 || j == DUNGEON_HGT - 1 ) { ! ta = f_info[ 63 ].x_attr; ! tc = f_info[ 63 ].x_char; } /* Get tile from cave table */ *************** *** 3253,3256 **** --- 3253,3257 ---- } ///} + diff -c -r angband-282/src/main-cap.c angband-283/src/main-cap.c *** angband-282/src/main-cap.c Wed Sep 3 11:57:33 1997 --- angband-283/src/main-cap.c Fri Feb 6 04:10:31 1998 *************** *** 8,23 **** * are included in all such copies. */ - /* Purpose: Support for "z-term.c" using "termcap" calls */ - - #include "angband.h" - - - #ifdef USE_CAP - /* ! * This file is a total hack, but is often very helpful. :-) * * This file allows use of the terminal without requiring the * "curses" routines. In fact, if "USE_HARDCODE" is defined, --- 8,17 ---- * are included in all such copies. */ /* ! * This file helps Angband run on really crappy Unix machines. ! * * * This file allows use of the terminal without requiring the * "curses" routines. In fact, if "USE_HARDCODE" is defined, *************** *** 30,41 **** * but which seem to be able to support the "termcap" library, or * which at least seem able to support "vt100" terminals. * - * Large portions of this file were stolen from "main-gcu.c" - * * This file incorrectly handles output to column 80, I think. */ /* * Require a "system" */ --- 24,42 ---- * but which seem to be able to support the "termcap" library, or * which at least seem able to support "vt100" terminals. * * This file incorrectly handles output to column 80, I think. + * + * + * Large portions of this file were stolen from "main-gcu.c" */ + #include "angband.h" + + + #ifdef USE_CAP + + /* * Require a "system" */ *************** *** 715,721 **** game_ltchars.t_werasc = (char)-1; game_ltchars.t_lnextc = (char)-1; ! /* XXX XXX XXX XXX Verify this before use */ /* Hack -- Turn off "echo" and "canonical" mode */ /* game_termios.c_lflag &= ~(ECHO | ICANON); */ game_ttyb.flag &= ~(ECHO | ICANON); --- 716,722 ---- game_ltchars.t_werasc = (char)-1; game_ltchars.t_lnextc = (char)-1; ! /* Verify this before use XXX XXX XXX */ /* Hack -- Turn off "echo" and "canonical" mode */ /* game_termios.c_lflag &= ~(ECHO | ICANON); */ game_ttyb.flag &= ~(ECHO | ICANON); Only in angband-283/src: main-dos.c diff -c -r angband-282/src/main-emx.c angband-283/src/main-emx.c *** angband-282/src/main-emx.c Wed Sep 3 11:57:33 1997 --- angband-283/src/main-emx.c Wed Feb 11 06:07:30 1998 *************** *** 12,17 **** --- 12,20 ---- /* Author: ekraemer@pluto.camelot.de (Ekkehard Kraemer) */ + /* Current maintainer: silasd@psyber.com (Silas Dunsmore) */ + /* Unless somebody else wants it.... */ + #ifdef USE_EMX /* *************** *** 60,66 **** * Introduced __EMX__CLIENT__ hack * * 15.12.95 EK 2.7.9 Updated for 2.7.9 ! * beta Added mirror view * Added number of line support in aclient * * 25.12.95 EK 2.7.9 Added 'install' target --- 63,69 ---- * Introduced __EMX__CLIENT__ hack * * 15.12.95 EK 2.7.9 Updated for 2.7.9 ! * beta Added third view * Added number of line support in aclient * * 25.12.95 EK 2.7.9 Added 'install' target *************** *** 82,87 **** --- 85,97 ---- * * 9.03.96 EK 2.7.9 Adjustable background color (PM) * v5 Added map window + + * 3 Dec 97 SWD 282 Brought key-handling, macros in sync with DOS. + * Hacked on sub-window code -- it compiles, but + * doesn't link. + * + * 23 Jan 98 SWD 282 Hacked more on sub-windows. Now links, with + * warnings. Seems to work. */ #include *************** *** 89,99 **** --- 99,133 ---- #include #include #include + #define INCL_KBD 1 #include #include #include "angband.h" + + /* + * Maximum windows + */ + #define MAX_TERM_DATA 8 + + + /* + * Keypress input modifier flags (copied from main-ibm.c) + * + * SWD: these could be changed to the definitions in , which are + * direct bitmasks instead of shift-counts. + */ + #define K_RSHIFT 0 /* Right shift key down */ + #define K_LSHIFT 1 /* Left shift key down */ + #define K_CTRL 2 /* Ctrl key down */ + #define K_ALT 3 /* Alt key down */ + #define K_SCROLL 4 /* Scroll lock on */ + #define K_NUM 5 /* Num lock on */ + #define K_CAPS 6 /* Caps lock on */ + #define K_INSERT 7 /* Insert on */ + + /* * Prototypes! */ *************** *** 211,220 **** --- 245,275 ---- */ static void Term_init_emx(term *t) { + struct _KBDINFO kbdinfo; /* see structure description ?somewhere? */ + v_init(); v_getctype(&curs_start, &curs_end); + /* hide cursor (?) XXX XXX XXX */ v_clear(); + /* the documentation I (SWD) have implies, in passing, that setting */ + /* "binary mode" on the keyboard device will prevent the O/S from */ + /* acting on keys such as ^S (pause) and ^P (printer echo). */ + + /* note also that "KbdSetStatus is ignored for a Vio-windowed application." */ + /* so there may well be problems with running this in a window. Damnit. */ + + /* this is kind of a nasty structure, as you can't just flip a bit */ + /* to change binary/ASCII mode, or echo on/off mode... nor can you */ + /* clear the whole thing -- certain bits need to be preserved. */ + + KbdGetStatus(&kbdinfo, (HKBD)0); + kbdinfo.fsMask &= ~ (KEYBOARD_ECHO_ON| /* clear lowest four bits */ + KEYBOARD_ECHO_OFF|KEYBOARD_BINARY_MODE|KEYBOARD_ASCII_MODE); + kbdinfo.fsMask |= (KEYBOARD_BINARY_MODE); /* set bit two */ + KbdSetStatus(&kbdinfo, (HKBD)0); + + #if 1 /* turn off for debug */ signal(SIGHUP, SIG_IGN); signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); *************** *** 233,238 **** --- 288,295 ---- signal(SIGUSR2, SIG_IGN); signal(SIGCHLD, SIG_IGN); signal(SIGBREAK, SIG_IGN); + #endif + } /* *************** *** 277,287 **** /* * The screens */ ! static termPipe term_screen_main, ! term_screen_recall, ! term_screen_choice, ! term_screen_mirror, ! term_screen_map; /* * Check for events -- called by "Term_scan_emx()" --- 334,341 ---- /* * The screens */ ! static termPipe term_screen[MAX_TERM_DATA]; ! /* * Check for events -- called by "Term_scan_emx()" *************** *** 289,354 **** * Note -- this is probably NOT the most efficient way * to "wait" for a keypress (TERM_XTRA_EVENT). * - * _read_kbd(0,0,0) does this: - * - if no key is available, return -1 - * - if extended key available, return 0 - * - normal key available, return ASCII value (1 ... 255) * ! * _read_kbd(0,1,0) waits on a key and then returns ! * - 0, if it's an extended key ! * - the ASCII value, if it's a normal key * ! * *If* _read_kbd() returns 0, *then*, and only then, the next ! * call to _read_kbd() will return the extended scan code. * - * See "main-ibm.c" for a "better" use of "macro sequences". * ! * Note that this file does *NOT* currently extract modifiers ! * (such as Control and Shift). See "main-ibm.c" for a method. * - * XXX XXX XXX XXX The "key handling" really needs to be fixed. - * See "main-ibm.c" for more information about "macro encoding". */ static errr CheckEvents(int returnImmediately) { ! int k = 0, ke = 0; ! /* Get key */ ! k=_read_kbd(0, returnImmediately?0:1, 0); - /* Nothing ready */ - if (k < 0) return (1); ! /* Get an extended scan code */ ! if (!k) ke = _read_kbd(0, 1, 0); ! /* Normal keypresses */ ! if (k) { ! /* Enqueue the key */ Term_keypress(k); /* Success */ return (0); } ! /* Hack -- introduce a macro sequence */ ! Term_keypress(31); - /* XXX We're not able to extract shift/ctrl/alt key information here. */ ! /* Hack -- send the key sequence */ ! Term_keypress('0' + (ke % 1000) / 100); ! Term_keypress('0' + (ke % 100) / 10); ! Term_keypress('0' + (ke % 10)); ! /* Hack -- end the macro sequence */ Term_keypress(13); /* Success */ return (0); } /* * Do a special thing (beep, flush, etc) */ --- 343,593 ---- * Note -- this is probably NOT the most efficient way * to "wait" for a keypress (TERM_XTRA_EVENT). * * ! * This code was ripped from "main-ibm.c" -- consult it to ! * figure out what's going on. * ! * See "main-ibm.c" for more information about "macro encoding". * * ! * The following documentation was cut&pasted from ! * the OS/2 Programming Reference, PRCP.INF ! * ! ------------------------------------------------------------------------------- ! ! ! This call returns a character data record from the keyboard. ! ! KbdCharIn (CharData, IOWait, KbdHandle) ! ! CharData (PKBDKEYINFO) - output ! Address of the character data structure: ! ! asciicharcode (UCHAR) ! ASCII character code. The scan code received from the keyboard is ! translated to the ASCII character code. ! ! scancode (UCHAR) ! Code received from the keyboard. The scan code received from the ! keyboard is translated to the ASCII character code. ! ! status (UCHAR) ! State of the keystroke event: ! ! Bit Description ! ! 7-6 00 = Undefined ! ! 01 = Final character, interim character flag off ! ! 10 = Interim character ! ! 11 = Final character, interim character flag on. ! ! 5 1 = Immediate conversion requested. ! ! 4-2 Reserved. ! ! 1 0 = Scan code is a character. ! ! 1 = Scan code is not a character; is an extended key code ! from the keyboard. ! ! 0 1 = Shift status returned without character. ! ! reserved (UCHAR) ! NLS shift status. Reserved, set to zero. ! ! shiftkeystat (USHORT) ! Shift key status. ! ! Bit Description ! 15 SysReq key down ! 14 CapsLock key down ! 13 NumLock key down ! 12 ScrollLock key down ! 11 Right Alt key down ! 10 Right Ctrl key down ! 9 Left Alt key down ! 8 Left Ctrl key down ! 7 Insert on ! 6 CapsLock on ! 5 NumLock on ! 4 ScrollLock on ! 3 Either Alt key down ! 2 Either Ctrl key down ! 1 Left Shift key down ! 0 Right Shift key down ! ! time (ULONG) ! Time stamp indicating when a key was pressed. It is specified in ! milliseconds from the time the system was started. ! ! IOWait (USHORT) - input ! Wait if a character is not available. ! ! Value Definition ! 0 Requestor waits for a character if one is not available. ! 1 Requestor gets an immediate return if no character is ! available. ! ! KbdHandle (HKBD) - input ! Default keyboard or the logical keyboard. ! ! rc (USHORT) - return ! Return code descriptions are: ! ! 0 NO_ERROR ! 375 ERROR_KBD_INVALID_IOWAIT ! 439 ERROR_KBD_INVALID_HANDLE ! 445 ERROR_KBD_FOCUS_REQUIRED ! 447 ERROR_KBD_KEYBOARD_BUSY ! 464 ERROR_KBD_DETACHED ! 504 ERROR_KBD_EXTENDED_SG ! ! Remarks ! ! On an enhanced keyboard, the secondary enter key returns the normal ! character 0DH and a scan code of E0H. ! ! Double-byte character codes (DBCS) require two function calls to obtain ! the entire code. ! ! If shift report is set with KbdSetStatus, the CharData record returned ! reflects changed shift information only. ! ! Extended ASCII codes are identified with the status byte, bit 1 on and the ! ASCII character code being either 00H or E0H. Both conditions must be ! satisfied for the character to be an extended keystroke. For extended ! ASCII codes, the scan code byte returned is the second code (extended ! code). Usually the extended ASCII code is the scan code of the primary ! key that was pressed. ! ! A thread in the foreground session that repeatedly polls the keyboard ! with KbdCharIn (with no wait), can prevent all regular priority class ! threads from executing. If polling must be used and a minimal amount of ! other processing is being performed, the thread should periodically yield to ! the CPU by issuing a DosSleep call for an interval of at least 5 ! milliseconds. ! ! ! Family API Considerations ! ! Some options operate differently in the DOS mode than in the OS /2 mode. ! Therefore, the following restrictions apply to KbdCharIn when coding in ! the DOS mode: ! ! o The CharData structure includes everything except the time stamp. ! o Interim character is not supported ! o Status can be 0 or 40H ! o KbdHandle is ignored. ! ! ! ------------------------------------------------------------------------------- ! ! ! typedef struct _KBDKEYINFO { / * kbci * / ! UCHAR chChar; / * ASCII character code * / ! UCHAR chScan; / * Scan Code * / ! UCHAR fbStatus; / * State of the character * / ! UCHAR bNlsShift; / * Reserved (set to zero) * / ! USHORT fsState; / * State of the shift keys * / ! ULONG time; / * Time stamp of keystroke (ms since ipl) * / ! }KBDKEYINFO; ! ! #define INCL_KBD ! ! USHORT rc = KbdCharIn(CharData, IOWait, KbdHandle); ! ! PKBDKEYINFO CharData; / * Buffer for data * / ! USHORT IOWait; / * Indicate if wait * / ! HKBD KbdHandle; / * Keyboard handle * / ! ! USHORT rc; / * return code * / ! ! ! ------------------------------------------------------------------------------- * */ static errr CheckEvents(int returnImmediately) { ! int i, k, s; ! bool mc = FALSE; ! bool ms = FALSE; ! bool ma = FALSE; ! ! /* start OS/2 specific section */ ! ! struct _KBDKEYINFO keyinfo; /* see structure description above */ ! ! /* Check (and possibly wait) for a keypress */ ! /* see function description above */ ! KbdCharIn( &keyinfo, returnImmediately, (HKBD)0 ); ! ! #if 0 ! printf("AC:%x SC:%x ST:%x R1:%x SH:%x TI:%ld\n", /* OS/2 debug */ ! keyinfo.chChar, ! keyinfo.chScan, ! keyinfo.fbStatus, ! keyinfo.bNlsShift, ! keyinfo.fsState, ! keyinfo.time ); ! #endif ! ! /* If there wasn't a key, leave now. */ ! if ((keyinfo.fbStatus & 0xC0) == 0) return(1); ! /* by a set of lucky coincidences, the data maps directly over. */ ! k = keyinfo.chChar; ! s = keyinfo.chScan; ! i = (keyinfo.fsState & 0xFF); ! /* end OS/2 specific section */ ! ! ! /* Process "normal" keys */ ! if ( k != 0 && ((s <= 58) || (s == 0xE0)) ) /* Tweak: allow for ALT-keys */ { ! /* Enqueue it */ Term_keypress(k); /* Success */ return (0); } ! /* Extract the modifier flags */ ! if (i & (1 << K_CTRL)) mc = TRUE; ! if (i & (1 << K_LSHIFT)) ms = TRUE; ! if (i & (1 << K_RSHIFT)) ms = TRUE; ! if (i & (1 << K_ALT)) ma = TRUE; ! /* Begin a "macro trigger" */ ! Term_keypress(31); ! ! /* Hack -- Send the modifiers */ ! if (mc) Term_keypress('C'); ! if (ms) Term_keypress('S'); ! if (ma) Term_keypress('A'); ! ! /* Introduce the hexidecimal scan code */ ! Term_keypress('x'); ! ! /* Encode the hexidecimal scan code */ ! Term_keypress(hexsym[s/16]); ! Term_keypress(hexsym[s%16]); ! /* End the "macro trigger" */ Term_keypress(13); /* Success */ return (0); } + + /* * Do a special thing (beep, flush, etc) */ *************** *** 530,545 **** */ errr init_emx(void) { term *t; /* Initialize the pipe windows */ ! initPipeTerm(&term_screen_recall, "recall", &term_recall); ! initPipeTerm(&term_screen_choice, "choice", &term_choice); ! initPipeTerm(&term_screen_mirror, "mirror", &term_mirror); ! initPipeTerm(&term_screen_map, "map", &term_map); /* Initialize main window */ ! t = (term*)(&term_screen_main); /* Initialize the term -- big key buffer */ term_init(t, 80, 24, 1024); --- 769,787 ---- */ errr init_emx(void) { + int i; + term *t; /* Initialize the pipe windows */ ! for (i = MAX_TERM_DATA-1; i > 0; --i) ! { ! const char *name = angband_term_name[i]; ! initPipeTerm(&term_screen[i], name, &angband_term[i]); ! } /* Initialize main window */ ! t = (term*)(&term_screen[0]); /* Initialize the term -- big key buffer */ term_init(t, 80, 24, 1024); *************** *** 591,597 **** /* Check command line */ if (argc!=2 && argc!=3) { ! printf("Usage: %s choice|recall|mirror [number of lines]\n" "Start this before angband.exe\n", argv[0]); exit(1); } --- 833,839 ---- /* Check command line */ if (argc!=2 && argc!=3) { ! printf("Usage: %s Term-1|...|Term-7 [number of lines]\n" "Start this before angband.exe\n", argv[0]); exit(1); } *************** *** 805,815 **** /* * The screens */ ! static termWindow term_screen_main, ! term_screen_recall, ! term_screen_choice, ! term_screen_mirror, ! term_screen_map; /* * Check for events -- called by "Term_scan_emx()" --- 1047,1053 ---- /* * The screens */ ! static termWindow term_screen[MAX_TERM_DATA]; /* * Check for events -- called by "Term_scan_emx()" *************** *** 900,914 **** */ errr init_emx(void) { /* Initialize the windows */ ! emx_init_term(&term_screen_main, NULL, &term_screen, 0); ! emx_init_term(&term_screen_recall, term_screen_main.instance, &term_recall, 1); ! emx_init_term(&term_screen_choice, term_screen_main.instance, &term_choice, 2); ! emx_init_term(&term_screen_mirror, term_screen_main.instance, &term_mirror, 3); ! emx_init_term(&term_screen_map, term_screen_main.instance, &term_map, 4); /* Activate main window */ ! Term_activate(term_screen); /* Success */ return (0); --- 1138,1155 ---- */ errr init_emx(void) { + int i; + /* Initialize the windows */ ! emx_init_term(&term_screen[0], NULL, &angband_term[0], 0); ! ! for (i = 1; i < MAX_TERM_DATA; ++i) ! { ! emx_init_term(&term_screen[i], term_screen[0].instance, &angband_term[i], i); ! } /* Activate main window */ ! Term_activate(angband_term[0]); /* Success */ return (0); *************** *** 934,976 **** static void quit_hook(cptr s) { ! /* Shut down the term windows */ ! if (term_choice) ! { ! term_nuke(term_choice); ! emx_nuke(((termWindow*)term_choice)->instance); ! } ! if (term_recall) ! { ! term_nuke(term_recall); ! emx_nuke(((termWindow*)term_recall)->instance); ! } ! if (term_mirror) ! { ! term_nuke(term_mirror); ! emx_nuke(((termWindow*)term_mirror)->instance); ! } ! if (term_map) ! { ! term_nuke(term_map); ! emx_nuke(((termWindow*)term_map)->instance); ! } ! if (term_screen) { ! term_nuke(term_screen); ! emx_nuke(((termWindow*)term_screen)->instance); ! } /* Shut down window system - doesn't return */ emx_endPM(s); } void angbandThread(void *arg) { bool new_game = FALSE; int show_score = 0; /* Save the "program name" */ argv0 = (char*)arg; --- 1175,1205 ---- static void quit_hook(cptr s) { ! int i; ! ! for (i = MAX_TERM_DATA - 1; i >= 0; --i) { ! /* Shut down the term windows */ ! if (angband_term[i]) ! { ! term_nuke(angband_term[i]); ! emx_nuke(((termWindow*)angband_term[i])->instance); ! } ! ] /* Shut down window system - doesn't return */ emx_endPM(s); } + void angbandThread(void *arg) { bool new_game = FALSE; int show_score = 0; + char player_name[32]; + /* Save the "program name" */ argv0 = (char*)arg; *************** *** 990,995 **** --- 1219,1227 ---- &arg_wizard, player_name)) quit(NULL); + /* XXX XXX XXX (?) */ + strcpy(op_ptr->full_name, player_name); + /* Process the player name */ process_player_name(TRUE); *************** *** 1002,1012 **** /* Catch nasty signals */ signals_init(); ! /* Display the 'news' file */ ! show_news(); ! ! /* Initialize the arrays */ ! init_some_arrays(); /* Wait for response */ pause_line(23); --- 1234,1241 ---- /* Catch nasty signals */ signals_init(); ! /* Initialize */ ! init_angband(); /* Wait for response */ pause_line(23); *************** *** 1028,1030 **** --- 1257,1260 ---- * End: * */ + diff -c -r angband-282/src/main-gcu.c angband-283/src/main-gcu.c *** angband-282/src/main-gcu.c Thu Sep 4 10:17:52 1997 --- angband-283/src/main-gcu.c Fri Feb 6 04:10:31 1998 *************** *** 8,19 **** * are included in all such copies. */ - /* Purpose: Allow use of Unix "curses" with Angband -BEN- */ - /* * To use this file, you must define "USE_GCU" in the Makefile. * * Hack -- note that "angband.h" is included AFTER the #ifdef test. * This was necessary because of annoying "curses.h" silliness. * --- 8,21 ---- * are included in all such copies. */ /* + * This file helps Angband run on Unix/Curses machines. + * + * * To use this file, you must define "USE_GCU" in the Makefile. * + * * Hack -- note that "angband.h" is included AFTER the #ifdef test. * This was necessary because of annoying "curses.h" silliness. * *************** *** 30,47 **** * and uses the "termcap" information directly, or even bypasses the * "termcap" information and sends direct vt100 escape sequences. * ! * XXX XXX XXX This file provides only a single "term" window. * * The "init" and "nuke" hooks are built so that only the first init and * the last nuke actually do anything, but the other functions are not * "correct" for multiple windows. Minor changes would also be needed * to allow the system to handle the "locations" of the various windows. * ! * But in theory, it should be possible to allow a 50 line screen to be ! * split into two (or more) sub-screens. ! * ! * XXX XXX XXX Consider the use of "savetty()" and "resetty()". */ #include "angband.h" --- 32,50 ---- * and uses the "termcap" information directly, or even bypasses the * "termcap" information and sends direct vt100 escape sequences. * ! * This file provides only a single "term" window. XXX XXX XXX ! * ! * But in theory, it should be possible to allow a 50 line screen to be ! * split into two (or more) sub-screens. * * The "init" and "nuke" hooks are built so that only the first init and * the last nuke actually do anything, but the other functions are not * "correct" for multiple windows. Minor changes would also be needed * to allow the system to handle the "locations" of the various windows. * ! * Consider the use of "savetty()" and "resetty()". XXX XXX XXX */ + #include "angband.h" diff -c -r angband-282/src/main-ibm.c angband-283/src/main-ibm.c *** angband-282/src/main-ibm.c Thu Sep 4 10:17:52 1997 --- angband-283/src/main-ibm.c Fri Feb 6 04:10:31 1998 *************** *** 8,51 **** * are included in all such copies. */ - /* Purpose: Visual Display Support for "term.c", for the IBM */ - /* ! * Original code by "Billy Tanksley (wtanksle@ucsd.edu)" ! * Use "Makefile.ibm" to compile Angband using this file. * - * Support for DJGPP v2 by "Scott Egashira (egashira@u.washington.edu)" * ! * Extensive modifications by "Ben Harrison (benh@voicenet.com)", ! * including "collation" of the Watcom C/C++ and DOS-286 patches. * ! * Watcom C/C++ changes by "David Boeren (akemi@netcom.com)" ! * Use "Makefile.wat" to compile this file with Watcom C/C++, and ! * be sure to define "USE_IBM" and "USE_WAT". * ! * DOS-286 (conio.h) changes by (Roland Jay Roberts (jay@map.com) ! * Use "Makefile.286" (not ready) to compile this file for DOS-286, ! * and be sure to define "USE_IBM", "USE_WAT", and "USE_286". Also, ! * depending on your compiler, you may need to define "USE_CONIO". * - * True color palette support by "Mike Marcelais (mrmarcel@eos.ncsu.edu)", - * with interface to the "color_table" array by Ben Harrison. * * Both "shift" keys are treated as "identical", and all the modifier keys * (control, shift, alt) are ignored when used with "normal" keys, unless * they modify the underlying "ascii" value of the key. You must use the * new "user pref files" to be able to interact with the keypad and such. * - * The "lib/user/pref-ibm.prf" file contains macro definitions and possible - * alternative color set definitions. The "lib/user/font-ibm.prf" contains - * attr/char mappings for walls and floors and such. - * * Note the "Term_user_ibm()" function hook, which could allow the user * to interact with the "main-ibm.c" visual system. Currently this hook * is unused, but, for example, it could allow the user to toggle "sound" * or "graphics" modes, or to select the number of screen rows, with the * extra screen rows being used for the mirror window. */ --- 8,64 ---- * are included in all such copies. */ /* ! * This file helps Angband work with DOS computers. ! * ! * To use this file with DJGPP, use "Makefile.ibm", which defines "USE_IBM". ! * ! * To use this file with Watcom C/C++, use "Makefile.wat", which defines ! * "USE_IBM" and "USE_WAT". ! * ! * To use this file with a DOS-286 machine, use "Makefile.286" (not ready), ! * which defines "USE_IBM", "USE_WAT", "USE_286", and, depending on your ! * compiler, perhaps "USE_CONIO". ! * ! * See also "main-dos.c" and "main-win.c". * * ! * The "lib/user/pref-ibm.prf" file contains keymaps, macro definitions, ! * and/or color redefinitions. * ! * The "lib/user/font-ibm.prf" contains attr/char mappings for use with the ! * normal DOS fonts. * ! * The "lib/user/graf-ibm.prf" contains attr/char mappings for use with the ! * special "lib/xtra/angband.fnt" font file, which is activated by the "-g" ! * flag. * * * Both "shift" keys are treated as "identical", and all the modifier keys * (control, shift, alt) are ignored when used with "normal" keys, unless * they modify the underlying "ascii" value of the key. You must use the * new "user pref files" to be able to interact with the keypad and such. * * Note the "Term_user_ibm()" function hook, which could allow the user * to interact with the "main-ibm.c" visual system. Currently this hook * is unused, but, for example, it could allow the user to toggle "sound" * or "graphics" modes, or to select the number of screen rows, with the * extra screen rows being used for the mirror window. + * + * + * Initial framework (and some code) by Ben Harrison (benh@phial.com). + * + * Original code by Billy Tanksley (wtanksle@ucsd.edu). + * + * Support for DJGPP v2 by Scott Egashira (egashira@u.washington.edu). + * + * Support for DOS-286 (conio.h) by Roland Jay Roberts (jay@map.com). + * + * Support for Watcom C/C++ by David Boeren (akemi@netcom.com). + * + * True color palette support, and graphics support, by Mike Marcelais + * (michmarc@microsoft.com). */ *************** *** 68,80 **** # include ! # ifndef USE_CONIO # include # define bioskey(C) _bios_keybrd(C) ! # endif # ifndef USE_286 # define int86(a,b,c) int386(a,b,c) --- 81,94 ---- # include ! # ifdef USE_CONIO ! # else /* USE_CONIO */ # include # define bioskey(C) _bios_keybrd(C) ! # endif /* USE_CONIO */ # ifndef USE_286 # define int86(a,b,c) int386(a,b,c) *************** *** 206,219 **** static int saved_cur_low; ! #ifndef USE_CONIO /* * This array is used for "wiping" the screen */ static byte wiper[160]; ! #endif /* --- 220,234 ---- static int saved_cur_low; ! #ifdef USE_CONIO ! #else /* USE_CONIO */ /* * This array is used for "wiping" the screen */ static byte wiper[160]; ! #endif /* USE_CONIO */ /* *************** *** 302,307 **** --- 317,327 ---- { int i; + #if 0 + /* Is this important? */ + printf("%c%c%c%c",8,8,8,8); + #endif + #if 1 /* Edit the EGA palette */ *************** *** 613,684 **** { /* Make a "bell" noise */ case TERM_XTRA_NOISE: ! /* Make a bell noise */ ! (void)write(1, "\007", 1); ! ! /* Success */ ! return (0); /* Set the cursor shape */ case TERM_XTRA_SHAPE: ! /* Set cursor shape */ ! curs_set(v); ! ! /* Success */ ! return (0); ! ! #ifdef USE_VIRTUAL /* Flush one line of output */ case TERM_XTRA_FROSH: # ifdef USE_WAT ! /* Copy the virtual screen to the physical screen */ ! memcpy(PhysicalScreen + (v*160), VirtualScreen + (v*160), 160); # else /* USE_WAT */ ! /* Apply the virtual screen to the physical screen */ ! ScreenUpdateLine(VirtualScreen + ((v*cols) << 1), v); # endif /* USE_WAT */ - /* Success */ - return (0); - #endif /* USE_VIRTUAL */ /* Clear the screen */ case TERM_XTRA_CLEAR: #ifdef USE_CONIO ! /* Clear the screen */ ! clrscr(); #else /* USE_CONIO */ ! /* Clear each line (virtual or physical) */ ! for (i = 0; i < rows; i++) ! { ! /* Clear the line */ ! memcpy((VirtualScreen + ((i*cols) << 1)), wiper, (cols << 1)); ! } # ifdef USE_VIRTUAL # ifdef USE_WAT ! /* Copy the virtual screen to the physical screen */ ! memcpy(PhysicalScreen, VirtualScreen, 25*80*2); # else /* USE_WAT */ ! /* Erase the physical screen */ ! ScreenClear(); # endif /* USE_WAT */ --- 633,709 ---- { /* Make a "bell" noise */ case TERM_XTRA_NOISE: + { + /* Make a bell noise */ + (void)write(1, "\007", 1); ! /* Success */ ! return (0); ! } /* Set the cursor shape */ case TERM_XTRA_SHAPE: + { + /* Set cursor shape */ + curs_set(v); ! /* Success */ ! return (0); ! } /* Flush one line of output */ case TERM_XTRA_FROSH: + { + + #ifdef USE_VIRTUAL # ifdef USE_WAT ! /* Copy the virtual screen to the physical screen */ ! memcpy(PhysicalScreen + (v*160), VirtualScreen + (v*160), 160); # else /* USE_WAT */ ! /* Apply the virtual screen to the physical screen */ ! ScreenUpdateLine(VirtualScreen + ((v*cols) << 1), v); # endif /* USE_WAT */ #endif /* USE_VIRTUAL */ + /* Success */ + return (0); + } + /* Clear the screen */ case TERM_XTRA_CLEAR: + { #ifdef USE_CONIO ! /* Clear the screen */ ! clrscr(); #else /* USE_CONIO */ ! /* Clear each line (virtual or physical) */ ! for (i = 0; i < rows; i++) ! { ! /* Clear the line */ ! memcpy((VirtualScreen + ((i*cols) << 1)), wiper, (cols << 1)); ! } # ifdef USE_VIRTUAL # ifdef USE_WAT ! /* Copy the virtual screen to the physical screen */ ! memcpy(PhysicalScreen, VirtualScreen, 25*80*2); # else /* USE_WAT */ ! /* Erase the physical screen */ ! ScreenClear(); # endif /* USE_WAT */ *************** *** 686,723 **** #endif /* USE_CONIO */ ! /* Success */ ! return (0); /* Process events */ case TERM_XTRA_EVENT: ! ! /* Process one event */ ! return (Term_xtra_ibm_event(v)); /* Flush events */ case TERM_XTRA_FLUSH: ! /* Strip events */ ! while (!Term_xtra_ibm_event(FALSE)); ! ! /* Success */ ! return (0); /* React to global changes */ case TERM_XTRA_REACT: ! ! /* React to "color_table" changes */ ! return (Term_xtra_ibm_react()); /* Delay for some milliseconds */ case TERM_XTRA_DELAY: ! /* Delay if needed */ ! if (v > 0) delay(v); ! ! /* Success */ ! return (0); } /* Unknown request */ --- 711,753 ---- #endif /* USE_CONIO */ ! /* Success */ ! return (0); ! } /* Process events */ case TERM_XTRA_EVENT: ! { ! /* Process one event */ ! return (Term_xtra_ibm_event(v)); ! } /* Flush events */ case TERM_XTRA_FLUSH: + { + /* Strip events */ + while (!Term_xtra_ibm_event(FALSE)) /* loop */; ! /* Success */ ! return (0); ! } /* React to global changes */ case TERM_XTRA_REACT: ! { ! /* React to "color_table" changes */ ! return (Term_xtra_ibm_react()); ! } /* Delay for some milliseconds */ case TERM_XTRA_DELAY: + { + /* Delay if needed */ + if (v > 0) delay(v); ! /* Success */ ! return (0); ! } } /* Unknown request */ *************** *** 942,961 **** */ static void Term_nuke_ibm(term *t) { union REGS r; /* Move the cursor to the bottom of the screen */ Term_curs_ibm(0, rows-1); #ifdef USE_WAT /* Restore the original video mode */ _setvideomode(_DEFAULTMODE); ! #else /* Restore the original video mode */ r.h.ah = 0x00; r.h.al = 0x03; int86(0x10, &r, &r); ! #endif /* Make the cursor visible */ curs_set(1); --- 972,1004 ---- */ static void Term_nuke_ibm(term *t) { + + #ifdef USE_WAT + + /* Nothing */ + + #else /* USE_WAT */ + union REGS r; + #endif /* USE_WAT */ + /* Move the cursor to the bottom of the screen */ Term_curs_ibm(0, rows-1); #ifdef USE_WAT + /* Restore the original video mode */ _setvideomode(_DEFAULTMODE); ! ! #else /* USE_WAT */ ! /* Restore the original video mode */ r.h.ah = 0x00; r.h.al = 0x03; int86(0x10, &r, &r); ! ! #endif /* USE_WAT */ /* Make the cursor visible */ curs_set(1); *************** *** 1096,1101 **** --- 1139,1145 ---- #endif /* USE_WAT */ + /* * Since you cannot send 32bit pointers to a 16bit interrupt handler * and the video BIOS wants a (16bit) pointer to the font, we have *************** *** 1107,1115 **** */ void enable_graphic_font(const char *font) { ! __dpmi_regs dblock = ! { ! {0}}; unsigned seg, sel, i; --- 1151,1157 ---- */ void enable_graphic_font(const char *font) { ! __dpmi_regs dblock = {{0}}; unsigned seg, sel, i; *************** *** 1169,1175 **** { int i; int mode; - int rv, gv, bv; term *t = &term_screen_body; --- 1211,1216 ---- *************** *** 1184,1189 **** --- 1225,1247 ---- int86(0x2F, &r, &r); /* Call the Windows API */ }; + /* Initialize "color_table" */ + for (i = 0; i < 16; i++) + { + long rv, gv, bv; + + /* Extract desired values */ + rv = angband_color_table[i][1] >> 2; + gv = angband_color_table[i][2] >> 2; + bv = angband_color_table[i][3] >> 2; + + /* Extract the "complex" codes */ + ibm_color_complex[i] = ((rv) | (gv << 8) | (bv << 16)); + + /* Save the "simple" codes */ + angband_color_table[i][0] = ibm_color_simple[i]; + } + #ifdef USE_WAT /* Set the video mode */ *************** *** 1271,1295 **** #endif ! /* Initialize "color_table" */ ! for (i = 0; i < 16; i++) ! { ! long rv, gv, bv; ! ! /* Extract desired values */ ! rv = angband_color_table[i][1] >> 2; ! gv = angband_color_table[i][2] >> 2; ! bv = angband_color_table[i][3] >> 2; ! ! /* Extract the "complex" codes */ ! ibm_color_complex[i] = ((rv) | (gv << 8) | (bv << 16)); ! ! /* Save the "simple" codes */ ! angband_color_table[i][0] = ibm_color_simple[i]; ! } ! ! ! #ifndef USE_CONIO /* Build a "wiper line" */ for (i = 0; i < 80; i++) --- 1329,1336 ---- #endif ! #ifdef USE_CONIO ! #else /* USE_CONIO */ /* Build a "wiper line" */ for (i = 0; i < 80; i++) *************** *** 1298,1307 **** wiper[2*i] = ' '; /* Black */ ! wiper[2*i+1] = 0; } ! #endif #ifdef USE_VIRTUAL --- 1339,1348 ---- wiper[2*i] = ' '; /* Black */ ! wiper[2*i+1] = TERM_WHITE; } ! #endif /* USE_CONIO */ #ifdef USE_VIRTUAL *************** *** 1309,1315 **** /* Make the virtual screen */ C_MAKE(VirtualScreen, rows * cols * 2, byte); ! #endif /* Erase the screen */ --- 1350,1356 ---- /* Make the virtual screen */ C_MAKE(VirtualScreen, rows * cols * 2, byte); ! #endif /* USE_VIRTUAL */ /* Erase the screen */ *************** *** 1336,1348 **** /* Initialize the term */ term_init(t, 80, 24, 256); ! #ifndef USE_CONIO /* Always use "Term_pict()" */ t->always_pict = TRUE; #endif /* USE_CONIO */ /* Prepare the init/nuke hooks */ t->init_hook = Term_init_ibm; t->nuke_hook = Term_nuke_ibm; --- 1377,1394 ---- /* Initialize the term */ term_init(t, 80, 24, 256); ! #ifdef USE_CONIO ! #else /* USE_CONIO */ /* Always use "Term_pict()" */ t->always_pict = TRUE; #endif /* USE_CONIO */ + /* Use "white space" to erase */ + t->attr_blank = TERM_WHITE; + t->char_blank = ' '; + /* Prepare the init/nuke hooks */ t->init_hook = Term_init_ibm; t->nuke_hook = Term_nuke_ibm; *************** *** 1366,1369 **** --- 1412,1416 ---- #endif /* USE_IBM */ + diff -c -r angband-282/src/main-mac.c angband-283/src/main-mac.c *** angband-282/src/main-mac.c Thu Sep 4 10:17:52 1997 --- angband-283/src/main-mac.c Wed Feb 11 06:30:28 1998 *************** *** 8,45 **** * are included in all such copies. */ - /* Purpose: Simple support for MACINTOSH Angband */ /* ! * This file should only be compiled with the "Macintosh" version * ! * This file written by "Ben Harrison (benh@voicenet.com)". * ! * Some code adapted from "MacAngband 2.6.1" by Keith Randall ! * ! * Maarten Hazewinkel (mmhazewi@cs.ruu.nl) provided some initial ! * suggestions for the PowerMac port. ! * ! * Steve Linberg (slinberg@crocker.com) provided the code surrounded ! * by "USE_SFL_CODE". ! * ! * The graphics code is adapted from an extremely minimal subset of ! * the code from "Sprite World II", an amazing animation package. ! * ! * See "z-term.c" for info on the concept of the "generic terminal". ! * ! * Note that the "preference" file is now a simple text file called ! * "Angband preferences", which contains a version stamp, so that ! * obsolete preference files can be ignored. This should probably ! * be replaced with a "structured" preference file of some kind. * ! * Note that "init1.c", "init2.c", "load1.c", "load2.c", and "birth.c" ! * should probably be "unloaded" as soon as they are no longer needed, ! * to save space, but I do not know how to do this. * - * Stange bug -- The first "ClipRect()" call crashes if the user closes - * all the windows, switches to another application, switches back, and - * then re-opens the main window, for example, using "command-a". * * By default, this file assumes that you will be using a 68020 or better * machine, running System 7 and Color Quickdraw. In fact, the game will --- 8,26 ---- * are included in all such copies. */ /* ! * This file helps Angband work with Macintosh computers. * ! * To use this file, use an appropriate "Makefile" or "Project File", which ! * should define "MACINTOSH". * ! * The official compilation uses the CodeWarrior Pro compiler. * ! * If you are never going to use "graphics" (especially if you are not ! * compiling support for graphics anyway) then you can delete the "pict" ! * resource with id "1001" with no dangerous side effects. * * * By default, this file assumes that you will be using a 68020 or better * machine, running System 7 and Color Quickdraw. In fact, the game will *************** *** 56,68 **** * flag will be automatically defined, which will disable many of the * advanced features of the game itself, reducing the total memory usage. * ! * If you are never going to use "graphics" (especially if you are not ! * compiling support for graphics anyway) then you can delete the "pict" ! * resource with id "1001" with no dangerous side effects. ! */ ! ! ! /* * Important Resources in the resource file: * * FREF 130 = 'A271' / 'APPL' (application) --- 37,69 ---- * flag will be automatically defined, which will disable many of the * advanced features of the game itself, reducing the total memory usage. * ! * ! * Note that the "preference" file is now a simple text file called ! * "Angband Preferences", which contains a version stamp, so that ! * obsolete preference files can be ignored. This should probably ! * be replaced with a "structured" preference file of some kind. ! * ! * Note that "init1.c", "init2.c", "load1.c", "load2.c", and "birth.c" ! * should probably be "unloaded" as soon as they are no longer needed, ! * to save space, but I do not know how to do this. XXX XXX XXX ! * ! * Stange bug -- The first "ClipRect()" call crashes if the user closes ! * all the windows, switches to another application, switches back, and ! * re-opens the main window, for example, using "command-a". XXX XXX XXX ! * ! * ! * Initial framework (and most code) by Ben Harrison (benh@phial.com). ! * ! * Some code adapted from "MacAngband 2.6.1" by Keith Randall ! * ! * Initial PowerMac port by Maarten Hazewinkel (mmhazewi@cs.ruu.nl). ! * ! * Most "USE_SFL_CODE" code provided by Steve Linberg (slinberg@crocker.com). ! * ! * Most of the graphics code is adapted from an extremely minimal subset of ! * the "Sprite World II" package, an amazing (and free) animation package. ! * ! * * Important Resources in the resource file: * * FREF 130 = 'A271' / 'APPL' (application) *************** *** 87,96 **** * MENU 130 = Edit (undo, -, cut, copy, paste, clear) * * PICT 1001 = Graphics tile set ! */ ! ! ! /* * File name patterns: * all 'APEX' files have a filename of the form "*:apex:*" (?) * all 'BONE' files have a filename of the form "*:bone:*" (?) --- 88,95 ---- * MENU 130 = Edit (undo, -, cut, copy, paste, clear) * * PICT 1001 = Graphics tile set ! * ! * * File name patterns: * all 'APEX' files have a filename of the form "*:apex:*" (?) * all 'BONE' files have a filename of the form "*:bone:*" (?) *************** *** 102,111 **** * to avoid nasty file type information being spread all through the * rest of the code. (?) This might require adding hooks into the * "fd_open()" and "my_fopen()" functions in "util.c". XXX XXX XXX ! */ ! ! ! /* * Reasons for each header file: * * angband.h = Angband header file --- 101,108 ---- * to avoid nasty file type information being spread all through the * rest of the code. (?) This might require adding hooks into the * "fd_open()" and "my_fopen()" functions in "util.c". XXX XXX XXX ! * ! * * Reasons for each header file: * * angband.h = Angband header file *************** *** 2217,2223 **** game_in_progress = 1; /* Flush input */ ! flush(); /* Play a game */ play_game(TRUE); --- 2214,2220 ---- game_in_progress = 1; /* Flush input */ ! Term_flush(); /* Play a game */ play_game(TRUE); *************** *** 2517,2523 **** AppendMenu(m, buf); /* Command-Key shortcuts */ ! if (i < 8) SetItemCmd(m, i + 1, '0' + i); } --- 2514,2520 ---- AppendMenu(m, buf); /* Command-Key shortcuts */ ! if (i < 8) SetItemCmd(m, i + 1, I2D(i)); } *************** *** 2582,2587 **** --- 2579,2588 ---- /* * Prepare the menus + * + * It is very important that the player not be allowed to "save" the game + * unless the "inkey_flag" variable is set, indicating that the game is + * waiting for a new command. XXX XXX XXX */ static void setup_menus(void) { *************** *** 2636,2650 **** } /* Enable "save" */ ! if (initialized && character_generated) { EnableItem(m, 5); } ! /* Enable "exit"/"quit" */ if (TRUE) { EnableItem(m, 7); EnableItem(m, 8); } --- 2637,2656 ---- } /* Enable "save" */ ! if (initialized && character_generated && inkey_flag) { EnableItem(m, 5); } ! /* Enable "exit" */ if (TRUE) { EnableItem(m, 7); + } + + /* Enable "quit" */ + if (!initialized || !character_generated || inkey_flag) + { EnableItem(m, 8); } *************** *** 2695,2701 **** /* SetItemStyle(m, 2, extend); */ /* Active window */ ! if (td) { /* Enable "bold" */ EnableItem(m, 1); --- 2701,2707 ---- /* SetItemStyle(m, 2, extend); */ /* Active window */ ! if (initialized && td) { /* Enable "bold" */ EnableItem(m, 1); *************** *** 2740,2746 **** } /* Active window */ ! if (td) { /* Analyze sizes */ for (i = 1; i <= n; i++) --- 2746,2752 ---- } /* Active window */ ! if (initialized && td) { /* Analyze sizes */ for (i = 1; i <= n; i++) *************** *** 2822,2828 **** } /* Active window */ ! if (td) { /* Analyze sizes */ for (i = 1; i <= n; i++) --- 2828,2834 ---- } /* Active window */ ! if (initialized && td) { /* Analyze sizes */ for (i = 1; i <= n; i++) *************** *** 2856,2862 **** } /* Active window */ ! if (td) { /* Analyze sizes */ for (i = 1; i <= n; i++) --- 2862,2868 ---- } /* Active window */ ! if (initialized && td) { /* Analyze sizes */ for (i = 1; i <= n; i++) *************** *** 3657,3670 **** Term_keypress(ch); } ! /* Hack -- normal "keypad keys" -> special keypress */ else if (!mc && !ms && !mo && !mx && (ck < 96)) { /* Hack -- "enter" is confused */ if (ck == 76) ch = '\n'; ! /* Send control-caret as a trigger */ ! Term_keypress(30); /* Send the "ascii" keypress */ Term_keypress(ch); --- 3663,3682 ---- Term_keypress(ch); } ! /* Keypad keys -> trigger plus simple keypress */ else if (!mc && !ms && !mo && !mx && (ck < 96)) { /* Hack -- "enter" is confused */ if (ck == 76) ch = '\n'; ! /* Begin special trigger */ ! Term_keypress(31); ! ! /* Send the "keypad" modifier */ ! Term_keypress('K'); ! ! /* Terminate the trigger */ ! Term_keypress(13); /* Send the "ascii" keypress */ Term_keypress(ch); *************** *** 3673,3679 **** /* Bizarre key -> encoded keypress */ else if (ck <= 127) { ! /* Hack -- introduce with control-underscore */ Term_keypress(31); /* Send some modifier keys */ --- 3685,3691 ---- /* Bizarre key -> encoded keypress */ else if (ck <= 127) { ! /* Begin special trigger */ Term_keypress(31); /* Send some modifier keys */ *************** *** 3682,3692 **** if (mo) Term_keypress('O'); if (mx) Term_keypress('X'); ! /* Hack -- Downshift and encode the keycode */ ! Term_keypress('0' + (ck - 64) / 10); ! Term_keypress('0' + (ck - 64) % 10); ! /* Hack -- Terminate the sequence */ Term_keypress(13); } --- 3694,3704 ---- if (mo) Term_keypress('O'); if (mx) Term_keypress('X'); ! /* Downshift and encode the keycode */ ! Term_keypress(I2D((ck - 64) / 10)); ! Term_keypress(I2D((ck - 64) % 10)); ! /* Terminate the trigger */ Term_keypress(13); } *************** *** 4399,4402 **** --- 4411,4415 ---- /* Hack -- Process Events Forever */ while (TRUE) CheckEvents(TRUE); } + diff -c -r angband-282/src/main-sla.c angband-283/src/main-sla.c *** angband-282/src/main-sla.c Wed Sep 3 11:57:33 1997 --- angband-283/src/main-sla.c Fri Feb 6 04:10:31 1998 *************** *** 8,21 **** * are included in all such copies. */ - /* Purpose: Actual Unix "slang" support for Angband */ /* * Author: hans@grumbeer.pfalz.de (Hans-Joachim Baader) * * Most of this code is adapted directly from "main-gcu.c" */ #include "angband.h" --- 8,26 ---- * are included in all such copies. */ /* + * This file helps Angband work with Unix/slang computers. + * + * This file is probably out of date. XXX XXX XXX + * + * * Author: hans@grumbeer.pfalz.de (Hans-Joachim Baader) * * Most of this code is adapted directly from "main-gcu.c" */ + #include "angband.h" *************** *** 460,463 **** --- 465,469 ---- } #endif /* USE_SLA */ + diff -c -r angband-282/src/main-vme.c angband-283/src/main-vme.c *** angband-282/src/main-vme.c Wed Sep 3 11:57:33 1997 --- angband-283/src/main-vme.c Fri Feb 6 04:10:31 1998 *************** *** 8,16 **** * are included in all such copies. */ - /* Purpose: Support for "Vax Angband" */ /* This is MAIN-VME C for VM/ESA machines. First enable definition of VM in file "h-config.h" You need to unpack archive EXT-VM VMARC . --- 8,26 ---- * are included in all such copies. */ /* + * This file helps Angband work with VM/ESA computers. + * + * + * This file is definitely out of date, and the rest of the source + * code is not quite compatible with VM/ESA computers. XXX XXX XXX + * + */ + + + /* + This is MAIN-VME C for VM/ESA machines. First enable definition of VM in file "h-config.h" You need to unpack archive EXT-VM VMARC . *************** *** 36,43 **** SM20616@vm.lanet.lv or SD30066@vm.lanet.lv - A large amount of this file appears to be a complete hack, but - what can you expect from a system designed for the Vax... :-) */ --- 46,51 ---- *************** *** 1201,1204 **** --- 1209,1213 ---- #endif /* USE_VME */ + diff -c -r angband-282/src/main-win.c angband-283/src/main-win.c *** angband-282/src/main-win.c Thu Sep 4 15:53:49 1997 --- angband-283/src/main-win.c Fri Feb 6 04:10:31 1998 *************** *** 9,23 **** */ - /* Purpose: Support for Windows Angband */ - /* ! * Original code by Skirmantas Kligys (kligys@scf.usc.edu). * ! * Additional code by Ross E Becker (beckerr@cis.ohio-state.edu), ! * and Chris R. Martin (crm7479@tam2000.tamu.edu). * - * Extensive modifications by Ben Harrison (benh@voicenet.com). * * Compiling this file, and using the resulting executable, requires * several extra files not distributed with the standard Angband code. --- 9,38 ---- */ /* ! * This file helps Angband work with Windows computers. * ! * To use this file, use an appropriate "Makefile" or "Project File", ! * make sure that "WINDOWS" and/or "WIN32" are defined somewhere, and ! * make sure to obtain various extra files as described below. ! * ! * The official compilation uses the CodeWarrior Pro compiler, which ! * includes a special project file and precompilable header file. ! * ! * ! * See also "main-dos.c" and "main-ibm.c". ! * ! * ! * The "lib/user/pref-win.prf" file contains keymaps, macro definitions, ! * and/or color redefinitions. ! * ! * The "lib/user/font-win.prf" contains attr/char mappings for use with the ! * normal "lib/xtra/font/*.fon" font files. ! * ! * The "lib/user/graf-win.prf" contains attr/char mappings for use with the ! * special "lib/xtra/graf/*.bmp" bitmap files, which are activated by a menu ! * item. * * * Compiling this file, and using the resulting executable, requires * several extra files not distributed with the standard Angband code. *************** *** 30,60 **** * files must be placed into "lib/xtra/sound/". All of these extra * files can be found in the "ext-win" archive. * - * See "h-config.h" for the extraction of the "WINDOWS" flag based - * on the "_Windows", "__WINDOWS__", "__WIN32__", "WIN32", "__WINNT__", - * or "__NT__" flags. If your compiler uses a different compiler flag, - * add it to "h-config.h", or, simply place it in the "Makefile". - * * - * XXX XXX XXX * The "Term_xtra_win_clear()" function should probably do a low-level * clear of the current window, and redraw the borders and other things, ! * if only for efficiency. * - * XXX XXX XXX * A simpler method is needed for selecting the "tile size" for windows. - * * XXX XXX XXX * The various "warning" messages assume the existance of the "screen.w" * window, I think, and only a few calls actually check for its existance, * this may be okay since "NULL" means "on top of all windows". (?) The * user must never be allowed to "hide" the main window, or the "menubar" ! * will disappear. * - * XXX XXX XXX * Special "Windows Help Files" can be placed into "lib/xtra/help/" for * use with the "winhelp.exe" program. These files *may* be available ! * at the ftp site somewhere, but I have not seen them. */ --- 45,75 ---- * files must be placed into "lib/xtra/sound/". All of these extra * files can be found in the "ext-win" archive. * * * The "Term_xtra_win_clear()" function should probably do a low-level * clear of the current window, and redraw the borders and other things, ! * if only for efficiency. XXX XXX XXX * * A simpler method is needed for selecting the "tile size" for windows. * XXX XXX XXX + * * The various "warning" messages assume the existance of the "screen.w" * window, I think, and only a few calls actually check for its existance, * this may be okay since "NULL" means "on top of all windows". (?) The * user must never be allowed to "hide" the main window, or the "menubar" ! * will disappear. XXX XXX XXX * * Special "Windows Help Files" can be placed into "lib/xtra/help/" for * use with the "winhelp.exe" program. These files *may* be available ! * at the ftp site somewhere, but I have not seen them. XXX XXX XXX ! * ! * ! * Initial framework (and most code) by Ben Harrison (benh@phial.com). ! * ! * Original code by Skirmantas Kligys (kligys@scf.usc.edu). ! * ! * Additional code by Ross E Becker (beckerr@cis.ohio-state.edu), ! * and Chris R. Martin (crm7479@tam2000.tamu.edu). */ *************** *** 513,518 **** --- 528,616 ---- }; + /* + * Hack -- define which keys are "special" + */ + static bool special_key[256]; + + /* + * Hack -- initialization list for "special_key" + * + * We ignore the modifier keys (shift, control, alt, num lock, scroll lock), + * and the normal keys (escape, tab, return, letters, numbers, etc), but we + * catch the keypad keys (with and without numlock set, including keypad 5), + * the function keys (including the "menu" key which maps to F10), and the + * "pause" key (between scroll lock and numlock). We also catch a few odd + * keys which I do not recognize, but which are listed among keys which we + * do catch, so they should be harmless to catch. + */ + static byte special_key_list[] = + { + VK_CLEAR, /* 0x0C (KP<5>) */ + + VK_PAUSE, /* 0x13 (pause) */ + + VK_PRIOR, /* 0x21 (KP<9>) */ + VK_NEXT, /* 0x22 (KP<3>) */ + VK_END, /* 0x23 (KP<1>) */ + VK_HOME, /* 0x24 (KP<7>) */ + VK_LEFT, /* 0x25 (KP<4>) */ + VK_UP, /* 0x26 (KP<8>) */ + VK_RIGHT, /* 0x27 (KP<6>) */ + VK_DOWN, /* 0x28 (KP<2>) */ + VK_SELECT, /* 0x29 (?????) */ + VK_PRINT, /* 0x2A (?????) */ + VK_EXECUTE, /* 0x2B (?????) */ + VK_SNAPSHOT, /* 0x2C (?????) */ + VK_INSERT, /* 0x2D (KP<0>) */ + VK_DELETE, /* 0x2E (KP<.>) */ + VK_HELP, /* 0x2F (?????) */ + + VK_NUMPAD0, /* 0x60 (KP<0>) */ + VK_NUMPAD1, /* 0x61 (KP<1>) */ + VK_NUMPAD2, /* 0x62 (KP<2>) */ + VK_NUMPAD3, /* 0x63 (KP<3>) */ + VK_NUMPAD4, /* 0x64 (KP<4>) */ + VK_NUMPAD5, /* 0x65 (KP<5>) */ + VK_NUMPAD6, /* 0x66 (KP<6>) */ + VK_NUMPAD7, /* 0x67 (KP<7>) */ + VK_NUMPAD8, /* 0x68 (KP<8>) */ + VK_NUMPAD9, /* 0x69 (KP<9>) */ + VK_MULTIPLY, /* 0x6A (KP<*>) */ + VK_ADD, /* 0x6B (KP<+>) */ + VK_SEPARATOR, /* 0x6C (?????) */ + VK_SUBTRACT, /* 0x6D (KP<->) */ + VK_DECIMAL, /* 0x6E (KP<.>) */ + VK_DIVIDE, /* 0x6F (KP) */ + + VK_F1, /* 0x70 */ + VK_F2, /* 0x71 */ + VK_F3, /* 0x72 */ + VK_F4, /* 0x73 */ + VK_F5, /* 0x74 */ + VK_F6, /* 0x75 */ + VK_F7, /* 0x76 */ + VK_F8, /* 0x77 */ + VK_F9, /* 0x78 */ + VK_F10, /* 0x79 */ + VK_F11, /* 0x7A */ + VK_F12, /* 0x7B */ + VK_F13, /* 0x7C */ + VK_F14, /* 0x7D */ + VK_F15, /* 0x7E */ + VK_F16, /* 0x7F */ + VK_F17, /* 0x80 */ + VK_F18, /* 0x81 */ + VK_F19, /* 0x82 */ + VK_F20, /* 0x83 */ + VK_F21, /* 0x84 */ + VK_F22, /* 0x85 */ + VK_F23, /* 0x86 */ + VK_F24, /* 0x87 */ + + 0 + }; + /* * Hack -- given a pathname, point at the filename *************** *** 2125,2147 **** } ! /* Main window */ ! td = &data[0]; ! my_td = td; ! td->w = CreateWindowEx(td->dwExStyle, AppName, ! td->s, td->dwStyle, ! td->pos_x, td->pos_y, ! td->size_wid, td->size_hgt, ! HWND_DESKTOP, NULL, hInstance, NULL); ! my_td = NULL; ! if (!td->w) quit("Failed to create Angband window"); ! term_data_link(td); ! angband_term[0] = &td->t; ! ! /* Sub windows */ ! for (i = 1; i < MAX_TERM_DATA; i++) { td = &data[i]; my_td = td; td->w = CreateWindowEx(td->dwExStyle, AngList, td->s, td->dwStyle, --- 2223,2233 ---- } ! /* Sub windows (reverse order) */ ! for (i = MAX_TERM_DATA - 1; i >= 1; --i) { td = &data[i]; + my_td = td; td->w = CreateWindowEx(td->dwExStyle, AngList, td->s, td->dwStyle, *************** *** 2150,2169 **** --- 2236,2279 ---- HWND_DESKTOP, NULL, hInstance, NULL); my_td = NULL; if (!td->w) quit("Failed to create sub-window"); + if (td->visible) { td->size_hack = TRUE; ShowWindow(td->w, SW_SHOW); td->size_hack = FALSE; } + term_data_link(td); angband_term[i] = &td->t; + + if (td->visible) + { + /* Activate the window */ + SetActiveWindow(td->w); + + /* Bring window to top */ + SetWindowPos(td->w, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + } } /* Main window */ td = &data[0]; + /* Main window */ + my_td = td; + td->w = CreateWindowEx(td->dwExStyle, AppName, + td->s, td->dwStyle, + td->pos_x, td->pos_y, + td->size_wid, td->size_hgt, + HWND_DESKTOP, NULL, hInstance, NULL); + my_td = NULL; + if (!td->w) quit("Failed to create Angband window"); + + term_data_link(td); + angband_term[0] = &td->t; + /* Activate the main window */ SetActiveWindow(td->w); *************** *** 2233,2239 **** /* Menu "File", Item "Exit" */ EnableMenuItem(hm, IDM_FILE_EXIT, ! MF_BYCOMMAND | MF_ENABLED); /* Menu "Window::Visibility" */ --- 2343,2349 ---- /* Menu "File", Item "Exit" */ EnableMenuItem(hm, IDM_FILE_EXIT, ! MF_BYCOMMAND | MF_ENABLED); /* Menu "Window::Visibility" */ *************** *** 2368,2374 **** #ifdef USE_SAVER /* Menu "Options", Item "ScreenSaver" */ EnableMenuItem(hm, IDM_OPTIONS_SAVER, ! MF_BYCOMMAND | MF_ENABLED); #endif } --- 2478,2484 ---- #ifdef USE_SAVER /* Menu "Options", Item "ScreenSaver" */ EnableMenuItem(hm, IDM_OPTIONS_SAVER, ! MF_BYCOMMAND | MF_ENABLED); #endif } *************** *** 2485,2497 **** /* Save game */ case IDM_FILE_SAVE: { ! if (!game_in_progress) { ! plog("No game in progress."); } else { ! do_cmd_save_game(); } break; } --- 2595,2618 ---- /* Save game */ case IDM_FILE_SAVE: { ! if (game_in_progress && character_generated) { ! /* Paranoia */ ! if (!inkey_flag) ! { ! plog("You may not do that right now."); ! break; ! } ! ! /* Hack -- Forget messages */ ! msg_flag = FALSE; ! ! /* Save the game */ ! do_cmd_save_game(); } else { ! plog("You may not do that right now."); } break; } *************** *** 2501,2506 **** --- 2622,2634 ---- { if (game_in_progress && character_generated) { + /* Paranoia */ + if (!inkey_flag) + { + plog("You may not do that right now."); + break; + } + /* Hack -- Forget messages */ msg_flag = FALSE; *************** *** 2713,2718 **** --- 2841,2853 ---- case IDM_OPTIONS_GRAPHICS: { + /* Paranoia */ + if (!inkey_flag) + { + plog("You may not do that right now."); + break; + } + /* Toggle "arg_graphics" */ arg_graphics = !arg_graphics; *************** *** 2727,2732 **** --- 2862,2874 ---- case IDM_OPTIONS_SOUND: { + /* Paranoia */ + if (!inkey_flag) + { + plog("You may not do that right now."); + break; + } + /* Toggle "arg_sound" */ arg_sound = !arg_sound; *************** *** 2793,2798 **** --- 2935,2941 ---- else { plog_fmt("Cannot find help file: %s", tmp); + plog("Use the online help files instead."); } break; } *************** *** 2810,2815 **** --- 2953,2959 ---- else { plog_fmt("Cannot find help file: %s", tmp); + plog("Use the online help files instead."); } break; } *************** *** 2910,2916 **** case WM_KEYDOWN: { BYTE KeyState = 0x00; ! bool enhanced = FALSE; bool mc = FALSE; bool ms = FALSE; bool ma = FALSE; --- 3054,3060 ---- case WM_KEYDOWN: { BYTE KeyState = 0x00; ! bool mc = FALSE; bool ms = FALSE; bool ma = FALSE; *************** *** 2920,2932 **** if (GetKeyState(VK_SHIFT) & 0x8000) ms = TRUE; if (GetKeyState(VK_MENU) & 0x8000) ma = TRUE; ! /* Check for non-normal keys */ ! if ((wParam >= VK_PRIOR) && (wParam <= VK_DOWN)) enhanced = TRUE; ! if ((wParam >= VK_F1) && (wParam <= VK_F12)) enhanced = TRUE; ! if ((wParam == VK_INSERT) || (wParam == VK_DELETE)) enhanced = TRUE; ! ! /* XXX XXX XXX */ ! if (enhanced) { /* Begin the macro trigger */ Term_keypress(31); --- 3064,3071 ---- if (GetKeyState(VK_SHIFT) & 0x8000) ms = TRUE; if (GetKeyState(VK_MENU) & 0x8000) ma = TRUE; ! /* Handle "special" keys */ ! if (special_key[(byte)(wParam)]) { /* Begin the macro trigger */ Term_keypress(31); *************** *** 2936,2942 **** if (ms) Term_keypress('S'); if (ma) Term_keypress('A'); ! /* Extract "scan code" from bits 16..23 of lParam */ i = LOBYTE(HIWORD(lParam)); /* Introduce the scan code */ --- 3075,3081 ---- if (ms) Term_keypress('S'); if (ma) Term_keypress('A'); ! /* Extract "scan code" */ i = LOBYTE(HIWORD(lParam)); /* Introduce the scan code */ *************** *** 3213,3219 **** case WM_KEYDOWN: { BYTE KeyState = 0x00; ! bool enhanced = FALSE; bool mc = FALSE; bool ms = FALSE; bool ma = FALSE; --- 3352,3358 ---- case WM_KEYDOWN: { BYTE KeyState = 0x00; ! bool mc = FALSE; bool ms = FALSE; bool ma = FALSE; *************** *** 3223,3235 **** if (GetKeyState(VK_SHIFT) & 0x8000) ms = TRUE; if (GetKeyState(VK_MENU) & 0x8000) ma = TRUE; ! /* Check for non-normal keys */ ! if ((wParam >= VK_PRIOR) && (wParam <= VK_DOWN)) enhanced = TRUE; ! if ((wParam >= VK_F1) && (wParam <= VK_F12)) enhanced = TRUE; ! if ((wParam == VK_INSERT) || (wParam == VK_DELETE)) enhanced = TRUE; ! ! /* XXX XXX XXX */ ! if (enhanced) { /* Begin the macro trigger */ Term_keypress(31); --- 3362,3369 ---- if (GetKeyState(VK_SHIFT) & 0x8000) ms = TRUE; if (GetKeyState(VK_MENU) & 0x8000) ma = TRUE; ! /* Handle "special" keys */ ! if (special_key[(byte)(wParam)]) { /* Begin the macro trigger */ Term_keypress(31); *************** *** 3239,3245 **** if (ms) Term_keypress('S'); if (ma) Term_keypress('A'); ! /* Extract "scan code" from bits 16..23 of lParam */ i = LOBYTE(HIWORD(lParam)); /* Introduce the scan code */ --- 3373,3379 ---- if (ms) Term_keypress('S'); if (ma) Term_keypress('A'); ! /* Extract "scan code" */ i = LOBYTE(HIWORD(lParam)); /* Introduce the scan code */ *************** *** 3702,3707 **** --- 3836,3847 ---- /* Prepare the filepaths */ init_stuff(); + /* Initialize the keypress analyzer */ + for (i = 0; special_key_list[i]; ++i) + { + special_key[special_key_list[i]] = TRUE; + } + /* Determine if display is 16/256/true color */ hdc = GetDC(NULL); colors16 = (GetDeviceCaps(hdc, BITSPIXEL) == 4); *************** *** 3765,3767 **** --- 3905,3909 ---- #endif /* WINDOWS */ + + diff -c -r angband-282/src/main-x11.c angband-283/src/main-x11.c *** angband-282/src/main-x11.c Thu Sep 4 10:17:52 1997 --- angband-283/src/main-x11.c Wed Feb 11 06:30:28 1998 *************** *** 8,25 **** * are included in all such copies. */ - /* Purpose: One (awful) way to run Angband under X11 -BEN- */ /* ! * Most of this file provides a user interface package composed of ! * several pseudo-objects, including "metadpy" (a display), "infowin" ! * (a window), "infoclr" (a color), and "infofnt" (a font). Actually, ! * the package was originally much more interesting, but I bastardized ! * it to keep this file simple. ! * ! * The rest of the file (search for 'ANGBAND') provides a simple ! * implementation of the "main-xxx.c" file for Angband using this ! * user interface package. */ --- 8,35 ---- * are included in all such copies. */ /* ! * This file helps Angband work with UNIX/X11 computers. ! * ! * See also "main-xaw.c" ! * ! * ! * Part of this file defines some "XImage" manipulation functions. ! * ! * Part of this file provides a user interface package composed of several ! * pseudo-objects, including "metadpy" (a display), "infowin" (a window), ! * "infoclr" (a color), and "infofnt" (a font). Actually, the package was ! * originally much more interesting, but it was bastardized to keep this ! * file simple. ! * ! * Part of this file supplies an implementation of the "main-xxx.c" file. ! * ! * ! * Initial framework (and most code) by Ben Harrison (benh@phial.com). ! * ! * Graphics support (the "XImage" functions) by Desvignes Sebastien ! * (desvigne@solar12.eerie.fr). */ *************** *** 42,47 **** --- 52,62 ---- #endif /* __MAKEDEPEND__ */ + /* + * Hack -- avoid some compiler warnings + */ + #define IGNORE_UNUSED_FUNCTIONS + /* * Notes on Colors: *************** *** 64,69 **** --- 79,294 ---- + /**** Graphics Functions ****/ + + + #ifdef USE_GRAPHICS + + + /* + * Read a raw file. XXX XXX XXX + * + * Also appears in "main-xaw.c". + */ + static XImage *ReadRaw(Display *disp, char Name[], int width, int height) + { + FILE *f; + + XImage *Res = NULL; + + char *Data; + + int depth, i; + + + f = fopen(Name, "r"); + + if (f != NULL) + { + depth = 4; + + Data = (char *)calloc(width * height * depth / 8, 1); + + if (Data != NULL) + { + Res = XCreateImage(disp, + DefaultVisual(disp, DefaultScreen(disp)), + depth, XYPixmap, 0, Data, + width, height, 8, 0); + + if (Res != NULL) + { + for (i=0; i<4; i++) + { + fread(Data+(3-i)*(width*height/8), width>>3, height, f); + } + } + else + { + free(Data); + } + } + + fclose(f); + } + + return Res; + } + + + /* + * Remap colors. XXX XXX XXX + * + * Also appears in "main-xaw.c". + */ + static XImage *RemapColors(Display *disp, XImage *Im, unsigned long ColT[]) + { + XImage *Tmp = NULL; + + char *Data; + + int width, height, depth; + + int x, y; + + + width = Im->width; + height = Im->height; + + depth = DefaultDepth(disp, DefaultScreen(disp)); + + x = 1; + y = (depth-1) >> 2; + + while (y>>=1) x<<=1; + + Data = (char *)malloc(width * height * x); + + if (Data != NULL) + { + Tmp = XCreateImage(disp, + DefaultVisual(disp, DefaultScreen(disp)), + depth, ZPixmap, 0, Data, width, height, + 32, 0); + + if (Tmp != NULL) + { + for (y=0; ywidth; + height1 = Im->height; + + width2 = ox * width1 / ix; + height2 = oy * height1 / iy; + + Data = (char *)malloc(width2 * height2 * Im->bits_per_pixel / 8); + + Tmp = XCreateImage(disp, + DefaultVisual(disp, DefaultScreen(disp)), + Im->depth, ZPixmap, 0, Data, width2, height2, + 32, 0); + + if (ix > ox) + { + px1 = &x1; + px2 = &x2; + dx1 = &ix; + dx2 = &ox; + } + else + { + px1 = &x2; + px2 = &x1; + dx1 = &ox; + dx2 = &ix; + } + + if (iy > oy) + { + py1 = &y1; + py2 = &y2; + dy1 = &iy; + dy2 = &oy; + } + else + { + py1 = &y2; + py2 = &y1; + dy1 = &oy; + dy2 = &iy; + } + + Ty = *dy1; + + for (y1=0, y2=0; (y1 < height1) && (y2 < height2); ) + { + Tx = *dx1; + + for (x1=0, x2=0; (x1 < width1) && (x2 < width2); ) + { + XPutPixel(Tmp, x2, y2, XGetPixel(Im, x1, y1)); + + (*px1)++; + + Tx -= *dx2; + if (Tx < 0) + { + Tx += *dx1; + (*px2)++; + } + } + + (*py1)++; + + Ty -= *dy2; + if (Ty < 0) + { + Ty += *dy1; + (*py2)++; + } + } + + return Tmp; + } + + + #endif /* USE_GRAPHICS */ + + /**** Available Types ****/ *************** *** 259,264 **** --- 484,491 ---- /* * Keysym macros, used on Keysyms to test for classes of symbols * These were stolen from one of the X11 header files + * + * Also appears in "main-xaw.c". */ #define IsKeypadKey(keysym) \ *************** *** 285,290 **** --- 512,519 ---- /* * Checks if the keysym is a special key or a normal key * Assume that XK_MISCELLANY keysyms are special + * + * Also appears in "main-xaw.c". */ #define IsSpecialKey(keysym) \ ((unsigned)(keysym) >= 0xFF00) *************** *** 489,494 **** --- 718,725 ---- } + #ifndef IGNORE_UNUSED_FUNCTIONS + /* * Nuke the current metadpy */ *************** *** 514,519 **** --- 745,752 ---- return (0); } + #endif /* IGNORE_UNUSED_FUNCTIONS */ + /* * General Flush/ Sync/ Discard routine *************** *** 560,565 **** --- 793,800 ---- } + #ifndef IGNORE_UNUSED_FUNCTIONS + /* * Set the icon name of Infowin */ *************** *** 594,599 **** --- 829,836 ---- return (0); } + #endif /* IGNORE_UNUSED_FUNCTIONS */ + /* * Prepare a new 'infowin'. *************** *** 604,610 **** Window tmp_win; XWindowAttributes xwa; ! int x, y, w, h, b, d; /* Assign stuff */ iwin->win = xid; --- 841,848 ---- Window tmp_win; XWindowAttributes xwa; ! int x, y; ! unsigned int w, h, b, d; /* Assign stuff */ iwin->win = xid; *************** *** 634,639 **** --- 872,879 ---- } + #ifndef IGNORE_UNUSED_FUNCTIONS + /* * Initialize a new 'infowin'. */ *************** *** 649,654 **** --- 889,896 ---- return (Infowin_prepare(xid)); } + #endif /* IGNORE_UNUSED_FUNCTIONS */ + /* * Init an infowin by giving some data. *************** *** 727,732 **** --- 969,976 ---- } + #ifndef IGNORE_UNUSED_FUNCTIONS + /* * Request that Infowin be unmapped */ *************** *** 739,744 **** --- 983,990 ---- return (0); } + #endif /* IGNORE_UNUSED_FUNCTIONS */ + /* * Request that Infowin be raised *************** *** 753,758 **** --- 999,1006 ---- } + #ifndef IGNORE_UNUSED_FUNCTIONS + /* * Request that Infowin be lowered */ *************** *** 778,783 **** --- 1026,1033 ---- return (0); } + #endif /* IGNORE_UNUSED_FUNCTIONS */ + /* * Resize an infowin *************** *** 792,797 **** --- 1042,1049 ---- } + #ifndef IGNORE_UNUSED_FUNCTIONS + /* * Move and Resize an infowin */ *************** *** 804,809 **** --- 1056,1063 ---- return (0); } + #endif /* IGNORE_UNUSED_FUNCTIONS */ + /* * Visually clear Infowin *************** *** 818,823 **** --- 1072,1079 ---- } + #ifndef IGNORE_UNUSED_FUNCTIONS + /* * Visually Paint Infowin with the current color */ *************** *** 831,836 **** --- 1087,1094 ---- return (0); } + #endif /* IGNORE_UNUSED_FUNCTIONS */ + /* * Set the size hints of Infowin *************** *** 1030,1035 **** --- 1288,1295 ---- } + #ifndef IGNORE_UNUSED_FUNCTIONS + /* * Initialize a new 'infoclr' with a real GC. */ *************** *** 1069,1074 **** --- 1329,1336 ---- return (0); } + #endif /* IGNORE_UNUSED_FUNCTIONS */ + /* * Initialize an infoclr with some data *************** *** 1179,1184 **** --- 1441,1448 ---- + #ifndef IGNORE_UNUSED_FUNCTIONS + /* * Nuke an old 'infofnt'. */ *************** *** 1204,1209 **** --- 1468,1475 ---- return (0); } + #endif /* IGNORE_UNUSED_FUNCTIONS */ + /* * Prepare a new 'infofnt' *************** *** 1237,1242 **** --- 1503,1510 ---- } + #ifndef IGNORE_UNUSED_FUNCTIONS + /* * Initialize a new 'infofnt'. */ *************** *** 1252,1257 **** --- 1520,1527 ---- return (Infofnt_prepare(info)); } + #endif /* IGNORE_UNUSED_FUNCTIONS */ + /* * Init an infofnt by its Name *************** *** 1448,1453 **** --- 1718,1730 ---- infowin *outer; infowin *inner; + + #ifdef USE_GRAPHICS + + XImage *tiles; + + #endif + }; *************** *** 1464,1471 **** /* * Process a keypress event */ ! static void react_keypress(XEvent *xev) { int i, n, mc, ms, mo, mx; --- 1741,1750 ---- /* * Process a keypress event + * + * Also appears in "main-xaw.c". */ ! static void react_keypress(XKeyEvent *xev) { int i, n, mc, ms, mo, mx; *************** *** 1485,1490 **** --- 1764,1774 ---- /* Terminate */ buf[n] = '\0'; + + /* Hack -- Ignore "modifier keys" */ + if (IsModifierKey(ks)) return; + + /* Hack -- convert into an unsigned int */ ks1 = (uint)(ks); *************** *** 1495,1504 **** mx = (ev->state & Mod2Mask) ? TRUE : FALSE; - /* Hack -- Ignore "modifier keys" */ - if (IsModifierKey(ks)) return; - - /* Normal keys with no modifiers */ if (n && !mo && !mx && !IsSpecialKey(ks)) { --- 1779,1784 ---- *************** *** 1510,1550 **** } ! /* Handle a few standard keys */ switch (ks1) { case XK_Escape: ! Term_keypress(ESCAPE); return; case XK_Return: ! Term_keypress('\r'); return; case XK_Tab: ! Term_keypress('\t'); return; case XK_Delete: case XK_BackSpace: ! Term_keypress('\010'); return; ! } ! ! ! #if 0 ! /* Hack -- Handle a few special KeySym codes */ ! switch (ks1) ! { ! case XK_Up: ! Term_keypress(30); Term_keypress('8'); return; ! ! case XK_Down: ! Term_keypress(30); Term_keypress('2'); return; ! ! case XK_Left: ! Term_keypress(30); Term_keypress('4'); return; ! ! case XK_Right: ! Term_keypress(30); Term_keypress('6'); return; } - #endif /* Hack -- Use the KeySym */ --- 1790,1823 ---- } ! /* Handle a few standard keys (bypass modifiers) XXX XXX XXX */ switch (ks1) { case XK_Escape: ! { ! Term_keypress(ESCAPE); ! return; ! } case XK_Return: ! { ! Term_keypress('\r'); ! return; ! } case XK_Tab: ! { ! Term_keypress('\t'); ! return; ! } case XK_Delete: case XK_BackSpace: ! { ! Term_keypress('\010'); ! return; ! } } /* Hack -- Use the KeySym */ *************** *** 1565,1585 **** ev->keycode, 13); } ! /* Enqueue the "fake" string */ for (i = 0; msg[i]; i++) Term_keypress(msg[i]); ! /* Hack -- dump an "extra" string */ ! if (n) { ! /* Start the "extra" string */ ! Term_keypress(28); ! ! /* Enqueue the "real" string */ ! for (i = 0; buf[i]; i++) Term_keypress(buf[i]); ! ! /* End the "extra" string */ ! Term_keypress(28); } } --- 1838,1852 ---- ev->keycode, 13); } ! /* Enqueue the "macro trigger" string */ for (i = 0; msg[i]; i++) Term_keypress(msg[i]); ! /* Hack -- auto-define macros as needed */ ! if (n && (macro_find_exact(msg) < 0)) { ! /* Create a macro */ ! macro_add(msg, buf); } } *************** *** 1727,1733 **** Term_activate(&old_td->t); /* Process the key */ ! react_keypress(xev); break; } --- 1994,2000 ---- Term_activate(&old_td->t); /* Process the key */ ! react_keypress(&(xev->xkey)); break; } *************** *** 1942,1948 **** /* ! * Erase a number of characters */ static errr Term_wipe_x11(int x, int y, int n) { --- 2209,2215 ---- /* ! * Erase some characters. */ static errr Term_wipe_x11(int x, int y, int n) { *************** *** 1958,1964 **** /* ! * Draw a number of characters (XXX Consider using "cpy" mode) */ static errr Term_text_x11(int x, int y, int n, byte a, cptr s) { --- 2225,2231 ---- /* ! * Draw some textual characters. */ static errr Term_text_x11(int x, int y, int n, byte a, cptr s) { *************** *** 1973,1978 **** --- 2240,2286 ---- } + #ifdef USE_GRAPHICS + + /* + * Draw some graphical characters. + */ + static errr Term_pict_x11(int x, int y, int n, const byte *ap, const char *cp) + { + int i; + + byte a; + char c; + + term_data *td = (term_data*)(Term->data); + + y *= Infofnt->hgt; + x *= Infofnt->wid; + + for (i = 0; i < n; ++i) + { + a = *ap++; + c = *cp++; + + XPutImage(Metadpy->dpy, td->inner->win, + clr[17]->gc, + td->tiles, + (c&0x7F) * td->fnt->wid + 1, + (a&0x7F) * td->fnt->hgt + 1, + x, y, + td->fnt->wid, td->fnt->hgt); + + x += td->fnt->wid; + } + + /* Success */ + return (0); + } + + #endif /* USE_GRAPHICS */ + + + /* * Initialize a term_data */ *************** *** 2011,2016 **** --- 2319,2327 ---- Infowin_set_mask(ExposureMask); Infowin_map(); + /* No graphics yet */ + td->tiles = NULL; + /* Initialize the term */ term_init(t, 80, 24, num); *************** *** 2027,2032 **** --- 2338,2357 ---- t->wipe_hook = Term_wipe_x11; t->text_hook = Term_text_x11; + #ifdef USE_GRAPHICS + + /* Use graphics */ + if (use_graphics) + { + /* Graphics hook */ + t->pict_hook = Term_pict_x11; + + /* Use graphics sometimes */ + t->higher_pict = TRUE; + } + + #endif /* USE_GRAPHICS */ + /* Save the data */ t->data = td; *************** *** 2051,2056 **** --- 2376,2387 ---- char buf[80]; + #ifdef USE_GRAPHICS + + char filename[1024]; + + #endif /* USE_GRAPHICS */ + /* Parse args */ for (i = 1; i < argc; i++) *************** *** 2079,2084 **** --- 2410,2447 ---- } + #ifdef USE_GRAPHICS + + /* Try graphics */ + if (arg_graphics) + { + /* Build the name of the "tiles.raw" file */ + path_build(filename, 1024, ANGBAND_DIR_XTRA, "tiles.raw"); + + /* Use graphics if bitmap file exists */ + if (0 == fd_close(fd_open(filename, O_RDONLY))) + { + /* Use graphics */ + use_graphics = TRUE; + } + } + + #endif /* USE_GRAPHICS */ + + + /* Load colors */ + if (use_graphics) + { + /* Process "graf-x11.prf" XXX XXX XXX */ + (void)process_pref_file("graf-x11.prf"); + } + else + { + /* Process "font-x11.prf" XXX XXX XXX */ + (void)process_pref_file("font-x11.prf"); + } + + /* Init the Metadpy if possible */ if (Metadpy_init_name(dpy_name)) return (-1); *************** *** 2118,2123 **** --- 2481,2488 ---- /* Initialize the windows */ for (i = 0; i < num_term; i++) { + term_data *td = &data[i]; + cptr fnt_name = NULL; cptr name = angband_term_name[i]; *************** *** 2141,2151 **** if (!fnt_name) fnt_name = DEFAULT_X11_FONT_SCREEN; /* Initialize the term_data */ ! term_data_init(&data[i], TRUE, name, fnt_name); /* Save global entry */ angband_term[i] = Term; } /* Activate the "Angband" window screen */ Term_activate(&data[0].t); --- 2506,2552 ---- if (!fnt_name) fnt_name = DEFAULT_X11_FONT_SCREEN; /* Initialize the term_data */ ! term_data_init(td, TRUE, name, fnt_name); /* Save global entry */ angband_term[i] = Term; } + + + #ifdef USE_GRAPHICS + + /* Load graphics */ + if (use_graphics) + { + unsigned long ColTable[256]; + + XImage *tiles_raw; + XImage *tiles_good; + + /* Prepare color table */ + for (i = 0; i < 256; ++i) + { + ColTable[i] = clr[i]->fg; + } + + /* Load the graphics XXX XXX XXX */ + tiles_raw = ReadRaw(Metadpy->dpy, filename, 256, 256); + tiles_good = RemapColors(Metadpy->dpy, tiles_raw, ColTable); + XDestroyImage(tiles_raw); + + /* Initialize the windows */ + for (i = 0; i < num_term; i++) + { + term_data *td = &data[i]; + + /* Resize tiles */ + td->tiles = ResizeImage(Metadpy->dpy, tiles_good, 8, 8, + td->fnt->wid, td->fnt->hgt); + } + } + + #endif /* USE_GRAPHICS */ + /* Activate the "Angband" window screen */ Term_activate(&data[0].t); diff -c -r angband-282/src/main-xaw.c angband-283/src/main-xaw.c *** angband-282/src/main-xaw.c Thu Sep 4 10:17:53 1997 --- angband-283/src/main-xaw.c Sat Feb 7 21:23:07 1998 *************** *** 1,19 **** /* File: main-xaw.c */ /* ! * Copyright (c) 1997 Ben Harrison, Torbjörn Lindgren, and others * * 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. */ - /* Purpose: Support for X Athena Widget based Angband */ /* ! * Most code written by Torbjörn Lindgren (tl@cd.chalmers.se) */ #ifdef USE_XAW #include "angband.h" --- 1,51 ---- /* File: main-xaw.c */ /* ! * Copyright (c) 1997 Ben Harrison, Torbjorn Lindgren, and others * * 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. */ /* ! * This file helps Angband work with UNIX/X11 computers. ! * ! * To use this file, use "Makefile.xaw", which defines "USE_XAW". ! * ! * See also "main-x11.c". ! * ! * ! * The Angband widget is not as self-contained as it really should be. ! * Originally everything was output to a Pixmap which was later copied ! * to the screen when necessary. The idea was abandoned since Pixmaps ! * create big performance problems for some really old X terminals (such ! * as 3/50's running Xkernel). ! * ! * The default colors used are based on the ones used in main-mac.c, with ! * the main difference being that they are gamma corrected for a gamma of ! * 1.6, since MacOS do gamma correction afterwards, but X uses raw colors. ! * The Gamma of most color screens are about 1.5 - 1.7. Color 12 was later ! * changed a bit so that it didn't look as similar to color 3/4. ! * ! * This file should really attempt to obey the "angband_colors" table, ! * even at initialization, since it is a better color specifier than the ! * stupid resources, and it must be initialized specially for the special ! * "use_graphics" code. XXX XXX XXX ! * ! * We should allow interactive color modifications. XXX XXX XXX ! * ! * ! * Initial framework (and some code) by Ben Harrison (benh@phial,com). ! * ! * Most code by Torbjorn Lindgren (tl@cd.chalmers.se). ! * ! * Graphics support (the "XImage" functions) by Desvignes Sebastien ! * (desvigne@solar12.eerie.fr). */ + #ifdef USE_XAW #include "angband.h" *************** *** 38,50 **** ! /***************************************************** * ! * Resource description * ! *****************************************************/ ! /* Resources: Name Class RepType Default Value ---- ----- ------- ------------- --- 70,289 ---- ! /**** Graphics Functions ****/ ! ! ! #ifdef USE_GRAPHICS ! ! ! /* ! * Read a raw file. XXX XXX XXX * ! * Also appears in "main-x11.c". ! */ ! static XImage *ReadRaw(Display *disp, char Name[], int width, int height) ! { ! FILE *f; ! ! XImage *Res = NULL; ! ! char *Data; ! ! int depth, i; ! ! ! f = fopen(Name, "r"); ! ! if (f != NULL) ! { ! depth = 4; ! ! Data = (char *)calloc(width * height * depth / 8, 1); ! ! if (Data != NULL) ! { ! Res = XCreateImage(disp, ! DefaultVisual(disp, DefaultScreen(disp)), ! depth, XYPixmap, 0, Data, ! width, height, 8, 0); ! ! if (Res != NULL) ! { ! for (i=0; i<4; i++) ! { ! fread(Data+(3-i)*(width*height/8), width>>3, height, f); ! } ! } ! else ! { ! free(Data); ! } ! } ! ! fclose(f); ! } ! ! return Res; ! } ! ! ! /* ! * Remap colors. XXX XXX XXX * ! * Also appears in "main-x11.c". ! */ ! static XImage *RemapColors(Display *disp, XImage *Im, unsigned long ColT[]) ! { ! XImage *Tmp = NULL; ! ! char *Data; ! ! int width, height, depth; ! ! int x, y; ! ! ! width = Im->width; ! height = Im->height; ! ! depth = DefaultDepth(disp, DefaultScreen(disp)); ! ! x = 1; ! y = (depth-1) >> 2; ! ! while (y>>=1) x<<=1; ! ! Data = (char *)malloc(width * height * x); ! ! if (Data != NULL) ! { ! Tmp = XCreateImage(disp, ! DefaultVisual(disp, DefaultScreen(disp)), ! depth, ZPixmap, 0, Data, width, height, ! 32, 0); ! ! if (Tmp != NULL) ! { ! for (y=0; ywidth; ! height1 = Im->height; ! ! width2 = ox * width1 / ix; ! height2 = oy * height1 / iy; ! ! Data = (char *)malloc(width2 * height2 * Im->bits_per_pixel / 8); ! ! Tmp = XCreateImage(disp, ! DefaultVisual(disp, DefaultScreen(disp)), ! Im->depth, ZPixmap, 0, Data, width2, height2, ! 32, 0); ! ! if (ix > ox) ! { ! px1 = &x1; ! px2 = &x2; ! dx1 = &ix; ! dx2 = &ox; ! } ! else ! { ! px1 = &x2; ! px2 = &x1; ! dx1 = &ox; ! dx2 = &ix; ! } ! ! if (iy > oy) ! { ! py1 = &y1; ! py2 = &y2; ! dy1 = &iy; ! dy2 = &oy; ! } ! else ! { ! py1 = &y2; ! py2 = &y1; ! dy1 = &oy; ! dy2 = &iy; ! } ! ! Ty = *dy1; ! ! for (y1=0, y2=0; (y1 < height1) && (y2 < height2); ) ! { ! Tx = *dx1; ! ! for (x1=0, x2=0; (x1 < width1) && (x2 < width2); ) ! { ! XPutPixel(Tmp, x2, y2, XGetPixel(Im, x1, y1)); ! ! (*px1)++; ! ! Tx -= *dx2; ! if (Tx < 0) ! { ! Tx += *dx1; ! (*px2)++; ! } ! } ! (*py1)++; ! ! Ty -= *dy2; ! if (Ty < 0) ! { ! Ty += *dy1; ! (*py2)++; ! } ! } ! ! return Tmp; ! } ! ! ! #endif /* USE_GRAPHICS */ ! ! ! /**** Resources ****/ ! ! ! /* Name Class RepType Default Value ---- ----- ------- ------------- *************** *** 64,72 **** x Position Position 0 y Position Position 0 - */ - - /* My own X Resources look like this (on a 1152x900 screen): --- 303,308 ---- *************** *** 116,121 **** --- 352,379 ---- angband*color14: #00c8ff angband*color15: #ffcc80 + And the bitmap colors look like: + + xxxxx + + angband*color16: #000000 + angband*color17: #F0E0D0 + angband*color18: #808080 + angband*color19: #505050 + angband*color20: #E0B000 + angband*color21: #C0A070 + angband*color22: #806040 + angband*color23: #403020 + angband*color24: #00A0F0 + angband*color25: #0000F0 + angband*color26: #000070 + angband*color27: #F00000 + angband*color28: #800000 + angband*color29: #9000B0 + angband*color30: #006010 + angband*color31: #60F040 + + Some older monochrome monitors have problem with white text on black background. The new code can handle the reverse situation if the user wants/needs this. *************** *** 129,135 **** */ ! /* New resource names */ #define XtNstartRows "startRows" #define XtNstartColumns "startColumns" #define XtNminRows "minRows" --- 387,396 ---- */ ! ! /* ! * New resource names ! */ #define XtNstartRows "startRows" #define XtNstartColumns "startColumns" #define XtNminRows "minRows" *************** *** 153,178 **** #define XtNcolor13 "color13" #define XtNcolor14 "color14" #define XtNcolor15 "color15" #define XtNredrawCallback "redrawCallback" ! /* External definitions */ ! #define COLOR_XOR 16 ! #define NUM_COLORS 16 ! /* C Widget type definition */ - typedef struct AngbandRec *AngbandWidget; - /* C Widget class type definition */ typedef struct AngbandClassRec *AngbandWidgetClass; /* * New fields for the Angband widget record */ ! ! typedef struct { /* Settable resources */ int start_rows; --- 414,467 ---- #define XtNcolor13 "color13" #define XtNcolor14 "color14" #define XtNcolor15 "color15" + #define XtNcolor16 "color16" + #define XtNcolor17 "color17" + #define XtNcolor18 "color18" + #define XtNcolor19 "color19" + #define XtNcolor20 "color20" + #define XtNcolor21 "color21" + #define XtNcolor22 "color22" + #define XtNcolor23 "color23" + #define XtNcolor24 "color24" + #define XtNcolor25 "color25" + #define XtNcolor26 "color26" + #define XtNcolor27 "color27" + #define XtNcolor28 "color28" + #define XtNcolor29 "color29" + #define XtNcolor30 "color30" + #define XtNcolor31 "color31" #define XtNredrawCallback "redrawCallback" ! /* ! * Total normal colors ! */ ! #define NUM_COLORS 256 ! /* ! * Special "XOR" color ! */ ! #define COLOR_XOR 256 + /**** The Widget Code ****/ + + + /* + * Forward declarations + */ + typedef struct AngbandPart AngbandPart; + typedef struct AngbandRec *AngbandWidget; + typedef struct AngbandRec AngbandRec; typedef struct AngbandClassRec *AngbandWidgetClass; + typedef struct AngbandClassPart AngbandClassPart; + typedef struct AngbandClassRec AngbandClassRec; /* * New fields for the Angband widget record */ ! struct AngbandPart { /* Settable resources */ int start_rows; *************** *** 186,209 **** Pixel color[NUM_COLORS]; XtCallbackList redraw_callbacks; /* Private state */ XFontStruct *fnt; Dimension fontheight; Dimension fontwidth; Dimension fontascent; ! /* Includes a special 'xor' color */ GC gc[NUM_COLORS+1]; ! ! } AngbandPart; /* * Full instance record declaration */ - - typedef struct AngbandRec AngbandRec; - struct AngbandRec { CorePart core; --- 475,501 ---- Pixel color[NUM_COLORS]; XtCallbackList redraw_callbacks; + #ifdef USE_GRAPHICS + + /* Tiles */ + XImage *tiles; + + #endif /* USE_GRAPHICS */ + /* Private state */ XFontStruct *fnt; Dimension fontheight; Dimension fontwidth; Dimension fontascent; ! /* Colors (includes "xor" color) */ GC gc[NUM_COLORS+1]; ! }; /* * Full instance record declaration */ struct AngbandRec { CorePart core; *************** *** 215,223 **** /* * New fields for the Angband widget class record */ - - typedef struct AngbandClassPart AngbandClassPart; - struct AngbandClassPart { int dummy; --- 507,512 ---- *************** *** 227,235 **** /* * Full class record declaration */ - - typedef struct AngbandClassRec AngbandClassRec; - struct AngbandClassRec { CoreClassPart core_class; --- 516,521 ---- *************** *** 239,266 **** ! /* Angband widget, Created by Torbjörn Lindgren (tl@cd.chalmers.se) */ ! ! /* ! * Note that it isn't as self-contained as it really should be, ! * originally everything was output to a Pixmap which was later copied ! * to the screen when necessary. I had to abandon that idea since ! * Pixmaps creates big performance problems for some really old X ! * terminals (such as 3/50's running Xkernel). ! */ ! ! ! /* ! * The default colors used is based on the ones used in main-mac.c. ! * The main difference is that they are gamma corrected for a gamma of ! * 1.6. MacOS do gamma correction afterwards, but X uses raw ! * colors. The Gamma of most color screens are about 1.5 - 1.7. ! * Color 12 was later changed a bit so that it didn't look as similar ! * to color 3/4. */ - #define offset(field) XtOffsetOf(AngbandRec, angband.field) /* * Fallback resources for Angband widget */ --- 525,536 ---- ! /* ! * Hack -- see below */ #define offset(field) XtOffsetOf(AngbandRec, angband.field) + /* * Fallback resources for Angband widget */ *************** *** 282,287 **** --- 552,560 ---- offset(internal_border), XtRImmediate, (XtPointer) 2 }, { XtNfont, XtCFont, XtRString, sizeof(char *), offset(font), XtRString, "9x15" }, + + #if 1 + { XtNcolor0, XtCColor, XtRPixel, sizeof(Pixel), offset(color[0]), XtRString, "black" }, { XtNcolor1, XtCColor, XtRPixel, sizeof(Pixel), *************** *** 315,322 **** { XtNcolor15, XtCColor, XtRPixel, sizeof(Pixel), offset(color[15]), XtRString, "#ffcc80" }, ! #if 0 { XtNcolor2, XtCColor, XtRPixel, sizeof(Pixel), offset(color[2]), XtRString, "#a6a6a6" }, { XtNcolor3, XtCColor, XtRPixel, sizeof(Pixel), --- 588,599 ---- { XtNcolor15, XtCColor, XtRPixel, sizeof(Pixel), offset(color[15]), XtRString, "#ffcc80" }, ! #else + { XtNcolor0, XtCColor, XtRPixel, sizeof(Pixel), + offset(color[0]), XtRString, "black" }, + { XtNcolor1, XtCColor, XtRPixel, sizeof(Pixel), + offset(color[1]), XtRString, "white" }, { XtNcolor2, XtCColor, XtRPixel, sizeof(Pixel), offset(color[2]), XtRString, "#a6a6a6" }, { XtNcolor3, XtCColor, XtRPixel, sizeof(Pixel), *************** *** 348,378 **** #endif { XtNredrawCallback, XtCCallback, XtRCallback, sizeof(XtPointer), offset(redraw_callbacks), XtRCallback, (XtPointer)NULL } }; #undef offset ! /* Forward declarations for Widget functions */ ! static void Initialize(AngbandWidget request, AngbandWidget new); static void Redisplay(AngbandWidget w, XEvent *event, Region region); static Boolean SetValues(AngbandWidget current, AngbandWidget request, ! AngbandWidget new, ArgList args, Cardinal *num_args); static void Destroy(AngbandWidget widget); ! /* Forward declaration for internal functions */ ! static void calculateSizeHints(AngbandWidget new); static XFontStruct *getFont(AngbandWidget widget, String font, Boolean fallback); ! /* Class record constanst */ AngbandClassRec angbandClassRec = { { /* Core class fields initialization */ - #define superclass (&simpleClassRec) /* superclass */ (WidgetClass) superclass, /* class_name */ "Angband", /* widget_size */ sizeof(AngbandRec), --- 625,704 ---- #endif + { XtNcolor16, XtCColor, XtRPixel, sizeof(Pixel), + offset(color[16]), XtRString, "#000000" }, + { XtNcolor17, XtCColor, XtRPixel, sizeof(Pixel), + offset(color[17]), XtRString, "#F0E0D0" }, + { XtNcolor18, XtCColor, XtRPixel, sizeof(Pixel), + offset(color[18]), XtRString, "#808080" }, + { XtNcolor19, XtCColor, XtRPixel, sizeof(Pixel), + offset(color[19]), XtRString, "#505050" }, + { XtNcolor20, XtCColor, XtRPixel, sizeof(Pixel), + offset(color[20]), XtRString, "#E0B000" }, + { XtNcolor21, XtCColor, XtRPixel, sizeof(Pixel), + offset(color[21]), XtRString, "#C0A070" }, + { XtNcolor22, XtCColor, XtRPixel, sizeof(Pixel), + offset(color[22]), XtRString, "#806040" }, + { XtNcolor23, XtCColor, XtRPixel, sizeof(Pixel), + offset(color[23]), XtRString, "#403020" }, + { XtNcolor24, XtCColor, XtRPixel, sizeof(Pixel), + offset(color[24]), XtRString, "#00A0F0" }, + { XtNcolor25, XtCColor, XtRPixel, sizeof(Pixel), + offset(color[25]), XtRString, "#0000F0" }, + { XtNcolor26, XtCColor, XtRPixel, sizeof(Pixel), + offset(color[26]), XtRString, "#000070" }, + { XtNcolor27, XtCColor, XtRPixel, sizeof(Pixel), + offset(color[27]), XtRString, "#F00000" }, + { XtNcolor28, XtCColor, XtRPixel, sizeof(Pixel), + offset(color[28]), XtRString, "#800000" }, + { XtNcolor29, XtCColor, XtRPixel, sizeof(Pixel), + offset(color[29]), XtRString, "#9000B0" }, + { XtNcolor30, XtCColor, XtRPixel, sizeof(Pixel), + offset(color[30]), XtRString, "#006010" }, + { XtNcolor31, XtCColor, XtRPixel, sizeof(Pixel), + offset(color[31]), XtRString, "#60F040" }, + { XtNredrawCallback, XtCCallback, XtRCallback, sizeof(XtPointer), offset(redraw_callbacks), XtRCallback, (XtPointer)NULL } }; + + /* + * Hack -- see above + */ #undef offset ! ! /* ! * Forward declarations for Widget functions ! */ ! static void Initialize(AngbandWidget request, AngbandWidget wnew); static void Redisplay(AngbandWidget w, XEvent *event, Region region); static Boolean SetValues(AngbandWidget current, AngbandWidget request, ! AngbandWidget wnew, ArgList args, Cardinal *num_args); static void Destroy(AngbandWidget widget); ! /* ! * Forward declaration for internal functions ! */ ! static void calculateSizeHints(AngbandWidget wnew); static XFontStruct *getFont(AngbandWidget widget, String font, Boolean fallback); ! /* ! * Hack -- see below ! */ ! #define superclass (&simpleClassRec) ! ! ! /* ! * Class record constanst ! */ AngbandClassRec angbandClassRec = { { /* Core class fields initialization */ /* superclass */ (WidgetClass) superclass, /* class_name */ "Angband", /* widget_size */ sizeof(AngbandRec), *************** *** 416,449 **** } }; ! /* Class record pointer */ ! WidgetClass angbandWidgetClass = (WidgetClass) &angbandClassRec; /* ! * Public procedures */ ! static void AngbandOutputText(AngbandWidget widget, int x, int y, ! String txt, int len, int color) ! { ! /* Do nothing if the string is null */ ! if (!txt || !*txt) ! return; - /* Check the length, and fix it if it's below zero */ - if (len < 0) - len = strlen(txt); ! /* Figure out where to place the text */ ! y = y * widget->angband.fontheight + widget->angband.fontascent + ! widget->angband.internal_border; ! x = x * widget->angband.fontwidth + widget->angband.internal_border; - /* Place the string */ - XDrawImageString (XtDisplay(widget), XtWindow(widget), - widget->angband.gc[color], x, y, txt, len); - } static void AngbandClearArea(AngbandWidget widget, int x, int y, int w, int h, int color) { --- 742,767 ---- } }; ! /* ! * Hack -- see above ! */ ! #undef superclass /* ! * Class record pointer */ ! WidgetClass angbandWidgetClass = (WidgetClass) &angbandClassRec; ! /* ! * Public procedures ! */ + /* + * Clear an area + */ static void AngbandClearArea(AngbandWidget widget, int x, int y, int w, int h, int color) { *************** *** 458,529 **** widget->angband.fontheight*h); } /* * Private procedures */ /* * Procedure Initialize() is called during the widget creation * process. Initialize() load fonts and calculates window geometry. * The request parameter is filled in by parents to this widget. The ! * new parameter is the request parameter plus data filled in by this ! * widget. All changes should be done to the new parameter. */ ! static void Initialize(AngbandWidget request, AngbandWidget new) { XGCValues gcv; ! int depth = DefaultDepthOfScreen(XtScreen((Widget) new)); TopLevelShellWidget parent = ! (TopLevelShellWidget)XtParent((Widget) new); int n; /* Fix the background color */ ! new->core.background_pixel = new->angband.color[0]; /* Get some information about the font */ ! new->angband.fnt = getFont(new, new->angband.font, TRUE); ! new->angband.fontheight = new->angband.fnt->ascent + ! new->angband.fnt->descent; ! new->angband.fontwidth = new->angband.fnt->max_bounds.width; ! new->angband.fontascent = new->angband.fnt->ascent; /* Create and initialize the graphics contexts */ /* GXset? */ ! gcv.font = new->angband.fnt->fid; gcv.graphics_exposures = FALSE; ! gcv.background = new->angband.color[0]; for (n = 0; n < NUM_COLORS; n++) { if (depth == 1 && n >= 1) ! gcv.foreground = new->angband.color[1]; else ! gcv.foreground = new->angband.color[n]; ! new->angband.gc[n] = XtGetGC((Widget)new, GCFont | GCForeground | GCBackground | GCGraphicsExposures, &gcv); } /* Create a special GC for highlighting */ ! gcv.foreground = BlackPixelOfScreen(XtScreen((Widget)new)) ^ ! WhitePixelOfScreen(XtScreen((Widget)new)); gcv.function = GXxor; ! new->angband.gc[NUM_COLORS] = XtGetGC((Widget)new, GCFunction | GCGraphicsExposures | GCForeground, &gcv); /* Calculate window geometry */ ! new->core.height = new->angband.start_rows * new->angband.fontheight + ! 2 * new->angband.internal_border; ! new->core.width = new->angband.start_columns * new->angband.fontwidth + ! 2 * new->angband.internal_border; /* We need to be able to resize the Widget if the user want's to change font on the fly! */ parent->shell.allow_shell_resize = TRUE; /* Calculates all the size hints */ ! calculateSizeHints(new); } /* * Procedure Destroy() is called during the destruction of the widget. * Destroy() releases and frees GCs, frees the pixmaps and frees the --- 776,918 ---- widget->angband.fontheight*h); } + + + /* + * Output some text + */ + static void AngbandOutputText(AngbandWidget widget, int x, int y, + String txt, int len, int color) + { + /* Do nothing if the string is null */ + if (!txt || !*txt) return; + + /* Check the length, and fix it if it's below zero */ + if (len < 0) len = strlen(txt); + + /* Figure out where to place the text */ + y = (y * widget->angband.fontheight + widget->angband.fontascent + + widget->angband.internal_border); + x = (x * widget->angband.fontwidth + widget->angband.internal_border); + + /* Place the string */ + XDrawImageString(XtDisplay(widget), XtWindow(widget), + widget->angband.gc[color], x, y, txt, len); + } + + + #ifdef USE_GRAPHICS + + /* + * Draw some graphical characters. + */ + static void AngbandOutputPict(AngbandWidget widget, int x, int y, int n, + const byte *ap, const char *cp) + { + int i; + + byte a; + char c; + + /* Figure out where to place the text */ + y = (y * widget->angband.fontheight + widget->angband.internal_border); + x = (x * widget->angband.fontwidth + widget->angband.internal_border); + + for (i = 0; i < n; ++i) + { + a = *ap++; + c = *cp++; + + XPutImage(XtDisplay(widget), XtWindow(widget), + widget->angband.gc[17], + widget->angband.tiles, + (c&0x7F) * widget->angband.fontwidth + 1, + (a&0x7F) * widget->angband.fontheight + 1, + x, y, + widget->angband.fontwidth, + widget->angband.fontheight); + + x += widget->angband.fontwidth; + } + } + + #endif /* USE_GRAPHICS */ + + + /* * Private procedures */ + /* * Procedure Initialize() is called during the widget creation * process. Initialize() load fonts and calculates window geometry. * The request parameter is filled in by parents to this widget. The ! * wnew parameter is the request parameter plus data filled in by this ! * widget. All changes should be done to the wnew parameter. */ ! static void Initialize(AngbandWidget request, AngbandWidget wnew) { XGCValues gcv; ! int depth = DefaultDepthOfScreen(XtScreen((Widget) wnew)); TopLevelShellWidget parent = ! (TopLevelShellWidget)XtParent((Widget) wnew); int n; /* Fix the background color */ ! wnew->core.background_pixel = wnew->angband.color[0]; /* Get some information about the font */ ! wnew->angband.fnt = getFont(wnew, wnew->angband.font, TRUE); ! wnew->angband.fontheight = wnew->angband.fnt->ascent + ! wnew->angband.fnt->descent; ! wnew->angband.fontwidth = wnew->angband.fnt->max_bounds.width; ! wnew->angband.fontascent = wnew->angband.fnt->ascent; /* Create and initialize the graphics contexts */ /* GXset? */ ! gcv.font = wnew->angband.fnt->fid; gcv.graphics_exposures = FALSE; ! gcv.background = wnew->angband.color[0]; for (n = 0; n < NUM_COLORS; n++) { if (depth == 1 && n >= 1) ! { ! gcv.foreground = wnew->angband.color[1]; ! } else ! { ! gcv.foreground = wnew->angband.color[n]; ! } ! ! wnew->angband.gc[n] = XtGetGC((Widget)wnew, GCFont | GCForeground | GCBackground | GCGraphicsExposures, &gcv); } /* Create a special GC for highlighting */ ! gcv.foreground = (BlackPixelOfScreen(XtScreen((Widget)wnew)) ^ ! WhitePixelOfScreen(XtScreen((Widget)wnew))); gcv.function = GXxor; ! wnew->angband.gc[COLOR_XOR] = XtGetGC((Widget)wnew, GCFunction | GCGraphicsExposures | GCForeground, &gcv); /* Calculate window geometry */ ! wnew->core.height = (wnew->angband.start_rows * wnew->angband.fontheight + ! 2 * wnew->angband.internal_border); ! wnew->core.width = (wnew->angband.start_columns * wnew->angband.fontwidth + ! 2 * wnew->angband.internal_border); /* We need to be able to resize the Widget if the user want's to change font on the fly! */ parent->shell.allow_shell_resize = TRUE; /* Calculates all the size hints */ ! calculateSizeHints(wnew); } + /* * Procedure Destroy() is called during the destruction of the widget. * Destroy() releases and frees GCs, frees the pixmaps and frees the *************** *** 543,548 **** --- 932,938 ---- XFreeFont(XtDisplay((Widget)widget), widget->angband.fnt); } + /* * Procedure Redisplay() is called as the result of an Expose event. * Use the redraw callback to do a full redraw *************** *** 555,570 **** } } /* * Font, colors and internal_border can be changed on the fly. * The entire widget is redrawn if any of those parameters change (all * can potentially have effects that spans the whole widget). */ static Boolean SetValues(AngbandWidget current, AngbandWidget request, ! AngbandWidget new, ArgList args, Cardinal *num_args) { ! int depth = DefaultDepthOfScreen(XtScreen((Widget) new)); Boolean font_changed = FALSE; Boolean border_changed = FALSE; Boolean color_changed = FALSE; --- 945,961 ---- } } + /* * Font, colors and internal_border can be changed on the fly. * The entire widget is redrawn if any of those parameters change (all * can potentially have effects that spans the whole widget). */ static Boolean SetValues(AngbandWidget current, AngbandWidget request, ! AngbandWidget wnew, ArgList args, Cardinal *num_args) { ! int depth = DefaultDepthOfScreen(XtScreen((Widget) wnew)); Boolean font_changed = FALSE; Boolean border_changed = FALSE; Boolean color_changed = FALSE; *************** *** 573,607 **** int n; /* Changed font? */ ! if (current->angband.font != new->angband.font) { /* Check if the font exists */ ! new->angband.fnt = getFont(new, new->angband.font, FALSE); /* The font didn't exist */ ! if (new->angband.fnt == NULL) { ! new->angband.fnt = current->angband.fnt; ! new->angband.font = current->angband.font; XtWarning("Couldn't find the request font!"); } else { font_changed = TRUE; /* Free the old font */ ! XFreeFont(XtDisplay((Widget)new), current->angband.fnt); /* Update font information */ ! new->angband.fontheight = new->angband.fnt->ascent + ! new->angband.fnt->descent; ! new->angband.fontwidth = new->angband.fnt->max_bounds.width; ! new->angband.fontascent = new->angband.fnt->ascent; } } /* Check all colors, if one or more has changed the redo all GC's */ for (n = 0; n < NUM_COLORS; n++) { ! if (current->angband.color[n] != new->angband.color[n]) { color_changed = TRUE; } --- 964,998 ---- int n; /* Changed font? */ ! if (current->angband.font != wnew->angband.font) { /* Check if the font exists */ ! wnew->angband.fnt = getFont(wnew, wnew->angband.font, FALSE); /* The font didn't exist */ ! if (wnew->angband.fnt == NULL) { ! wnew->angband.fnt = current->angband.fnt; ! wnew->angband.font = current->angband.font; XtWarning("Couldn't find the request font!"); } else { font_changed = TRUE; /* Free the old font */ ! XFreeFont(XtDisplay((Widget)wnew), current->angband.fnt); /* Update font information */ ! wnew->angband.fontheight = wnew->angband.fnt->ascent + ! wnew->angband.fnt->descent; ! wnew->angband.fontwidth = wnew->angband.fnt->max_bounds.width; ! wnew->angband.fontascent = wnew->angband.fnt->ascent; } } /* Check all colors, if one or more has changed the redo all GC's */ for (n = 0; n < NUM_COLORS; n++) { ! if (current->angband.color[n] != wnew->angband.color[n]) { color_changed = TRUE; } *************** *** 610,649 **** /* Change all GC's if color or font has changed */ if (color_changed || font_changed) { ! gcv.font = new->angband.fnt->fid; gcv.graphics_exposures = FALSE; ! gcv.background = new->angband.color[0]; /* Do all GC's */ for (n = 0; n < NUM_COLORS; n++) { if (depth == 1 && n >= 1) ! gcv.foreground = new->angband.color[1]; else ! gcv.foreground = new->angband.color[n]; /* Release the old GC */ XtReleaseGC((Widget)current, current->angband.gc[n]); /* Get the new GC */ ! new->angband.gc[n] = XtGetGC((Widget)new, GCFont | GCForeground | GCBackground | GCGraphicsExposures, &gcv); } /* Replace the old XOR/highlighting GC */ ! gcv.foreground = (BlackPixelOfScreen(XtScreen((Widget)new)) ^ ! WhitePixelOfScreen(XtScreen((Widget)new))); gcv.function = GXxor; ! XtReleaseGC((Widget)current, current->angband.gc[NUM_COLORS]); ! new->angband.gc[NUM_COLORS] = XtGetGC((Widget)new, GCFunction | GCGraphicsExposures | GCForeground, &gcv); /* Fix the background color */ ! new->core.background_pixel = new->angband.color[0]; } /* Check if internal border width has changed, used later */ ! if (current->angband.internal_border != new->angband.internal_border) border_changed = TRUE; /* If the font or the internal border has changed, all geometry --- 1001,1049 ---- /* Change all GC's if color or font has changed */ if (color_changed || font_changed) { ! gcv.font = wnew->angband.fnt->fid; gcv.graphics_exposures = FALSE; ! gcv.background = wnew->angband.color[0]; /* Do all GC's */ for (n = 0; n < NUM_COLORS; n++) { if (depth == 1 && n >= 1) ! { ! gcv.foreground = wnew->angband.color[1]; ! } else ! { ! gcv.foreground = wnew->angband.color[n]; ! } ! /* Release the old GC */ XtReleaseGC((Widget)current, current->angband.gc[n]); + /* Get the new GC */ ! wnew->angband.gc[n] = XtGetGC((Widget)wnew, GCFont | GCForeground | GCBackground | GCGraphicsExposures, &gcv); } /* Replace the old XOR/highlighting GC */ ! gcv.foreground = (BlackPixelOfScreen(XtScreen((Widget)wnew)) ^ ! WhitePixelOfScreen(XtScreen((Widget)wnew))); gcv.function = GXxor; ! XtReleaseGC((Widget)current, current->angband.gc[COLOR_XOR]); ! wnew->angband.gc[NUM_COLORS] = XtGetGC((Widget)wnew, GCFunction | GCGraphicsExposures | GCForeground, &gcv); + /* Fix the background color */ ! wnew->core.background_pixel = wnew->angband.color[0]; } /* Check if internal border width has changed, used later */ ! if (current->angband.internal_border != wnew->angband.internal_border) ! { border_changed = TRUE; + } /* If the font or the internal border has changed, all geometry *************** *** 651,665 **** if (font_changed || border_changed) { /* Change window size */ ! height = (current->core.height - 2 * current->angband.internal_border) / ! current->angband.fontheight * new->angband.fontheight + ! 2 * current->angband.internal_border; ! width = (current->core.width - 2 * current->angband.internal_border) / ! current->angband.fontwidth * new->angband.fontwidth + ! 2 * new->angband.internal_border; /* Get the new width */ ! if (XtMakeResizeRequest((Widget)new, width, height, NULL, NULL) == XtGeometryNo) { /* Not allowed */ --- 1051,1065 ---- if (font_changed || border_changed) { /* Change window size */ ! height = ((current->core.height - 2 * current->angband.internal_border) / ! current->angband.fontheight * wnew->angband.fontheight + ! 2 * current->angband.internal_border); ! width = ((current->core.width - 2 * current->angband.internal_border) / ! current->angband.fontwidth * wnew->angband.fontwidth + ! 2 * wnew->angband.internal_border); /* Get the new width */ ! if (XtMakeResizeRequest((Widget)wnew, width, height, NULL, NULL) == XtGeometryNo) { /* Not allowed */ *************** *** 668,674 **** else { /* Recalculate size hints */ ! calculateSizeHints(new); } } --- 1068,1074 ---- else { /* Recalculate size hints */ ! calculateSizeHints(wnew); } } *************** *** 676,718 **** return (font_changed || color_changed || border_changed); } /* * Calculate size hints */ ! static void calculateSizeHints(AngbandWidget new) { TopLevelShellWidget parent = ! (TopLevelShellWidget)XtParent((Widget) new); /* Calculate minimum size */ parent->wm.size_hints.min_height = ! new->angband.min_rows * new->angband.fontheight + ! 2 * new->angband.internal_border; parent->wm.size_hints.min_width = ! new->angband.min_columns * new->angband.fontwidth + ! 2 * new->angband.internal_border; parent->wm.size_hints.flags |= PMinSize; /* Calculate maximum size */ parent->wm.size_hints.max_height = ! new->angband.max_rows * new->angband.fontheight + ! 2 * new->angband.internal_border; parent->wm.size_hints.max_width = ! new->angband.max_columns * new->angband.fontwidth + ! 2 * new->angband.internal_border; parent->wm.size_hints.flags |= PMaxSize; /* Calculate increment size */ ! parent->wm.size_hints.height_inc = new->angband.fontheight; ! parent->wm.size_hints.width_inc = new->angband.fontwidth; parent->wm.size_hints.flags |= PResizeInc; /* Calculate base size */ ! parent->wm.base_height = 2 * new->angband.internal_border; ! parent->wm.base_width = 2 * new->angband.internal_border; parent->wm.size_hints.flags |= PBaseSize; } /* * Load a font */ --- 1076,1128 ---- return (font_changed || color_changed || border_changed); } + /* * Calculate size hints */ ! static void calculateSizeHints(AngbandWidget wnew) { TopLevelShellWidget parent = ! (TopLevelShellWidget)XtParent((Widget) wnew); /* Calculate minimum size */ parent->wm.size_hints.min_height = ! (wnew->angband.min_rows * wnew->angband.fontheight + ! 2 * wnew->angband.internal_border); ! ! /* Calculate minimum size */ parent->wm.size_hints.min_width = ! (wnew->angband.min_columns * wnew->angband.fontwidth + ! 2 * wnew->angband.internal_border); ! ! /* Calculate minimum size */ parent->wm.size_hints.flags |= PMinSize; /* Calculate maximum size */ parent->wm.size_hints.max_height = ! (wnew->angband.max_rows * wnew->angband.fontheight + ! 2 * wnew->angband.internal_border); ! ! /* Calculate maximum size */ parent->wm.size_hints.max_width = ! (wnew->angband.max_columns * wnew->angband.fontwidth + ! 2 * wnew->angband.internal_border); ! ! /* Calculate maximum size */ parent->wm.size_hints.flags |= PMaxSize; /* Calculate increment size */ ! parent->wm.size_hints.height_inc = wnew->angband.fontheight; ! parent->wm.size_hints.width_inc = wnew->angband.fontwidth; parent->wm.size_hints.flags |= PResizeInc; /* Calculate base size */ ! parent->wm.base_height = 2 * wnew->angband.internal_border; ! parent->wm.base_width = 2 * wnew->angband.internal_border; parent->wm.size_hints.flags |= PBaseSize; } + /* * Load a font */ *************** *** 738,744 **** ! /*** The non-widget code ****/ --- 1148,1154 ---- ! /*** The Angband code ****/ *************** *** 747,752 **** --- 1157,1164 ---- /* * Keysym macros, used on Keysyms to test for classes of symbols * These were stolen from one of the X11 header files + * + * Also appears in "main-x11.c". */ #define IsKeypadKey(keysym) \ *************** *** 773,778 **** --- 1185,1192 ---- /* * Checks if the keysym is a special key or a normal key * Assume that XK_MISCELLANY keysyms are special + * + * Also appears in "main-x11.c". */ #define IsSpecialKey(keysym) \ ((unsigned)(keysym) >= 0xFF00) *************** *** 784,799 **** --- 1198,1216 ---- */ #define MAX_TERM_DATA 8 + /* * Number of fallback resources per window */ #define TERM_FALLBACKS 6 + /* * Forward declare */ typedef struct term_data term_data; + /* * A structure for each "term" */ *************** *** 804,814 **** --- 1221,1236 ---- AngbandWidget widget; }; + /* * An array of term_data's */ static term_data data[MAX_TERM_DATA]; + + /* + * The names of the term_data's + */ char *termNames[MAX_TERM_DATA] = { "angband", *************** *** 821,826 **** --- 1243,1252 ---- "term-7" }; + + /* + * The special Arg's + */ Arg specialArgs[TERM_FALLBACKS] = { { XtNstartRows, 24}, *************** *** 831,836 **** --- 1257,1266 ---- { XtNmaxColumns, 80} }; + + /* + * The default Arg's + */ Arg defaultArgs[TERM_FALLBACKS] = { { XtNstartRows, 24}, *************** *** 847,852 **** --- 1277,1283 ---- */ XtAppContext appcon; + /* * User changable information about widgets */ *************** *** 892,904 **** Term_activate(&old_td->t); } /* * Process a keypress event */ ! static void react_keypress(XKeyEvent *ev) { int i, n, mc, ms, mo, mx; KeySym ks; char buf[128]; --- 1323,1343 ---- Term_activate(&old_td->t); } + + /* * Process a keypress event + * + * Also appears in "main-x11.c". */ ! static void react_keypress(XKeyEvent *xev) { int i, n, mc, ms, mo, mx; + uint ks1; + + XKeyEvent *ev = (XKeyEvent*)(xev); + KeySym ks; char buf[128]; *************** *** 911,924 **** /* Terminate */ buf[n] = '\0'; /* Extract four "modifier flags" */ mc = (ev->state & ControlMask) ? TRUE : FALSE; ms = (ev->state & ShiftMask) ? TRUE : FALSE; mo = (ev->state & Mod1Mask) ? TRUE : FALSE; mx = (ev->state & Mod2Mask) ? TRUE : FALSE; - /* Hack -- Ignore "modifier keys" */ - if (IsModifierKey(ks)) return; /* Normal keys with no modifiers */ if (n && !mo && !mx && !IsSpecialKey(ks)) --- 1350,1369 ---- /* Terminate */ buf[n] = '\0'; + + /* Hack -- Ignore "modifier keys" */ + if (IsModifierKey(ks)) return; + + + /* Hack -- convert into an unsigned int */ + ks1 = (uint)(ks); + /* Extract four "modifier flags" */ mc = (ev->state & ControlMask) ? TRUE : FALSE; ms = (ev->state & ShiftMask) ? TRUE : FALSE; mo = (ev->state & Mod1Mask) ? TRUE : FALSE; mx = (ev->state & Mod2Mask) ? TRUE : FALSE; /* Normal keys with no modifiers */ if (n && !mo && !mx && !IsSpecialKey(ks)) *************** *** 930,952 **** return; } ! /* Handle a few standard keys */ ! switch (ks) { case XK_Escape: ! Term_keypress(ESCAPE); return; case XK_Return: ! Term_keypress('\r'); return; case XK_Tab: ! Term_keypress('\t'); return; case XK_Delete: case XK_BackSpace: ! Term_keypress('\010'); return; } /* Hack -- Use the KeySym */ if (ks) { --- 1375,1411 ---- return; } ! ! /* Handle a few standard keys (bypass modifiers) XXX XXX XXX */ ! switch (ks1) { case XK_Escape: ! { ! Term_keypress(ESCAPE); ! return; ! } case XK_Return: ! { ! Term_keypress('\r'); ! return; ! } case XK_Tab: ! { ! Term_keypress('\t'); ! return; ! } case XK_Delete: case XK_BackSpace: ! { ! Term_keypress('\010'); ! return; ! } } + /* Hack -- Use the KeySym */ if (ks) { *************** *** 965,992 **** ev->keycode, 13); } ! /* Enqueue the "fake" string */ ! for (i = 0; msg[i]; i++) ! Term_keypress(msg[i]); ! ! /* Hack -- dump an "extra" string */ ! if (n) ! { ! /* Start the "extra" string */ ! Term_keypress(28); - /* Enqueue the "real" string */ - for (i = 0; buf[i]; i++) - Term_keypress(buf[i]); ! /* End the "extra" string */ ! Term_keypress(28); } } ! static void handle_event (Widget widget, XtPointer client_data, XEvent *event, ! Boolean *continue_to_dispatch) { term_data *old_td = (term_data*)(Term->data); term_data *td = (term_data *)client_data; --- 1424,1447 ---- ev->keycode, 13); } ! /* Enqueue the "macro trigger" string */ ! for (i = 0; msg[i]; i++) Term_keypress(msg[i]); ! /* Hack -- auto-define macros as needed */ ! if (n && (macro_find_exact(msg) < 0)) ! { ! /* Create a macro */ ! macro_add(msg, buf); } } ! /* ! * Handle an event ! */ ! static void handle_event(Widget widget, XtPointer client_data, XEvent *event, ! Boolean *continue_to_dispatch) { term_data *old_td = (term_data*)(Term->data); term_data *td = (term_data *)client_data; *************** *** 1000,1011 **** switch (event->type) { case KeyPress: ! react_keypress(&(event->xkey)); ! *continue_to_dispatch = FALSE; /* We took care of the event */ ! break; default: ! break; /* Huh? Shouldn't happen! */ } /* Activate the old term */ --- 1455,1478 ---- switch (event->type) { case KeyPress: ! { ! /* Hack -- use old term */ ! Term_activate(&old_td->t); ! ! /* Handle the keypress */ ! react_keypress(&(event->xkey)); + /* We took care of the event */ + *continue_to_dispatch = FALSE; + + break; + } + + /* Oops */ default: ! { ! break; ! } } /* Activate the old term */ *************** *** 1111,1117 **** /* ! * Draw the cursor (XXX by hiliting) */ static errr Term_curs_xaw(int x, int y) { --- 1578,1584 ---- /* ! * Draw the cursor, by hiliting with XOR */ static errr Term_curs_xaw(int x, int y) { *************** *** 1140,1145 **** --- 1607,1631 ---- } + #ifdef USE_GRAPHICS + + /* + * Draw some graphical characters. + */ + static errr Term_pict_xaw(int x, int y, int n, const byte *ap, const char *cp) + { + term_data *td = (term_data*)(Term->data); + + /* Draw the pictures */ + AngbandOutputPict(td->widget, x, y, n, ap, cp); + + /* Success */ + return (0); + } + + #endif /* USE_GRAPHICS */ + + /* * Raise a term */ *************** *** 1167,1174 **** /* Create the interior widget */ td->widget = (AngbandWidget) ! XtCreateManagedWidget (name, angbandWidgetClass, ! parent, widget_arg, widget_arg_no); /* Initialize the term (full size) */ term_init(t, 80, 24, key_buf); --- 1653,1660 ---- /* Create the interior widget */ td->widget = (AngbandWidget) ! XtCreateManagedWidget(name, angbandWidgetClass, ! parent, widget_arg, widget_arg_no); /* Initialize the term (full size) */ term_init(t, 80, 24, key_buf); *************** *** 1186,1191 **** --- 1672,1688 ---- t->wipe_hook = Term_wipe_xaw; t->text_hook = Term_text_xaw; + #ifdef USE_GRAPHICS + + if (use_graphics) + { + t->pict_hook = Term_pict_xaw; + + t->higher_pict = TRUE; + } + + #endif /* USE_GRAPHICS */ + /* Save the data */ t->data = td; *************** *** 1221,1226 **** --- 1718,1731 ---- Widget topLevel; Display *dpy; + #ifdef USE_GRAPHICS + + char filename[1024]; + + XImage *tiles_good = NULL; + + #endif /* USE_GRAPHICS */ + /* Attempt to open the local display */ dpy = XOpenDisplay(""); *************** *** 1237,1255 **** XtSetLanguageProc(NULL, NULL, NULL); #endif ! /* Initialize the toolkit */ ! topLevel = XtAppInitialize (&appcon, "Angband", NULL, 0, &argc, argv, ! fallback, NULL, 0); /* Initialize the windows */ for (i=0; iwidget); ! ! unsigned long ColTable[256]; ! ! XImage *tiles_raw; ! ! dpy = XtDisplay(widget); ! ! /* Prepare color table */ ! for (i = 0; i < 256; ++i) ! { ! XGCValues xgcv; ! ! XGetGCValues(dpy, td->widget->angband.gc[i], ! GCForeground, &xgcv); ! ! ColTable[i] = xgcv.foreground; ! } ! ! /* Load the graphics XXX XXX XXX */ ! tiles_raw = ReadRaw(dpy, filename, 256, 256); ! tiles_good = RemapColors(dpy, tiles_raw, ColTable); ! XDestroyImage(tiles_raw); } + /* Load graphics */ + if (use_graphics) + { + /* Initialize the windows */ + for (i=0; iwidget); + + dpy = XtDisplay(widget); + + /* Resize tiles */ + td->widget->angband.tiles = + (ResizeImage(dpy, tiles_good, 8, 8, + td->widget->angband.fontwidth, + td->widget->angband.fontheight)); + } + } + + #endif /* USE_GRAPHICS */ + + /* Activate the "Angband" window screen */ Term_activate(&data[0].t); *************** *** 1261,1264 **** --- 1859,1863 ---- } #endif + diff -c -r angband-282/src/main-xxx.c angband-283/src/main-xxx.c *** angband-282/src/main-xxx.c Wed Sep 3 11:57:33 1997 --- angband-283/src/main-xxx.c Fri Feb 6 04:10:31 1998 *************** *** 1,17 **** /* File: main-xxx.c */ /* ! * Copyright (c) 1997 Ben Harrison, and others * * 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. */ - /* Purpose: Sample visual module for Angband 2.8.1 */ /* ! * This file written by "Ben Harrison (benh@voicenet.com)". * * This file is intended to show one way to build a "visual module" * for Angband to allow it to work with a new system. It does not --- 1,19 ---- /* File: main-xxx.c */ /* ! * Copyright (c) 1997 Ben Harrison * * 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. */ /* ! * This file helps Angband work on non-existant computers. ! * ! * To use this file, use "Makefile.xxx", which defines USE_XXX. ! * * * This file is intended to show one way to build a "visual module" * for Angband to allow it to work with a new system. It does not *************** *** 54,63 **** * When you complete a port to a new system, you should email any * newly created files, and any changes made to existing files, * including "h-config.h", "config.h", and any of the "Makefile" ! * files, to "benh@voicenet.com" for inclusion in the next version. * ! * Try to stick to a "three letter" naming scheme for "main-xxx.c" * and "Makefile.xxx" and such for consistency and simplicity. */ --- 56,68 ---- * When you complete a port to a new system, you should email any * newly created files, and any changes made to existing files, * including "h-config.h", "config.h", and any of the "Makefile" ! * files, to "benh@phial.com" for inclusion in the next version. * ! * Always choose a "three letter" naming scheme for "main-xxx.c" * and "Makefile.xxx" and such for consistency and simplicity. + * + * + * Initial framework (and all code) by Ben Harrison (benh@phial.com). */ *************** *** 106,155 **** static term_data data[MAX_TERM_DATA]; ! #if 0 /* Fix the syntax below XXX XXX XXX */ /* ! * The "color" array for the visual module XXX XXX XXX * ! * This table should be used in whetever way is necessary to ! * convert the Angband Color Indexes into the proper "color data" ! * for the visual system. On the Macintosh, these are arrays of ! * three shorts, on the IBM, these are combinations of the eight ! * basic color codes with optional "bright" bits, on X11, these ! * are actual "pixel" codes extracted from another table which ! * contains textual color names. ! * ! * The Angband Color Set (0 to 15): ! * Black, White, Slate, Orange, Red, Blue, Green, Umber ! * D-Gray, L-Gray, Violet, Yellow, L-Red, L-Blue, L-Green, L-Umber ! * ! * Colors 8 to 15 are basically "enhanced" versions of Colors 0 to 7. ! * ! * As decribed in one of the header files, in a perfect world, the ! * colors below should fit a nice clean "quartered" specification ! * in RGB codes, but this must often be Gamma Corrected. The 1/4 ! * parts of each Red,Green,Blue are shown in the comments below, ! * again, these values are *before* gamma correction. ! */ ! static local_color_data_type color_data[16] = ! { ! /* XXX XXX XXX 0,0,0 */, /* TERM_DARK */ ! /* XXX XXX XXX 4,4,4 */, /* TERM_WHITE */ ! /* XXX XXX XXX 2,2,2 */, /* TERM_SLATE */ ! /* XXX XXX XXX 4,2,0 */, /* TERM_ORANGE */ ! /* XXX XXX XXX 3,0,0 */, /* TERM_RED */ ! /* XXX XXX XXX 0,2,1 */, /* TERM_GREEN */ ! /* XXX XXX XXX 0,0,4 */, /* TERM_BLUE */ ! /* XXX XXX XXX 2,1,0 */, /* TERM_UMBER */ ! /* XXX XXX XXX 1,1,1 */, /* TERM_L_DARK */ ! /* XXX XXX XXX 3,3,3 */, /* TERM_L_WHITE */ ! /* XXX XXX XXX 4,0,4 */, /* TERM_VIOLET */ ! /* XXX XXX XXX 4,4,0 */, /* TERM_YELLOW */ ! /* XXX XXX XXX 4,0,0 */, /* TERM_L_RED */ ! /* XXX XXX XXX 0,4,0 */, /* TERM_L_GREEN */ ! /* XXX XXX XXX 0,4,4 */, /* TERM_L_BLUE */ ! /* XXX XXX XXX 3,2,1 */ /* TERM_L_UMBER */ ! }; #endif --- 111,126 ---- static term_data data[MAX_TERM_DATA]; ! #if 0 /* ! * Often, it is helpful to create an array of "color data" containing ! * a representation of the "angband_colors" array in some "local" form. * ! * Often, the "Term_xtra(TERM_XTRA_REACT, 0)" hook is used to initialize ! * "color_data" from "angband_colors". XXX XXX XXX ! */ ! static local_color_data_type color_data[256]; #endif *************** *** 384,390 **** * React to global changes XXX XXX XXX * * For example, this action can be used to react to ! * changes in the global "color_table[256][4]" array. * * This action is optional, but can be very useful for * handling "color changes" and the "arg_sound" and/or --- 355,361 ---- * React to global changes XXX XXX XXX * * For example, this action can be used to react to ! * changes in the global "angband_colors[256][4]" array. * * This action is optional, but can be very useful for * handling "color changes" and the "arg_sound" and/or *************** *** 674,679 **** --- 645,652 ---- /* Initialize "term_data" structures XXX XXX XXX */ + /* Initialize the "color_data" array XXX XXX XXX */ + /* Create windows (backwards!) */ for (i = TERM_DATA_MAX - 1; i >= 0; i--) { *************** *** 775,777 **** --- 748,752 ---- #endif /* USE_XXX */ + + diff -c -r angband-282/src/main.c angband-283/src/main.c *** angband-282/src/main.c Wed Sep 3 11:57:33 1997 --- angband-283/src/main.c Wed Feb 11 06:30:28 1998 *************** *** 470,475 **** --- 470,479 ---- + /* Install "quit" hook */ + quit_aux = quit_hook; + + /* Drop privs (so X11 will work correctly) */ safe_setuid_drop(); *************** *** 500,506 **** } #endif - #ifdef USE_GCU /* Attempt to use the "main-gcu.c" support */ if (!done && (!mstr || (streq(mstr, "gcu")))) --- 504,509 ---- *************** *** 528,594 **** #endif #ifdef USE_IBM /* Attempt to use the "main-ibm.c" support */ ! if (!done) { extern errr init_ibm(void); ! if (0 == init_ibm()) done = TRUE; ! if (done) ANGBAND_SYS = "ibm"; } #endif #ifdef USE_EMX /* Attempt to use the "main-emx.c" support */ ! if (!done) { extern errr init_emx(void); ! if (0 == init_emx()) done = TRUE; ! if (done) ANGBAND_SYS = "emx"; } #endif #ifdef USE_SLA /* Attempt to use the "main-sla.c" support */ ! if (!done) { extern errr init_sla(void); ! if (0 == init_sla()) done = TRUE; ! if (done) ANGBAND_SYS = "sla"; } #endif #ifdef USE_LSL /* Attempt to use the "main-lsl.c" support */ ! if (!done) { extern errr init_lsl(void); ! if (0 == init_lsl()) done = TRUE; ! if (done) ANGBAND_SYS = "lsl"; } #endif #ifdef USE_AMI /* Attempt to use the "main-ami.c" support */ ! if (!done) { extern errr init_ami(void); ! if (0 == init_ami()) done = TRUE; ! if (done) ANGBAND_SYS = "ami"; } #endif #ifdef USE_VME /* Attempt to use the "main-vme.c" support */ ! if (!done) { extern errr init_vme(void); ! if (0 == init_vme()) done = TRUE; ! if (done) ANGBAND_SYS = "vme"; } #endif --- 531,629 ---- #endif + #ifdef USE_DOS + /* Attempt to use the "main-dos.c" support */ + if (!done && (!mstr || (streq(mstr, "dos")))) + { + extern errr init_dos(void); + if (0 == init_dos()) + { + ANGBAND_SYS = "dos"; + done = TRUE; + } + } + #endif + #ifdef USE_IBM /* Attempt to use the "main-ibm.c" support */ ! if (!done && (!mstr || (streq(mstr, "ibm")))) { extern errr init_ibm(void); ! if (0 == init_ibm()) ! { ! ANGBAND_SYS = "ibm"; ! done = TRUE; ! } } #endif + #ifdef USE_EMX /* Attempt to use the "main-emx.c" support */ ! if (!done && (!mstr || (streq(mstr, "emx")))) { extern errr init_emx(void); ! if (0 == init_emx()) ! { ! ANGBAND_SYS = "emx"; ! done = TRUE; ! } } #endif #ifdef USE_SLA /* Attempt to use the "main-sla.c" support */ ! if (!done && (!mstr || (streq(mstr, "sla")))) { extern errr init_sla(void); ! if (0 == init_sla()) ! { ! ANGBAND_SYS = "sla"; ! done = TRUE; ! } } #endif #ifdef USE_LSL /* Attempt to use the "main-lsl.c" support */ ! if (!done && (!mstr || (streq(mstr, "lsl")))) { extern errr init_lsl(void); ! if (0 == init_lsl()) ! { ! ANGBAND_SYS = "lsl"; ! done = TRUE; ! } } #endif #ifdef USE_AMI /* Attempt to use the "main-ami.c" support */ ! if (!done && (!mstr || (streq(mstr, "ami")))) { extern errr init_ami(void); ! if (0 == init_ami()) ! { ! ANGBAND_SYS = "ami"; ! done = TRUE; ! } } #endif #ifdef USE_VME /* Attempt to use the "main-vme.c" support */ ! if (!done && (!mstr || (streq(mstr, "vme")))) { extern errr init_vme(void); ! if (0 == init_vme()) ! { ! ANGBAND_SYS = "vme"; ! done = TRUE; ! } } #endif *************** *** 601,611 **** if (!done) quit("Unable to prepare any 'display module'!"); ! /* Tell "quit()" to call "Term_nuke()" */ ! quit_aux = quit_hook; ! ! ! /* If requested, display scores and quit */ if (show_score > 0) display_scores(0, show_score); --- 636,642 ---- if (!done) quit("Unable to prepare any 'display module'!"); ! /* Hack -- If requested, display scores and quit */ if (show_score > 0) display_scores(0, show_score); diff -c -r angband-282/src/melee1.c angband-283/src/melee1.c *** angband-282/src/melee1.c Thu Sep 4 10:17:53 1997 --- angband-283/src/melee1.c Wed Feb 11 06:30:28 1998 *************** *** 583,589 **** p_ptr->redraw |= (PR_GOLD); /* Window stuff */ ! p_ptr->window |= (PW_SPELL | PW_PLAYER); /* Blink away */ blinked = TRUE; --- 583,589 ---- p_ptr->redraw |= (PR_GOLD); /* Window stuff */ ! p_ptr->window |= (PW_PLAYER_0 | PW_PLAYER_1); /* Blink away */ blinked = TRUE; diff -c -r angband-282/src/melee2.c angband-283/src/melee2.c *** angband-282/src/melee2.c Thu Sep 4 10:17:53 1997 --- angband-283/src/melee2.c Wed Feb 11 06:30:28 1998 *************** *** 386,399 **** * Perhaps smart monsters should decline to use "bolt" spells if * there is a monster in the way, unless they wish to kill it. * - * Note that, to allow the use of the "track_target" option at some - * later time, certain non-optimal things are done in the code below, - * including explicit checks against the "direct" variable, which is - * currently always true by the time it is checked, but which should - * really be set according to an explicit "projectable()" test, and - * the use of generic "x,y" locations instead of the player location, - * with those values being initialized with the player location. - * * It will not be possible to "correctly" handle the case in which a * monster attempts to attack a location which is thought to contain * the player, but which in fact is nowhere near the player, since this --- 386,391 ---- *************** *** 410,417 **** * Note that certain spell attacks do not use the "project()" function * but "simulate" it via the "direct" variable, which is always at least * as restrictive as the "project()" function. This is necessary to ! * prevent "blindness" attacks and such from bending around walls, etc, ! * and to allow the use of the "track_target" option in the future. * * Note that this function attempts to optimize the use of spells for the * cases in which the monster has no spells, or has spells but cannot use --- 402,408 ---- * Note that certain spell attacks do not use the "project()" function * but "simulate" it via the "direct" variable, which is always at least * as restrictive as the "project()" function. This is necessary to ! * prevent "blindness" attacks and such from bending around walls. * * Note that this function attempts to optimize the use of spells for the * cases in which the monster has no spells, or has spells but cannot use *************** *** 480,488 **** if (rand_int(100) >= chance) return (FALSE); - /* XXX XXX XXX Handle "track_target" option (?) */ - - /* Hack -- require projectable player */ if (normal) { --- 471,476 ---- *************** *** 1039,1045 **** p_ptr->redraw |= (PR_MANA); /* Window stuff */ ! p_ptr->window |= (PW_SPELL | PW_PLAYER); /* Heal the monster */ if (m_ptr->hp < m_ptr->maxhp) --- 1027,1033 ---- p_ptr->redraw |= (PR_MANA); /* Window stuff */ ! p_ptr->window |= (PW_PLAYER_0 | PW_PLAYER_1); /* Heal the monster */ if (m_ptr->hp < m_ptr->maxhp) *************** *** 3158,3165 **** /* Notice changes in view */ if (do_view) { ! /* Update some things */ ! p_ptr->update |= (PU_VIEW | PU_LITE | PU_FLOW | PU_MONSTERS); } --- 3146,3156 ---- /* Notice changes in view */ if (do_view) { ! /* Update the visuals */ ! p_ptr->update |= (PU_UPDATE_VIEW | PU_MONSTERS); ! ! /* Fully update the flow XXX XXX XXX */ ! p_ptr->update |= (PU_FORGET_FLOW | PU_UPDATE_FLOW); } diff -c -r angband-282/src/monster2.c angband-283/src/monster2.c *** angband-282/src/monster2.c Wed Sep 3 11:57:33 1997 --- angband-283/src/monster2.c Wed Feb 11 06:30:29 1998 *************** *** 41,50 **** /* Hack -- remove target monster */ ! if (i == p_ptr->target_who) p_ptr->target_who = 0; /* Hack -- remove tracked monster */ ! if (i == p_ptr->health_who) health_track(0); /* Monster is gone */ --- 41,50 ---- /* Hack -- remove target monster */ ! if (p_ptr->target_who == i) target_set_monster(0); /* Hack -- remove tracked monster */ ! if (p_ptr->health_who == i) health_track(0); /* Monster is gone */ *************** *** 140,146 **** if (p_ptr->target_who == i1) p_ptr->target_who = i2; /* Hack -- Update the health bar */ ! if (p_ptr->health_who == i1) health_track(i2); /* Hack -- move monster */ COPY(&m_list[i2], &m_list[i1], monster_type); --- 140,146 ---- if (p_ptr->target_who == i1) p_ptr->target_who = i2; /* Hack -- Update the health bar */ ! if (p_ptr->health_who == i1) p_ptr->health_who = i2; /* Hack -- move monster */ COPY(&m_list[i2], &m_list[i1], monster_type); *************** *** 279,285 **** num_repro = 0; /* Hack -- no more target */ ! p_ptr->target_who = 0; /* Hack -- no more tracking */ health_track(0); --- 279,285 ---- num_repro = 0; /* Hack -- no more target */ ! target_set_monster(0); /* Hack -- no more tracking */ health_track(0); *************** *** 794,818 **** /* * This function updates the monster record of the given monster * ! * This involves extracting the distance to the player (if needed), * and then checking for visibility (natural, infravision, see-invis, * telepathy), updating the monster visibility flag, redrawing (or ! * erasing) the monster when the visibility changes, and taking note * of any interesting monster flags (cold-blooded, invisible, etc). * ! * Note the new "mflag" field which encodes several monster state ! * flags, including "view" for "currently in line of sight" and ! * "mark" for "currently visible via detection". * * The only monster fields that are changed here are "cdis" (the * distance from the player), "ml" (visible to the player), and * "mflag" (to maintain the "MFLAG_VIEW" flag). * ! * Note the special "update_monsters()" function which can be used ! * to call this function for every monster. * ! * Note the "full" flag which requests that the "cdis" field be ! * updated, often, such an update is not needed. * * Every time a monster moves, we must call this function for that * monster, and update the distance, and the visibility. Every time --- 794,818 ---- /* * This function updates the monster record of the given monster * ! * This involves extracting the distance to the player (if requested), * and then checking for visibility (natural, infravision, see-invis, * telepathy), updating the monster visibility flag, redrawing (or ! * erasing) the monster when its visibility changes, and taking note * of any interesting monster flags (cold-blooded, invisible, etc). * ! * Note the new "mflag" field which encodes several monster state flags, ! * including "view" for when the monster is currently in line of sight, ! * and "mark" for when the monster is currently visible via detection. * * The only monster fields that are changed here are "cdis" (the * distance from the player), "ml" (visible to the player), and * "mflag" (to maintain the "MFLAG_VIEW" flag). * ! * Note the special "update_monsters()" function which can be used to ! * call this function once for every monster. * ! * Note the "full" flag which requests that the "cdis" field be updated, ! * this is only needed when the monster (or the player) has moved. * * Every time a monster moves, we must call this function for that * monster, and update the distance, and the visibility. Every time *************** *** 822,830 **** * and "see invisible"), we must call this function for every monster, * and update the visibility. * ! * Routines that change the "illumination" of grids must also call ! * this function, since the "visibility" of some monsters may be ! * based on the illumination of their grid. * * Note that this function is called once per monster every time the * player moves. When the player is running, this function is one --- 822,830 ---- * and "see invisible"), we must call this function for every monster, * and update the visibility. * ! * Routines that change the "illumination" of a grid must also call this ! * function for any monster in that grid, since the "visibility" of some ! * monsters may be based on the illumination of their grid. * * Note that this function is called once per monster every time the * player moves. When the player is running, this function is one *************** *** 833,848 **** * * Note the optimized "inline" version of the "distance()" function. * - * Note the optimized "inline" version of the "player_can_see_bold()" - * function, which has been so optimized that it no longer has the - * same semantics, in particular, monsters in perma-lit walls can - * be seen even from the wrong side of the wall. - * * A monster is "visible" to the player if (1) it has been detected * by the player, (2) it is close to the player and the player has * telepathy, or (3) it is close to the player, and in line of sight * of the player, and it is "illuminated" by some combination of ! * light, infravision, and/or see-invisible. * * Monsters which are not on the current panel may be "visible" to * the player, and their descriptions will include an "offscreen" --- 833,844 ---- * * Note the optimized "inline" version of the "distance()" function. * * A monster is "visible" to the player if (1) it has been detected * by the player, (2) it is close to the player and the player has * telepathy, or (3) it is close to the player, and in line of sight * of the player, and it is "illuminated" by some combination of ! * infravision, torch light, or permanent light (invisible monsters ! * are only affected by "light" if the player can see invisible). * * Monsters which are not on the current panel may be "visible" to * the player, and their descriptions will include an "offscreen" *************** *** 949,955 **** } /* Normal line of sight, and not blind */ ! if ((cave_info[fy][fx] & (CAVE_VIEW)) && !p_ptr->blind) { bool do_invisible = FALSE; bool do_cold_blood = FALSE; --- 945,951 ---- } /* Normal line of sight, and not blind */ ! if (player_has_los_bold(fy, fx) && !p_ptr->blind) { bool do_invisible = FALSE; bool do_cold_blood = FALSE; *************** *** 973,979 **** } /* Use "illumination" */ ! if (cave_info[fy][fx] & (CAVE_LITE | CAVE_GLOW)) { /* Handle "invisible" monsters */ if (r_ptr->flags2 & (RF2_INVISIBLE)) --- 969,975 ---- } /* Use "illumination" */ ! if (player_can_see_bold(fy, fx)) { /* Handle "invisible" monsters */ if (r_ptr->flags2 & (RF2_INVISIBLE)) *************** *** 1221,1234 **** p_ptr->py = y2; p_ptr->px = x2; ! /* Check for new panel (redraw map) */ ! verify_panel(); ! /* Update stuff */ ! p_ptr->update |= (PU_VIEW | PU_LITE | PU_FLOW); ! /* Update the monsters */ ! p_ptr->update |= (PU_DISTANCE); /* Window stuff */ p_ptr->window |= (PW_OVERHEAD); --- 1217,1230 ---- p_ptr->py = y2; p_ptr->px = x2; ! /* Update the panel */ ! p_ptr->update |= (PU_PANEL); ! /* Update the visuals (and monster distances) */ ! p_ptr->update |= (PU_UPDATE_VIEW | PU_DISTANCE); ! /* Update the flow */ ! p_ptr->update |= (PU_UPDATE_FLOW); /* Window stuff */ p_ptr->window |= (PW_OVERHEAD); *************** *** 1248,1267 **** } /* Player 2 */ ! else if (m2 > 0) { /* Move player */ p_ptr->py = y1; p_ptr->px = x1; ! /* Check for new panel (redraw map) */ ! verify_panel(); ! /* Update stuff */ ! p_ptr->update |= (PU_VIEW | PU_LITE | PU_FLOW); ! /* Update the monsters */ ! p_ptr->update |= (PU_DISTANCE); /* Window stuff */ p_ptr->window |= (PW_OVERHEAD); --- 1244,1263 ---- } /* Player 2 */ ! else if (m2 < 0) { /* Move player */ p_ptr->py = y1; p_ptr->px = x1; ! /* Update the panel */ ! p_ptr->update |= (PU_PANEL); ! /* Update the visuals (and monster distances) */ ! p_ptr->update |= (PU_UPDATE_VIEW | PU_DISTANCE); ! /* Update the flow */ ! p_ptr->update |= (PU_UPDATE_FLOW); /* Window stuff */ p_ptr->window |= (PW_OVERHEAD); diff -c -r angband-282/src/object1.c angband-283/src/object1.c *** angband-282/src/object1.c Thu Sep 4 16:55:09 1997 --- angband-283/src/object1.c Wed Feb 11 06:30:29 1998 *************** *** 12,23 **** /* ! * XXX XXX Hack -- note that "TERM_MULTI" is now just "TERM_VIOLET" * We will have to find a cleaner method for "MULTI_HUED" later. * There were only two multi-hued "flavors" (one potion, one food). * Plus five multi-hued "base-objects" (3 dragon scales, one blade * of chaos, and one something else). See the SHIMMER_OBJECTS code * in "dungeon.c" and the object color extractor in "cave.c". */ #define TERM_MULTI TERM_VIOLET --- 12,24 ---- /* ! * Hack -- note that "TERM_MULTI" is now just "TERM_VIOLET". * We will have to find a cleaner method for "MULTI_HUED" later. * There were only two multi-hued "flavors" (one potion, one food). * Plus five multi-hued "base-objects" (3 dragon scales, one blade * of chaos, and one something else). See the SHIMMER_OBJECTS code * in "dungeon.c" and the object color extractor in "cave.c". + * Currently, the "SHIMMER_OBJECTS" code is disabled anyway. */ #define TERM_MULTI TERM_VIOLET *************** *** 258,292 **** * Certain items have a flavor * This function is used only by "flavor_init()" */ ! static bool object_has_flavor(int i) { ! object_kind *k_ptr = &k_info[i]; ! /* Check for flavor */ switch (k_ptr->tval) { - /* The standard "flavored" items */ case TV_AMULET: case TV_RING: case TV_STAFF: case TV_WAND: case TV_SCROLL: case TV_POTION: - case TV_ROD: { ! return (TRUE); } - /* Hack -- food SOMETIMES has a flavor */ case TV_FOOD: { ! if (k_ptr->sval < SV_FOOD_MIN_FOOD) return (TRUE); ! return (FALSE); } } ! /* Assume no flavor */ ! return (FALSE); } --- 259,319 ---- * Certain items have a flavor * This function is used only by "flavor_init()" */ ! static bool object_flavor(int k_idx) { ! object_kind *k_ptr = &k_info[k_idx]; ! /* Analyze the item */ switch (k_ptr->tval) { case TV_AMULET: + { + return (0x80 + amulet_col[k_ptr->sval]); + } + case TV_RING: + { + return (0x90 + ring_col[k_ptr->sval]); + } + case TV_STAFF: + { + return (0xA0 + staff_col[k_ptr->sval]); + } + case TV_WAND: + { + return (0xB0 + wand_col[k_ptr->sval]); + } + + case TV_ROD: + { + return (0xC0 + rod_col[k_ptr->sval]); + } + case TV_SCROLL: + { + return (0xD0 + scroll_col[k_ptr->sval]); + } + case TV_POTION: { ! return (0xE0 + potion_col[k_ptr->sval]); } case TV_FOOD: { ! if (k_ptr->sval < SV_FOOD_MIN_FOOD) ! { ! return (0xF0 + food_col[k_ptr->sval]); ! } ! ! break; } } ! /* No flavor */ ! return (0); } *************** *** 294,300 **** * Certain items, if aware, are known instantly * This function is used only by "flavor_init()" * ! * XXX XXX XXX Add "EASY_KNOW" flag to "k_info.txt" file */ static bool object_easy_know(int i) { --- 321,327 ---- * Certain items, if aware, are known instantly * This function is used only by "flavor_init()" * ! * Add "EASY_KNOW" flag to "k_info.txt" file. XXX XXX XXX */ static bool object_easy_know(int i) { *************** *** 345,482 **** /* - * Hack -- prepare the default object attr codes by tval - * - * XXX XXX XXX Off-load to "pref.prf" file - */ - static byte default_tval_to_attr(int tval) - { - switch (tval) - { - case TV_SKELETON: - case TV_BOTTLE: - case TV_JUNK: - { - return (TERM_WHITE); - } - - case TV_CHEST: - { - return (TERM_SLATE); - } - - case TV_SHOT: - case TV_BOLT: - case TV_ARROW: - { - return (TERM_L_UMBER); - } - - case TV_LITE: - { - return (TERM_YELLOW); - } - - case TV_SPIKE: - { - return (TERM_SLATE); - } - - case TV_BOW: - { - return (TERM_UMBER); - } - - case TV_DIGGING: - { - return (TERM_SLATE); - } - - case TV_HAFTED: - case TV_POLEARM: - case TV_SWORD: - { - return (TERM_L_WHITE); - } - - case TV_BOOTS: - case TV_GLOVES: - case TV_CROWN: - case TV_HELM: - case TV_SHIELD: - case TV_CLOAK: - { - return (TERM_L_UMBER); - } - - case TV_SOFT_ARMOR: - case TV_HARD_ARMOR: - case TV_DRAG_ARMOR: - { - return (TERM_SLATE); - } - - case TV_AMULET: - { - return (TERM_ORANGE); - } - - case TV_RING: - { - return (TERM_RED); - } - - case TV_STAFF: - { - return (TERM_L_UMBER); - } - - case TV_WAND: - { - return (TERM_L_GREEN); - } - - case TV_ROD: - { - return (TERM_L_WHITE); - } - - case TV_SCROLL: - { - return (TERM_WHITE); - } - - case TV_POTION: - { - return (TERM_L_BLUE); - } - - case TV_FLASK: - { - return (TERM_YELLOW); - } - - case TV_FOOD: - { - return (TERM_L_UMBER); - } - - case TV_MAGIC_BOOK: - { - return (TERM_L_RED); - } - - case TV_PRAYER_BOOK: - { - return (TERM_L_GREEN); - } - } - - return (TERM_WHITE); - } - - - /* * Prepare the "variable" part of the "k_info" array. * * The "color"/"metal"/"type" of an item is its "flavor". --- 372,377 ---- *************** *** 504,511 **** * This is accomplished by the use of a saved "random seed", as in * "town_gen()". Since no other functions are called while the special * seed is in effect, so this function is pretty "safe". - * - * Note that the "hacked seed" may provide an RNG with alternating parity! */ void flavor_init(void) { --- 399,404 ---- *************** *** 703,713 **** /* Skip "empty" objects */ if (!k_ptr->name) continue; ! /* Check for a "flavor" */ ! k_ptr->has_flavor = object_has_flavor(i); /* No flavor yields aware */ ! if (!k_ptr->has_flavor) k_ptr->aware = TRUE; /* Check for "easily known" */ k_ptr->easy_know = object_easy_know(i); --- 596,606 ---- /* Skip "empty" objects */ if (!k_ptr->name) continue; ! /* Extract "flavor" (if any) */ ! k_ptr->flavor = object_flavor(i); /* No flavor yields aware */ ! if (!k_ptr->flavor) k_ptr->aware = TRUE; /* Check for "easily known" */ k_ptr->easy_know = object_easy_know(i); *************** *** 715,770 **** } - - - /* - * Extract the "default" attr for each object - * This function is used only by "flavor_init()" - */ - static byte object_d_attr(int i) - { - object_kind *k_ptr = &k_info[i]; - - /* Flavored items */ - if (k_ptr->has_flavor) - { - /* Extract the indexx */ - int indexx = k_ptr->sval; - - /* Analyze the item */ - switch (k_ptr->tval) - { - case TV_FOOD: return (food_col[indexx]); - case TV_POTION: return (potion_col[indexx]); - case TV_SCROLL: return (scroll_col[indexx]); - case TV_AMULET: return (amulet_col[indexx]); - case TV_RING: return (ring_col[indexx]); - case TV_STAFF: return (staff_col[indexx]); - case TV_WAND: return (wand_col[indexx]); - case TV_ROD: return (rod_col[indexx]); - } - } - - /* Default attr if legal */ - if (k_ptr->k_attr) return (k_ptr->k_attr); - - /* Default to white */ - return (TERM_WHITE); - } - - - /* - * Extract the "default" char for each object - * This function is used only by "flavor_init()" - */ - static byte object_d_char(int i) - { - object_kind *k_ptr = &k_info[i]; - - return (k_ptr->k_char); - } - - /* * Reset the "visual" lists * --- 608,613 ---- *************** *** 773,846 **** * If the "prefs" flag is TRUE, then we will also load the appropriate * "user pref file" based on the current setting of the "use_graphics" * flag. This is useful for switching "graphics" on/off. */ ! void reset_visuals(bool prefs) { int i; ! /* Extract some info about terrain features */ for (i = 0; i < MAX_F_IDX; i++) { feature_type *f_ptr = &f_info[i]; /* Assume we will use the underlying values */ ! f_ptr->z_attr = f_ptr->f_attr; ! f_ptr->z_char = f_ptr->f_char; } ! /* Extract some info about objects */ for (i = 0; i < MAX_K_IDX; i++) { object_kind *k_ptr = &k_info[i]; ! /* Extract the "underlying" attr */ ! k_ptr->d_attr = object_d_attr(i); ! ! /* Extract the "underlying" char */ ! k_ptr->d_char = object_d_char(i); ! ! /* Assume we will use the underlying values */ k_ptr->x_attr = k_ptr->d_attr; k_ptr->x_char = k_ptr->d_char; } ! /* Extract some info about monsters */ for (i = 0; i < MAX_R_IDX; i++) { ! /* Extract the "underlying" attr */ ! r_info[i].x_attr = r_info[i].d_attr; ! /* Extract the "underlying" char */ ! r_info[i].x_char = r_info[i].d_char; } ! /* Default to white elsewhere? XXX XXX XXX */ ! /* Extract attr/chars for equippy items (by tval) */ for (i = 0; i < 128; i++) { ! /* Extract a default attr */ ! tval_to_attr[i] = default_tval_to_attr(i); } ! /* Process user pref files */ ! if (prefs) { ! /* Graphic symbols */ ! if (use_graphics) ! { ! /* Process "graf.prf" */ ! process_pref_file("graf.prf"); ! } ! /* Normal symbols */ ! else ! { ! /* Process "font.prf" */ ! process_pref_file("font.prf"); ! } } } --- 616,683 ---- * If the "prefs" flag is TRUE, then we will also load the appropriate * "user pref file" based on the current setting of the "use_graphics" * flag. This is useful for switching "graphics" on/off. + * + * The features, objects, and monsters, should all be encoded in the + * relevant "font.pref" and/or "graf.prf" files. XXX XXX XXX + * + * The "prefs" parameter is no longer meaningful. XXX XXX XXX */ ! void reset_visuals(bool unused) { int i; ! /* Extract default attr/char code for features */ for (i = 0; i < MAX_F_IDX; i++) { feature_type *f_ptr = &f_info[i]; /* Assume we will use the underlying values */ ! f_ptr->x_attr = f_ptr->d_attr; ! f_ptr->x_char = f_ptr->d_char; } ! /* Extract default attr/char code for objects */ for (i = 0; i < MAX_K_IDX; i++) { object_kind *k_ptr = &k_info[i]; ! /* Default attr/char */ k_ptr->x_attr = k_ptr->d_attr; k_ptr->x_char = k_ptr->d_char; } ! /* Extract default attr/char code for monsters */ for (i = 0; i < MAX_R_IDX; i++) { ! monster_race *r_ptr = &r_info[i]; ! /* Default attr/char */ ! r_ptr->x_attr = r_ptr->d_attr; ! r_ptr->x_char = r_ptr->d_char; } ! /* Extract attr/chars for inventory objects (by tval) */ for (i = 0; i < 128; i++) { ! /* Default to white */ ! tval_to_attr[i] = TERM_WHITE; } ! /* Graphic symbols */ ! if (use_graphics) { ! /* Process "graf.prf" */ ! process_pref_file("graf.prf"); ! } ! /* Normal symbols */ ! else ! { ! /* Process "font.prf" */ ! process_pref_file("font.prf"); } } *************** *** 995,1121 **** - /* ! * Print a char "c" into a string "t", as if by sprintf(t, "%c", c), ! * and return a pointer to the terminator (t + 1). */ ! static char *object_desc_chr(char *t, char c) ! { ! /* Copy the char */ ! *t++ = c; - /* Terminate */ - *t = '\0'; - - /* Result */ - return (t); - } - - - /* - * Print a string "s" into a string "t", as if by strcpy(t, s), - * and return a pointer to the terminator. - */ - static char *object_desc_str(char *t, cptr s) - { - /* Copy the string */ - while (*s) *t++ = *s++; - - /* Terminate */ - *t = '\0'; - - /* Result */ - return (t); - } - - - - /* - * Print an unsigned number "n" into a string "t", as if by - * sprintf(t, "%u", n), and return a pointer to the terminator. - */ - static char *object_desc_num(char *t, uint n) - { - uint p; - - /* Find "size" of "n" */ - for (p = 1; n >= p * 10; p = p * 10) /* loop */; - - /* Dump each digit */ - while (p >= 1) - { - /* Dump the digit */ - *t++ = '0' + n / p; - - /* Remove the digit */ - n = n % p; - - /* Process next digit */ - p = p / 10; - } - - /* Terminate */ - *t = '\0'; - - /* Result */ - return (t); - } - - - - - /* - * Print an signed number "v" into a string "t", as if by - * sprintf(t, "%+d", n), and return a pointer to the terminator. - * Note that we always print a sign, either "+" or "-". - */ - static char *object_desc_int(char *t, sint v) - { - uint p, n; - - /* Negative */ - if (v < 0) - { - /* Take the absolute value */ - n = 0 - v; - - /* Use a "minus" sign */ - *t++ = '-'; - } - - /* Positive (or zero) */ - else - { - /* Use the actual number */ - n = v; - - /* Use a "plus" sign */ - *t++ = '+'; - } - - /* Find "size" of "n" */ - for (p = 1; n >= p * 10; p = p * 10) /* loop */; - - /* Dump each digit */ - while (p >= 1) - { - /* Dump the digit */ - *t++ = '0' + n / p; - - /* Remove the digit */ - n = n % p; - - /* Process next digit */ - p = p / 10; - } - - /* Terminate */ - *t = '\0'; - - /* Result */ - return (t); - } --- 832,921 ---- /* ! * Efficient version of '(T) += strfmt((T), "%c", (C))' */ ! #define object_desc_chr_macro(T,C) do { \ ! \ ! /* Copy the char */ \ ! *(T)++ = (C); \ ! \ ! } while (0) ! ! ! ! /* ! * Efficient version of '(T) += strfmt((T), "%s", (S))' ! */ ! #define object_desc_str_macro(T,S) do { \ ! \ ! cptr s = (S); \ ! \ ! /* Copy the string */ \ ! while (*s) *(T)++ = *s++; \ ! \ ! } while (0) ! ! ! ! /* ! * Efficient version of '(T) += strfmt((T), "%u", (N))' ! */ ! #define object_desc_num_macro(T,N) do { \ ! \ ! uint n = (N); \ ! \ ! uint p; \ ! \ ! /* Find "size" of "n" */ \ ! for (p = 1; n >= p * 10; p = p * 10) /* loop */; \ ! \ ! /* Dump each digit */ \ ! while (p >= 1) \ ! { \ ! /* Dump the digit */ \ ! *(T)++ = I2D(n / p); \ ! \ ! /* Remove the digit */ \ ! n = n % p; \ ! \ ! /* Process next digit */ \ ! p = p / 10; \ ! } \ ! \ ! } while (0) ! ! ! ! /* ! * Efficient version of '(T) += strfmt((T), "%+d", (I))' ! */ ! #define object_desc_int_macro(T,I) do { \ ! \ ! sint i = (I); \ ! \ ! /* Negative */ \ ! if (i < 0) \ ! { \ ! /* Take the absolute value */ \ ! i = 0 - i; \ ! \ ! /* Use a "minus" sign */ \ ! *(T)++ = '-'; \ ! } \ ! \ ! /* Positive (or zero) */ \ ! else \ ! { \ ! /* Use a "plus" sign */ \ ! *(T)++ = '+'; \ ! } \ ! \ ! /* Dump the number itself */ \ ! object_desc_num_macro(T, i); \ ! \ ! } while (0) *************** *** 1132,1139 **** * Note that the inscription will be clipped to keep the total description * under 79 chars (plus a terminator). * ! * Note the use of "object_desc_num()" and "object_desc_int()" as hyper-efficient, ! * portable, versions of some common "sprintf()" commands. * * Note that all ego-items (when known) append an "Ego-Item Name", unless * the item is also an artifact, which should NEVER happen. --- 932,941 ---- * Note that the inscription will be clipped to keep the total description * under 79 chars (plus a terminator). * ! * Note the use of "object_desc_int_macro()" and "object_desc_num_macro()" ! * and "object_desc_str_macro()" and "object_desc_chr_macro()" as extremely ! * efficient, portable, versions of some common "sprintf()" (or "strfmt()") ! * commands. * * Note that all ego-items (when known) append an "Ego-Item Name", unless * the item is also an artifact, which should NEVER happen. *************** *** 1156,1185 **** * * Hack -- Display "The One Ring" as "a Plain Gold Ring" until aware. * ! * If "pref" then a "numeric" prefix will be pre-pended. ! * ! * Mode: ! * 0 -- The Cloak of Death ! * 1 -- The Cloak of Death [1,+3] ! * 2 -- The Cloak of Death [1,+3] (+2 to Stealth) ! * 3 -- The Cloak of Death [1,+3] (+2 to Stealth) {nifty} */ void object_desc(char *buf, object_type *o_ptr, int pref, int mode) { cptr basenm, modstr; - int power, indexx; ! bool aware = FALSE; ! bool known = FALSE; ! bool append_name = FALSE; ! bool show_weapon = FALSE; ! bool show_armour = FALSE; - cptr s, u; char *t; char p1 = '(', p2 = ')'; char b1 = '[', b2 = ']'; char c1 = '{', c2 = '}'; --- 958,1004 ---- * * Hack -- Display "The One Ring" as "a Plain Gold Ring" until aware. * ! * The "pluralization" rules are extremely hackish, in fact, for efficiency, ! * we only handle things like "torch"/"torches" and "cutlass"/"cutlasses", ! * and we would not handle "box"/"boxes", or "knife"/"knives", correctly. ! * ! * If "pref" is true then a "numeric" prefix will be pre-pended, else is is ! * assumed that a string such as "The" or "Your" will be pre-pended later. ! * ! * Modes ("pref" is TRUE): ! * 0 -- Chain Mail of Death ! * 1 -- A Cloak of Death [1,+3] ! * 2 -- An Amulet of Death [1,+3] (+2 to Stealth) ! * 3 -- 5 Rings of Death [1,+3] (+2 to Stealth) {nifty} ! * ! * Modes ("pref" is FALSE): ! * 0 -- Chain Mail of Death ! * 1 -- Cloak of Death [1,+3] ! * 2 -- Amulet of Death [1,+3] (+2 to Stealth) ! * 3 -- Rings of Death [1,+3] (+2 to Stealth) {nifty} */ void object_desc(char *buf, object_type *o_ptr, int pref, int mode) { cptr basenm, modstr; ! int power; ! ! bool aware; ! bool known; ! ! bool flavor; ! bool append_name; ! bool show_weapon; ! bool show_armour; char *t; + cptr s; + cptr u; + cptr v; + char p1 = '(', p2 = ')'; char b1 = '[', b2 = ']'; char c1 = '{', c2 = '}'; *************** *** 1196,1208 **** /* See if the object is "aware" */ ! if (object_aware_p(o_ptr)) aware = TRUE; /* See if the object is "known" */ ! if (object_known_p(o_ptr)) known = TRUE; ! /* Hack -- Extract the sub-type "indexx" */ ! indexx = o_ptr->sval; /* Extract default "base" string */ basenm = (k_name + k_ptr->name); --- 1015,1039 ---- /* See if the object is "aware" */ ! aware = (object_aware_p(o_ptr) ? TRUE : FALSE); /* See if the object is "known" */ ! known = (object_known_p(o_ptr) ? TRUE : FALSE); ! ! /* See if the object is "flavored" */ ! flavor = (k_ptr->flavor ? TRUE : FALSE); ! ! /* Allow flavors to be hidden when aware */ ! if (aware && !show_flavors) flavor = FALSE; ! ! /* Assume no name appending */ ! append_name = FALSE; ! ! /* Assume no need to show "weapon" bonuses */ ! show_weapon = FALSE; ! /* Assume no need to show "armour" bonuses */ ! show_armour = FALSE; /* Extract default "base" string */ basenm = (k_name + k_ptr->name); *************** *** 1214,1220 **** /* Analyze the object */ switch (o_ptr->tval) { ! /* Some objects are easy to describe */ case TV_SKELETON: case TV_BOTTLE: case TV_JUNK: --- 1045,1051 ---- /* Analyze the object */ switch (o_ptr->tval) { ! /* Some objects are easy to describe */ case TV_SKELETON: case TV_BOTTLE: case TV_JUNK: *************** *** 1225,1232 **** break; } ! ! /* Missiles/ Bows/ Weapons */ case TV_SHOT: case TV_BOLT: case TV_ARROW: --- 1056,1062 ---- break; } ! /* Missiles/Bows/Weapons */ case TV_SHOT: case TV_BOLT: case TV_ARROW: *************** *** 1240,1247 **** break; } ! ! /* Armour */ case TV_BOOTS: case TV_GLOVES: case TV_CLOAK: --- 1070,1076 ---- break; } ! /* Armour */ case TV_BOOTS: case TV_GLOVES: case TV_CLOAK: *************** *** 1256,1360 **** break; } ! ! /* Lites (including a few "Specials") */ case TV_LITE: { break; } ! ! /* Amulets (including a few "Specials") */ case TV_AMULET: { ! /* Known artifacts */ if (artifact_p(o_ptr) && aware) break; /* Color the object */ ! modstr = amulet_adj[indexx]; if (aware) append_name = TRUE; ! basenm = aware ? "& Amulet~" : "& # Amulet~"; break; } ! ! /* Rings (including a few "Specials") */ case TV_RING: { ! /* Known artifacts */ if (artifact_p(o_ptr) && aware) break; /* Color the object */ ! modstr = ring_adj[indexx]; if (aware) append_name = TRUE; ! basenm = aware ? "& Ring~" : "& # Ring~"; ! /* Hack -- The One Ring */ ! if (!aware && (o_ptr->sval == SV_RING_POWER)) modstr = "Plain Gold"; break; } ! case TV_STAFF: { /* Color the object */ ! modstr = staff_adj[indexx]; if (aware) append_name = TRUE; ! basenm = aware ? "& Staff~" : "& # Staff~"; break; } case TV_WAND: { /* Color the object */ ! modstr = wand_adj[indexx]; if (aware) append_name = TRUE; ! basenm = aware ? "& Wand~" : "& # Wand~"; break; } case TV_ROD: { /* Color the object */ ! modstr = rod_adj[indexx]; if (aware) append_name = TRUE; ! basenm = aware ? "& Rod~" : "& # Rod~"; break; } case TV_SCROLL: { /* Color the object */ ! modstr = scroll_adj[indexx]; if (aware) append_name = TRUE; ! basenm = aware ? "& Scroll~" : "& Scroll~ titled \"#\""; break; } case TV_POTION: { /* Color the object */ ! modstr = potion_adj[indexx]; if (aware) append_name = TRUE; ! basenm = aware ? "& Potion~" : "& # Potion~"; break; } case TV_FOOD: { /* Ordinary food is "boring" */ if (o_ptr->sval >= SV_FOOD_MIN_FOOD) break; /* Color the object */ ! modstr = food_adj[indexx]; if (aware) append_name = TRUE; ! basenm = aware ? "& Mushroom~" : "& # Mushroom~"; break; } ! ! /* Magic Books */ case TV_MAGIC_BOOK: { modstr = basenm; --- 1085,1200 ---- break; } ! /* Lites (including a few "Specials") */ case TV_LITE: { break; } ! /* Amulets (including a few "Specials") */ case TV_AMULET: { ! /* Hack -- Known artifacts */ if (artifact_p(o_ptr) && aware) break; /* Color the object */ ! modstr = amulet_adj[o_ptr->sval]; if (aware) append_name = TRUE; ! basenm = (flavor ? "& # Amulet ~" : "& Amulet~"); ! break; } ! /* Rings (including a few "Specials") */ case TV_RING: { ! /* Hack -- Known artifacts */ if (artifact_p(o_ptr) && aware) break; /* Color the object */ ! modstr = ring_adj[o_ptr->sval]; if (aware) append_name = TRUE; ! basenm = (flavor ? "& # Ring~" : "& Ring~"); ! /* Mega-Hack -- The One Ring */ ! if (!aware && (o_ptr->sval == SV_RING_POWER)) ! { ! modstr = "Plain Gold"; ! } break; } ! /* Staffs */ case TV_STAFF: { /* Color the object */ ! modstr = staff_adj[o_ptr->sval]; if (aware) append_name = TRUE; ! basenm = (flavor ? "& # Staff~" : "& Staff~"); ! break; } + /* Wands */ case TV_WAND: { /* Color the object */ ! modstr = wand_adj[o_ptr->sval]; if (aware) append_name = TRUE; ! basenm = (flavor ? "& # Wand~" : "& Wand~"); ! break; } + /* Rods */ case TV_ROD: { /* Color the object */ ! modstr = rod_adj[o_ptr->sval]; if (aware) append_name = TRUE; ! basenm = (flavor ? "& # Rod~" : "& Rod~"); ! break; } + /* Scrolls */ case TV_SCROLL: { /* Color the object */ ! modstr = scroll_adj[o_ptr->sval]; if (aware) append_name = TRUE; ! basenm = (flavor ? "& Scroll~ titled \"#\"" : "& Scroll~"); ! break; } + /* Potions */ case TV_POTION: { /* Color the object */ ! modstr = potion_adj[o_ptr->sval]; if (aware) append_name = TRUE; ! basenm = (flavor ? "& # Potion~" : "& Potion~"); ! break; } + /* Food */ case TV_FOOD: { /* Ordinary food is "boring" */ if (o_ptr->sval >= SV_FOOD_MIN_FOOD) break; /* Color the object */ ! modstr = food_adj[o_ptr->sval]; if (aware) append_name = TRUE; ! basenm = (flavor ? "& # Mushroom~" : "& Mushroom~"); ! break; } ! /* Magic Books */ case TV_MAGIC_BOOK: { modstr = basenm; *************** *** 1362,1368 **** break; } ! /* Prayer Books */ case TV_PRAYER_BOOK: { modstr = basenm; --- 1202,1208 ---- break; } ! /* Prayer Books */ case TV_PRAYER_BOOK: { modstr = basenm; *************** *** 1370,1383 **** break; } ! /* Hack -- Gold/Gems */ case TV_GOLD: { strcpy(buf, basenm); return; } ! /* Used in the "inventory" routine */ default: { strcpy(buf, "(nothing)"); --- 1210,1223 ---- break; } ! /* Hack -- Gold/Gems */ case TV_GOLD: { strcpy(buf, basenm); return; } ! /* Hack -- Default -- Used in the "inventory" routine */ default: { strcpy(buf, "(nothing)"); *************** *** 1389,1394 **** --- 1229,1235 ---- /* Start dumping the result */ t = buf; + /* The object "expects" a "number" */ if (basenm[0] == '&') { *************** *** 1404,1441 **** /* Hack -- None left */ else if (o_ptr->number <= 0) { ! t = object_desc_str(t, "no more "); } /* Extract the number */ else if (o_ptr->number > 1) { ! t = object_desc_num(t, o_ptr->number); ! t = object_desc_chr(t, ' '); } /* Hack -- The only one of its kind */ else if (known && artifact_p(o_ptr)) { ! t = object_desc_str(t, "The "); ! } ! ! /* A single one, with a vowel in the modifier */ ! else if ((*s == '#') && (is_a_vowel(modstr[0]))) ! { ! t = object_desc_str(t, "an "); } ! /* A single one, with a vowel */ ! else if (is_a_vowel(*s)) { ! t = object_desc_str(t, "an "); } ! /* A single one, without a vowel */ else { ! t = object_desc_str(t, "a "); } } --- 1245,1276 ---- /* Hack -- None left */ else if (o_ptr->number <= 0) { ! object_desc_str_macro(t, "no more "); } /* Extract the number */ else if (o_ptr->number > 1) { ! object_desc_num_macro(t, o_ptr->number); ! object_desc_chr_macro(t, ' '); } /* Hack -- The only one of its kind */ else if (known && artifact_p(o_ptr)) { ! object_desc_str_macro(t, "The "); } ! /* A single one, and next character will be a vowel */ ! else if ((*s == '#') ? is_a_vowel(modstr[0]) : is_a_vowel(*s)) { ! object_desc_str_macro(t, "an "); } ! /* A single one, and next character will be a non-vowel */ else { ! object_desc_str_macro(t, "a "); } } *************** *** 1454,1483 **** /* Hack -- all gone */ else if (o_ptr->number <= 0) { ! t = object_desc_str(t, "no more "); } /* Prefix a number if required */ else if (o_ptr->number > 1) { ! t = object_desc_num(t, o_ptr->number); ! t = object_desc_chr(t, ' '); } /* Hack -- The only one of its kind */ else if (known && artifact_p(o_ptr)) { ! t = object_desc_str(t, "The "); } ! /* Hack -- single items get no prefix */ else { /* Nothing */ } } ! /* Paranoia -- skip illegal tildes */ /* while (*s == '~') s++; */ /* Copy the string */ --- 1289,1319 ---- /* Hack -- all gone */ else if (o_ptr->number <= 0) { ! object_desc_str_macro(t, "no more "); } /* Prefix a number if required */ else if (o_ptr->number > 1) { ! object_desc_num_macro(t, o_ptr->number); ! object_desc_chr_macro(t, ' '); } /* Hack -- The only one of its kind */ else if (known && artifact_p(o_ptr)) { ! object_desc_str_macro(t, "The "); } ! /* Hack -- A single item, so no prefix needed */ else { /* Nothing */ } } ! ! /* Paranoia XXX XXX XXX */ /* while (*s == '~') s++; */ /* Copy the string */ *************** *** 1491,1498 **** { char k = t[-1]; - /* XXX XXX XXX Mega-Hack */ - /* Hack -- "Cutlass-es" and "Torch-es" */ if ((k == 's') || (k == 'h')) *t++ = 'e'; --- 1327,1332 ---- *************** *** 1516,1530 **** } } - /* Terminate */ - *t = '\0'; - /* Append the "kind name" to the "base name" */ if (append_name) { ! t = object_desc_str(t, " of "); ! t = object_desc_str(t, (k_name + k_ptr->name)); } --- 1350,1361 ---- } } /* Append the "kind name" to the "base name" */ if (append_name) { ! object_desc_str_macro(t, " of "); ! object_desc_str_macro(t, (k_name + k_ptr->name)); } *************** *** 1536,1543 **** { artifact_type *a_ptr = &a_info[o_ptr->name1]; ! t = object_desc_chr(t, ' '); ! t = object_desc_str(t, (a_name + a_ptr->name)); } /* Grab any ego-item name */ --- 1367,1374 ---- { artifact_type *a_ptr = &a_info[o_ptr->name1]; ! object_desc_chr_macro(t, ' '); ! object_desc_str_macro(t, (a_name + a_ptr->name)); } /* Grab any ego-item name */ *************** *** 1545,1563 **** { ego_item_type *e_ptr = &e_info[o_ptr->name2]; ! t = object_desc_chr(t, ' '); ! t = object_desc_str(t, (e_name + e_ptr->name)); } } /* No more details wanted */ ! if (mode < 1) return; /* Hack -- Chests must be described in detail */ if (o_ptr->tval == TV_CHEST) { /* Not searched yet */ if (!known) { --- 1376,1401 ---- { ego_item_type *e_ptr = &e_info[o_ptr->name2]; ! object_desc_chr_macro(t, ' '); ! object_desc_str_macro(t, (e_name + e_ptr->name)); } } /* No more details wanted */ ! if (mode < 1) ! { ! /* Terminate and return */ ! *t = '\0'; ! return; ! } /* Hack -- Chests must be described in detail */ if (o_ptr->tval == TV_CHEST) { + cptr tail = ""; + /* Not searched yet */ if (!known) { *************** *** 1567,1573 **** /* May be "empty" */ else if (!o_ptr->pval) { ! t = object_desc_str(t, " (empty)"); } /* May be "disarmed" */ --- 1405,1411 ---- /* May be "empty" */ else if (!o_ptr->pval) { ! tail = " (empty)"; } /* May be "disarmed" */ *************** *** 1575,1585 **** { if (chest_traps[o_ptr->pval]) { ! t = object_desc_str(t, " (disarmed)"); } else { ! t = object_desc_str(t, " (unlocked)"); } } --- 1413,1423 ---- { if (chest_traps[o_ptr->pval]) { ! tail = " (disarmed)"; } else { ! tail = " (unlocked)"; } } *************** *** 1591,1636 **** { case 0: { ! t = object_desc_str(t, " (Locked)"); break; } case CHEST_LOSE_STR: { ! t = object_desc_str(t, " (Poison Needle)"); break; } case CHEST_LOSE_CON: { ! t = object_desc_str(t, " (Poison Needle)"); break; } case CHEST_POISON: { ! t = object_desc_str(t, " (Gas Trap)"); break; } case CHEST_PARALYZE: { ! t = object_desc_str(t, " (Gas Trap)"); break; } case CHEST_EXPLODE: { ! t = object_desc_str(t, " (Explosion Device)"); break; } case CHEST_SUMMON: { ! t = object_desc_str(t, " (Summoning Runes)"); break; } default: { ! t = object_desc_str(t, " (Multiple Traps)"); break; } } } } --- 1429,1477 ---- { case 0: { ! tail = " (Locked)"; break; } case CHEST_LOSE_STR: { ! tail = " (Poison Needle)"; break; } case CHEST_LOSE_CON: { ! tail = " (Poison Needle)"; break; } case CHEST_POISON: { ! tail = " (Gas Trap)"; break; } case CHEST_PARALYZE: { ! tail = " (Gas Trap)"; break; } case CHEST_EXPLODE: { ! tail = " (Explosion Device)"; break; } case CHEST_SUMMON: { ! tail = " (Summoning Runes)"; break; } default: { ! tail = " (Multiple Traps)"; break; } } } + + /* Append the tail */ + object_desc_str_macro(t, tail); } *************** *** 1662,1690 **** case TV_DIGGING: { /* Append a "damage" string */ ! t = object_desc_chr(t, ' '); ! t = object_desc_chr(t, p1); ! t = object_desc_num(t, o_ptr->dd); ! t = object_desc_chr(t, 'd'); ! t = object_desc_num(t, o_ptr->ds); ! t = object_desc_chr(t, p2); /* All done */ break; } ! /* Bows get a special "damage string" */ case TV_BOW: { /* Hack -- Extract the "base power" */ power = (o_ptr->sval % 10); /* Append a "power" string */ ! t = object_desc_chr(t, ' '); ! t = object_desc_chr(t, p1); ! t = object_desc_chr(t, 'x'); ! t = object_desc_num(t, power); ! t = object_desc_chr(t, p2); /* All done */ break; --- 1503,1531 ---- case TV_DIGGING: { /* Append a "damage" string */ ! object_desc_chr_macro(t, ' '); ! object_desc_chr_macro(t, p1); ! object_desc_num_macro(t, o_ptr->dd); ! object_desc_chr_macro(t, 'd'); ! object_desc_num_macro(t, o_ptr->ds); ! object_desc_chr_macro(t, p2); /* All done */ break; } ! /* Bows */ case TV_BOW: { /* Hack -- Extract the "base power" */ power = (o_ptr->sval % 10); /* Append a "power" string */ ! object_desc_chr_macro(t, ' '); ! object_desc_chr_macro(t, p1); ! object_desc_chr_macro(t, 'x'); ! object_desc_num_macro(t, power); ! object_desc_chr_macro(t, p2); /* All done */ break; *************** *** 1698,1727 **** /* Show the tohit/todam on request */ if (show_weapon) { ! t = object_desc_chr(t, ' '); ! t = object_desc_chr(t, p1); ! t = object_desc_int(t, o_ptr->to_h); ! t = object_desc_chr(t, ','); ! t = object_desc_int(t, o_ptr->to_d); ! t = object_desc_chr(t, p2); } /* Show the tohit if needed */ else if (o_ptr->to_h) { ! t = object_desc_chr(t, ' '); ! t = object_desc_chr(t, p1); ! t = object_desc_int(t, o_ptr->to_h); ! t = object_desc_chr(t, p2); } /* Show the todam if needed */ else if (o_ptr->to_d) { ! t = object_desc_chr(t, ' '); ! t = object_desc_chr(t, p1); ! t = object_desc_int(t, o_ptr->to_d); ! t = object_desc_chr(t, p2); } } --- 1539,1568 ---- /* Show the tohit/todam on request */ if (show_weapon) { ! object_desc_chr_macro(t, ' '); ! object_desc_chr_macro(t, p1); ! object_desc_int_macro(t, o_ptr->to_h); ! object_desc_chr_macro(t, ','); ! object_desc_int_macro(t, o_ptr->to_d); ! object_desc_chr_macro(t, p2); } /* Show the tohit if needed */ else if (o_ptr->to_h) { ! object_desc_chr_macro(t, ' '); ! object_desc_chr_macro(t, p1); ! object_desc_int_macro(t, o_ptr->to_h); ! object_desc_chr_macro(t, p2); } /* Show the todam if needed */ else if (o_ptr->to_d) { ! object_desc_chr_macro(t, ' '); ! object_desc_chr_macro(t, p1); ! object_desc_int_macro(t, o_ptr->to_d); ! object_desc_chr_macro(t, p2); } } *************** *** 1732,1767 **** /* Show the armor class info */ if (show_armour) { ! t = object_desc_chr(t, ' '); ! t = object_desc_chr(t, b1); ! t = object_desc_num(t, o_ptr->ac); ! t = object_desc_chr(t, ','); ! t = object_desc_int(t, o_ptr->to_a); ! t = object_desc_chr(t, b2); } /* No base armor, but does increase armor */ else if (o_ptr->to_a) { ! t = object_desc_chr(t, ' '); ! t = object_desc_chr(t, b1); ! t = object_desc_int(t, o_ptr->to_a); ! t = object_desc_chr(t, b2); } } /* Hack -- always show base armor */ else if (show_armour) { ! t = object_desc_chr(t, ' '); ! t = object_desc_chr(t, b1); ! t = object_desc_num(t, o_ptr->ac); ! t = object_desc_chr(t, b2); } /* No more details wanted */ ! if (mode < 2) return; /* Hack -- Wands and Staffs have charges */ --- 1573,1613 ---- /* Show the armor class info */ if (show_armour) { ! object_desc_chr_macro(t, ' '); ! object_desc_chr_macro(t, b1); ! object_desc_num_macro(t, o_ptr->ac); ! object_desc_chr_macro(t, ','); ! object_desc_int_macro(t, o_ptr->to_a); ! object_desc_chr_macro(t, b2); } /* No base armor, but does increase armor */ else if (o_ptr->to_a) { ! object_desc_chr_macro(t, ' '); ! object_desc_chr_macro(t, b1); ! object_desc_int_macro(t, o_ptr->to_a); ! object_desc_chr_macro(t, b2); } } /* Hack -- always show base armor */ else if (show_armour) { ! object_desc_chr_macro(t, ' '); ! object_desc_chr_macro(t, b1); ! object_desc_num_macro(t, o_ptr->ac); ! object_desc_chr_macro(t, b2); } /* No more details wanted */ ! if (mode < 2) ! { ! /* Terminate and return */ ! *t = '\0'; ! return; ! } /* Hack -- Wands and Staffs have charges */ *************** *** 1770,1809 **** (o_ptr->tval == TV_WAND))) { /* Dump " (N charges)" */ ! t = object_desc_chr(t, ' '); ! t = object_desc_chr(t, p1); ! t = object_desc_num(t, o_ptr->pval); ! t = object_desc_str(t, " charge"); ! if (o_ptr->pval != 1) t = object_desc_chr(t, 's'); ! t = object_desc_chr(t, p2); } /* Hack -- Rods have a "charging" indicator */ else if (known && (o_ptr->tval == TV_ROD)) { /* Hack -- Dump " (charging)" if relevant */ ! if (o_ptr->pval) t = object_desc_str(t, " (charging)"); } /* Hack -- Process Lanterns/Torches */ else if ((o_ptr->tval == TV_LITE) && (!artifact_p(o_ptr))) { /* Hack -- Turns of light for normal lites */ ! t = object_desc_str(t, " (with "); ! t = object_desc_num(t, o_ptr->pval); ! t = object_desc_str(t, " turns of light)"); } /* Dump "pval" flags for wearable items */ if (known && (f1 & (TR1_PVAL_MASK))) { /* Start the display */ ! t = object_desc_chr(t, ' '); ! t = object_desc_chr(t, p1); /* Dump the "pval" itself */ ! t = object_desc_int(t, o_ptr->pval); /* Do not display the "pval" flags */ if (f3 & (TR3_HIDE_TYPE)) --- 1616,1664 ---- (o_ptr->tval == TV_WAND))) { /* Dump " (N charges)" */ ! object_desc_chr_macro(t, ' '); ! object_desc_chr_macro(t, p1); ! object_desc_num_macro(t, o_ptr->pval); ! object_desc_str_macro(t, " charge"); ! if (o_ptr->pval != 1) ! { ! object_desc_chr_macro(t, 's'); ! } ! object_desc_chr_macro(t, p2); } /* Hack -- Rods have a "charging" indicator */ else if (known && (o_ptr->tval == TV_ROD)) { /* Hack -- Dump " (charging)" if relevant */ ! if (o_ptr->pval) ! { ! object_desc_str_macro(t, " (charging)"); ! } } /* Hack -- Process Lanterns/Torches */ else if ((o_ptr->tval == TV_LITE) && (!artifact_p(o_ptr))) { /* Hack -- Turns of light for normal lites */ ! object_desc_str_macro(t, " (with "); ! object_desc_num_macro(t, o_ptr->pval); ! object_desc_str_macro(t, " turns of light)"); } /* Dump "pval" flags for wearable items */ if (known && (f1 & (TR1_PVAL_MASK))) { + cptr tail = ""; + cptr tail2 = ""; + /* Start the display */ ! object_desc_chr_macro(t, ' '); ! object_desc_chr_macro(t, p1); /* Dump the "pval" itself */ ! object_desc_int_macro(t, o_ptr->pval); /* Do not display the "pval" flags */ if (f3 & (TR3_HIDE_TYPE)) *************** *** 1815,1835 **** else if (f1 & (TR1_STEALTH)) { /* Dump " to stealth" */ ! t = object_desc_str(t, " to stealth"); } /* Searching */ else if (f1 & (TR1_SEARCH)) { /* Dump " to searching" */ ! t = object_desc_str(t, " to searching"); } /* Infravision */ else if (f1 & (TR1_INFRA)) { /* Dump " to infravision" */ ! t = object_desc_str(t, " to infravision"); } #if 0 --- 1670,1690 ---- else if (f1 & (TR1_STEALTH)) { /* Dump " to stealth" */ ! tail = " to stealth"; } /* Searching */ else if (f1 & (TR1_SEARCH)) { /* Dump " to searching" */ ! tail = " to searching"; } /* Infravision */ else if (f1 & (TR1_INFRA)) { /* Dump " to infravision" */ ! tail = " to infravision"; } #if 0 *************** *** 1838,1844 **** else if (f1 & (TR1_TUNNEL)) { /* Dump " to digging" */ ! t = object_desc_str(t, " to digging"); } #endif --- 1693,1699 ---- else if (f1 & (TR1_TUNNEL)) { /* Dump " to digging" */ ! tail = " to digging"; } #endif *************** *** 1847,1863 **** else if (f1 & (TR1_SPEED)) { /* Dump " to speed" */ ! t = object_desc_str(t, " to speed"); } /* Blows */ else if (f1 & (TR1_BLOWS)) { /* Add " attack" */ ! t = object_desc_str(t, " attack"); /* Add "attacks" */ ! if (ABS(o_ptr->pval) != 1) t = object_desc_chr(t, 's'); } #if 0 --- 1702,1718 ---- else if (f1 & (TR1_SPEED)) { /* Dump " to speed" */ ! tail = " to speed"; } /* Blows */ else if (f1 & (TR1_BLOWS)) { /* Add " attack" */ ! tail = " attack"; /* Add "attacks" */ ! if (ABS(o_ptr->pval) != 1) tail2 = "s"; } #if 0 *************** *** 1876,1952 **** #endif /* Finish the display */ ! t = object_desc_chr(t, p2); } ! /* Indicate "charging" artifacts XXX XXX XXX */ if (known && o_ptr->timeout) { /* Hack -- Dump " (charging)" if relevant */ ! t = object_desc_str(t, " (charging)"); } /* No more details wanted */ ! if (mode < 3) return; ! /* No inscription yet */ ! tmp_val[0] = '\0'; /* Use the standard inscription if available */ if (o_ptr->note) { ! strcpy(tmp_val, quark_str(o_ptr->note)); } /* Note "cursed" if the item is known to be cursed */ else if (cursed_p(o_ptr) && (known || (o_ptr->ident & (IDENT_SENSE)))) { ! strcpy(tmp_val, "cursed"); } /* Mega-Hack -- note empty wands/staffs */ else if (!known && (o_ptr->ident & (IDENT_EMPTY))) { ! strcpy(tmp_val, "empty"); } /* Note "tried" if the object has been tested unsuccessfully */ else if (!aware && object_tried_p(o_ptr)) { ! strcpy(tmp_val, "tried"); } /* Note the discount, if any */ else if (o_ptr->discount) { ! object_desc_num(tmp_val, o_ptr->discount); ! strcat(tmp_val, "% off"); } /* Append the inscription, if any */ ! if (tmp_val[0]) { - int n; - - /* Hack -- How much so far */ - n = (t - buf); - - /* Paranoia -- do not be stupid */ - if (n > 75) n = 75; - - /* Hack -- shrink the inscription */ - tmp_val[75 - n] = '\0'; - /* Append the inscription */ ! t = object_desc_chr(t, ' '); ! t = object_desc_chr(t, c1); ! t = object_desc_str(t, tmp_val); ! t = object_desc_chr(t, c2); } } --- 1731,1810 ---- #endif + /* Add the descriptor */ + object_desc_str_macro(t, tail); + object_desc_str_macro(t, tail2); + /* Finish the display */ ! object_desc_chr_macro(t, p2); } ! /* Indicate "charging" artifacts */ if (known && o_ptr->timeout) { /* Hack -- Dump " (charging)" if relevant */ ! object_desc_str_macro(t, " (charging)"); } /* No more details wanted */ ! if (mode < 3) ! { ! /* Terminate and return */ ! *t = '\0'; ! return; ! } ! /* Default to nothing */ ! v = NULL; /* Use the standard inscription if available */ if (o_ptr->note) { ! v = quark_str(o_ptr->note); } /* Note "cursed" if the item is known to be cursed */ else if (cursed_p(o_ptr) && (known || (o_ptr->ident & (IDENT_SENSE)))) { ! v = "cursed"; } /* Mega-Hack -- note empty wands/staffs */ else if (!known && (o_ptr->ident & (IDENT_EMPTY))) { ! v = "empty"; } /* Note "tried" if the object has been tested unsuccessfully */ else if (!aware && object_tried_p(o_ptr)) { ! v = "tried"; } /* Note the discount, if any */ else if (o_ptr->discount) { ! char *q = tmp_val; ! object_desc_num_macro(q, o_ptr->discount); ! strcpy(q, "% off"); ! v = tmp_val; } /* Append the inscription, if any */ ! if (v) { /* Append the inscription */ ! object_desc_chr_macro(t, ' '); ! object_desc_chr_macro(t, c1); ! while ((t < buf + 75) && *v) *t++ = *v++; ! object_desc_chr_macro(t, c2); } + + /* Terminate */ + *t = '\0'; } *************** *** 1956,1961 **** --- 1814,1822 ---- */ void object_desc_store(char *buf, object_type *o_ptr, int pref, int mode) { + /* Save the "flavor" */ + byte hack_flavor = k_info[o_ptr->k_idx].flavor; + /* Save the "aware" flag */ bool hack_aware = k_info[o_ptr->k_idx].aware; *************** *** 1963,1968 **** --- 1824,1832 ---- bool hack_known = (o_ptr->ident & (IDENT_KNOWN)) ? TRUE : FALSE; + /* Clear the flavor */ + k_info[o_ptr->k_idx].flavor = FALSE; + /* Set the "known" flag */ o_ptr->ident |= (IDENT_KNOWN); *************** *** 1974,1979 **** --- 1838,1846 ---- object_desc(buf, o_ptr, pref, mode); + /* Restore "flavor" value */ + k_info[o_ptr->k_idx].flavor = hack_flavor; + /* Restore "aware" flag */ k_info[o_ptr->k_idx].aware = hack_aware; *************** *** 2601,2607 **** info[i++] = "It provides resistance to life draining."; } ! if (f3 & (TR3_TELEPORT)) { info[i++] = "It induces earthquakes."; } --- 2468,2474 ---- info[i++] = "It provides resistance to life draining."; } ! if (f3 & (TR3_IMPACT)) { info[i++] = "It induces earthquakes."; } *************** *** 2664,2671 **** if (!i) return (FALSE); ! /* Save the screen */ ! Term_save(); /* Erase the screen */ Term_clear(); --- 2531,2539 ---- if (!i) return (FALSE); ! /* Save screen */ ! screen_save(); ! /* Erase the screen */ Term_clear(); *************** *** 2695,2704 **** /* Wait for it */ prt("[Press any key to continue]", k, 0); ! inkey(); - /* Restore the screen */ - Term_load(); /* Gave knowledge */ return (TRUE); --- 2563,2574 ---- /* Wait for it */ prt("[Press any key to continue]", k, 0); ! (void)inkey(); ! ! ! /* Load screen */ ! screen_load(); /* Gave knowledge */ return (TRUE); *************** *** 3043,3051 **** /* Acquire inventory color */ attr = tval_to_attr[o_ptr->tval & 0x7F]; - /* Disable inventory colors */ - if (!inventory_colors) attr = TERM_WHITE; - /* Display the entry itself */ Term_putstr(3, i, n, attr, o_name); --- 2913,2918 ---- *************** *** 3116,3124 **** /* Acquire inventory color */ attr = tval_to_attr[o_ptr->tval & 0x7F]; - /* Disable inventory colors */ - if (!inventory_colors) attr = TERM_WHITE; - /* Display the entry itself */ Term_putstr(3, i - INVEN_WIELD, n, attr, o_name); --- 2983,2988 ---- *************** *** 3218,3226 **** /* Acquire inventory color */ out_color[k] = tval_to_attr[o_ptr->tval & 0x7F]; - /* Disable inventory colors */ - if (!inventory_colors) out_color[k] = TERM_WHITE; - /* Save the object description */ strcpy(out_desc[k], o_name); --- 3082,3087 ---- *************** *** 3327,3335 **** /* Acquire inventory color */ out_color[k] = tval_to_attr[o_ptr->tval & 0x7F]; - /* Disable inventory colors */ - if (!inventory_colors) out_color[k] = TERM_WHITE; - /* Save the description */ strcpy(out_desc[k], o_name); --- 3188,3193 ---- *************** *** 3623,3629 **** * and there are any acceptable items in that location. * * The equipment or inventory are displayed (even if no acceptable ! * items are in that location) if the proper flag was given. XXX XXX * * If there are no acceptable items available anywhere, and "str" is * not NULL, then it will be used as the text of a warning message --- 3481,3487 ---- * and there are any acceptable items in that location. * * The equipment or inventory are displayed (even if no acceptable ! * items are in that location) if the proper flag was given. * * If there are no acceptable items available anywhere, and "str" is * not NULL, then it will be used as the text of a warning message *************** *** 3657,3664 **** * * We always erase the prompt when we are done, leaving a blank line, * or a warning message, if appropriate, if no items are available. - * - * Note that "Term_save()" / "Term_load()" blocks must not overlap. */ bool get_item(int *cp, cptr pmt, cptr str, int mode) { --- 3515,3520 ---- *************** *** 3671,3677 **** int j, k, i1, i2, e1, e2; ! bool ver, done, item; bool oops = FALSE; --- 3527,3533 ---- int j, k, i1, i2, e1, e2; ! bool done, item; bool oops = FALSE; *************** *** 3791,3797 **** /* Hack -- start out in "display" mode */ ! if (p_ptr->command_see) Term_save(); /* Repeat until done */ --- 3647,3657 ---- /* Hack -- start out in "display" mode */ ! if (p_ptr->command_see) ! { ! /* Save screen */ ! screen_save(); ! } /* Repeat until done */ *************** *** 3933,3948 **** case '?': case ' ': { ! /* Show/hide the list */ ! if (!p_ptr->command_see) { ! Term_save(); ! p_ptr->command_see = TRUE; } else { ! Term_load(); ! p_ptr->command_see = FALSE; } break; } --- 3793,3816 ---- case '?': case ' ': { ! /* Hide the list */ ! if (p_ptr->command_see) { ! /* Flip flag */ ! p_ptr->command_see = FALSE; ! ! /* Load screen */ ! screen_load(); } + + /* Show the list */ else { ! /* Save screen */ ! screen_save(); ! ! /* Flip flag */ ! p_ptr->command_see = TRUE; } break; } *************** *** 3952,3966 **** /* Verify legality */ if (!inven || !equip) { ! bell(); break; } ! /* Fix screen */ if (p_ptr->command_see) { ! Term_load(); ! Term_save(); } /* Switch inven/equip */ --- 3820,3837 ---- /* Verify legality */ if (!inven || !equip) { ! bell("Cannot switch item selector!"); break; } ! /* Hack -- Fix screen */ if (p_ptr->command_see) { ! /* Load screen */ ! screen_load(); ! ! /* Save screen */ ! screen_save(); } /* Switch inven/equip */ *************** *** 3993,3999 **** k = 0 - this_o_idx; /* Verify the item (if required) */ ! if (other_query_flag && !verify("Try", k)) continue; /* Allow player to "refuse" certain actions */ if (!get_item_allow(k)) continue; --- 3864,3870 ---- k = 0 - this_o_idx; /* Verify the item (if required) */ ! if (floor_query_flag && !verify("Try", k)) continue; /* Allow player to "refuse" certain actions */ if (!get_item_allow(k)) continue; *************** *** 4010,4016 **** } /* Oops */ ! bell(); break; } --- 3881,3887 ---- } /* Oops */ ! bell("Illegal object choice (floor)!"); break; } *************** *** 4022,4042 **** /* Look up the tag */ if (!get_tag(&k, which)) { ! bell(); break; } /* Hack -- Validate the item */ if ((k < INVEN_WIELD) ? !inven : !equip) { ! bell(); break; } /* Validate the item */ if (!get_item_okay(k)) { ! bell(); break; } --- 3893,3913 ---- /* Look up the tag */ if (!get_tag(&k, which)) { ! bell("Illegal object choice (tag)!"); break; } /* Hack -- Validate the item */ if ((k < INVEN_WIELD) ? !inven : !equip) { ! bell("Illegal object choice (tag)!"); break; } /* Validate the item */ if (!get_item_okay(k)) { ! bell("Illegal object choice (tag)!"); break; } *************** *** 4072,4078 **** /* Validate the item */ if (!get_item_okay(k)) { ! bell(); break; } --- 3943,3949 ---- /* Validate the item */ if (!get_item_okay(k)) { ! bell("Illegal object choice (default)!"); break; } *************** *** 4092,4100 **** default: { /* Extract "query" setting */ ver = isupper(which); ! if (ver) which = tolower(which); /* Convert letter to inventory index */ if (!p_ptr->command_wrk) --- 3963,3973 ---- default: { + int ver; + /* Extract "query" setting */ ver = isupper(which); ! which = tolower(which); /* Convert letter to inventory index */ if (!p_ptr->command_wrk) *************** *** 4111,4117 **** /* Validate the item */ if (!get_item_okay(k)) { ! bell(); break; } --- 3984,3990 ---- /* Validate the item */ if (!get_item_okay(k)) { ! bell("Illegal object choice (normal)!"); break; } *************** *** 4140,4149 **** /* Fix the screen if necessary */ ! if (p_ptr->command_see) Term_load(); ! /* Hack -- Cancel "display" */ ! p_ptr->command_see = FALSE; /* Forget the item_tester_tval restriction */ --- 4013,4026 ---- /* Fix the screen if necessary */ ! if (p_ptr->command_see) ! { ! /* Load screen */ ! screen_load(); ! /* Hack -- Cancel "display" */ ! p_ptr->command_see = FALSE; ! } /* Forget the item_tester_tval restriction */ *************** *** 4176,4181 **** /* Result */ return (item); } - --- 4053,4057 ---- diff -c -r angband-282/src/object2.c angband-283/src/object2.c *** angband-282/src/object2.c Fri Sep 5 13:31:45 1997 --- angband-283/src/object2.c Wed Feb 11 06:30:29 1998 *************** *** 1405,1414 **** * we simply round the results of division in such a way as to "average" the * correct floating point value. * ! * This function has been changed. It uses "randnor()" to choose values from ! * a normal distribution, whose mean moves from zero towards the max as the ! * level increases, and whose standard deviation is equal to 1/4 of the max, ! * and whose values are forced to lie between zero and the max, inclusive. * * Since the "level" rarely passes 100 before Morgoth is dead, it is very * rare to get the "full" enchantment on an object, even a deep levels. --- 1405,1414 ---- * we simply round the results of division in such a way as to "average" the * correct floating point value. * ! * This function has been changed. It uses "Rand_normal()" to choose values ! * from a normal distribution, whose mean moves from zero towards the max as ! * the level increases, and whose standard deviation is equal to 1/4 of the ! * max, and whose values are forced to lie between zero and the max, inclusive. * * Since the "level" rarely passes 100 before Morgoth is dead, it is very * rare to get the "full" enchantment on an object, even a deep levels. *************** *** 1467,1473 **** /* Choose an "interesting" value */ ! value = randnor(bonus, stand); /* Enforce the minimum value */ if (value < 0) return (0); --- 1467,1473 ---- /* Choose an "interesting" value */ ! value = Rand_normal(bonus, stand); /* Enforce the minimum value */ if (value < 0) return (0); *************** *** 1546,1552 **** /* Cannot make an artifact twice */ if (a_ptr->cur_num) continue; ! /* XXX XXX Enforce minimum "depth" (loosely) */ if (a_ptr->level > p_ptr->depth) { /* Acquire the "out-of-depth factor" */ --- 1546,1552 ---- /* Cannot make an artifact twice */ if (a_ptr->cur_num) continue; ! /* Enforce minimum "depth" (loosely) */ if (a_ptr->level > p_ptr->depth) { /* Acquire the "out-of-depth factor" */ *************** *** 1557,1568 **** } /* Artifact "rarity roll" */ ! if (rand_int(a_ptr->rarity) != 0) return (0); /* Find the base object */ k_idx = lookup_kind(a_ptr->tval, a_ptr->sval); ! /* XXX XXX Enforce minimum "object" level (loosely) */ if (k_info[k_idx].level > object_level) { /* Acquire the "out-of-depth factor" */ --- 1557,1568 ---- } /* Artifact "rarity roll" */ ! if (rand_int(a_ptr->rarity) != 0) continue; /* Find the base object */ k_idx = lookup_kind(a_ptr->tval, a_ptr->sval); ! /* Enforce minimum "object" level (loosely) */ if (k_info[k_idx].level > object_level) { /* Acquire the "out-of-depth factor" */ *************** *** 1956,1962 **** } /* Hack -- Super-charge the damage dice */ ! while (rand_int(10L * o_ptr->dd * o_ptr->ds) == 0) o_ptr->dd++; /* Hack -- Lower the damage dice */ if (o_ptr->dd > 9) o_ptr->dd = 9; --- 1956,1966 ---- } /* Hack -- Super-charge the damage dice */ ! while ((o_ptr->dd * o_ptr->ds > 0) && ! (rand_int(10L * o_ptr->dd * o_ptr->ds) == 0)) ! { ! o_ptr->dd++; ! } /* Hack -- Lower the damage dice */ if (o_ptr->dd > 9) o_ptr->dd = 9; *************** *** 2092,2098 **** } /* Hack -- super-charge the damage dice */ ! while (rand_int(10L * o_ptr->dd * o_ptr->ds) == 0) o_ptr->dd++; /* Hack -- restrict the damage dice */ if (o_ptr->dd > 9) o_ptr->dd = 9; --- 2096,2106 ---- } /* Hack -- super-charge the damage dice */ ! while ((o_ptr->dd * o_ptr->ds > 0) && ! (rand_int(10L * o_ptr->dd * o_ptr->ds) == 0)) ! { ! o_ptr->dd++; ! } /* Hack -- restrict the damage dice */ if (o_ptr->dd > 9) o_ptr->dd = 9; *************** *** 2952,2964 **** /* Hack -- Torches -- random fuel */ if (o_ptr->sval == SV_LITE_TORCH) { ! if (o_ptr->pval) o_ptr->pval = randint(o_ptr->pval); } /* Hack -- Lanterns -- random fuel */ if (o_ptr->sval == SV_LITE_LANTERN) { ! if (o_ptr->pval) o_ptr->pval = randint(o_ptr->pval); } break; --- 2960,2972 ---- /* Hack -- Torches -- random fuel */ if (o_ptr->sval == SV_LITE_TORCH) { ! if (o_ptr->pval > 0) o_ptr->pval = randint(o_ptr->pval); } /* Hack -- Lanterns -- random fuel */ if (o_ptr->sval == SV_LITE_LANTERN) { ! if (o_ptr->pval > 0) o_ptr->pval = randint(o_ptr->pval); } break; *************** *** 3055,3077 **** power = 0; /* Roll for "good" */ ! if (good || magik(f1)) { /* Assume "good" */ power = 1; /* Roll for "great" */ ! if (great || magik(f2)) power = 2; } /* Roll for "cursed" */ ! else if (magik(f1)) { /* Assume "cursed" */ power = -1; /* Roll for "broken" */ ! if (magik(f2)) power = -2; } --- 3063,3085 ---- power = 0; /* Roll for "good" */ ! if (good || (rand_int(100) < f1)) { /* Assume "good" */ power = 1; /* Roll for "great" */ ! if (great || (rand_int(100) < f2)) power = 2; } /* Roll for "cursed" */ ! else if (rand_int(100) < f1) { /* Assume "cursed" */ power = -1; /* Roll for "broken" */ ! if (rand_int(100) < f2) power = -2; } *************** *** 3226,3249 **** if (cursed_p(o_ptr) || broken_p(o_ptr)) { /* Hack -- obtain bonuses */ ! if (e_ptr->max_to_h) o_ptr->to_h -= randint(e_ptr->max_to_h); ! if (e_ptr->max_to_d) o_ptr->to_d -= randint(e_ptr->max_to_d); ! if (e_ptr->max_to_a) o_ptr->to_a -= randint(e_ptr->max_to_a); /* Hack -- obtain pval */ ! if (e_ptr->max_pval) o_ptr->pval -= randint(e_ptr->max_pval); } /* Hack -- apply extra bonuses if needed */ else { /* Hack -- obtain bonuses */ ! if (e_ptr->max_to_h) o_ptr->to_h += randint(e_ptr->max_to_h); ! if (e_ptr->max_to_d) o_ptr->to_d += randint(e_ptr->max_to_d); ! if (e_ptr->max_to_a) o_ptr->to_a += randint(e_ptr->max_to_a); /* Hack -- obtain pval */ ! if (e_ptr->max_pval) o_ptr->pval += randint(e_ptr->max_pval); } /* Hack -- apply rating bonus */ --- 3234,3257 ---- if (cursed_p(o_ptr) || broken_p(o_ptr)) { /* Hack -- obtain bonuses */ ! if (e_ptr->max_to_h > 0) o_ptr->to_h -= randint(e_ptr->max_to_h); ! if (e_ptr->max_to_d > 0) o_ptr->to_d -= randint(e_ptr->max_to_d); ! if (e_ptr->max_to_a > 0) o_ptr->to_a -= randint(e_ptr->max_to_a); /* Hack -- obtain pval */ ! if (e_ptr->max_pval > 0) o_ptr->pval -= randint(e_ptr->max_pval); } /* Hack -- apply extra bonuses if needed */ else { /* Hack -- obtain bonuses */ ! if (e_ptr->max_to_h > 0) o_ptr->to_h += randint(e_ptr->max_to_h); ! if (e_ptr->max_to_d > 0) o_ptr->to_d += randint(e_ptr->max_to_d); ! if (e_ptr->max_to_a > 0) o_ptr->to_a += randint(e_ptr->max_to_a); /* Hack -- obtain pval */ ! if (e_ptr->max_pval > 0) o_ptr->pval += randint(e_ptr->max_pval); } /* Hack -- apply rating bonus */ *************** *** 3978,3984 **** object_desc(o_name, o_ptr, TRUE, 3); /* Print a message */ ! msg_format("You have %s.", o_name); } --- 3986,3992 ---- object_desc(o_name, o_ptr, TRUE, 3); /* Print a message */ ! msg_format("You have %s (%c).", o_name, index_to_label(item)); } *************** *** 4077,4083 **** p_ptr->update |= (PU_MANA); /* Window stuff */ ! p_ptr->window |= (PW_EQUIP | PW_SPELL | PW_PLAYER); } } --- 4085,4091 ---- p_ptr->update |= (PU_MANA); /* Window stuff */ ! p_ptr->window |= (PW_EQUIP | PW_PLAYER_0 | PW_PLAYER_1); } } *************** *** 4734,4752 **** /* Extract the minimum failure rate */ minfail = adj_mag_fail[p_ptr->stat_ind[mp_ptr->spell_stat]]; ! /* Non mage/priest characters never get too good */ ! if ((p_ptr->pclass != 1) && (p_ptr->pclass != 2)) { if (minfail < 5) minfail = 5; } ! /* Hack -- Priest prayer penalty for "edged" weapons -DGK */ ! if ((p_ptr->pclass == 2) && (p_ptr->icky_wield)) chance += 25; /* Minimum failure rate */ if (chance < minfail) chance = minfail; ! /* Stunning makes spells harder */ if (p_ptr->stun > 50) chance += 25; else if (p_ptr->stun) chance += 15; --- 4742,4763 ---- /* Extract the minimum failure rate */ minfail = adj_mag_fail[p_ptr->stat_ind[mp_ptr->spell_stat]]; ! /* Non mage/priest characters never get better than 5 percent */ ! if ((p_ptr->pclass != CLASS_MAGE) && (p_ptr->pclass != CLASS_PRIEST)) { if (minfail < 5) minfail = 5; } ! /* Priest prayer penalty for "edged" weapons (before minfail) */ ! if ((p_ptr->pclass == CLASS_PRIEST) && (p_ptr->icky_wield)) ! { ! chance += 25; ! } /* Minimum failure rate */ if (chance < minfail) chance = minfail; ! /* Stunning makes spells harder (after minfail) */ if (p_ptr->stun > 50) chance += 25; else if (p_ptr->stun) chance += 15; *************** *** 5046,5049 **** --- 5057,5061 ---- print_spells(spells, num, 2, 0); } } + diff -c -r angband-282/src/save.c angband-283/src/save.c *** angband-282/src/save.c Wed Sep 3 11:57:34 1997 --- angband-283/src/save.c Fri Feb 6 04:10:31 1998 *************** *** 1150,1155 **** --- 1150,1161 ---- /* + * The cave grid flags that get saved in the savefile + */ + #define IMPORTANT_FLAGS (CAVE_MARK | CAVE_GLOW | CAVE_ICKY | CAVE_ROOM) + + + /* * Write the current dungeon */ static void wr_dungeon(void) *************** *** 1186,1193 **** { for (x = 0; x < DUNGEON_WID; x++) { ! /* Extract a byte */ ! tmp8u = cave_info[y][x]; /* If the run is broken, or too full, flush it */ if ((tmp8u != prev_char) || (count == MAX_UCHAR)) --- 1192,1199 ---- { for (x = 0; x < DUNGEON_WID; x++) { ! /* Extract the important cave_info flags */ ! tmp8u = (cave_info[y][x] & (IMPORTANT_FLAGS)); /* If the run is broken, or too full, flush it */ if ((tmp8u != prev_char) || (count == MAX_UCHAR)) diff -c -r angband-282/src/spells1.c angband-283/src/spells1.c *** angband-282/src/spells1.c Thu Sep 4 10:17:54 1997 --- angband-283/src/spells1.c Wed Feb 11 06:30:29 1998 *************** *** 370,375 **** --- 370,420 ---- + /* + * Find the attr/char pair to use for a spell effect + * + * It is moving (or has moved) from (x,y) to (nx,ny). + * + * If the distance is not "one", we (may) return "*". + */ + static u16b bolt_pict(int y, int x, int ny, int nx, int typ) + { + int base; + + byte k; + + byte a; + char c; + + /* No motion (*) */ + if ((ny == y) && (nx == x)) base = 0x30; + + /* Vertical (|) */ + else if (nx == x) base = 0x40; + + /* Horizontal (-) */ + else if (ny == y) base = 0x50; + + /* Diagonal (/) */ + else if ((ny-y) == (x-nx)) base = 0x60; + + /* Diagonal (\) */ + else if ((ny-y) == (nx-x)) base = 0x70; + + /* Weird (*) */ + else base = 0x30; + + /* Basic spell color */ + k = spell_color(typ); + + /* Obtain attr/char */ + a = misc_to_attr[base+k]; + c = misc_to_char[base+k]; + + /* Create pict */ + return (PICT(a,c)); + } + *************** *** 380,386 **** * * Hack -- this function allows the user to save (or quit) the game * when he dies, since the "You die." message is shown before setting ! * the player to "dead". XXX XXX XXX */ void take_hit(int dam, cptr kb_str) { --- 425,431 ---- * * Hack -- this function allows the user to save (or quit) the game * when he dies, since the "You die." message is shown before setting ! * the player to "dead". */ void take_hit(int dam, cptr kb_str) { *************** *** 406,412 **** p_ptr->redraw |= (PR_HP); /* Window stuff */ ! p_ptr->window |= (PW_SPELL | PW_PLAYER); /* Dead player */ if (p_ptr->chp < 0) --- 451,457 ---- p_ptr->redraw |= (PR_HP); /* Window stuff */ ! p_ptr->window |= (PW_PLAYER_0 | PW_PLAYER_1); /* Dead player */ if (p_ptr->chp < 0) *************** *** 438,444 **** if (p_ptr->chp < warning) { /* Hack -- bell on first notice */ ! if (alert_hitpoint && (old_chp > warning)) bell(); /* Message */ msg_print("*** LOW HITPOINT WARNING! ***"); --- 483,492 ---- if (p_ptr->chp < warning) { /* Hack -- bell on first notice */ ! if (alert_hitpoint && (old_chp > warning)) ! { ! bell("Low hitpoint warning!"); ! } /* Message */ msg_print("*** LOW HITPOINT WARNING! ***"); *************** *** 784,790 **** p_ptr->update |= (PU_BONUS); /* Window stuff */ ! p_ptr->window |= (PW_EQUIP | PW_SPELL | PW_PLAYER); /* Item was damaged */ return (TRUE); --- 832,838 ---- p_ptr->update |= (PU_BONUS); /* Window stuff */ ! p_ptr->window |= (PW_EQUIP | PW_PLAYER_0 | PW_PLAYER_1); /* Item was damaged */ return (TRUE); *************** *** 1038,1043 **** --- 1086,1092 ---- /* and one-half of the stat bonus times the percentage, with a */ /* minimum damage of half the percentage. -CWS */ loss = (((max-18) / 2 + 1) / 2 + 1); + if (loss < 1) loss = 1; loss = ((randint(loss) + loss) * amount) / 100; if (loss < amount/2) loss = amount/2; *************** *** 1099,1109 **** /* * Apply disenchantment to the player's stuff * ! * XXX XXX XXX This function is also called from the "melee" code * * The "mode" is currently unused. * ! * Return "TRUE" if the player notices anything */ bool apply_disenchant(int mode) { --- 1148,1158 ---- /* * Apply disenchantment to the player's stuff * ! * This function is also called from the "melee" code. * * The "mode" is currently unused. * ! * Return "TRUE" if the player notices anything. */ bool apply_disenchant(int mode) { *************** *** 1184,1190 **** p_ptr->update |= (PU_BONUS); /* Window stuff */ ! p_ptr->window |= (PW_EQUIP | PW_SPELL | PW_PLAYER); /* Notice */ return (TRUE); --- 1233,1239 ---- p_ptr->update |= (PU_BONUS); /* Window stuff */ ! p_ptr->window |= (PW_EQUIP | PW_PLAYER_0 | PW_PLAYER_1); /* Notice */ return (TRUE); *************** *** 1283,1289 **** * * Hack -- We also "see" grids which are "memorized". * ! * Perhaps we should affect doors and/or walls. XXX XXX */ static bool project_f(int who, int r, int y, int x, int dam, int typ) { --- 1332,1338 ---- * * Hack -- We also "see" grids which are "memorized". * ! * Perhaps we should affect doors and/or walls. */ static bool project_f(int who, int r, int y, int x, int dam, int typ) { *************** *** 1378,1385 **** if ((cave_feat[y][x] >= FEAT_DOOR_HEAD) && (cave_feat[y][x] <= FEAT_DOOR_TAIL)) { ! /* Update some things */ ! p_ptr->update |= (PU_VIEW | PU_LITE | PU_MONSTERS); } } --- 1427,1434 ---- if ((cave_feat[y][x] >= FEAT_DOOR_HEAD) && (cave_feat[y][x] <= FEAT_DOOR_TAIL)) { ! /* Update the visuals */ ! p_ptr->update |= (PU_UPDATE_VIEW | PU_MONSTERS); } } *************** *** 1505,1512 **** cave_set_feat(y, x, FEAT_FLOOR); } ! /* Update some things */ ! p_ptr->update |= (PU_VIEW | PU_LITE | PU_FLOW | PU_MONSTERS); break; } --- 1554,1564 ---- 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); break; } *************** *** 1523,1530 **** /* Observe */ if (cave_info[y][x] & (CAVE_MARK)) obvious = TRUE; ! /* Update some things */ ! p_ptr->update |= (PU_VIEW | PU_LITE | PU_MONSTERS); break; } --- 1575,1582 ---- /* Observe */ if (cave_info[y][x] & (CAVE_MARK)) obvious = TRUE; ! /* Update the visuals */ ! p_ptr->update |= (PU_UPDATE_VIEW | PU_MONSTERS); break; } *************** *** 1548,1565 **** /* Turn on the light */ cave_info[y][x] |= (CAVE_GLOW); ! /* Notice */ ! note_spot(y, x); ! ! /* Redraw */ ! lite_spot(y, x); ! ! /* Observe */ ! if (player_can_see_bold(y, x)) obvious = TRUE; ! /* Mega-Hack -- Update the monster in the affected grid */ ! /* This allows "spear of light" (etc) to work "correctly" */ ! if (cave_m_idx[y][x] > 0) update_mon(cave_m_idx[y][x], FALSE); break; } --- 1600,1614 ---- /* Turn on the light */ cave_info[y][x] |= (CAVE_GLOW); ! /* Grid is in line of sight */ ! if (player_has_los_bold(y, x)) ! { ! /* Observe */ ! obvious = TRUE; ! /* Fully update the visuals */ ! p_ptr->update |= (PU_FORGET_VIEW | PU_UPDATE_VIEW | PU_MONSTERS); ! } break; } *************** *** 1568,1577 **** case GF_DARK_WEAK: case GF_DARK: { ! /* Notice */ ! if (player_can_see_bold(y, x)) obvious = TRUE; ! ! /* Turn off the light. */ cave_info[y][x] &= ~(CAVE_GLOW); /* Hack -- Forget "boring" grids */ --- 1617,1623 ---- case GF_DARK_WEAK: case GF_DARK: { ! /* Turn off the light */ cave_info[y][x] &= ~(CAVE_GLOW); /* Hack -- Forget "boring" grids */ *************** *** 1579,1595 **** { /* Forget */ cave_info[y][x] &= ~(CAVE_MARK); - - /* Notice */ - note_spot(y, x); } ! /* Redraw */ ! lite_spot(y, x); ! /* Mega-Hack -- Update the monster in the affected grid */ ! /* This allows "spear of light" (etc) to work "correctly" */ ! if (cave_m_idx[y][x] > 0) update_mon(cave_m_idx[y][x], FALSE); /* All done */ break; --- 1625,1641 ---- { /* Forget */ cave_info[y][x] &= ~(CAVE_MARK); } ! /* Grid is in line of sight */ ! if (player_has_los_bold(y, x)) ! { ! /* Observe */ ! obvious = TRUE; ! /* Fully update the visuals */ ! p_ptr->update |= (PU_FORGET_VIEW | PU_UPDATE_VIEW | PU_MONSTERS); ! } /* All done */ break; *************** *** 2083,2096 **** break; } ! /* Arrow -- XXX no defense */ case GF_ARROW: { if (seen) obvious = TRUE; break; } ! /* Plasma -- XXX perhaps check ELEC or FIRE */ case GF_PLASMA: { if (seen) obvious = TRUE; --- 2129,2142 ---- break; } ! /* Arrow -- no defense XXX */ case GF_ARROW: { if (seen) obvious = TRUE; break; } ! /* Plasma -- perhaps check ELEC or FIRE XXX */ case GF_PLASMA: { if (seen) obvious = TRUE; *************** *** 2905,2911 **** /* Create a new monster (no groups) */ (void)place_monster_aux(y, x, tmp, FALSE, FALSE); ! /* XXX XXX XXX Hack -- Assume success */ /* Hack -- Get new monster */ m_ptr = &m_list[cave_m_idx[y][x]]; --- 2951,2957 ---- /* Create a new monster (no groups) */ (void)place_monster_aux(y, x, tmp, FALSE, FALSE); ! /* Hack -- Assume success XXX XXX XXX */ /* Hack -- Get new monster */ m_ptr = &m_list[cave_m_idx[y][x]]; *************** *** 3114,3121 **** * is reduced (see "project_m()" above). This can happen if a monster breathes * at the player and hits a wall instead. * ! * We return "TRUE" if any "obvious" effects were observed. XXX XXX Actually, ! * we just assume that the effects were obvious, for historical reasons. */ static bool project_p(int who, int r, int y, int x, int dam, int typ) { --- 3160,3169 ---- * is reduced (see "project_m()" above). This can happen if a monster breathes * at the player and hits a wall instead. * ! * We return "TRUE" if any "obvious" effects were observed. ! * ! * Actually, for historical reasons, we just assume that the effects were ! * obvious. XXX XXX XXX */ static bool project_p(int who, int r, int y, int x, int dam, int typ) { *************** *** 3150,3157 **** if (cave_m_idx[y][x] == who) return (FALSE); ! /* XXX XXX XXX */ ! /* Limit maximum damage */ if (dam > 1600) dam = 1600; /* Reduce damage by distance */ --- 3198,3204 ---- if (cave_m_idx[y][x] == who) return (FALSE); ! /* Limit maximum damage XXX XXX XXX */ if (dam > 1600) dam = 1600; /* Reduce damage by distance */ *************** *** 3238,3244 **** break; } ! /* Arrow -- XXX no dodging */ case GF_ARROW: { if (fuzzy) msg_print("You are hit by something sharp!"); --- 3285,3291 ---- break; } ! /* Arrow -- no dodging XXX */ case GF_ARROW: { if (fuzzy) msg_print("You are hit by something sharp!"); *************** *** 3246,3252 **** break; } ! /* Plasma -- XXX No resist */ case GF_PLASMA: { if (fuzzy) msg_print("You are hit by something!"); --- 3293,3299 ---- break; } ! /* Plasma -- No resist XXX */ case GF_PLASMA: { if (fuzzy) msg_print("You are hit by something!"); *************** *** 3598,3624 **** - - - - - /* - * Find the char to use to draw a moving bolt - * It is moving (or has moved) from (x,y) to (nx,ny). - * If the distance is not "one", we (may) return "*". - */ - static char bolt_char(int y, int x, int ny, int nx) - { - if ((ny == y) && (nx == x)) return '*'; - if (ny == y) return '-'; - if (nx == x) return '|'; - if ((ny-y) == (x-nx)) return '/'; - if ((ny-y) == (nx-x)) return '\\'; - return '*'; - } - - - /* * Generic "beam"/"bolt"/"ball" projection routine. * --- 3645,3650 ---- *************** *** 3743,3751 **** * maximum distance allowed (MAX_RANGE), no "blast" will be induced. This * may be relevant even for bolts, since they have a "1x1" mini-blast. * - * Some people have requested an "auto-explode ball attacks at max range" - * option, which should probably be handled by this function. XXX XXX XXX - * * Note that for consistency, we "pretend" that the bolt actually takes "time" * to move from point A to point B, even if the player cannot see part of the * projection path. Note that in general, the player will *always* see part --- 3769,3774 ---- *************** *** 3753,3760 **** * * Hack -- we assume that every "projection" is "self-illuminating". * ! * Mega-Hack -- when only a single monster is affected, we automatically track ! * (and recall) that monster, unless "PROJECT_JUMP" is used. XXX XXX XXX */ bool project(int who, int rad, int y, int x, int dam, int typ, int flg) { --- 3776,3791 ---- * * Hack -- we assume that every "projection" is "self-illuminating". * ! * Hack -- when only a single monster is affected, we automatically track ! * (and recall) that monster, unless "PROJECT_JUMP" is used. ! * ! * Note that all projections now "explode" at their final destination, even ! * if they were being projected at a more distant destination. This means ! * that "ball" spells will *always* explode. ! * ! * Note that we must call "handle_stuff()" after affecting terrain features ! * in the blast radius, in case the "illumination" of the grid was changed, ! * and "update_view()" and "update_monsters()" need to be called. */ bool project(int who, int rad, int y, int x, int dam, int typ, int flg) { *************** *** 3762,3768 **** int px = p_ptr->px; int i, t, dist; ! int y9, x9; int y1, x1; int y2, x2; --- 3793,3799 ---- int px = p_ptr->px; int i, t, dist; ! int y1, x1; int y2, x2; *************** *** 3780,3785 **** --- 3811,3822 ---- /* Is the player blind? */ bool blind = (p_ptr->blind ? TRUE : FALSE); + /* Number of grids in the "path" */ + int path_n = 0; + + /* Actual grids in the "path" */ + u16b path_g[512]; + /* Number of grids in the "blast area" (including the "beam" path) */ int grids = 0; *************** *** 3795,3800 **** --- 3832,3840 ---- { x1 = x; y1 = y; + + /* Clear the flag */ + flg &= ~(PROJECT_JUMP); } /* Start at player */ *************** *** 3838,3856 **** for (dist = 0; dist < 16; dist++) gm[dist] = 0; /* Hack -- Handle stuff */ handle_stuff(); ! /* Start at the source */ ! x = x9 = x1; ! y = y9 = y1; ! dist = 0; ! /* Project until done */ ! while (1) ! { ! /* Gather beam grids */ if (flg & (PROJECT_BEAM)) { gy[grids] = y; --- 3878,3920 ---- for (dist = 0; dist < 16; dist++) gm[dist] = 0; + /* Initial grid */ + y = y1; + x = x1; + + /* Collect beam grids */ + if (flg & (PROJECT_BEAM)) + { + gy[grids] = y; + gx[grids] = x; + grids++; + } + + + /* Calculate the projection path */ + path_n = project_path(path_g, MAX_RANGE, y1, x1, y2, x2, flg); + + /* Hack -- Handle stuff */ handle_stuff(); + /* Project along the path */ + for (i = 0; i < path_n; ++i) + { + int oy = y; + int ox = x; ! int ny = GRID_Y(path_g[i]); ! int nx = GRID_X(path_g[i]); ! /* Hack -- Balls explode before reaching walls */ ! if (!cave_floor_bold(ny, nx) && (rad > 0)) break; ! ! /* Advance */ ! y = ny; ! x = nx; ! ! /* Collect beam grids */ if (flg & (PROJECT_BEAM)) { gy[grids] = y; *************** *** 3858,3924 **** grids++; } ! /* XXX XXX Hack -- Display "beam" grids */ ! if (!blind && !(flg & (PROJECT_HIDE)) && ! dist && (flg & (PROJECT_BEAM)) && ! panel_contains(y, x) && player_has_los_bold(y, x)) { ! /* Hack -- Visual effect -- "explode" the grids */ ! print_rel('*', spell_color(typ), y, x); ! } ! ! /* Never pass through walls */ ! if (dist && !cave_floor_bold(y, x)) break; ! /* Check for arrival at "final target" (if desired) */ ! if (!(flg & (PROJECT_THRU)) && (x == x2) && (y == y2)) break; ! /* If allowed, and we have moved at all, stop when we hit anybody */ ! if ((flg & (PROJECT_STOP)) && dist && (cave_m_idx[y][x] != 0)) break; ! /* Calculate the new location */ ! y9 = y; ! x9 = x; ! mmove2(&y9, &x9, y1, x1, y2, x2); ! /* Hack -- Balls explode BEFORE reaching walls or doors */ ! if (!cave_floor_bold(y9, x9) && (rad > 0)) break; ! /* Keep track of the distance traveled */ ! dist++; ! /* Nothing can travel furthur than the maximal distance */ ! if (dist > MAX_RANGE) break; ! /* Only do visual effects (and delay) if requested */ ! if (!blind && !(flg & (PROJECT_HIDE))) ! { ! /* Only do visuals if the player can "see" the bolt */ ! if (panel_contains(y9, x9) && player_has_los_bold(y9, x9)) ! { ! /* Use misc_to_attr/misc_to_char XXX XXX XXX XXX */ ! /* Visual effects -- Display, Highlight, Flush, Pause, Erase */ ! print_rel(bolt_char(y, x, y9, x9), spell_color(typ), y9, x9); ! move_cursor_relative(y9, x9); ! Term_fresh(); visual = TRUE; - Term_xtra(TERM_XTRA_DELAY, msec); - lite_spot(y9, x9); - Term_fresh(); } ! /* Hack -- make sure to delay anyway for consistency */ else if (visual) { /* Delay for consistency */ Term_xtra(TERM_XTRA_DELAY, msec); } } - - /* Save the new location */ - y = y9; - x = x9; } --- 3922,3978 ---- grids++; } ! /* Only do visuals if requested */ ! if (!blind && !(flg & (PROJECT_HIDE))) { ! /* Only do visuals if the player can "see" the bolt */ ! if (panel_contains(y, x) && player_has_los_bold(y, x)) ! { ! u16b p; ! byte a; ! char c; ! /* Obtain the bolt pict */ ! p = bolt_pict(oy, ox, y, x, typ); + /* Extract attr/char */ + a = PICT_A(p); + c = PICT_C(p); ! /* Visual effects */ ! print_rel(c, a, 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(); ! /* Display "beam" grids */ ! if (flg & (PROJECT_BEAM)) ! { ! /* Obtain the explosion pict */ ! p = bolt_pict(y, x, y, x, typ); ! /* Extract attr/char */ ! a = PICT_A(p); ! c = PICT_C(p); ! /* Visual effects */ ! print_rel(c, a, y, x); ! } ! /* Hack -- Activate delay */ visual = TRUE; } ! /* Hack -- delay anyway for consistency */ else if (visual) { /* Delay for consistency */ Term_xtra(TERM_XTRA_DELAY, msec); } } } *************** *** 3932,3942 **** /* Hack -- make sure beams get to "explode" */ gm[1] = grids; ! /* If we found a "target", explode there */ ! if (dist <= MAX_RANGE) { ! /* Mega-Hack -- remove the final "beam" grid */ ! if ((flg & (PROJECT_BEAM)) && (grids > 0)) grids--; /* Determine the blast area, work from the inside out */ for (dist = 0; dist <= rad; dist++) --- 3986,3999 ---- /* Hack -- make sure beams get to "explode" */ gm[1] = grids; ! /* Explode */ ! if (TRUE) { ! /* Hack -- remove final beam grid */ ! if (flg & (PROJECT_BEAM)) ! { ! grids--; ! } /* Determine the blast area, work from the inside out */ for (dist = 0; dist <= rad; dist++) *************** *** 3972,3978 **** if (!grids) return (FALSE); ! /* Display the "blast area" */ if (!blind && !(flg & (PROJECT_HIDE))) { /* Then do the "blast", from inside out */ --- 4029,4035 ---- if (!grids) return (FALSE); ! /* Display the "blast area" if requested */ if (!blind && !(flg & (PROJECT_HIDE))) { /* Then do the "blast", from inside out */ *************** *** 3985,3998 **** y = gy[i]; x = gx[i]; ! /* The player can see it */ if (panel_contains(y, x) && player_has_los_bold(y, x)) { drawn = TRUE; ! /* Use misc_to_attr/misc_to_char XXX XXX XXX XXX */ /* Visual effects -- Display */ ! print_rel('*', spell_color(typ), y, x); } } --- 4042,4066 ---- y = gy[i]; x = gx[i]; ! /* Only do visuals if the player can "see" the blast */ if (panel_contains(y, x) && player_has_los_bold(y, x)) { + u16b p; + + byte a; + char c; + drawn = TRUE; ! /* Obtain the explosion pict */ ! p = bolt_pict(y, x, y, x, typ); ! ! /* Extract attr/char */ ! a = PICT_A(p); ! c = PICT_C(p); ! /* Visual effects -- Display */ ! print_rel(c, a, y, x); } } *************** *** 4000,4006 **** move_cursor_relative(y2, x2); /* Flush each "radius" seperately */ ! Term_fresh(); /* Delay (efficiently) */ if (visual || drawn) --- 4068,4074 ---- move_cursor_relative(y2, x2); /* Flush each "radius" seperately */ ! if (fresh_before) Term_fresh(); /* Delay (efficiently) */ if (visual || drawn) *************** *** 4030,4036 **** move_cursor_relative(y2, x2); /* Flush the explosion */ ! Term_fresh(); } } --- 4098,4104 ---- move_cursor_relative(y2, x2); /* Flush the explosion */ ! if (fresh_before) Term_fresh(); } } *************** *** 4057,4062 **** --- 4125,4134 ---- } + /* Update stuff if needed */ + if (p_ptr->update) update_stuff(); + + /* Check objects */ if (flg & (PROJECT_ITEM)) { *************** *** 4151,4158 **** /* Return "something was noticed" */ return (notice); } - - --- 4223,4228 ---- diff -c -r angband-282/src/spells2.c angband-283/src/spells2.c *** angband-282/src/spells2.c Thu Sep 4 10:17:54 1997 --- angband-283/src/spells2.c Wed Feb 11 06:30:29 1998 *************** *** 36,42 **** p_ptr->redraw |= (PR_HP); /* Window stuff */ ! p_ptr->window |= (PW_SPELL | PW_PLAYER); /* Heal 0-4 */ if (num < 5) --- 36,42 ---- p_ptr->redraw |= (PR_HP); /* Window stuff */ ! p_ptr->window |= (PW_PLAYER_0 | PW_PLAYER_1); /* Heal 0-4 */ if (num < 5) *************** *** 144,150 **** if (sust) { /* Message */ ! msg_format("You feel %s for a moment, but the feeling passes.", desc_stat_neg[stat]); /* Notice effect */ --- 144,150 ---- if (sust) { /* Message */ ! msg_format("You feel very %s for a moment, but the feeling passes.", desc_stat_neg[stat]); /* Notice effect */ *************** *** 200,206 **** if (inc_stat(stat)) { /* Message */ ! msg_format("Wow! You feel very %s!", desc_stat_pos[stat]); /* Notice */ return (TRUE); --- 200,206 ---- if (inc_stat(stat)) { /* Message */ ! msg_format("You feel very %s!", desc_stat_pos[stat]); /* Notice */ return (TRUE); *************** *** 242,247 **** --- 242,256 ---- object_aware(o_ptr); object_known(o_ptr); } + + /* Recalculate bonuses */ + p_ptr->update |= (PU_BONUS); + + /* Combine / Reorder the pack (later) */ + p_ptr->notice |= (PN_COMBINE | PN_REORDER); + + /* Window stuff */ + p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER_0 | PW_PLAYER_1); } *************** *** 372,380 **** * * See also "identify_fully()". * ! * Use the "roff()" routines, perhaps. XXX XXX * ! * Use the "show_file()" method, perhaps. XXX XXX */ void self_knowledge(void) { --- 381,391 ---- * * See also "identify_fully()". * ! * Use the "roff()" routines, perhaps. XXX XXX XXX ! * ! * Use the "show_file()" method, perhaps. XXX XXX XXX * ! * This function cannot display more than 20 lines. XXX XXX XXX */ void self_knowledge(void) { *************** *** 793,800 **** } ! /* Save the screen */ ! Term_save(); /* Clear the screen */ Term_clear(); --- 804,812 ---- } ! /* Save screen */ ! screen_save(); ! /* Clear the screen */ Term_clear(); *************** *** 819,833 **** /* Label the information */ prt(" Your Attributes:", 1, 0); } } /* Pause */ prt("[Press any key to continue]", k, 0); ! inkey(); ! /* Restore the screen */ ! Term_load(); } --- 831,849 ---- /* Label the information */ prt(" Your Attributes:", 1, 0); + + /* Reset */ + k = 2; } } /* Pause */ prt("[Press any key to continue]", k, 0); ! (void)inkey(); ! ! /* Load screen */ ! screen_load(); } *************** *** 891,897 **** p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* Window stuff */ ! p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER); /* Mega-Hack -- Forget the map */ wiz_dark(); --- 907,913 ---- p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* Window stuff */ ! p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER_0 | PW_PLAYER_1); /* Mega-Hack -- Forget the map */ wiz_dark(); *************** *** 1614,1620 **** for (i=0; i= 100) continue; /* Enchant to hit */ if (eflag & (ENCH_TOHIT)) --- 1630,1636 ---- for (i=0; i 100) && (rand_int(prob) >= 100)) continue; /* Enchant to hit */ if (eflag & (ENCH_TOHIT)) *************** *** 1702,1708 **** p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* Window stuff */ ! p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER); /* Success */ return (TRUE); --- 1718,1724 ---- p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* Window stuff */ ! p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER_0 | PW_PLAYER_1); /* Success */ return (TRUE); *************** *** 1824,1830 **** p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* Window stuff */ ! p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER); /* Description */ object_desc(o_name, o_ptr, TRUE, 3); --- 1840,1846 ---- p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* Window stuff */ ! p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER_0 | PW_PLAYER_1); /* Description */ object_desc(o_name, o_ptr, TRUE, 3); *************** *** 1900,1906 **** p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* Window stuff */ ! p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER); /* Handle stuff */ handle_stuff(); --- 1916,1922 ---- p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* Window stuff */ ! p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER_0 | PW_PLAYER_1); /* Handle stuff */ handle_stuff(); *************** *** 2020,2030 **** /* Extract a recharge power */ i = (100 - lev + num) / 5; - /* Paranoia -- prevent crashes */ - if (i < 1) i = 1; - /* Back-fire */ ! if (rand_int(i) == 0) { /* Hack -- backfire */ msg_print("The recharge backfires, draining the rod further!"); --- 2036,2043 ---- /* Extract a recharge power */ i = (100 - lev + num) / 5; /* Back-fire */ ! if ((i <= 1) || (rand_int(i) == 0)) { /* Hack -- backfire */ msg_print("The recharge backfires, draining the rod further!"); *************** *** 2059,2069 **** /* Recharge power */ i = (num + 100 - lev - (10 * o_ptr->pval)) / 15; - /* Paranoia -- prevent crashes */ - if (i < 1) i = 1; - /* Back-fire XXX XXX XXX */ ! if (rand_int(i) == 0) { /* Dangerous Hack -- Destroy the item */ msg_print("There is a bright flash of light."); --- 2072,2079 ---- /* Recharge power */ i = (num + 100 - lev - (10 * o_ptr->pval)) / 15; /* Back-fire XXX XXX XXX */ ! if ((i <= 1) || (rand_int(i) == 0)) { /* Dangerous Hack -- Destroy the item */ msg_print("There is a bright flash of light."); *************** *** 2457,2463 **** cave_info[y][x] &= ~(CAVE_ROOM | CAVE_ICKY); /* Lose light and knowledge */ ! cave_info[y][x] &= ~(CAVE_MARK | CAVE_GLOW); /* Hack -- Notice player affect */ if (cave_m_idx[y][x] < 0) --- 2467,2473 ---- cave_info[y][x] &= ~(CAVE_ROOM | CAVE_ICKY); /* Lose light and knowledge */ ! cave_info[y][x] &= ~(CAVE_GLOW | CAVE_MARK); /* Hack -- Notice player affect */ if (cave_m_idx[y][x] < 0) *************** *** 2478,2483 **** --- 2488,2495 ---- /* Destroy "valid" grids */ if (cave_valid_bold(y, x)) { + int feat = FEAT_FLOOR; + /* Delete objects */ delete_object(y, x); *************** *** 2488,2516 **** 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; ! } } } } --- 2500,2524 ---- if (t < 20) { /* Create granite wall */ ! feat = FEAT_WALL_EXTRA; } /* Quartz */ else if (t < 70) { /* Create quartz vein */ ! feat = FEAT_QUARTZ; } /* Magma */ else if (t < 100) { /* Create magma vein */ ! feat = FEAT_MAGMA; } ! /* Change the feature */ ! cave_set_feat(y, x, feat); } } } *************** *** 2531,2544 **** } ! /* Mega-Hack -- Forget the view and lite */ ! p_ptr->update |= (PU_UN_VIEW | PU_UN_LITE); ! /* Update stuff */ ! p_ptr->update |= (PU_VIEW | PU_LITE | PU_FLOW); ! ! /* Update the monsters */ ! p_ptr->update |= (PU_MONSTERS); /* Redraw map */ p_ptr->redraw |= (PR_MAP); --- 2539,2549 ---- } ! /* Fully update the visuals */ ! p_ptr->update |= (PU_FORGET_VIEW | PU_UPDATE_VIEW | PU_MONSTERS); ! /* Fully update the flow */ ! p_ptr->update |= (PU_FORGET_FLOW | PU_UPDATE_FLOW); /* Redraw map */ p_ptr->redraw |= (PR_MAP); *************** *** 2642,2652 **** /* Important -- Skip "quake" grids */ if (map[16+y-cy][16+x-cx]) continue; ! /* Count "safe" grids */ ! sn++; ! ! /* Randomize choice */ ! if (rand_int(sn) > 0) continue; /* Save the safe location */ sy = y; sx = x; --- 2647,2654 ---- /* Important -- Skip "quake" grids */ if (map[16+y-cy][16+x-cx]) continue; ! /* Count "safe" grids, apply the randomizer */ ! if ((++sn > 1) && (rand_int(sn) != 0)) continue; /* Save the safe location */ sy = y; sx = x; *************** *** 2667,2673 **** } default: { ! msg_print("The cave quakes! You are pummeled with debris!"); break; } } --- 2669,2676 ---- } default: { ! msg_print("The cave quakes!"); ! msg_print("You are pummeled with debris!"); break; } } *************** *** 2763,2773 **** /* Important -- Skip "quake" grids */ if (map[16+y-cy][16+x-cx]) continue; ! /* Count "safe" grids */ ! sn++; ! ! /* Randomize choice */ ! if (rand_int(sn) > 0) continue; /* Save the safe grid */ sy = y; --- 2766,2773 ---- /* Important -- Skip "quake" grids */ if (map[16+y-cy][16+x-cx]) continue; ! /* Count "safe" grids, apply the randomizer */ ! if ((++sn > 1) && (rand_int(sn) != 0)) continue; /* Save the safe grid */ sy = y; *************** *** 2843,2848 **** --- 2843,2850 ---- /* Destroy location (if valid) */ if (cave_valid_bold(yy, xx)) { + int feat = FEAT_FLOOR; + bool floor = cave_floor_bold(yy, xx); /* Delete objects */ *************** *** 2855,2903 **** if (t < 20) { /* Create granite wall */ ! cave_feat[yy][xx] = FEAT_WALL_EXTRA; } /* Quartz */ else if (t < 70) { /* Create quartz vein */ ! cave_feat[yy][xx] = FEAT_QUARTZ; } /* Magma */ else if (t < 100) { /* Create magma vein */ ! cave_feat[yy][xx] = FEAT_MAGMA; } ! /* Floor */ ! else ! { ! /* Create floor */ ! cave_feat[yy][xx] = FEAT_FLOOR; ! } } } } ! /* Mega-Hack -- Forget the view and lite */ ! p_ptr->update |= (PU_UN_VIEW | PU_UN_LITE); ! /* Update stuff */ ! p_ptr->update |= (PU_VIEW | PU_LITE | PU_FLOW); ! /* Update the monsters */ ! p_ptr->update |= (PU_DISTANCE); /* Update the health bar */ p_ptr->redraw |= (PR_HEALTH); - /* Redraw map */ - p_ptr->redraw |= (PR_MAP); - /* Window stuff */ p_ptr->window |= (PW_OVERHEAD); } --- 2857,2898 ---- if (t < 20) { /* Create granite wall */ ! feat = FEAT_WALL_EXTRA; } /* Quartz */ else if (t < 70) { /* Create quartz vein */ ! feat = FEAT_QUARTZ; } /* Magma */ else if (t < 100) { /* Create magma vein */ ! feat = FEAT_MAGMA; } ! /* Change the feature */ ! cave_set_feat(yy, xx, feat); } } } ! /* Fully update the visuals */ ! p_ptr->update |= (PU_FORGET_VIEW | PU_UPDATE_VIEW | PU_MONSTERS); ! /* Fully update the flow */ ! p_ptr->update |= (PU_FORGET_FLOW | PU_UPDATE_FLOW); ! /* Redraw map */ ! p_ptr->redraw |= (PR_MAP); /* Update the health bar */ p_ptr->redraw |= (PR_HEALTH); /* Window stuff */ p_ptr->window |= (PW_OVERHEAD); } *************** *** 2923,2929 **** { int i; ! /* Clear them all */ for (i = 0; i < temp_n; i++) { int y = temp_y[i]; --- 2918,2924 ---- { int i; ! /* Apply flag changes */ for (i = 0; i < temp_n; i++) { int y = temp_y[i]; *************** *** 2932,2942 **** /* No longer in the array */ cave_info[y][x] &= ~(CAVE_TEMP); - /* Update only non-CAVE_GLOW grids */ - /* if (cave_info[y][x] & (CAVE_GLOW)) continue; */ - /* Perma-Lite */ cave_info[y][x] |= (CAVE_GLOW); /* Process affected monsters */ if (cave_m_idx[y][x] > 0) --- 2927,2950 ---- /* No longer in the array */ cave_info[y][x] &= ~(CAVE_TEMP); /* Perma-Lite */ cave_info[y][x] |= (CAVE_GLOW); + } + + /* Fully update the visuals */ + p_ptr->update |= (PU_FORGET_VIEW | PU_UPDATE_VIEW | PU_MONSTERS); + + /* Update stuff */ + update_stuff(); + + /* Process the grids */ + for (i = 0; i < temp_n; i++) + { + int y = temp_y[i]; + int x = temp_x[i]; + + /* Redraw the grid */ + lite_spot(y, x); /* Process affected monsters */ if (cave_m_idx[y][x] > 0) *************** *** 2946,2954 **** monster_type *m_ptr = &m_list[cave_m_idx[y][x]]; monster_race *r_ptr = &r_info[m_ptr->r_idx]; - /* Update the monster */ - update_mon(cave_m_idx[y][x], FALSE); - /* Stupid monsters rarely wake up */ if (r_ptr->flags2 & (RF2_STUPID)) chance = 10; --- 2954,2959 ---- *************** *** 2974,2985 **** } } } - - /* Note */ - note_spot(y, x); - - /* Redraw */ - lite_spot(y, x); } /* None left */ --- 2979,2984 ---- *************** *** 2996,3009 **** * In addition, some of these grids will be "unmarked". * * This routine is used (only) by "unlite_room()" - * - * Also, process all affected monsters */ static void cave_temp_room_unlite(void) { int i; ! /* Clear them all */ for (i = 0; i < temp_n; i++) { int y = temp_y[i]; --- 2995,3006 ---- * In addition, some of these grids will be "unmarked". * * This routine is used (only) by "unlite_room()" */ static void cave_temp_room_unlite(void) { int i; ! /* Apply flag changes */ for (i = 0; i < temp_n; i++) { int y = temp_y[i]; *************** *** 3020,3038 **** { /* Forget the grid */ cave_info[y][x] &= ~(CAVE_MARK); - - /* Notice */ - note_spot(y, x); } ! /* Process affected monsters */ ! if (cave_m_idx[y][x] > 0) ! { ! /* Update the monster */ ! update_mon(cave_m_idx[y][x], FALSE); ! } ! /* Redraw */ lite_spot(y, x); } --- 3017,3038 ---- { /* Forget the grid */ cave_info[y][x] &= ~(CAVE_MARK); } + } ! /* Fully update the visuals */ ! p_ptr->update |= (PU_FORGET_VIEW | PU_UPDATE_VIEW | PU_MONSTERS); ! ! /* Update stuff */ ! update_stuff(); ! ! /* Process the grids */ ! for (i = 0; i < temp_n; i++) ! { ! int y = temp_y[i]; ! int x = temp_x[i]; ! /* Redraw the grid */ lite_spot(y, x); } *************** *** 3222,3229 **** if ((dir == 5) && target_okay()) { flg &= ~(PROJECT_STOP); ! tx = p_ptr->target_col; ty = p_ptr->target_row; } /* Analyze the "dir" and the "target". Hurt items on floor. */ --- 3222,3230 ---- if ((dir == 5) && target_okay()) { flg &= ~(PROJECT_STOP); ! ty = p_ptr->target_row; + tx = p_ptr->target_col; } /* Analyze the "dir" and the "target". Hurt items on floor. */ *************** *** 3251,3258 **** /* Hack -- Use an actual "target" */ if ((dir == 5) && target_okay()) { - tx = p_ptr->target_col; ty = p_ptr->target_row; } /* Analyze the "dir" and the "target", do NOT explode */ --- 3252,3259 ---- /* Hack -- Use an actual "target" */ if ((dir == 5) && target_okay()) { ty = p_ptr->target_row; + tx = p_ptr->target_col; } /* Analyze the "dir" and the "target", do NOT explode */ diff -c -r angband-282/src/store.c angband-283/src/store.c *** angband-282/src/store.c Thu Sep 4 10:17:54 1997 --- angband-283/src/store.c Wed Feb 11 06:30:29 1998 *************** *** 257,262 **** --- 257,263 ---- "The shopkeeper smiles gleefully." }; + /* * Let a shop-keeper React to a purchase * *************** *** 378,391 **** /* ! * Determine the price of an item (qty one) in a store. * * This function takes into account the player's charisma, and the * shop-keepers friendliness, and the shop-keeper's base greed, but * never lets a shop-keeper lose money in a transaction. * * The "greed" value should exceed 100 when the player is "buying" the ! * item, and should be less than 100 when the player is "selling" it. * * Hack -- the black market always charges twice as much as it should. * --- 379,392 ---- /* ! * Determine the price of an object (qty one) in a store. * * This function takes into account the player's charisma, and the * shop-keepers friendliness, and the shop-keeper's base greed, but * never lets a shop-keeper lose money in a transaction. * * The "greed" value should exceed 100 when the player is "buying" the ! * object, and should be less than 100 when the player is "selling" it. * * Hack -- the black market always charges twice as much as it should. * *************** *** 460,466 **** static int mass_roll(int num, int max) { int i, t = 0; ! for (i = 0; i < num; i++) t += rand_int(max); return (t); } --- 461,470 ---- static int mass_roll(int num, int max) { int i, t = 0; ! for (i = 0; i < num; i++) ! { ! t += ((max > 1) ? rand_int(max) : 1); ! } return (t); } *************** *** 571,583 **** /* ! * Determine if a store item can "absorb" another item * * See "object_similar()" for the same function for the "player" */ --- 575,615 ---- + /* + * Convert a store item index into a one character label + * + * We use labels "a"-"l" for page 1, and labels "m"-"x" for page 2. + */ + static s16b store_to_label(int i) + { + /* Assume legal */ + return (I2A(i)); + } + /* + * Convert a one character label into a store item index. + * + * Return "-1" if the label does not indicate a real store item. + */ + static s16b label_to_store(int c) + { + int i; + + /* Convert */ + i = (islower(c) ? A2I(c) : -1); + + /* Verify the index */ + if ((i < 0) || (i >= st_ptr->stock_num)) return (-1); + + /* Return the index */ + return (i); + } /* ! * Determine if a store object can "absorb" another object * * See "object_similar()" for the same function for the "player" */ *************** *** 626,632 **** /* ! * Allow a store item to absorb another item */ static void store_object_absorb(object_type *o_ptr, object_type *j_ptr) { --- 658,664 ---- /* ! * Allow a store object to absorb another object */ static void store_object_absorb(object_type *o_ptr, object_type *j_ptr) { *************** *** 655,664 **** /* The "home" acts like the player */ if (store_num == 7) { ! /* Check all the items */ for (i = 0; i < st_ptr->stock_num; i++) { ! /* Get the existing item */ j_ptr = &st_ptr->stock[i]; /* Can the new object be combined with the old one? */ --- 687,696 ---- /* The "home" acts like the player */ if (store_num == 7) { ! /* Check all the objects */ for (i = 0; i < st_ptr->stock_num; i++) { ! /* Get the existing object */ j_ptr = &st_ptr->stock[i]; /* Can the new object be combined with the old one? */ *************** *** 669,678 **** /* Normal stores do special stuff */ else { ! /* Check all the items */ for (i = 0; i < st_ptr->stock_num; i++) { ! /* Get the existing item */ j_ptr = &st_ptr->stock[i]; /* Can the new object be combined with the old one? */ --- 701,710 ---- /* Normal stores do special stuff */ else { ! /* Check all the objects */ for (i = 0; i < st_ptr->stock_num; i++) { ! /* Get the existing object */ j_ptr = &st_ptr->stock[i]; /* Can the new object be combined with the old one? */ *************** *** 688,696 **** /* ! * Determine if the current store will purchase the given item * ! * Note that a shop-keeper must refuse to buy "worthless" items */ static bool store_will_buy(object_type *o_ptr) { --- 720,728 ---- /* ! * Determine if the current store will purchase the given object * ! * Note that a shop-keeper must refuse to buy "worthless" objects */ static bool store_will_buy(object_type *o_ptr) { *************** *** 819,825 **** } } ! /* XXX XXX XXX Ignore "worthless" items */ if (object_value(o_ptr) <= 0) return (FALSE); /* Assume okay */ --- 851,857 ---- } } ! /* Ignore "worthless" items XXX XXX XXX */ if (object_value(o_ptr) <= 0) return (FALSE); /* Assume okay */ *************** *** 829,837 **** /* ! * Add the item "o_ptr" to the inventory of the "Home" * ! * In all cases, return the slot (or -1) where the object was placed * * Note that this is a hacked up version of "inven_carry()". * --- 861,869 ---- /* ! * Add an object to the inventory of the "Home" * ! * In all cases, return the slot (or -1) where the object was placed. * * Note that this is a hacked up version of "inven_carry()". * *************** *** 840,855 **** */ static int home_carry(object_type *o_ptr) { ! int slot; s32b value, j_value; - int i; object_type *j_ptr; ! /* Check each existing item (try to combine) */ for (slot = 0; slot < st_ptr->stock_num; slot++) { ! /* Get the existing item */ j_ptr = &st_ptr->stock[slot]; /* The home acts just like the player */ --- 872,886 ---- */ static int home_carry(object_type *o_ptr) { ! int i, slot; s32b value, j_value; object_type *j_ptr; ! /* Check each existing object (try to combine) */ for (slot = 0; slot < st_ptr->stock_num; slot++) { ! /* Get the existing object */ j_ptr = &st_ptr->stock[slot]; /* The home acts just like the player */ *************** *** 867,879 **** if (st_ptr->stock_num >= st_ptr->stock_size) return (-1); ! /* Determine the "value" of the item */ value = object_value(o_ptr); /* Check existing slots to see if we must "slide" */ for (slot = 0; slot < st_ptr->stock_num; slot++) { ! /* Get that item */ j_ptr = &st_ptr->stock[slot]; /* Hack -- readable books always come first */ --- 898,910 ---- if (st_ptr->stock_num >= st_ptr->stock_size) return (-1); ! /* Determine the "value" of the object */ value = object_value(o_ptr); /* Check existing slots to see if we must "slide" */ for (slot = 0; slot < st_ptr->stock_num; slot++) { ! /* Get that object */ j_ptr = &st_ptr->stock[slot]; /* Hack -- readable books always come first */ *************** *** 914,920 **** /* More stuff now */ st_ptr->stock_num++; ! /* Hack -- Insert the new item */ object_copy(&st_ptr->stock[slot], o_ptr); /* Return the location */ --- 945,951 ---- /* More stuff now */ st_ptr->stock_num++; ! /* Hack -- Insert the new object */ object_copy(&st_ptr->stock[slot], o_ptr); /* Return the location */ *************** *** 923,936 **** /* ! * Add the item "o_ptr" to a real stores inventory. * ! * If the item is "worthless", it is thrown away (except in the home). * ! * If the item cannot be combined with an object already in the inventory, * make a new slot for it, and calculate its "per item" price. Note that * this price will be negative, since the price will not be "fixed" yet. ! * Adding an item to a "fixed" price stack will not change the fixed price. * * In all cases, return the slot (or -1) where the object was placed */ --- 954,967 ---- /* ! * Add an object to a real stores inventory. * ! * If the object is "worthless", it is thrown away (except in the home). * ! * If the object cannot be combined with an object already in the inventory, * make a new slot for it, and calculate its "per item" price. Note that * this price will be negative, since the price will not be "fixed" yet. ! * Adding an object to a "fixed" price stack will not change the fixed price. * * In all cases, return the slot (or -1) where the object was placed */ *************** *** 951,960 **** /* Erase the inscription */ o_ptr->note = 0; ! /* Check each existing item (try to combine) */ for (slot = 0; slot < st_ptr->stock_num; slot++) { ! /* Get the existing item */ j_ptr = &st_ptr->stock[slot]; /* Can the existing items be incremented? */ --- 982,991 ---- /* Erase the inscription */ o_ptr->note = 0; ! /* Check each existing object (try to combine) */ for (slot = 0; slot < st_ptr->stock_num; slot++) { ! /* Get the existing object */ j_ptr = &st_ptr->stock[slot]; /* Can the existing items be incremented? */ *************** *** 975,981 **** /* Check existing slots to see if we must "slide" */ for (slot = 0; slot < st_ptr->stock_num; slot++) { ! /* Get that item */ j_ptr = &st_ptr->stock[slot]; /* Objects sort by decreasing type */ --- 1006,1012 ---- /* Check existing slots to see if we must "slide" */ for (slot = 0; slot < st_ptr->stock_num; slot++) { ! /* Get that object */ j_ptr = &st_ptr->stock[slot]; /* Objects sort by decreasing type */ *************** *** 1004,1010 **** /* More stuff now */ st_ptr->stock_num++; ! /* Hack -- Insert the new item */ object_copy(&st_ptr->stock[slot], o_ptr); /* Return the location */ --- 1035,1041 ---- /* More stuff now */ st_ptr->stock_num++; ! /* Hack -- Insert the new object */ object_copy(&st_ptr->stock[slot], o_ptr); /* Return the location */ *************** *** 1021,1027 **** int cnt; object_type *o_ptr; ! /* Get the item */ o_ptr = &st_ptr->stock[item]; /* Verify the number */ --- 1052,1058 ---- int cnt; object_type *o_ptr; ! /* Get the object */ o_ptr = &st_ptr->stock[item]; /* Verify the number */ *************** *** 1043,1049 **** int j; object_type *o_ptr; ! /* Get the item */ o_ptr = &st_ptr->stock[item]; /* Must exist */ --- 1074,1080 ---- int j; object_type *o_ptr; ! /* Get the object */ o_ptr = &st_ptr->stock[item]; /* Must exist */ *************** *** 1052,1058 **** /* Must have no items */ if (o_ptr->number) return; ! /* One less item */ st_ptr->stock_num--; /* Slide everyone */ --- 1083,1089 ---- /* Must have no items */ if (o_ptr->number) return; ! /* One less object */ st_ptr->stock_num--; /* Slide everyone */ *************** *** 1068,1074 **** /* * This function will keep 'crap' out of the black market. ! * Crap is defined as any item that is "available" elsewhere * Based on a suggestion by "Lee Vogt" */ static bool black_market_crap(object_type *o_ptr) --- 1099,1105 ---- /* * This function will keep 'crap' out of the black market. ! * Crap is defined as any object that is "available" elsewhere * Based on a suggestion by "Lee Vogt" */ static bool black_market_crap(object_type *o_ptr) *************** *** 1086,1097 **** /* Check the other "normal" stores */ for (i = 0; i < 6; i++) { ! /* Check every item in the store */ for (j = 0; j < store[i].stock_num; j++) { object_type *j_ptr = &store[i].stock[j]; ! /* Duplicate item "type", assume crappy */ if (o_ptr->k_idx == j_ptr->k_idx) return (TRUE); } } --- 1117,1128 ---- /* Check the other "normal" stores */ for (i = 0; i < 6; i++) { ! /* Check every object in the store */ for (j = 0; j < store[i].stock_num; j++) { object_type *j_ptr = &store[i].stock[j]; ! /* Duplicate object "type", assume crappy */ if (o_ptr->k_idx == j_ptr->k_idx) return (TRUE); } } *************** *** 1102,1134 **** /* ! * Attempt to delete (some of) a random item from the store * Hack -- we attempt to "maintain" piles of items when possible. */ static void store_delete(void) { int what, num; /* Pick a random slot */ what = rand_int(st_ptr->stock_num); ! /* Determine how many items are here */ num = st_ptr->stock[what].number; ! /* Hack -- sometimes, only destroy half the items */ if (rand_int(100) < 50) num = (num + 1) / 2; ! /* Hack -- sometimes, only destroy a single item */ if (rand_int(100) < 50) num = 1; ! /* Actually destroy (part of) the item */ store_item_increase(what, -num); store_item_optimize(what); } /* ! * Creates a random item and gives it to a store * This algorithm needs to be rethought. A lot. * Currently, "normal" stores use a pre-built array. * --- 1133,1168 ---- /* ! * Attempt to delete (some of) a random object from the store * Hack -- we attempt to "maintain" piles of items when possible. */ static void store_delete(void) { int what, num; + /* Paranoia */ + if (st_ptr->stock_num <= 0) return; + /* Pick a random slot */ what = rand_int(st_ptr->stock_num); ! /* Determine how many objects are in the slot */ num = st_ptr->stock[what].number; ! /* Hack -- sometimes, only destroy half the objects */ if (rand_int(100) < 50) num = (num + 1) / 2; ! /* Hack -- sometimes, only destroy a single object */ if (rand_int(100) < 50) num = 1; ! /* Actually destroy (part of) the object */ store_item_increase(what, -num); store_item_optimize(what); } /* ! * Creates a random object and gives it to a store * This algorithm needs to be rethought. A lot. * Currently, "normal" stores use a pre-built array. * *************** *** 1136,1146 **** * level, that is, there is a much higher chance of getting * items with a level approaching that of the given level... * ! * Should we check for "permission" to have the given item? */ static void store_create(void) { ! int i, tries, level; object_type *i_ptr; object_type object_type_body; --- 1170,1180 ---- * level, that is, there is a much higher chance of getting * items with a level approaching that of the given level... * ! * Should we check for "permission" to have the given object? */ static void store_create(void) { ! int k_idx, tries, level; object_type *i_ptr; object_type object_type_body; *************** *** 1159,1176 **** /* Pick a level for object/magic */ level = 25 + rand_int(25); ! /* Random item (usually of given level) */ ! i = get_obj_num(level); /* Handle failure */ ! if (!i) continue; } /* Normal Store */ else { ! /* Hack -- Pick an item to sell */ ! i = st_ptr->table[rand_int(st_ptr->table_num)]; /* Hack -- fake level for apply_magic() */ level = rand_range(1, STORE_OBJ_LEVEL); --- 1193,1210 ---- /* Pick a level for object/magic */ level = 25 + rand_int(25); ! /* Random object kind (usually of given level) */ ! k_idx = get_obj_num(level); /* Handle failure */ ! if (!k_idx) continue; } /* Normal Store */ else { ! /* Hack -- Pick an object kind to sell */ ! k_idx = st_ptr->table[rand_int(st_ptr->table_num)]; /* Hack -- fake level for apply_magic() */ level = rand_range(1, STORE_OBJ_LEVEL); *************** *** 1181,1187 **** i_ptr = &object_type_body; /* Create a new object of the chosen kind */ ! object_prep(i_ptr, i); /* Apply some "low-level" magic (no artifacts) */ apply_magic(i_ptr, level, FALSE, FALSE, FALSE); --- 1215,1221 ---- i_ptr = &object_type_body; /* Create a new object of the chosen kind */ ! object_prep(i_ptr, k_idx); /* Apply some "low-level" magic (no artifacts) */ apply_magic(i_ptr, level, FALSE, FALSE, FALSE); *************** *** 1194,1200 **** } ! /* The item is "known" */ object_known(i_ptr); /* Mega-Hack -- no chests in stores */ --- 1228,1234 ---- } ! /* The object is "known" */ object_known(i_ptr); /* Mega-Hack -- no chests in stores */ *************** *** 1224,1230 **** /* Mass produce and/or Apply discount */ mass_produce(i_ptr); ! /* Attempt to carry the (known) item */ (void)store_carry(i_ptr); /* Definitely done */ --- 1258,1264 ---- /* Mass produce and/or Apply discount */ mass_produce(i_ptr); ! /* Attempt to carry the (known) object */ (void)store_carry(i_ptr); /* Definitely done */ *************** *** 1291,1321 **** /* ! * Re-displays a single store entry */ ! static void display_entry(int pos) { ! int i; object_type *o_ptr; s32b x; char o_name[80]; char out_val[160]; - int maxwid = 75; - /* Get the item */ - o_ptr = &st_ptr->stock[pos]; ! /* Get the "offset" */ ! i = (pos % 12); /* Label it, clear the line --(-- */ ! sprintf(out_val, "%c) ", I2A(i)); ! prt(out_val, i+6, 0); ! /* Describe an item in the home */ if (store_num == 7) { byte attr; --- 1325,1359 ---- /* ! * Redisplay a single store entry */ ! static void display_entry(int item) { ! int y; object_type *o_ptr; s32b x; char o_name[80]; char out_val[160]; int maxwid = 75; ! /* Must be on current "page" to get displayed */ ! if (!((item >= store_top) && (item < store_top + 12))) return; ! ! ! /* Get the object */ ! o_ptr = &st_ptr->stock[item]; ! ! /* Get the row */ ! y = (item % 12) + 6; /* Label it, clear the line --(-- */ ! sprintf(out_val, "%c) ", store_to_label(item)); ! prt(out_val, y, 0); ! /* Describe an object in the home */ if (store_num == 7) { byte attr; *************** *** 1332,1354 **** /* 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, i+6, 3); /* Show weights */ if (show_weights) { ! /* Only show the weight of an individual item */ int wgt = o_ptr->weight; sprintf(out_val, "%3d.%d lb", wgt / 10, wgt % 10); ! put_str(out_val, i+6, 68); } } ! /* Describe an item (fully) in a store */ else { byte attr; --- 1370,1389 ---- /* Acquire inventory color */ attr = tval_to_attr[o_ptr->tval & 0x7F]; /* Display the object */ ! c_put_str(attr, o_name, y, 3); /* Show weights */ if (show_weights) { ! /* Only show the weight of a single object */ int wgt = o_ptr->weight; sprintf(out_val, "%3d.%d lb", wgt / 10, wgt % 10); ! put_str(out_val, y, 68); } } ! /* Describe an object (fully) in a store */ else { byte attr; *************** *** 1366,1384 **** /* 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, i+6, 3); /* Show weights */ if (show_weights) { ! /* Only show the weight of an individual item */ int wgt = o_ptr->weight; sprintf(out_val, "%3d.%d", wgt / 10, wgt % 10); ! put_str(out_val, i+6, 61); } /* Display a "fixed" cost */ --- 1401,1416 ---- /* Acquire inventory color */ attr = tval_to_attr[o_ptr->tval & 0x7F]; /* Display the object */ ! c_put_str(attr, o_name, y, 3); /* Show weights */ if (show_weights) { ! /* Only show the weight of a single object */ int wgt = o_ptr->weight; sprintf(out_val, "%3d.%d", wgt / 10, wgt % 10); ! put_str(out_val, y, 61); } /* Display a "fixed" cost */ *************** *** 1389,1395 **** /* Actually draw the price (not fixed) */ sprintf(out_val, "%9ld F", (long)x); ! put_str(out_val, i+6, 68); } /* Display a "taxed" cost */ --- 1421,1427 ---- /* Actually draw the price (not fixed) */ sprintf(out_val, "%9ld F", (long)x); ! put_str(out_val, y, 68); } /* Display a "taxed" cost */ *************** *** 1403,1409 **** /* Actually draw the price (with tax) */ sprintf(out_val, "%9ld ", (long)x); ! put_str(out_val, i+6, 68); } /* Display a "haggle" cost */ --- 1435,1441 ---- /* Actually draw the price (with tax) */ sprintf(out_val, "%9ld ", (long)x); ! put_str(out_val, y, 68); } /* Display a "haggle" cost */ *************** *** 1414,1420 **** /* Actually draw the price (not fixed) */ sprintf(out_val, "%9ld ", (long)x); ! put_str(out_val, i+6, 68); } } } --- 1446,1452 ---- /* Actually draw the price (not fixed) */ sprintf(out_val, "%9ld ", (long)x); ! put_str(out_val, y, 68); } } } *************** *** 1432,1438 **** /* Display the next 12 items */ for (k = 0; k < 12; k++) { ! /* Do not display "dead" items */ if (store_top + k >= st_ptr->stock_num) break; /* Display that line */ --- 1464,1470 ---- /* Display the next 12 items */ for (k = 0; k < 12; k++) { ! /* Stop when we run out of items */ if (store_top + k >= st_ptr->stock_num) break; /* Display that line */ *************** *** 1448,1454 **** /* Visual reminder of "more items" */ if (st_ptr->stock_num > 12) { ! /* Show "more" reminder (after the last item) */ prt("-more-", k + 6, 3); /* Indicate the "current page" */ --- 1480,1486 ---- /* Visual reminder of "more items" */ if (st_ptr->stock_num > 12) { ! /* Show "more" reminder (after the last object ) */ prt("-more-", k + 6, 3); /* Indicate the "current page" */ *************** *** 1488,1494 **** /* Put the owner name */ put_str("Your Home", 3, 30); ! /* Label the item descriptions */ put_str("Item Description", 5, 3); /* If showing weights, show label */ --- 1520,1526 ---- /* Put the owner name */ put_str("Your Home", 3, 30); ! /* Label the object descriptions */ put_str("Item Description", 5, 3); /* If showing weights, show label */ *************** *** 1513,1519 **** sprintf(buf, "%s (%ld)", store_name, (long)(ot_ptr->max_cost)); prt(buf, 3, 50); ! /* Label the item descriptions */ put_str("Item Description", 5, 3); /* If showing weights, show label */ --- 1545,1551 ---- sprintf(buf, "%s (%ld)", store_name, (long)(ot_ptr->max_cost)); prt(buf, 3, 50); ! /* Label the object descriptions */ put_str("Item Description", 5, 3); /* If showing weights, show label */ *************** *** 1536,1590 **** /* ! * Get the index of a store item * ! * Return TRUE if an item was selected */ ! static bool get_stock(int *com_val, cptr pmt, int i, int j) { ! char command; ! char out_val[160]; ! /* Paranoia XXX XXX XXX */ ! msg_print(NULL); /* Assume failure */ *com_val = (-1); /* Build the prompt */ ! sprintf(out_val, "(Items %c-%c, ESC to exit) %s", ! I2A(i), I2A(j), pmt); /* Ask until done */ while (TRUE) { ! int k; /* Escape */ ! if (!get_com(out_val, &command)) break; ! /* Convert */ ! k = (islower(command) ? A2I(command) : -1); ! /* Legal responses */ ! if ((k >= i) && (k <= j)) { ! *com_val = k; ! break; } ! /* Oops */ ! bell(); ! } ! /* Clear the prompt */ ! prt("", 0, 0); ! /* Cancel */ ! if (command == ESCAPE) return (FALSE); /* Success */ return (TRUE); --- 1568,1656 ---- /* ! * Get the index of a store object * ! * Return TRUE if an object was selected */ ! static bool get_stock(int *com_val, cptr pmt) { ! int item; ! char which; + char buf[160]; ! char o_name[80]; ! ! char out_val[160]; ! ! object_type *o_ptr; /* Assume failure */ *com_val = (-1); /* Build the prompt */ ! sprintf(buf, "(Items %c-%c, ESC to exit) %s", ! store_to_label(0), store_to_label(st_ptr->stock_num - 1), ! pmt); /* Ask until done */ while (TRUE) { ! int ver; /* Escape */ ! if (!get_com(buf, &which)) return (FALSE); ! /* Extract "query" setting */ ! ver = isupper(which); ! which = tolower(which); ! /* Convert response to item */ ! item = label_to_store(which); ! ! /* Oops */ ! if (item < 0) { ! /* Oops */ ! bell("Illegal store object choice!"); ! ! continue; } ! /* No verification */ ! if (!ver) break; ! /* Object */ ! o_ptr = &st_ptr->stock[item]; ! /* Home */ ! if (store_num == 7) ! { ! /* Describe */ ! object_desc(o_name, o_ptr, TRUE, 3); ! } ! ! /* Shop */ ! else ! { ! /* Describe */ ! object_desc_store(o_name, o_ptr, TRUE, 3); ! } ! ! /* Prompt */ ! sprintf(out_val, "Try %s? ", o_name); ! ! /* Query */ ! if (!get_check(out_val)) return (FALSE); ! ! /* Done */ ! break; ! } ! ! /* Save item */ ! (*com_val) = item; /* Success */ return (TRUE); *************** *** 1664,1675 **** */ static int get_haggle(cptr pmt, s32b *poffer, s32b price, int final) { - s32b i; - - cptr p; - char buf[128]; - char out_val[160]; /* Clear old increment if necessary */ --- 1730,1736 ---- *************** *** 1708,1718 **** /* Ask until done */ while (TRUE) { /* Default */ strcpy(out_val, ""); /* Ask the user for a response */ ! if (!get_string(buf, out_val, 32)) return (FALSE); /* Skip leading spaces */ for (p = out_val; *p == ' '; p++) /* loop */; --- 1769,1783 ---- /* Ask until done */ while (TRUE) { + cptr p; + + char out_val[81]; + /* Default */ strcpy(out_val, ""); /* Ask the user for a response */ ! if (!get_string(buf, out_val, 80)) return (FALSE); /* Skip leading spaces */ for (p = out_val; *p == ' '; p++) /* loop */; *************** *** 1739,1744 **** --- 1804,1811 ---- /* Normal response */ else { + s32b i; + /* Extract a number */ i = atol(p); *************** *** 2098,2104 **** final_ask *= o_ptr->number; ! /* XXX XXX XXX Display commands */ /* Haggling parameters */ min_per = ot_ptr->haggle_per; --- 2165,2171 ---- final_ask *= o_ptr->number; ! /* Display commands XXX XXX XXX */ /* Haggling parameters */ min_per = ot_ptr->haggle_per; *************** *** 2222,2232 **** /* ! * Buy an item from a store */ static void store_purchase(void) { ! int i, amt, choice; int item, item_new; s32b price; --- 2289,2300 ---- /* ! * Buy an object from a store */ static void store_purchase(void) { ! int n; ! int amt, choice; int item, item_new; s32b price; *************** *** 2244,2261 **** /* Empty? */ if (st_ptr->stock_num <= 0) { ! if (store_num == 7) msg_print("Your home is empty."); ! else msg_print("I am currently out of stock."); return; } - /* Find the number of objects on this and following pages */ - i = (st_ptr->stock_num - store_top); - - /* And then restrict it to the current page */ - if (i > 12) i = 12; - /* Prompt */ if (store_num == 7) { --- 2312,2329 ---- /* Empty? */ if (st_ptr->stock_num <= 0) { ! if (store_num == 7) ! { ! msg_print("Your home is empty."); ! } ! else ! { ! msg_print("I am currently out of stock."); ! } return; } /* Prompt */ if (store_num == 7) { *************** *** 2266,2295 **** sprintf(out_val, "Which item are you interested in? "); } ! /* Get the item number to be bought */ ! if (!get_stock(&item, out_val, 0, i-1)) return; ! /* Get the actual index */ ! item = item + store_top; ! ! /* Get the actual item */ o_ptr = &st_ptr->stock[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; ! } /* Get local object */ i_ptr = &object_type_body; --- 2334,2350 ---- sprintf(out_val, "Which item are you interested in? "); } ! /* Get the object number to be bought */ ! if (!get_stock(&item, out_val)) return; ! /* Get the actual object */ o_ptr = &st_ptr->stock[item]; ! /* Get a quantity */ ! amt = get_quantity(NULL, o_ptr->number); ! /* Allow user abort */ ! if (amt <= 0) return; /* Get local object */ i_ptr = &object_type_body; *************** *** 2314,2320 **** object_desc_store(o_name, i_ptr, TRUE, 3); /* Message */ ! msg_format("Buying %s (%c).", o_name, I2A(item)); msg_print(NULL); /* Haggle for a final price */ --- 2369,2376 ---- object_desc_store(o_name, i_ptr, TRUE, 3); /* Message */ ! msg_format("Buying %s (%c).", ! o_name, store_to_label(item)); msg_print(NULL); /* Haggle for a final price */ *************** *** 2348,2364 **** /* Update the display */ store_prt_gold(); ! /* Hack -- buying an item makes you aware of it */ object_aware(i_ptr); ! /* Hack -- clear the "fixed" flag from the item */ i_ptr->ident &= ~(IDENT_FIXED); /* Describe the transaction */ object_desc(o_name, i_ptr, TRUE, 3); /* Message */ ! msg_format("You bought %s for %ld gold.", o_name, (long)price); /* Erase the inscription */ i_ptr->note = 0; --- 2404,2425 ---- /* Update the display */ store_prt_gold(); ! /* Buying an object makes you aware of it */ object_aware(i_ptr); ! /* Combine / Reorder the pack (later) */ ! p_ptr->notice |= (PN_COMBINE | PN_REORDER); ! ! /* Clear the "fixed" flag from the object */ i_ptr->ident &= ~(IDENT_FIXED); /* Describe the transaction */ object_desc(o_name, i_ptr, TRUE, 3); /* Message */ ! msg_format("You bought %s (%c) for %ld gold.", ! o_name, store_to_label(item), ! (long)price); /* Erase the inscription */ i_ptr->note = 0; *************** *** 2377,2391 **** handle_stuff(); /* Note how many slots the store used to have */ ! i = st_ptr->stock_num; ! /* Remove the bought items from the store */ store_item_increase(item, -amt); store_item_optimize(item); /* Store is empty */ if (st_ptr->stock_num == 0) { /* Shuffle */ if (rand_int(STORE_SHUFFLE) == 0) { --- 2438,2454 ---- handle_stuff(); /* Note how many slots the store used to have */ ! n = st_ptr->stock_num; ! /* Remove the bought objects from the store */ store_item_increase(item, -amt); store_item_optimize(item); /* Store is empty */ if (st_ptr->stock_num == 0) { + int i; + /* Shuffle */ if (rand_int(STORE_SHUFFLE) == 0) { *************** *** 2404,2410 **** } /* New inventory */ ! for (i = 0; i < 10; i++) { /* Maintain the store */ store_maint(store_num); --- 2467,2473 ---- } /* New inventory */ ! for (i = 0; i < 10; ++i) { /* Maintain the store */ store_maint(store_num); *************** *** 2417,2436 **** display_inventory(); } ! /* The item is gone */ ! else if (st_ptr->stock_num != i) { ! /* Pick the correct screen */ ! if (store_top >= st_ptr->stock_num) store_top -= 12; /* Redraw everything */ display_inventory(); } ! /* Item is still here */ else { ! /* Redraw the item */ display_entry(item); } } --- 2480,2502 ---- display_inventory(); } ! /* The object is gone */ ! else if (st_ptr->stock_num != n) { ! /* Only one screen left */ ! if (st_ptr->stock_num <= 12) ! { ! store_top = 0; ! } /* Redraw everything */ display_inventory(); } ! /* The object is still here */ else { ! /* Redraw the object */ display_entry(item); } } *************** *** 2447,2452 **** --- 2513,2530 ---- /* Home is much easier */ else { + + #if 0 + + /* Describe the object */ + object_desc(o_name, i_ptr, TRUE, 3); + + /* Message */ + msg_format("You pick up %s (%c).", + o_name, store_to_label(item)); + + #endif + /* Give it to the player */ item_new = inven_carry(i_ptr); *************** *** 2460,2489 **** handle_stuff(); /* Take note if we take the last one */ ! i = st_ptr->stock_num; /* Remove the items from the home */ store_item_increase(item, -amt); store_item_optimize(item); ! /* Hack -- Item is still here */ ! if (i == st_ptr->stock_num) { ! /* Redraw the item */ ! display_entry(item); } ! /* The item is gone */ else { ! /* Nothing left */ ! if (st_ptr->stock_num == 0) store_top = 0; ! ! /* Nothing left on that screen */ ! else if (store_top >= st_ptr->stock_num) store_top -= 12; ! ! /* Redraw everything */ ! display_inventory(); } } --- 2538,2567 ---- handle_stuff(); /* Take note if we take the last one */ ! n = st_ptr->stock_num; /* Remove the items from the home */ store_item_increase(item, -amt); store_item_optimize(item); ! /* The object is gone */ ! if (st_ptr->stock_num != n) { ! /* Only one screen left */ ! if (st_ptr->stock_num <= 12) ! { ! store_top = 0; ! } ! ! /* Redraw everything */ ! display_inventory(); } ! /* The object is still here */ else { ! /* Redraw the object */ ! display_entry(item); } } *************** *** 2493,2499 **** /* ! * Sell an item to the store (or home) */ static void store_sell(void) { --- 2571,2577 ---- /* ! * Sell an object to the store (or home) */ static void store_sell(void) { *************** *** 2543,2549 **** } ! /* Hack -- Cannot remove cursed items */ if ((item >= INVEN_WIELD) && cursed_p(o_ptr)) { /* Oops */ --- 2621,2627 ---- } ! /* Hack -- Cannot remove cursed objects */ if ((item >= INVEN_WIELD) && cursed_p(o_ptr)) { /* Oops */ *************** *** 2553,2573 **** return; } ! /* 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; ! } /* Get local object */ i_ptr = &object_type_body; --- 2631,2641 ---- return; } ! /* Get a quantity */ ! amt = get_quantity(NULL, o_ptr->number); ! /* Allow user abort */ ! if (amt <= 0) return; /* Get local object */ i_ptr = &object_type_body; *************** *** 2587,2594 **** /* Is there room in the store (or the home?) */ if (!store_check_num(i_ptr)) { ! if (store_num == 7) msg_print("Your home is full."); ! else msg_print("I have not the room in my store to keep it."); return; } --- 2655,2668 ---- /* Is there room in the store (or the home?) */ if (!store_check_num(i_ptr)) { ! if (store_num == 7) ! { ! msg_print("Your home is full."); ! } ! else ! { ! msg_print("I have not the room in my store to keep it."); ! } return; } *************** *** 2624,2630 **** /* Get the "apparent" value */ dummy = object_value(i_ptr) * i_ptr->number; ! /* Identify original item */ object_aware(o_ptr); object_known(o_ptr); --- 2698,2704 ---- /* Get the "apparent" value */ dummy = object_value(i_ptr) * i_ptr->number; ! /* Identify original object */ object_aware(o_ptr); object_known(o_ptr); *************** *** 2632,2638 **** p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* Window stuff */ ! p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER); /* Get local object */ i_ptr = &object_type_body; --- 2706,2712 ---- p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* Window stuff */ ! p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER_0 | PW_PLAYER_1); /* Get local object */ i_ptr = &object_type_body; *************** *** 2650,2661 **** object_desc(o_name, i_ptr, TRUE, 3); /* Describe the result (in message buffer) */ ! msg_format("You sold %s for %ld gold.", o_name, (long)price); /* Analyze the prices (and comment verbally) */ purchase_analyze(price, value, dummy); ! /* Take the item from the player, describe the result */ inven_item_increase(item, -amt); inven_item_describe(item); inven_item_optimize(item); --- 2724,2736 ---- object_desc(o_name, i_ptr, TRUE, 3); /* Describe the result (in message buffer) */ ! msg_format("You sold %s (%c) for %ld gold.", ! o_name, index_to_label(item), (long)price); /* Analyze the prices (and comment verbally) */ purchase_analyze(price, value, dummy); ! /* Take the object from the player */ inven_item_increase(item, -amt); inven_item_describe(item); inven_item_optimize(item); *************** *** 2663,2675 **** /* Handle stuff */ handle_stuff(); ! /* The store gets that (known) item */ item_pos = store_carry(i_ptr); ! /* Re-display if item is now in store */ if (item_pos >= 0) { ! store_top = (item_pos / 12) * 12; display_inventory(); } } --- 2738,2755 ---- /* Handle stuff */ handle_stuff(); ! #if 0 ! /* Take note if we add a new item */ ! n = st_ptr->stock_num; ! #endif ! ! /* The store gets that (known) object */ item_pos = store_carry(i_ptr); ! /* Update the display */ if (item_pos >= 0) { ! /* Redisplay wares */ display_inventory(); } } *************** *** 2689,2701 **** /* Handle stuff */ handle_stuff(); /* Let the home carry it */ item_pos = home_carry(i_ptr); /* Update store display */ if (item_pos >= 0) { ! store_top = (item_pos / 12) * 12; display_inventory(); } } --- 2769,2786 ---- /* Handle stuff */ handle_stuff(); + #if 0 + /* Take note if we add a new item */ + n = st_ptr->stock_num; + #endif + /* Let the home carry it */ item_pos = home_carry(i_ptr); /* Update store display */ if (item_pos >= 0) { ! /* Redisplay wares */ display_inventory(); } } *************** *** 2738,2751 **** { if (st_ptr->stock_num <= 12) { msg_print("Entire inventory is shown."); } else { ! store_top += 12; ! if (store_top >= st_ptr->stock_num) store_top = 0; display_inventory(); } break; } --- 2823,2850 ---- { if (st_ptr->stock_num <= 12) { + /* Nothing to see */ msg_print("Entire inventory is shown."); } + + else if (store_top == 0) + { + /* Page 2 */ + store_top = 12; + + /* Redisplay wares */ + display_inventory(); + } + else { ! /* Page 1 */ ! store_top = 0; ! ! /* Redisplay wares */ display_inventory(); } + break; } *************** *** 2936,2942 **** case '=': { do_cmd_options(); - character_icky = TRUE; do_cmd_redraw(); display_store(); break; --- 3035,3040 ---- *************** *** 3052,3066 **** } - /* Forget the lite */ - forget_lite(); - /* Forget the view */ forget_view(); ! /* Hack -- Character is in "icky" mode */ ! character_icky = TRUE; /* No command argument */ --- 3150,3161 ---- } /* Forget the view */ forget_view(); ! /* Hack -- Increase "icky" depth */ ! character_icky++; /* No command argument */ *************** *** 3111,3129 **** prt(" SPACE) Next page of stock", 23, 0); } ! /* Home commands */ ! if (store_num == 7) ! { ! prt(" g) Get an item.", 22, 40); ! prt(" d) Drop an item.", 23, 40); ! } ! ! /* Shop commands XXX XXX XXX */ ! else ! { ! prt(" p) Purchase an item.", 22, 40); ! prt(" s) Sell an item.", 23, 40); ! } /* Prompt */ prt("You may: ", 21, 0); --- 3206,3214 ---- prt(" SPACE) Next page of stock", 23, 0); } ! /* Commands */ ! prt(" g) Get/Purchase an item.", 22, 40); ! prt(" d) Drop/Sell an item.", 23, 40); /* Prompt */ prt("You may: ", 21, 0); *************** *** 3134,3149 **** /* Process the command */ store_process_command(); - /* Hack -- Character is still in "icky" mode */ - character_icky = TRUE; - /* Notice stuff */ notice_stuff(); /* Handle stuff */ handle_stuff(); ! /* XXX XXX XXX Pack Overflow */ if (inventory[INVEN_PACK].k_idx) { int item = INVEN_PACK; --- 3219,3231 ---- /* Process the command */ store_process_command(); /* Notice stuff */ notice_stuff(); /* Handle stuff */ handle_stuff(); ! /* Pack Overflow XXX XXX XXX */ if (inventory[INVEN_PACK].k_idx) { int item = INVEN_PACK; *************** *** 3187,3193 **** /* Get local object */ i_ptr = &object_type_body; ! /* Grab a copy of the item */ object_copy(i_ptr, o_ptr); /* Describe it */ --- 3269,3275 ---- /* Get local object */ i_ptr = &object_type_body; ! /* Grab a copy of the object */ object_copy(i_ptr, o_ptr); /* Describe it */ *************** *** 3204,3223 **** /* Handle stuff */ handle_stuff(); /* Let the home carry it */ item_pos = home_carry(i_ptr); /* Redraw the home */ if (item_pos >= 0) { ! store_top = (item_pos / 12) * 12; display_inventory(); } } } ! /* Hack -- Redisplay store prices if charisma changes */ ! if (tmp_chr != p_ptr->stat_use[A_CHR]) display_inventory(); /* Hack -- get kicked out of the store */ if (st_ptr->store_open >= turn) leave_store = TRUE; --- 3286,3313 ---- /* Handle stuff */ handle_stuff(); + #if 0 + /* Take note if we add a new item */ + n = st_ptr->stock_num; + #endif /* Let the home carry it */ item_pos = home_carry(i_ptr); /* Redraw the home */ if (item_pos >= 0) { ! /* Redisplay wares */ display_inventory(); } } } ! /* Hack -- Handle charisma changes */ ! if (tmp_chr != p_ptr->stat_use[A_CHR]) ! { ! /* Redisplay wares */ ! display_inventory(); ! } /* Hack -- get kicked out of the store */ if (st_ptr->store_open >= turn) leave_store = TRUE; *************** *** 3228,3237 **** p_ptr->energy_use = 0; - /* Hack -- Character is no longer in "icky" mode */ - character_icky = FALSE; - - /* Hack -- Cancel automatic command */ p_ptr->command_new = 0; --- 3318,3323 ---- *************** *** 3243,3255 **** msg_print(NULL); /* Clear the screen */ Term_clear(); ! /* Update everything */ ! p_ptr->update |= (PU_VIEW | PU_LITE); ! p_ptr->update |= (PU_MONSTERS); /* Redraw entire screen */ p_ptr->redraw |= (PR_BASIC | PR_EXTRA); --- 3329,3344 ---- msg_print(NULL); + /* Hack -- Decrease "icky" depth */ + character_icky--; + + /* Clear the screen */ Term_clear(); ! /* Update the visuals */ ! p_ptr->update |= (PU_UPDATE_VIEW | PU_MONSTERS); /* Redraw entire screen */ p_ptr->redraw |= (PR_BASIC | PR_EXTRA); *************** *** 3303,3318 **** { object_type *o_ptr; ! /* Get the item */ o_ptr = &st_ptr->stock[i]; ! /* Hack -- Sell all old items for "half price" */ o_ptr->discount = 50; ! /* Hack -- Items are no longer "fixed price" */ o_ptr->ident &= ~(IDENT_FIXED); ! /* Mega-Hack -- Note that the item is "on sale" */ o_ptr->note = quark_add("on sale"); } } --- 3392,3407 ---- { object_type *o_ptr; ! /* Get the object */ o_ptr = &st_ptr->stock[i]; ! /* Sell all old items for "half price" */ o_ptr->discount = 50; ! /* Clear the "fixed price" flag */ o_ptr->ident &= ~(IDENT_FIXED); ! /* Inscribe the object as "on sale" */ o_ptr->note = quark_add("on sale"); } } *************** *** 3357,3363 **** /* Destroy crappy items */ if (black_market_crap(o_ptr)) { ! /* Destroy the item */ store_item_increase(j, 0 - o_ptr->number); store_item_optimize(j); } --- 3446,3452 ---- /* Destroy crappy items */ if (black_market_crap(o_ptr)) { ! /* Destroy the object */ store_item_increase(j, 0 - o_ptr->number); store_item_optimize(j); } *************** *** 3445,3448 **** --- 3534,3538 ---- object_wipe(&st_ptr->stock[k]); } } + diff -c -r angband-282/src/tables.c angband-283/src/tables.c *** angband-282/src/tables.c Thu Sep 4 10:17:54 1997 --- angband-283/src/tables.c Wed Feb 11 06:30:29 1998 *************** *** 1147,1153 **** /* General store */ { "Bilbo the Friendly", 200, 170, 108, 5, 15, RACE_HOBBIT}, { "Rincewind the Chicken", 200, 175, 108, 4, 12, RACE_HUMAN}, ! { "Sultan the Midget", 300, 170, 107, 5, 15, RACE_GNOME}, { "Lyar-el the Comely", 300, 165, 107, 6, 18, RACE_ELF}, }, { --- 1147,1153 ---- /* General store */ { "Bilbo the Friendly", 200, 170, 108, 5, 15, RACE_HOBBIT}, { "Rincewind the Chicken", 200, 175, 108, 4, 12, RACE_HUMAN}, ! { "Snafu the Midget", 300, 170, 107, 5, 15, RACE_GNOME}, { "Lyar-el the Comely", 300, 165, 107, 6, 18, RACE_ELF}, }, { *************** *** 1175,1181 **** { "Mauser the Chemist", 10000, 190, 111, 5, 8, RACE_HALF_ELF}, { "Wizzle the Chaotic", 10000, 190, 110, 6, 8, RACE_HOBBIT}, { "Ga-nat the Greedy", 15000, 200, 116, 6, 9, RACE_GNOME}, ! { "Sasha the Slender", 15000, 220, 111, 4, 9, RACE_ELF}, }, { /* Magic Shop */ --- 1175,1181 ---- { "Mauser the Chemist", 10000, 190, 111, 5, 8, RACE_HALF_ELF}, { "Wizzle the Chaotic", 10000, 190, 110, 6, 8, RACE_HOBBIT}, { "Ga-nat the Greedy", 15000, 200, 116, 6, 9, RACE_GNOME}, ! { "Vella the Slender", 15000, 220, 111, 4, 9, RACE_HUMAN}, }, { /* Magic Shop */ *************** *** 2532,2539 **** { "Display inven/equip", "Display equip/inven", ! "Display player flags", ! "Display player screen", NULL, NULL, "Display messages", --- 2532,2539 ---- { "Display inven/equip", "Display equip/inven", ! "Display player (basic)", ! "Display player (extra)", NULL, NULL, "Display messages", *************** *** 2572,2578 **** { "rogue_like_commands", /* OPT_rogue_like_commands */ "quick_messages", /* OPT_quick_messages */ ! "other_query_flag", /* OPT_other_query_flag */ "carry_query_flag", /* OPT_carry_query_flag */ "use_old_target", /* OPT_use_old_target */ "always_pickup", /* OPT_always_pickup */ --- 2572,2578 ---- { "rogue_like_commands", /* OPT_rogue_like_commands */ "quick_messages", /* OPT_quick_messages */ ! "floor_query_flag", /* OPT_floor_query_flag */ "carry_query_flag", /* OPT_carry_query_flag */ "use_old_target", /* OPT_use_old_target */ "always_pickup", /* OPT_always_pickup */ *************** *** 2585,2591 **** "show_choices", /* OPT_show_choices */ "show_details", /* OPT_show_details */ "ring_bell", /* OPT_ring_bell */ ! "inventory_colors", /* OPT_inventory_colors */ "run_ignore_stairs", /* OPT_run_ignore_stairs */ "run_ignore_doors", /* OPT_run_ignore_doors */ "run_cut_corners", /* OPT_run_cut_corners */ --- 2585,2591 ---- "show_choices", /* OPT_show_choices */ "show_details", /* OPT_show_details */ "ring_bell", /* OPT_ring_bell */ ! "show_flavors", /* OPT_flavors */ "run_ignore_stairs", /* OPT_run_ignore_stairs */ "run_ignore_doors", /* OPT_run_ignore_doors */ "run_cut_corners", /* OPT_run_cut_corners */ *************** *** 2598,2606 **** "disturb_other", /* OPT_disturb_other */ "alert_hitpoint", /* OPT_alert_hitpoint */ "alert_failure", /* OPT_alert_failure */ ! NULL, /* xxx */ ! NULL, /* xxx */ ! NULL, /* xxx */ NULL, /* xxx */ "auto_haggle", /* OPT_auto_haggle */ "auto_scum", /* OPT_auto_scum */ --- 2598,2606 ---- "disturb_other", /* OPT_disturb_other */ "alert_hitpoint", /* OPT_alert_hitpoint */ "alert_failure", /* OPT_alert_failure */ ! "verify_destroy", /* OPT_verify_destroy */ ! "verify_special", /* OPT_verify_special */ ! "allow_quantity", /* OPT_allow_quantity */ NULL, /* xxx */ "auto_haggle", /* OPT_auto_haggle */ "auto_scum", /* OPT_auto_scum */ *************** *** 2614,2633 **** "dungeon_stair", /* OPT_dungeon_stair */ "flow_by_sound", /* OPT_flow_by_sound */ "flow_by_smell", /* OPT_flow_by_smell */ ! "track_follow", /* OPT_track_follow */ ! "track_target", /* OPT_track_target */ "smart_learn", /* OPT_smart_learn */ "smart_cheat", /* OPT_smart_cheat */ "view_reduce_lite", /* OPT_view_reduce_lite */ ! "view_reduce_view", /* OPT_view_reduce_view */ "avoid_abort", /* OPT_avoid_abort */ "avoid_other", /* OPT_avoid_other */ "flush_failure", /* OPT_flush_failure */ "flush_disturb", /* OPT_flush_disturb */ ! "flush_command", /* OPT_flush_command */ "fresh_before", /* OPT_fresh_before */ "fresh_after", /* OPT_fresh_after */ ! "fresh_message", /* OPT_fresh_message */ "compress_savefile", /* OPT_compress_savefile */ "hilite_player", /* OPT_hilite_player */ "view_yellow_lite", /* OPT_view_yellow_lite */ --- 2614,2633 ---- "dungeon_stair", /* OPT_dungeon_stair */ "flow_by_sound", /* OPT_flow_by_sound */ "flow_by_smell", /* OPT_flow_by_smell */ ! NULL, /* xxx track_follow */ ! NULL, /* xxx track_target */ "smart_learn", /* OPT_smart_learn */ "smart_cheat", /* OPT_smart_cheat */ "view_reduce_lite", /* OPT_view_reduce_lite */ ! "hidden_player", /* OPT_hidden_player */ "avoid_abort", /* OPT_avoid_abort */ "avoid_other", /* OPT_avoid_other */ "flush_failure", /* OPT_flush_failure */ "flush_disturb", /* OPT_flush_disturb */ ! NULL, /* xxx flush_command */ "fresh_before", /* OPT_fresh_before */ "fresh_after", /* OPT_fresh_after */ ! NULL, /* xxx fresh_message */ "compress_savefile", /* OPT_compress_savefile */ "hilite_player", /* OPT_hilite_player */ "view_yellow_lite", /* OPT_view_yellow_lite */ *************** *** 2644,2650 **** { "Rogue-like commands", /* OPT_rogue_like_commands */ "Activate quick messages", /* OPT_quick_messages */ ! "Prompt for floor item selection", /* OPT_other_query_flag */ "Prompt before picking things up", /* OPT_carry_query_flag */ "Use old target by default", /* OPT_use_old_target */ "Pick things up by default", /* OPT_always_pickup */ --- 2644,2650 ---- { "Rogue-like commands", /* OPT_rogue_like_commands */ "Activate quick messages", /* OPT_quick_messages */ ! "Prompt for floor item selection", /* OPT_floor_query_flag */ "Prompt before picking things up", /* OPT_carry_query_flag */ "Use old target by default", /* OPT_use_old_target */ "Pick things up by default", /* OPT_always_pickup */ *************** *** 2652,2663 **** "Show dungeon level in feet", /* OPT_depth_in_feet */ "Merge inscriptions when stacking", /* OPT_stack_force_notes */ "Merge discounts when stacking", /* OPT_stack_force_costs */ ! "Show labels in object listings", /* OPT_show_labels */ ! "Show weights in object listings", /* OPT_show_weights */ ! "Show choices in certain sub-windows", /* OPT_show_choices */ ! "Show details in certain sub-windows", /* OPT_show_details */ "Audible bell (on errors, etc)", /* OPT_ring_bell */ ! "Use color for inventory listings", /* OPT_inventory_colors */ "When running, ignore stairs", /* OPT_run_ignore_stairs */ "When running, ignore doors", /* OPT_run_ignore_doors */ "When running, cut corners", /* OPT_run_cut_corners */ --- 2652,2663 ---- "Show dungeon level in feet", /* OPT_depth_in_feet */ "Merge inscriptions when stacking", /* OPT_stack_force_notes */ "Merge discounts when stacking", /* OPT_stack_force_costs */ ! "Show labels in equipment listings", /* OPT_show_labels */ ! "Show weights in all object listings", /* OPT_show_weights */ ! "Show choices in inven/equip windows", /* OPT_show_choices */ ! "Show details in monster descriptions", /* OPT_show_details */ "Audible bell (on errors, etc)", /* OPT_ring_bell */ ! "Show flavors in object descriptions", /* OPT_show_flacors */ "When running, ignore stairs", /* OPT_run_ignore_stairs */ "When running, ignore doors", /* OPT_run_ignore_doors */ "When running, cut corners", /* OPT_run_cut_corners */ *************** *** 2670,2683 **** "Disturb whenever various things happen", /* OPT_disturb_other */ "Alert user to critical hitpoints", /* OPT_alert_hitpoint */ "Alert user to various failures", /* OPT_alert_failure */ ! NULL, /* xxx */ ! NULL, /* xxx */ ! NULL, /* xxx */ NULL, /* xxx */ "Auto-haggle in stores", /* OPT_auto_haggle */ "Auto-scum for good levels", /* OPT_auto_scum */ ! "Allow objects to stack on floor (beta)", /* OPT_testing_stack */ ! "Allow monsters to carry objects (beta)", /* OPT_testing_carry */ "Expand the power of the look command", /* OPT_expand_look */ "Expand the power of the list commands", /* OPT_expand_list */ "Map remembers all perma-lit grids", /* OPT_view_perma_grids */ --- 2670,2683 ---- "Disturb whenever various things happen", /* OPT_disturb_other */ "Alert user to critical hitpoints", /* OPT_alert_hitpoint */ "Alert user to various failures", /* OPT_alert_failure */ ! "Verify destruction of objects", /* OPT_verify_destroy */ ! "Verify use of special commands", /* OPT_verify_special */ ! "Allow quantity specification", /* OPT_allow_quantity */ NULL, /* xxx */ "Auto-haggle in stores", /* OPT_auto_haggle */ "Auto-scum for good levels", /* OPT_auto_scum */ ! "Allow objects to stack on floor", /* OPT_testing_stack */ ! "Allow monsters to carry objects", /* OPT_testing_carry */ "Expand the power of the look command", /* OPT_expand_look */ "Expand the power of the list commands", /* OPT_expand_list */ "Map remembers all perma-lit grids", /* OPT_view_perma_grids */ *************** *** 2686,2711 **** "Generate dungeons with connected stairs", /* OPT_dungeon_stair */ "Monsters chase current location (v.slow)", /* OPT_flow_by_sound */ "Monsters chase recent locations (v.slow)", /* OPT_flow_by_smell */ ! "Monsters follow the player (broken)", /* OPT_track_follow */ ! "Monsters target the player (broken)", /* OPT_track_target */ "Monsters learn from their mistakes", /* OPT_smart_learn */ "Monsters exploit players weaknesses", /* OPT_smart_cheat */ "Reduce lite-radius when running", /* OPT_view_reduce_lite */ ! "Reduce view-radius in town", /* OPT_view_reduce_view */ "Avoid checking for user abort", /* OPT_avoid_abort */ "Avoid processing special colors", /* OPT_avoid_other */ "Flush input on various failures", /* OPT_flush_failure */ "Flush input whenever disturbed", /* OPT_flush_disturb */ ! "Flush input before every command", /* OPT_flush_command */ "Flush output before every command", /* OPT_fresh_before */ ! "Flush output after every command", /* OPT_fresh_after */ ! "Flush output after every message", /* OPT_fresh_message */ "Compress messages in savefiles", /* OPT_compress_savefile */ "Hilite the player with the cursor", /* OPT_hilite_player */ ! "Use special colors for torch-lit grids", /* OPT_view_yellow_lite */ ! "Use special colors for 'viewable' grids", /* OPT_view_bright_lite */ ! "Use special colors for wall grids (slow)", /* OPT_view_granite_lite */ ! "Use special colors for floor grids (slow)" /* OPT_view_special_lite */ }; --- 2686,2711 ---- "Generate dungeons with connected stairs", /* OPT_dungeon_stair */ "Monsters chase current location (v.slow)", /* OPT_flow_by_sound */ "Monsters chase recent locations (v.slow)", /* OPT_flow_by_smell */ ! NULL, /* xxx */ ! NULL, /* xxx */ "Monsters learn from their mistakes", /* OPT_smart_learn */ "Monsters exploit players weaknesses", /* OPT_smart_cheat */ "Reduce lite-radius when running", /* OPT_view_reduce_lite */ ! "Hide player symbol when running", /* OPT_hidden_player */ "Avoid checking for user abort", /* OPT_avoid_abort */ "Avoid processing special colors", /* OPT_avoid_other */ "Flush input on various failures", /* OPT_flush_failure */ "Flush input whenever disturbed", /* OPT_flush_disturb */ ! NULL, /* xxx */ "Flush output before every command", /* OPT_fresh_before */ ! "Flush output after various things", /* OPT_fresh_after */ ! NULL, /* xxx */ "Compress messages in savefiles", /* OPT_compress_savefile */ "Hilite the player with the cursor", /* OPT_hilite_player */ ! "Use special colors for torch lite", /* OPT_view_yellow_lite */ ! "Use special colors for field of view", /* OPT_view_bright_lite */ ! "Use special colors for wall grids", /* OPT_view_granite_lite */ ! "Use special colors for floor grids" /* OPT_view_special_lite */ }; *************** *** 2716,2722 **** { FALSE, /* OPT_rogue_like_commands */ FALSE, /* OPT_quick_messages */ ! TRUE, /* OPT_other_query_flag */ FALSE, /* OPT_carry_query_flag */ FALSE, /* OPT_use_old_target */ TRUE, /* OPT_always_pickup */ --- 2716,2722 ---- { FALSE, /* OPT_rogue_like_commands */ FALSE, /* OPT_quick_messages */ ! TRUE, /* OPT_floor_query_flag */ FALSE, /* OPT_carry_query_flag */ FALSE, /* OPT_use_old_target */ TRUE, /* OPT_always_pickup */ *************** *** 2729,2735 **** TRUE, /* OPT_show_choices */ TRUE, /* OPT_show_details */ TRUE, /* OPT_ring_bell */ ! TRUE, /* OPT_inventory_colors */ TRUE, /* OPT_run_ignore_stairs */ TRUE, /* OPT_run_ignore_doors */ TRUE, /* OPT_run_cut_corners */ --- 2729,2735 ---- TRUE, /* OPT_show_choices */ TRUE, /* OPT_show_details */ TRUE, /* OPT_ring_bell */ ! TRUE, /* OPT_show_flavors */ TRUE, /* OPT_run_ignore_stairs */ TRUE, /* OPT_run_ignore_doors */ TRUE, /* OPT_run_cut_corners */ *************** *** 2742,2750 **** TRUE, /* OPT_disturb_other */ FALSE, /* OPT_alert_hitpoint */ FALSE, /* OPT_alert_failure */ ! FALSE, /* xxx */ ! FALSE, /* xxx */ ! FALSE, /* xxx */ FALSE, /* xxx */ TRUE, /* OPT_auto_haggle */ FALSE, /* OPT_auto_scum */ --- 2742,2750 ---- TRUE, /* OPT_disturb_other */ FALSE, /* OPT_alert_hitpoint */ FALSE, /* OPT_alert_failure */ ! TRUE, /* OPT_verify_destroy */ ! TRUE, /* OPT_verify_special */ ! TRUE, /* OPT_allow_quantity */ FALSE, /* xxx */ TRUE, /* OPT_auto_haggle */ FALSE, /* OPT_auto_scum */ *************** *** 2758,2777 **** TRUE, /* OPT_dungeon_stair */ FALSE, /* OPT_flow_by_sound */ FALSE, /* OPT_flow_by_smell */ ! FALSE, /* OPT_track_follow */ ! FALSE, /* OPT_track_target */ FALSE, /* OPT_smart_learn */ FALSE, /* OPT_smart_cheat */ FALSE, /* OPT_view_reduce_lite */ ! FALSE, /* OPT_view_reduce_view */ FALSE, /* OPT_avoid_abort */ FALSE, /* OPT_avoid_other */ TRUE, /* OPT_flush_failure */ FALSE, /* OPT_flush_disturb */ ! FALSE, /* OPT_flush_command */ TRUE, /* OPT_fresh_before */ FALSE, /* OPT_fresh_after */ ! FALSE, /* OPT_fresh_message */ TRUE, /* OPT_compress_savefile */ FALSE, /* OPT_hilite_player */ FALSE, /* OPT_view_yellow_lite */ --- 2758,2777 ---- TRUE, /* OPT_dungeon_stair */ FALSE, /* OPT_flow_by_sound */ FALSE, /* OPT_flow_by_smell */ ! FALSE, /* xxx */ ! FALSE, /* xxx */ FALSE, /* OPT_smart_learn */ FALSE, /* OPT_smart_cheat */ FALSE, /* OPT_view_reduce_lite */ ! FALSE, /* OPT_hidden_player */ FALSE, /* OPT_avoid_abort */ FALSE, /* OPT_avoid_other */ TRUE, /* OPT_flush_failure */ FALSE, /* OPT_flush_disturb */ ! FALSE, /* xxx */ TRUE, /* OPT_fresh_before */ FALSE, /* OPT_fresh_after */ ! FALSE, /* xxx */ TRUE, /* OPT_compress_savefile */ FALSE, /* OPT_hilite_player */ FALSE, /* OPT_view_yellow_lite */ *************** *** 2791,2797 **** { OPT_rogue_like_commands, OPT_quick_messages, ! OPT_other_query_flag, OPT_carry_query_flag, OPT_use_old_target, OPT_always_pickup, --- 2791,2797 ---- { OPT_rogue_like_commands, OPT_quick_messages, ! OPT_floor_query_flag, OPT_carry_query_flag, OPT_use_old_target, OPT_always_pickup, *************** *** 2803,2810 **** OPT_show_weights, OPT_show_choices, OPT_show_details, ! OPT_ring_bell, ! OPT_inventory_colors }, /*** Disturbance ***/ --- 2803,2810 ---- OPT_show_weights, OPT_show_choices, OPT_show_details, ! OPT_show_flavors, ! OPT_ring_bell }, /*** Disturbance ***/ *************** *** 2822,2830 **** OPT_disturb_other, OPT_alert_hitpoint, OPT_alert_failure, ! 255, ! 255, ! 255, 255 }, --- 2822,2830 ---- OPT_disturb_other, OPT_alert_hitpoint, OPT_alert_failure, ! OPT_verify_destroy, ! OPT_verify_special, ! OPT_allow_quantity, 255 }, *************** *** 2843,2873 **** OPT_dungeon_stair, OPT_flow_by_sound, OPT_flow_by_smell, - OPT_track_follow, - OPT_track_target, OPT_smart_learn, ! OPT_smart_cheat }, /*** Efficiency ***/ { OPT_view_reduce_lite, ! OPT_view_reduce_view, OPT_avoid_abort, OPT_avoid_other, OPT_flush_failure, OPT_flush_disturb, - OPT_flush_command, OPT_fresh_before, OPT_fresh_after, - OPT_fresh_message, OPT_compress_savefile, OPT_hilite_player, OPT_view_yellow_lite, OPT_view_bright_lite, OPT_view_granite_lite, ! OPT_view_special_lite } }; --- 2843,2873 ---- OPT_dungeon_stair, OPT_flow_by_sound, OPT_flow_by_smell, OPT_smart_learn, ! OPT_smart_cheat, ! 255, ! 255 }, /*** Efficiency ***/ { OPT_view_reduce_lite, ! OPT_hidden_player, OPT_avoid_abort, OPT_avoid_other, OPT_flush_failure, OPT_flush_disturb, OPT_fresh_before, OPT_fresh_after, OPT_compress_savefile, OPT_hilite_player, OPT_view_yellow_lite, OPT_view_bright_lite, OPT_view_granite_lite, ! OPT_view_special_lite, ! 255, ! 255 } }; diff -c -r angband-282/src/types.h angband-283/src/types.h *** angband-282/src/types.h Wed Sep 3 11:57:34 1997 --- angband-283/src/types.h Mon Feb 9 01:11:57 1998 *************** *** 41,46 **** --- 41,72 ---- /**** Available Types ****/ + /* + * An array of 256 byte's + */ + typedef byte byte_256[256]; + + /* + * An array of 256 s16b's + */ + typedef s16b s16b_256[256]; + + + /* + * An array of DUNGEON_WID byte's + */ + typedef byte byte_wid[DUNGEON_WID]; + + /* + * An array of DUNGEON_WID s16b's + */ + typedef s16b s16b_wid[DUNGEON_WID]; + + + + /**** Available Structs ****/ + + typedef struct header header; typedef struct feature_type feature_type; typedef struct object_kind object_kind; *************** *** 133,143 **** s16b unused; /* Extra bytes (unused) */ - byte f_attr; /* Object "attribute" */ - char f_char; /* Object "symbol" */ ! byte z_attr; /* The desired attr for this feature */ ! char z_char; /* The desired char for this feature */ }; --- 159,171 ---- s16b unused; /* Extra bytes (unused) */ ! byte d_attr; /* Default feature attribute */ ! char d_char; /* Default feature character */ ! ! ! byte x_attr; /* Desired feature attribute */ ! char x_char; /* Desired feature character */ }; *************** *** 179,188 **** byte extra; /* Something */ - byte k_attr; /* Standard object attribute */ - char k_char; /* Standard object character */ - - byte d_attr; /* Default object attribute */ char d_char; /* Default object character */ --- 207,212 ---- *************** *** 191,197 **** char x_char; /* Desired object character */ ! bool has_flavor; /* This object has a flavor */ bool easy_know; /* This object is always known (if aware) */ --- 215,221 ---- char x_char; /* Desired object character */ ! byte flavor; /* Special object flavor (or zero) */ bool easy_know; /* This object is always known (if aware) */ *************** *** 911,916 **** --- 935,941 ---- s16b inven_cnt; /* Number of items in inventory */ s16b equip_cnt; /* Number of items in equipment */ + s16b target_set; /* Target flag */ s16b target_who; /* Target identity */ s16b target_row; /* Target location */ s16b target_col; /* Target location */ diff -c -r angband-282/src/util.c angband-283/src/util.c *** angband-282/src/util.c Wed Sep 3 11:57:34 1997 --- angband-283/src/util.c Wed Feb 11 06:30:29 1998 *************** *** 448,460 **** * * Dump a string, plus a newline, to a file * ! * XXX XXX XXX Process internal weirdness? */ errr my_fputs(FILE *fff, cptr buf, huge n) { - /* XXX XXX */ - n = n ? n : 0; - /* Dump, ignore errors */ (void)fprintf(fff, "%s\n", buf); --- 448,457 ---- * * Dump a string, plus a newline, to a file * ! * Perhaps this function should handle internal weirdness. */ errr my_fputs(FILE *fff, cptr buf, huge n) { /* Dump, ignore errors */ (void)fprintf(fff, "%s\n", buf); *************** *** 498,504 **** /* Remove */ (void)remove(buf); ! /* XXX XXX XXX */ return (0); } --- 495,501 ---- /* Remove */ (void)remove(buf); ! /* Assume success XXX XXX XXX */ return (0); } *************** *** 520,526 **** /* Rename */ (void)rename(buf, aux); ! /* XXX XXX XXX */ return (0); } --- 517,523 ---- /* Rename */ (void)rename(buf, aux); ! /* Assume success XXX XXX XXX */ return (0); } *************** *** 542,548 **** /* Copy XXX XXX XXX */ /* (void)rename(buf, aux); */ ! /* XXX XXX XXX */ return (1); } --- 539,545 ---- /* Copy XXX XXX XXX */ /* (void)rename(buf, aux); */ ! /* Assume success XXX XXX XXX */ return (1); } *************** *** 610,618 **** */ errr fd_lock(int fd, int what) { - /* XXX XXX */ - what = what ? what : 0; - /* Verify the fd */ if (fd < 0) return (-1); --- 607,612 ---- *************** *** 696,704 **** */ errr fd_chop(int fd, huge n) { - /* XXX XXX */ - n = n ? n : 0; - /* Verify the fd */ if (fd < 0) return (-1); --- 690,695 ---- *************** *** 789,795 **** /* Close */ (void)close(fd); ! /* XXX XXX XXX */ return (0); } --- 780,786 ---- /* Close */ (void)close(fd); ! /* Assume success XXX XXX XXX */ return (0); } *************** *** 800,869 **** /* - * XXX XXX XXX Important note about "colors" XXX XXX XXX - * - * The "TERM_*" color definitions list the "composition" of each - * "Angband color" in terms of "quarters" of each of the three color - * components (Red, Green, Blue), for example, TERM_UMBER is defined - * as 2/4 Red, 1/4 Green, 0/4 Blue. - * - * The following info is from "Torbjorn Lindgren" (see "main-xaw.c"). - * - * These values are NOT gamma-corrected. On most machines (with the - * Macintosh being an important exception), you must "gamma-correct" - * the given values, that is, "correct for the intrinsic non-linearity - * of the phosphor", by converting the given intensity levels based - * on the "gamma" of the target screen, which is usually 1.7 (or 1.5). - * - * The actual formula for conversion is unknown to me at this time, - * but you can use the table below for the most common gamma values. - * - * So, on most machines, simply convert the values based on the "gamma" - * of the target screen, which is usually in the range 1.5 to 1.7, and - * usually is closest to 1.7. The converted value for each of the five - * different "quarter" values is given below: - * - * Given Gamma 1.0 Gamma 1.5 Gamma 1.7 Hex 1.7 - * ----- ---- ---- ---- --- - * 0/4 0.00 0.00 0.00 #00 - * 1/4 0.25 0.27 0.28 #47 - * 2/4 0.50 0.55 0.56 #8f - * 3/4 0.75 0.82 0.84 #d7 - * 4/4 1.00 1.00 1.00 #ff - * - * Note that some machines (i.e. most IBM machines) are limited to a - * hard-coded set of colors, and so the information above is useless. - * - * Also, some machines are limited to a pre-determined set of colors, - * for example, the IBM can only display 16 colors, and only 14 of - * those colors resemble colors used by Angband, and then only when - * you ignore the fact that "Slate" and "cyan" are not really matches, - * so on the IBM, we use "orange" for both "Umber", and "Light Umber" - * in addition to the obvious "Orange", since by combining all of the - * "indeterminate" colors into a single color, the rest of the colors - * are left with "meaningful" values. - */ - - - /* - * Move the cursor - */ - void move_cursor(int row, int col) - { - Term_gotoxy(col, row); - } - - - - /* - * Convert a decimal to a single digit octal number - */ - static char octify(uint i) - { - return (hexsym[i%8]); - } - - /* * Convert a decimal to a single digit hex number */ static char hexify(uint i) --- 791,796 ---- *************** *** 872,885 **** } - /* - * Convert a octal-digit into a decimal - */ - static int deoct(char c) - { - if (isdigit(c)) return (D2I(c)); - return (0); - } /* * Convert a hexidecimal-digit into a decimal --- 799,804 ---- *************** *** 887,894 **** static int dehex(char c) { if (isdigit(c)) return (D2I(c)); ! if (islower(c)) return (A2I(c) + 10); ! if (isupper(c)) return (A2I(tolower(c)) + 10); return (0); } --- 806,812 ---- static int dehex(char c) { if (isdigit(c)) return (D2I(c)); ! if (isalpha(c)) return (A2I(tolower(c)) + 10); return (0); } *************** *** 896,904 **** /* * Hack -- convert a printable string into real ascii * ! * I have no clue if this function correctly handles, for example, ! * parsing "\xFF" into a (signed) char. Whoever thought of making ! * the "sign" of a "char" undefined is a complete moron. Oh well. */ void text_to_ascii(char *buf, cptr str) { --- 814,822 ---- /* * Hack -- convert a printable string into real ascii * ! * This function will not work on non-ascii systems. ! * ! * To be safe, "buf" should be at least as large as "str". */ void text_to_ascii(char *buf, cptr str) { *************** *** 913,935 **** /* Skip the backslash */ str++; ! /* Hex-mode XXX */ ! if (*str == 'x') ! { ! *s = 16 * dehex(*++str); ! *s++ += dehex(*++str); ! } ! ! /* Hack -- simple way to specify "backslash" */ ! else if (*str == '\\') ! { ! *s++ = '\\'; ! } ! ! /* Hack -- simple way to specify "caret" */ ! else if (*str == '^') { ! *s++ = '^'; } /* Hack -- simple way to specify "space" */ --- 831,840 ---- /* Skip the backslash */ str++; ! /* Hack -- simple way to specify Escape */ ! if (*str == 'e') { ! *s++ = ESCAPE; } /* Hack -- simple way to specify "space" */ *************** *** 938,949 **** *s++ = ' '; } - /* Hack -- simple way to specify Escape */ - else if (*str == 'e') - { - *s++ = ESCAPE; - } - /* Backspace */ else if (*str == 'b') { --- 843,848 ---- *************** *** 968,999 **** *s++ = '\t'; } ! /* Octal-mode */ ! else if (*str == '0') { ! *s = 8 * deoct(*++str); ! *s++ += deoct(*++str); } ! /* Octal-mode */ ! else if (*str == '1') { ! *s = 64 + 8 * deoct(*++str); ! *s++ += deoct(*++str); } ! /* Octal-mode */ ! else if (*str == '2') { ! *s = 64 * 2 + 8 * deoct(*++str); ! *s++ += deoct(*++str); } ! /* Octal-mode */ ! else if (*str == '3') { ! *s = 64 * 3 + 8 * deoct(*++str); ! *s++ += deoct(*++str); } /* Skip the final char */ --- 867,895 ---- *s++ = '\t'; } ! /* Actual "backslash" */ ! else if (*str == '\\') { ! *s++ = '\\'; } ! /* Hack -- Actual "caret" */ ! else if (*str == '^') { ! *s++ = '^'; } ! /* Hack -- Hex-mode */ ! else if (*str == 'x') { ! *s = 16 * dehex(*++str); ! *s++ += dehex(*++str); } ! /* Oops */ ! else { ! *s = *str; } /* Skip the final char */ *************** *** 1021,1026 **** --- 917,926 ---- /* * Hack -- convert a string into a printable form + * + * This function will not work on non-ascii systems. + * + * To be safe, "buf" should be at least four times as large as "str". */ void ascii_to_text(char *buf, cptr str) { *************** *** 1061,1075 **** *s++ = '\\'; *s++ = 'r'; } ! else if (i == '^') { *s++ = '\\'; ! *s++ = '^'; } ! else if (i == '\\') { *s++ = '\\'; ! *s++ = '\\'; } else if (i < 32) { --- 961,975 ---- *s++ = '\\'; *s++ = 'r'; } ! else if (i == '\\') { *s++ = '\\'; ! *s++ = '\\'; } ! else if (i == '^') { *s++ = '\\'; ! *s++ = '^'; } else if (i < 32) { *************** *** 1080,1092 **** { *s++ = i; } - else if (i < 64) - { - *s++ = '\\'; - *s++ = '0'; - *s++ = octify(i / 8); - *s++ = octify(i % 8); - } else { *s++ = '\\'; --- 980,985 ---- *************** *** 1103,1447 **** /* ! * Variable used by the functions below ! */ ! static int hack_dir = 0; ! ! ! /* ! * Convert a "Rogue" keypress into an "Angband" keypress ! * Pass extra information as needed via "hack_dir" * ! * Note that many "Rogue" keypresses encode a direction. */ - static char roguelike_commands(char command) - { - /* Process the command */ - switch (command) - { - /* Movement (rogue keys) */ - case 'b': hack_dir = 1; return (';'); - case 'j': hack_dir = 2; return (';'); - case 'n': hack_dir = 3; return (';'); - case 'h': hack_dir = 4; return (';'); - case 'l': hack_dir = 6; return (';'); - case 'y': hack_dir = 7; return (';'); - case 'k': hack_dir = 8; return (';'); - case 'u': hack_dir = 9; return (';'); - - /* Running (shift + rogue keys) */ - case 'B': hack_dir = 1; return ('.'); - case 'J': hack_dir = 2; return ('.'); - case 'N': hack_dir = 3; return ('.'); - case 'H': hack_dir = 4; return ('.'); - case 'L': hack_dir = 6; return ('.'); - case 'Y': hack_dir = 7; return ('.'); - case 'K': hack_dir = 8; return ('.'); - case 'U': hack_dir = 9; return ('.'); - /* Altering (control + rogue keys) */ - case KTRL('B'): hack_dir = 1; return ('+'); - case KTRL('J'): hack_dir = 2; return ('+'); - case KTRL('N'): hack_dir = 3; return ('+'); - case KTRL('H'): hack_dir = 4; return ('+'); - case KTRL('L'): hack_dir = 6; return ('+'); - case KTRL('Y'): hack_dir = 7; return ('+'); - case KTRL('K'): hack_dir = 8; return ('+'); - case KTRL('U'): hack_dir = 9; return ('+'); - - /* Hack -- White-space */ - case KTRL('M'): return ('\r'); - - /* Allow use of the "tunnel" command */ - case KTRL('T'): return ('T'); - - /* Allow use of the "destroy" command */ - case KTRL('D'): return ('k'); - - /* Hack -- Commit suicide */ - case KTRL('C'): return ('Q'); - - /* Locate player on map */ - case 'W': return ('L'); - - /* Browse a book (Peruse) */ - case 'P': return ('b'); - - /* Jam a door (Spike) */ - case 'S': return ('j'); - - /* Toggle search mode */ - case '#': return ('S'); - - /* Use a staff (Zap) */ - case 'Z': return ('u'); - - /* Take off equipment */ - case 'T': return ('t'); - - /* Fire an item */ - case 't': return ('f'); - - /* Bash a door (Force) */ - case 'f': return ('B'); - - /* Look around (examine) */ - case 'x': return ('l'); - - /* Aim a wand (Zap) */ - case 'z': return ('a'); - - /* Zap a rod (Activate) */ - case 'a': return ('z'); - - /* Run */ - case ',': return ('.'); - - /* Stay still (fake direction) */ - case '.': hack_dir = 5; return (','); - - /* Stay still (fake direction) */ - case '5': hack_dir = 5; return (','); - - /* Standard walking */ - case '1': hack_dir = 1; return (';'); - case '2': hack_dir = 2; return (';'); - case '3': hack_dir = 3; return (';'); - case '4': hack_dir = 4; return (';'); - case '6': hack_dir = 6; return (';'); - case '7': hack_dir = 7; return (';'); - case '8': hack_dir = 8; return (';'); - case '9': hack_dir = 9; return (';'); - } - - /* Default */ - return (command); - } /* ! * Convert an "Original" keypress into an "Angband" keypress ! * ! * Pass direction information back via "hack_dir". ! * ! * Note that the "Original" keyset adds only a few commands to ! * the "Angband" keyset, most importantly, the ability to use ! * pure directions as "walk" commands. */ ! static char original_commands(char command) ! { ! /* Process the command */ ! switch (command) ! { ! /* Hack -- White space */ ! case KTRL('J'): return ('\r'); ! case KTRL('M'): return ('\r'); ! ! /* Stay still (fake direction) */ ! case ',': hack_dir = 5; return (','); ! ! /* Stay still (fake direction) */ ! case '5': hack_dir = 5; return (','); ! ! /* Standard walking */ ! case '1': hack_dir = 1; return (';'); ! case '2': hack_dir = 2; return (';'); ! case '3': hack_dir = 3; return (';'); ! case '4': hack_dir = 4; return (';'); ! case '6': hack_dir = 6; return (';'); ! case '7': hack_dir = 7; return (';'); ! case '8': hack_dir = 8; return (';'); ! case '9': hack_dir = 9; return (';'); ! ! /* Hack -- Commit suicide */ ! case KTRL('K'): return ('Q'); ! case KTRL('C'): return ('Q'); ! } ! ! /* Default */ ! return (command); ! } /* ! * React to new value of "rogue_like_commands". ! * ! * Initialize the "keymap" arrays based on the current value of ! * "rogue_like_commands". Note that all "undefined" keypresses ! * by default map to themselves with no direction. This allows ! * "standard" commands to use the same keys in both keysets. ! * ! * To reset the keymap, simply set "rogue_like_commands" to -1, ! * call this function, restore its value, call this function. ! * ! * The keymap arrays map keys to "p_ptr->command_cmd" and "p_ptr->command_dir". ! * ! * It is illegal for keymap_cmds[N] to be zero, except for ! * keymaps_cmds[0], which is unused. ! * ! * You can map a key to "tab" to make it "non-functional". */ ! void keymap_init(void) { ! int i, k; ! ! /* Notice changes in the "rogue_like_commands" flag */ ! static old_rogue_like = -1; ! ! /* Hack -- notice changes in "rogue_like_commands" */ ! if (old_rogue_like == rogue_like_commands) return; ! /* Initialize every entry */ ! for (i = 0; i < 128; i++) { ! /* Default to "no direction" */ ! hack_dir = 0; ! ! /* Attempt to translate */ ! if (rogue_like_commands) ! { ! k = roguelike_commands(i); ! } ! else ! { ! k = original_commands(i); ! } ! /* Save the keypress */ ! keymap_cmds[i] = k; ! /* Save the direction */ ! keymap_dirs[i] = hack_dir; } ! /* Save the "rogue_like_commands" setting */ ! old_rogue_like = rogue_like_commands; } - - - - - - /* ! * Legal bit-flags for macro__use[X] */ ! #define MACRO_USE_CMD 0x01 /* X triggers a command macro */ ! #define MACRO_USE_STD 0x02 /* X triggers a standard macro */ ! ! /* ! * Fast check for trigger of any macros ! */ ! static byte macro__use[256]; ! ! ! ! /* ! * Hack -- add a macro definition (or redefinition). ! * ! * If "cmd_flag" is set then this macro is only active when ! * the user is being asked for a command (see below). ! */ ! void macro_add(cptr pat, cptr act, bool cmd_flag) { ! int n; ! ! ! /* Paranoia -- require data */ ! if (!pat || !act) return; ! ! /* Look for a re-usable slot */ ! for (n = 0; n < macro__num; n++) { ! /* Notice macro redefinition */ ! if (streq(macro__pat[n], pat)) ! { ! /* Free the old macro action */ ! string_free(macro__act[n]); ! ! /* Save the macro action */ ! macro__act[n] = string_make(act); ! ! /* Save the "cmd_flag" */ ! macro__cmd[n] = cmd_flag; ! ! /* All done */ ! return; ! } } ! /* Save the pattern */ ! macro__pat[macro__num] = string_make(pat); ! ! /* Save the macro action */ ! macro__act[macro__num] = string_make(act); ! ! /* Save the "cmd_flag" */ ! macro__cmd[macro__num] = cmd_flag; ! ! /* One more macro */ ! macro__num++; ! ! ! /* Hack -- Note the "trigger" char */ ! macro__use[(byte)(pat[0])] |= (MACRO_USE_STD); ! /* Hack -- Note the "trigger" char of command macros */ ! if (cmd_flag) macro__use[(byte)(pat[0])] |= (MACRO_USE_CMD); } - /* ! * Check for possibly pending macros */ ! static int macro_maybe(cptr buf, int n) { int i; /* Scan the macros */ ! for (i = n; i < macro__num; i++) { ! /* Skip inactive macros */ ! if (macro__cmd[i] && !inkey_flag) continue; ! /* Check for "prefix" */ ! if (prefix(macro__pat[i], buf)) ! { ! /* Ignore complete macros */ ! if (!streq(macro__pat[i], buf)) return (i); ! } } ! /* No matches */ return (-1); } /* ! * Find the longest completed macro */ ! static int macro_ready(cptr buf) { int i, t, n = -1, s = -1; ! /* Scan the macros */ ! for (i = 0; i < macro__num; i++) { ! /* Skip inactive macros */ ! if (macro__cmd[i] && !inkey_flag) continue; ! /* Check for "prefix" */ ! if (!prefix(buf, macro__pat[i])) continue; ! /* Check the length of this entry */ t = strlen(macro__pat[i]); ! /* Find the "longest" entry */ if ((n >= 0) && (s > t)) continue; /* Track the entry */ --- 996,1126 ---- /* ! * The "macro" package * ! * Functions are provided to manipulate a collection of macros, each ! * of which has a trigger pattern string and a resulting action string ! * and a small set of flags. */ /* ! * Determine if any macros have ever started with a given character. */ ! static bool macro__use[256]; /* ! * Find the macro (if any) which exactly matches the given pattern */ ! sint macro_find_exact(cptr pat) { ! int i; ! /* Nothing possible */ ! if (!macro__use[(byte)(pat[0])]) { ! return (-1); ! } ! /* Scan the macros */ ! for (i = 0; i < macro__num; ++i) ! { ! /* Skip macros which do not match the pattern */ ! if (!streq(macro__pat[i], pat)) continue; ! /* Found one */ ! return (i); } ! /* No matches */ ! return (-1); } /* ! * Find the first macro (if any) which contains the given pattern */ ! static sint macro_find_check(cptr pat) { ! int i; ! /* Nothing possible */ ! if (!macro__use[(byte)(pat[0])]) { ! return (-1); } + /* Scan the macros */ + for (i = 0; i < macro__num; ++i) + { + /* Skip macros which do not contain the pattern */ + if (!prefix(macro__pat[i], pat)) continue; ! /* Found one */ ! return (i); ! } ! /* Nothing */ ! return (-1); } /* ! * Find the first macro (if any) which contains the given pattern and more */ ! static sint macro_find_maybe(cptr pat) { int i; + /* Nothing possible */ + if (!macro__use[(byte)(pat[0])]) + { + return (-1); + } + /* Scan the macros */ ! for (i = 0; i < macro__num; ++i) { ! /* Skip macros which do not contain the pattern */ ! if (!prefix(macro__pat[i], pat)) continue; ! /* Skip macros which exactly match the pattern XXX XXX */ ! if (streq(macro__pat[i], pat)) continue; ! ! /* Found one */ ! return (i); } ! /* Nothing */ return (-1); } /* ! * Find the longest macro (if any) which starts with the given pattern */ ! static sint macro_find_ready(cptr pat) { int i, t, n = -1, s = -1; ! /* Nothing possible */ ! if (!macro__use[(byte)(pat[0])]) { ! return (-1); ! } ! /* Scan the macros */ ! for (i = 0; i < macro__num; ++i) ! { ! /* Skip macros which are not contained by the pattern */ ! if (!prefix(pat, macro__pat[i])) continue; ! /* Obtain the length of this macro */ t = strlen(macro__pat[i]); ! /* Only track the "longest" pattern */ if ((n >= 0) && (s > t)) continue; /* Track the entry */ *************** *** 1449,1534 **** s = t; } ! /* Return the result */ return (n); } - /* ! * Local "need flush" variable */ ! static bool flush_later = FALSE; ! /* ! * Local variable -- we just finished a macro action ! */ ! static bool after_macro = FALSE; - /* - * Local variable -- we are inside a macro action - */ - static bool parse_macro = FALSE; ! /* ! * Local variable -- we are inside a "control-underscore" sequence ! */ ! static bool parse_under = FALSE; - /* - * Local variable -- we are inside a "control-backslash" sequence - */ - static bool parse_slash = FALSE; /* ! * Local variable -- we are stripping symbols for a while */ ! static bool strip_chars = FALSE; /* ! * Flush all input chars. Actually, remember the flush, ! * and do a "special flush" before the next "inkey()". * ! * This is not only more efficient, but also necessary to make sure ! * that various "inkey()" codes are not "lost" along the way. */ void flush(void) { /* Do it later */ ! flush_later = TRUE; } /* ! * Flush the screen, make a noise */ ! void bell(void) ! { ! /* Mega-Hack -- Flush the output */ ! Term_fresh(); ! ! /* Make a bell noise (if allowed) */ ! if (ring_bell) Term_xtra(TERM_XTRA_NOISE, 0); ! ! /* Flush the input (later!) */ ! flush(); ! } /* ! * Hack -- Make a (relevant?) sound */ ! void sound(int val) ! { ! /* No sound */ ! if (!use_sound) return; ! ! /* Make a sound (if allowed) */ ! Term_xtra(TERM_XTRA_SOUND, val); ! } --- 1128,1240 ---- s = t; } ! /* Result */ return (n); } /* ! * Add a macro definition (or redefinition). ! * ! * We should use "act == NULL" to "remove" a macro, but this might make it ! * impossible to save the "removal" of a macro definition. XXX XXX XXX ! * ! * We should consider refusing to allow macros which contain existing macros, ! * or which are contained in existing macros, because this would simplify the ! * macro analysis code. XXX XXX XXX ! * ! * We should consider removing the "command macro" crap, and replacing it ! * with some kind of "powerful keymap" ability, but this might make it hard ! * to change the "roguelike" option from inside the game. XXX XXX XXX */ ! errr macro_add(cptr pat, cptr act) ! { ! int n; ! /* Paranoia -- require data */ ! if (!pat || !act) return (-1); ! /* Look for any existing macro */ ! n = macro_find_exact(pat); ! ! /* Replace existing macro */ ! if (n >= 0) ! { ! /* Free the old macro action */ ! string_free(macro__act[n]); ! } ! ! /* Create a new macro */ ! else ! { ! /* Acquire a new index */ ! n = macro__num++; ! ! /* Save the pattern */ ! macro__pat[n] = string_make(pat); ! } ! ! /* Save the action */ ! macro__act[n] = string_make(act); ! ! /* Efficiency */ ! macro__use[(byte)(pat[0])] = TRUE; ! ! /* Success */ ! return (0); ! } ! /* ! * Initialize the "macro" package */ ! errr macro_init(void) ! { ! /* Macro patterns */ ! C_MAKE(macro__pat, MACRO_MAX, cptr); ! ! /* Macro actions */ ! C_MAKE(macro__act, MACRO_MAX, cptr); ! ! /* Success */ ! return (0); ! } ! /* ! * Flush all pending input. * ! * Actually, remember the flush, using the "inkey_xtra" flag, and in the ! * next call to "inkey()", perform the actual flushing, for efficiency, ! * and correctness of the "inkey()" function. */ void flush(void) { /* Do it later */ ! inkey_xtra = TRUE; } + /* ! * Local variable -- we are inside a "macro action" ! * ! * Do not match any macros until "ascii 30" is found. */ ! static bool parse_macro = FALSE; /* ! * Local variable -- we are inside a "macro trigger" ! * ! * Strip all keypresses until a low ascii value is found. */ ! static bool parse_under = FALSE; *************** *** 1536,1555 **** /* * Helper function called only from "inkey()" * ! * This function does most of the "macro" processing. ! * ! * We use the "Term_key_push()" function to handle "failed" macros, ! * as well as "extra" keys read in while choosing a macro, and the ! * actual action for the macro. * ! * Embedded macros are illegal, although "clever" use of special ! * control chars may bypass this restriction. Be very careful. ! * ! * The user only gets 500 (1+2+...+29+30) milliseconds for the macro. ! * ! * Note the annoying special processing to "correctly" handle the ! * special "control-backslash" codes following a "control-underscore" ! * macro sequence. See "main-x11.c" and "main-xaw.c" for details. */ static char inkey_aux(void) { --- 1242,1260 ---- /* * Helper function called only from "inkey()" * ! * This function does almost all of the "macro" processing. * ! * We use the "Term_key_push()" function to handle "failed" macros, as well ! * as "extra" keys read in while choosing the proper macro, and also to hold ! * the action for the macro, plus a special "ascii 30" character indicating ! * that any macro action in progress is complete. Embedded macros are thus ! * illegal, unless a macro action includes an explicit "ascii 30" character, ! * which would probably be a massive hack, and might break things. ! * ! * Only 500 (0+1+2+...+29+30) milliseconds may elapse between each key in ! * the macro trigger sequence. If a key sequence forms the "prefix" of a ! * macro trigger, 500 milliseconds must pass before the key sequence is ! * known not to be that macro trigger. XXX XXX XXX */ static char inkey_aux(void) { *************** *** 1562,1611 **** char buf[1024]; ! /* Wait for keypress */ (void)(Term_inkey(&ch, TRUE, TRUE)); ! /* End of internal macro */ ! if (ch == 29) parse_macro = FALSE; ! ! /* Do not check "ascii 28" */ ! if (ch == 28) return (ch); ! /* Do not check "ascii 29" */ ! if (ch == 29) return (ch); ! ! ! /* Do not check macro actions */ if (parse_macro) return (ch); ! /* Do not check "control-underscore" sequences */ if (parse_under) return (ch); - /* Do not check "control-backslash" sequences */ - if (parse_slash) return (ch); - - - /* Efficiency -- Ignore impossible macros */ - if (!macro__use[(byte)(ch)]) return (ch); - - /* Efficiency -- Ignore inactive macros */ - if (!inkey_flag && (macro__use[(byte)(ch)] == MACRO_USE_CMD)) return (ch); - /* Save the first key, advance */ buf[p++] = ch; buf[p] = '\0'; /* Wait for a macro, or a timeout */ while (TRUE) { ! /* Check for possible macros */ ! k = macro_maybe(buf, k); ! /* Nothing matches */ if (k < 0) break; /* Check for (and remove) a pending key */ --- 1267,1308 ---- char buf[1024]; ! /* Wait for a keypress */ (void)(Term_inkey(&ch, TRUE, TRUE)); ! /* End "macro action" */ ! if (ch == 30) parse_macro = FALSE; ! /* Inside "macro action" */ ! if (ch == 30) return (ch); ! /* Inside "macro action" */ if (parse_macro) return (ch); ! /* Inside "macro trigger" */ if (parse_under) return (ch); /* Save the first key, advance */ buf[p++] = ch; buf[p] = '\0'; + /* Check for possible macro */ + k = macro_find_check(buf); + + /* No macro pending */ + if (k < 0) return (ch); + + /* Wait for a macro, or a timeout */ while (TRUE) { ! /* Check for pending macro */ ! k = macro_find_maybe(buf); ! /* No macro pending */ if (k < 0) break; /* Check for (and remove) a pending key */ *************** *** 1634,1641 **** } ! /* Check for a successful macro */ ! k = macro_ready(buf); /* No macro available */ if (k < 0) --- 1331,1338 ---- } ! /* Check for available macro */ ! k = macro_find_ready(buf); /* No macro available */ if (k < 0) *************** *** 1655,1661 **** } ! /* Access the macro pattern */ pat = macro__pat[k]; /* Get the length of the pattern */ --- 1352,1358 ---- } ! /* Get the pattern */ pat = macro__pat[k]; /* Get the length of the pattern */ *************** *** 1669,1679 **** } ! /* We are now inside a macro */ parse_macro = TRUE; ! /* Push the "macro complete" key */ ! if (Term_key_push(29)) return (0); /* Access the macro action */ --- 1366,1376 ---- } ! /* Begin "macro action" */ parse_macro = TRUE; ! /* Push the "end of macro action" key */ ! if (Term_key_push(30)) return (0); /* Access the macro action */ *************** *** 1690,1701 **** } ! /* Force "inkey()" to call us again */ return (0); } /* * Get a keypress from the user. --- 1387,1421 ---- } ! /* Hack -- Force "inkey()" to call us again */ return (0); } + /* + * Mega-Hack -- special "inkey_next" pointer. XXX XXX XXX + * + * This special pointer allows a sequence of keys to be "inserted" into + * the stream of keys returned by "inkey()". This key sequence will not + * trigger any macros, and cannot be bypassed by the Borg. It is used + * in Angband to handle "keymaps". + */ + static cptr inkey_next = NULL; + + + #ifdef ALLOW_BORG + + /* + * Mega-Hack -- special "inkey_hack" hook. XXX XXX XXX + * + * This special function hook allows the "Borg" (see elsewhere) to take + * control of the "inkey()" function, and substitute in fake keypresses. + */ + char (*inkey_hack)(int flush_first) = NULL; + + #endif /* ALLOW_BORG */ + /* * Get a keypress from the user. *************** *** 1706,1791 **** * before this function returns. Thus they function just like normal * parameters, except that most calls to this function can ignore them. * ! * Normally, this function will process "macros", but if "inkey_base" is ! * TRUE, then we will bypass all "macro" processing. This allows direct ! * usage of the "Term_inkey()" function. ! * ! * Normally, this function will do something, but if "inkey_xtra" is TRUE, ! * then something else will happen. ! * ! * Normally, this function will wait until a "real" key is ready, but if ! * "inkey_scan" is TRUE, then we will return zero if no keys are ready. * ! * Normally, this function will show the cursor, and will process all normal ! * macros, but if "inkey_flag" is TRUE, then we will only show the cursor if ! * "hilite_player" is TRUE, and also, we will only process "command" macros. ! * ! * Note that the "flush()" function does not actually flush the input queue, ! * but waits until "inkey()" is called to perform the "flush". ! * ! * Refresh the screen if waiting for a keypress and no key is ready. * * Note that "back-quote" is automatically converted into "escape" for * convenience on machines with no "escape" key. This is done after the * macro matching, so the user can still make a macro for "backquote". * ! * Note the special handling of a few "special" control-keys, which ! * are reserved to simplify the use of various "main-xxx.c" files, ! * or used by the "macro" code above. ! * ! * Ascii 27 is "control left bracket" -- normal "Escape" key ! * Ascii 28 is "control backslash" -- special macro delimiter ! * Ascii 29 is "control right bracket" -- end of macro action ! * Ascii 30 is "control caret" -- indicates "keypad" key ! * Ascii 31 is "control underscore" -- begin macro-trigger ! * ! * Hack -- Make sure to allow calls to "inkey()" even if "term_screen" ! * is not the active Term, this allows the various "main-xxx.c" files ! * to only handle input when "term_screen" is "active". ! * ! * Note the nasty code used to process the "inkey_base" flag, which allows ! * various "macro triggers" to be entered as normal key-sequences, with the ! * appropriate timing constraints, but without actually matching against any ! * macro sequences. Most of the nastiness is to handle "ascii 28" (see below). ! * ! * The "ascii 28" code is a complete hack, used to allow "default actions" ! * to be associated with a given keypress, and used only by the X11 module, ! * it may or may not actually work. The theory is that a keypress can send ! * a special sequence, consisting of a "macro trigger" plus a "default action", ! * with the "default action" surrounded by "ascii 28" symbols. Then, when that ! * key is pressed, if the trigger matches any macro, the correct action will be ! * executed, and the "strip default action" code will remove the "default action" ! * from the keypress queue, while if it does not match, the trigger itself will ! * be stripped, and then the "ascii 28" symbols will be stripped as well, leaving ! * the "default action" keys in the "key queue". Again, this may not work. */ char inkey(void) { int v; ! char kk, ch; bool done = FALSE; term *old = Term; - int w = 0; ! /* Hack -- handle delayed "flush()" */ ! if (flush_later) { ! /* Done */ ! flush_later = FALSE; - /* Cancel "macro" info */ - parse_macro = after_macro = FALSE; ! /* Cancel "sequence" info */ ! parse_under = parse_slash = FALSE; ! /* Cancel "strip" mode */ ! strip_chars = FALSE; /* Forget old keypresses */ Term_flush(); --- 1426,1537 ---- * before this function returns. Thus they function just like normal * parameters, except that most calls to this function can ignore them. * ! * If "inkey_xtra" is TRUE, then all pending keypresses will be flushed, ! * and any macro processing in progress will be aborted. This flag is ! * set by the "flush()" function, which does not actually flush anything ! * itself, but rather, triggers delayed input flushing via "inkey_xtra". ! * ! * If "inkey_scan" is TRUE, then we will immediately return "zero" if no ! * keypress is available, instead of waiting for a keypress. ! * ! * If "inkey_base" is TRUE, then all macro processing will be bypassed. ! * If "inkey_base" and "inkey_scan" are both TRUE, then this function will ! * not return immediately, but will wait for a keypress for as long as the ! * normal macro matching code would, allowing the direct entry of macro ! * triggers. The "inkey_base" flag is extremely dangerous! ! * ! * If "inkey_flag" is TRUE, then we will assume that we are waiting for a ! * normal command, and we will only show the cursor if "hilite_player" is ! * TRUE (or if the player is in a store), instead of always showing the ! * cursor. The various "main-xxx.c" files should avoid saving the game ! * in response to a "menu item" request unless "inkey_flag" is TRUE, to ! * prevent savefile corruption. * ! * If we are waiting for a keypress, and no keypress is ready, then we will ! * refresh (once) the window which was active when this function was called. * * Note that "back-quote" is automatically converted into "escape" for * convenience on machines with no "escape" key. This is done after the * macro matching, so the user can still make a macro for "backquote". * ! * Note the special handling of "ascii 30" (ctrl-caret, aka ctrl-shift-six) ! * and "ascii 31" (ctrl-underscore, aka ctrl-shift-minus), which are used to ! * provide support for simple keyboard "macros". These keys are so strange ! * that their loss as normal keys will probably be noticed by nobody. The ! * "ascii 30" key is used to indicate the "end" of a macro action, which ! * allows recursive macros to be avoided. The "ascii 31" key is used by ! * some of the "main-xxx.c" files to introduce macro trigger sequences. ! * ! * Hack -- we use "ascii 29" (ctrl-right-bracket) as a special "magic" key, ! * which can be used to give a variety of "sub-commands" which can be used ! * any time. These sub-commands could include commands to take a picture of ! * the current screen, to start/stop recording a macro action, etc. ! * ! * If "angband_term[0]" is not active, we will make it active during this ! * function, so that the various "main-xxx.c" files can assume that input ! * is only requested (via "Term_inkey()") when "angband_term[0]" is active. ! * ! * Mega-Hack -- This function is used as the entry point for clearing the ! * "signal_count" variable, and of the "character_saved" variable. ! * ! * Hack -- Note the use of "inkey_next" to allow "keymaps" to be processed. ! * ! * Mega-Hack -- Note the use of "inkey_hack" to allow the "Borg" to steal ! * control of the keyboard from the user. */ char inkey(void) { int v; ! char kk; ! ! char ch = 0; bool done = FALSE; term *old = Term; + /* Hack -- Use the "inkey_next" pointer */ + if (inkey_next && *inkey_next && !inkey_xtra) + { + /* Get next character, and advance */ + ch = *inkey_next++; + + /* Cancel the various "global parameters" */ + inkey_base = inkey_xtra = inkey_flag = inkey_scan = FALSE; ! /* Accept result */ ! return (ch); ! } ! ! /* Forget pointer */ ! inkey_next = NULL; ! ! ! #ifdef ALLOW_BORG ! ! /* Mega-Hack -- Use the special hook */ ! if (inkey_hack && ((ch = (*inkey_hack)(inkey_xtra)) != 0)) { ! /* Cancel the various "global parameters" */ ! inkey_base = inkey_xtra = inkey_flag = inkey_scan = FALSE; ! ! /* Accept result */ ! return (ch); ! } ! ! #endif /* ALLOW_BORG */ ! /* Hack -- handle delayed "flush()" */ ! if (inkey_xtra) ! { ! /* End "macro action" */ ! parse_macro = FALSE; ! /* End "macro trigger" */ ! parse_under = FALSE; /* Forget old keypresses */ Term_flush(); *************** *** 1803,1820 **** } ! /* Hack -- Activate the screen */ ! Term_activate(term_screen); ! /* Get a (non-zero) keypress */ ! for (ch = 0; !ch; ) { ! /* Nothing ready, not waiting, and not doing "inkey_base", all done */ ! if (!inkey_base && inkey_scan && (0 != Term_inkey(&kk, FALSE, FALSE))) break; ! /* Hack -- flush output once when no key ready */ if (!done && (0 != Term_inkey(&kk, FALSE, FALSE))) { /* Hack -- activate proper term */ --- 1549,1570 ---- } ! /* Hack -- Activate main screen */ ! Term_activate(angband_term[0]); ! /* Get a key */ ! while (!ch) { ! /* Hack -- Handle "inkey_scan" */ ! if (!inkey_base && inkey_scan && ! (0 != Term_inkey(&kk, FALSE, FALSE))) ! { ! break; ! } ! /* Hack -- Flush output once when no key ready */ if (!done && (0 != Term_inkey(&kk, FALSE, FALSE))) { /* Hack -- activate proper term */ *************** *** 1823,1830 **** /* Flush output */ Term_fresh(); ! /* Hack -- activate the screen */ ! Term_activate(term_screen); /* Mega-Hack -- reset saved flag */ character_saved = FALSE; --- 1573,1580 ---- /* Flush output */ Term_fresh(); ! /* Hack -- activate main screen */ ! Term_activate(angband_term[0]); /* Mega-Hack -- reset saved flag */ character_saved = FALSE; *************** *** 1837,1987 **** } ! /* Hack */ if (inkey_base) { ! /* Check for keypress, optional wait */ ! (void)Term_inkey(&kk, !inkey_scan, TRUE); ! /* Key ready */ ! if (kk) { ! /* Reset delay */ ! w = 0; ! ! /* Mega-Hack */ ! if (kk == 28) { ! /* Toggle "strip_chars" */ ! strip_chars = !strip_chars; } ! /* Use normal keys */ ! else if (!strip_chars) ! { ! /* Use it */ ! ch = kk; ! } } ! /* No key ready */ ! else { ! /* Increase "wait" */ ! w += 10; ! /* Excessive delay */ ! if (w >= 100) break; ! /* Delay */ ! Term_xtra(TERM_XTRA_DELAY, w); } ! /* Continue */ ! continue; } /* Get a key (see above) */ ! kk = ch = inkey_aux(); ! /* Finished a "control-underscore" sequence */ ! if (parse_under && (ch <= 32)) { - /* Found the edge */ - parse_under = FALSE; - - /* Stop stripping */ - strip_chars = FALSE; - /* Strip this key */ ch = 0; - } - - - /* Finished a "control-backslash" sequence */ - if (parse_slash && (ch == 28)) - { - /* Found the edge */ - parse_slash = FALSE; - - /* Stop stripping */ - strip_chars = FALSE; ! /* Strip this key */ ! ch = 0; } ! /* Handle some special keys */ ! switch (ch) ! { ! /* Hack -- convert back-quote into escape */ ! case '`': ! ! /* Convert to "Escape" */ ! ch = ESCAPE; ! ! /* Done */ ! break; - /* Hack -- strip "control-right-bracket" end-of-macro-action */ - case 29: /* Strip this key */ ch = 0; ! /* Done */ ! break; - /* Hack -- strip "control-caret" special-keypad-indicator */ - case 30: /* Strip this key */ ch = 0; ! /* Done */ ! break; ! ! /* Hack -- strip "control-underscore" special-macro-triggers */ ! case 31: ! /* Strip this key */ ch = 0; ! /* Inside a "underscore" sequence */ parse_under = TRUE; ! /* Strip chars (always) */ ! strip_chars = TRUE; ! ! /* Done */ ! break; ! ! /* Hack -- strip "control-backslash" special-fallback-strings */ ! case 28: ! /* Strip this key */ ch = 0; - - /* Inside a "control-backslash" sequence */ - parse_slash = TRUE; - - /* Strip chars (sometimes) */ - strip_chars = after_macro; - - /* Done */ - break; } - - - /* Hack -- Set "after_macro" code */ - after_macro = ((kk == 29) ? TRUE : FALSE); - - - /* Hack -- strip chars */ - if (strip_chars) ch = 0; } --- 1587,1693 ---- } ! /* Hack -- Handle "inkey_base" */ if (inkey_base) { ! int w = 0; ! /* Wait forever */ ! if (!inkey_scan) { ! /* Wait for (and remove) a pending key */ ! if (0 == Term_inkey(&ch, TRUE, TRUE)) { ! /* Done */ ! break; } ! /* Oops */ ! break; } ! /* Wait */ ! while (TRUE) { ! /* Check for (and remove) a pending key */ ! if (0 == Term_inkey(&ch, FALSE, TRUE)) ! { ! /* Done */ ! break; ! } ! /* No key ready */ ! else ! { ! /* Increase "wait" */ ! w += 10; ! /* Excessive delay */ ! if (w >= 100) break; ! ! /* Delay */ ! Term_xtra(TERM_XTRA_DELAY, w); ! } } ! /* Done */ ! break; } /* Get a key (see above) */ ! ch = inkey_aux(); ! /* Handle "control-right-bracket" */ ! if (ch == 29) { /* Strip this key */ ch = 0; ! /* Continue */ ! continue; } ! /* Treat back-quote as escape */ ! if (ch == '`') ch = ESCAPE; + /* End "macro trigger" */ + if (parse_under && (ch <= 32)) + { /* Strip this key */ ch = 0; ! /* End "macro trigger" */ ! parse_under = FALSE; ! } + /* Handle "control-caret" */ + if (ch == 30) + { /* Strip this key */ ch = 0; + } ! /* Handle "control-underscore" */ ! else if (ch == 31) ! { /* Strip this key */ ch = 0; ! /* Begin "macro trigger" */ parse_under = TRUE; + } ! /* Inside "macro trigger" */ ! else if (parse_under) ! { /* Strip this key */ ch = 0; } } *************** *** 2005,2023 **** /* ! * We use a global array for all inscriptions to reduce the memory ! * spent maintaining inscriptions. Of course, it is still possible ! * to run out of inscription memory, especially if too many different ! * inscriptions are used, but hopefully this will be rare. ! * ! * We use dynamic string allocation because otherwise it is necessary ! * to pre-guess the amount of quark activity. We limit the total ! * number of quarks, but this is much easier to "expand" as needed. * ! * Any two items with the same inscription will have the same "quark" ! * index, which should greatly reduce the need for inscription space. * ! * Note that "quark zero" is NULL and should not be "dereferenced". */ /* --- 1711,1763 ---- /* ! * Flush the screen, make a noise ! */ ! void bell(cptr reason) ! { ! /* Mega-Hack -- Flush the output */ ! Term_fresh(); ! ! /* Hack -- memorize the reason if possible */ ! if (character_generated && reason) message_add(reason); ! ! /* Make a bell noise (if allowed) */ ! if (ring_bell) Term_xtra(TERM_XTRA_NOISE, 0); ! ! /* Flush the input (later!) */ ! flush(); ! } ! ! ! /* ! * Hack -- Make a (relevant?) sound ! */ ! void sound(int val) ! { ! /* No sound */ ! if (!use_sound) return; ! ! /* Make a sound (if allowed) */ ! Term_xtra(TERM_XTRA_SOUND, val); ! } ! ! ! ! ! /* ! * The "quark" package ! * ! * This package is used to reduce the memory usage of object inscriptions. ! * ! * We use dynamic string allocation because otherwise it is necessary to ! * pre-guess the amount of quark activity. We limit the total number of ! * quarks, but this is much easier to "expand" as needed. XXX XXX XXX * ! * Two objects with the same inscription will have the same "quark" index. * ! * Some code uses "zero" to indicate the non-existance of a quark. ! * ! * Note that "quark zero" is NULL and should never be "dereferenced". */ /* *************** *** 2034,2044 **** if (streq(quark__str[i], str)) return (i); } ! /* Paranoia -- Require room */ if (quark__num == QUARK_MAX) return (0); ! /* New maximal quark */ ! quark__num = i + 1; /* Add a new quark */ quark__str[i] = string_make(str); --- 1774,1784 ---- if (streq(quark__str[i], str)) return (i); } ! /* Hack -- Require room XXX XXX XXX */ if (quark__num == QUARK_MAX) return (0); ! /* New quark */ ! i = quark__num++; /* Add a new quark */ quark__str[i] = string_make(str); *************** *** 2066,2089 **** } /* ! * Second try for the "message" handling routines. * * Each call to "message_add(s)" will add a new "most recent" message * to the "message recall list", using the contents of the string "s". * ! * The messages will be stored in such a way as to maximize "efficiency", ! * that is, we attempt to maximize the number of sequential messages that ! * can be retrieved, given a limited amount of storage space. ! * ! * We keep a buffer of chars to hold the "text" of the messages, not ! * necessarily in "order", and an array of offsets into that buffer, ! * representing the actual messages. This is made more complicated ! * by the fact that both the array of indexes, and the buffer itself, ! * are both treated as "circular arrays" for efficiency purposes, but ! * the strings may not be "broken" across the ends of the array. * * The "message_add()" function is rather "complex", because it must be * extremely efficient, both in space and time, for use with the Borg. --- 1806,1860 ---- } + /* + * Initialize the "quark" package + */ + errr quark_init(void) + { + /* Quark variables */ + C_MAKE(quark__str, QUARK_MAX, cptr); + + /* Success */ + return (0); + } + /* ! * The "message memorization" package. * * Each call to "message_add(s)" will add a new "most recent" message * to the "message recall list", using the contents of the string "s". * ! * The number of memorized messages is available as "message_num()". ! * ! * Old messages can be retrieved by "message_str(age)", where the "age" ! * of the most recently memorized message is zero, and the oldest "age" ! * which is available is "message_num() - 1". Messages outside this ! * range are returned as the empty string. ! * ! * The messages are stored in a special manner that maximizes "efficiency", ! * that is, we attempt to maximize the number of semi-sequential messages ! * that can be retrieved, given a limited amount of storage space, without ! * causing the memorization of new messages or the recall of old messages ! * to be too expensive. ! * ! * We keep a buffer of chars to hold the "text" of the messages, more or ! * less in the order they were memorized, and an array of offsets into that ! * buffer, representing the actual messages, but we allow the "text" to be ! * "shared" by two messages with "similar" ages, as long as we never cause ! * sharing to reach too far back in the the buffer. ! * ! * The implementation is complicated by the fact that both the array of ! * offsets, and the buffer itself, are both treated as "circular arrays" ! * for efficiency purposes, but the strings may not be "broken" across ! * the ends of the array. ! * ! * When we want to memorize a new message, we attempt to "reuse" the buffer ! * space by checking for message duplication within the recent messages. ! * ! * Otherwise, if we need more buffer space, we grab a full quarter of the ! * total buffer space at a time, to keep the reclamation code efficient. * * The "message_add()" function is rather "complex", because it must be * extremely efficient, both in space and time, for use with the Borg. *************** *** 2096,2115 **** */ s16b message_num(void) { ! int last, next, n; ! ! /* Extract the indexes */ ! last = message__last; ! next = message__next; ! ! /* Handle "wrap" */ ! if (next < last) next += MESSAGE_MAX; ! ! /* Extract the space */ ! n = (next - last); ! ! /* Return the result */ ! return (n); } --- 1867,1874 ---- */ s16b message_num(void) { ! /* Determine how many messages are "available" */ ! return (message__next + MESSAGE_MAX - message__last) % MESSAGE_MAX; } *************** *** 2143,2152 **** /* * Add a new message, with great efficiency */ void message_add(cptr str) { ! int i, k, x, n; /*** Step 1 -- Analyze the message ***/ --- 1902,1927 ---- /* * Add a new message, with great efficiency + * + * We must ignore long messages to prevent internal overflow, since we + * assume that we can always get enough space by advancing "message__tail" + * by one quarter the total buffer space. + * + * We must not attempt to optimize using a message index or buffer space + * which is "far away" from the most recent entries, or we will lose a lot + * of messages when we "expire" the old message index and/or buffer space. + * + * We attempt to minimize the use of "string compare" operations in this + * function, because they are expensive when used in mass quantities. */ void message_add(cptr str) { ! int n, k, i, x, o; ! ! cptr s; ! cptr t; ! cptr u; ! char *v; /*** Step 1 -- Analyze the message ***/ *************** *** 2157,2163 **** /* Message length */ n = strlen(str); ! /* Important Hack -- Ignore "long" messages */ if (n >= MESSAGE_BUF / 4) return; --- 1932,1938 ---- /* Message length */ n = strlen(str); ! /* Hack -- Ignore "long" messages */ if (n >= MESSAGE_BUF / 4) return; *************** *** 2167,2210 **** k = message_num() / 4; /* Limit number of messages to check */ ! if (k > MESSAGE_MAX / 32) k = MESSAGE_MAX / 32; ! /* Check the last few messages (if any to count) */ ! for (i = message__next; k; k--) { u16b q; cptr old; ! /* Back up and wrap if needed */ if (i-- == 0) i = MESSAGE_MAX - 1; /* Stop before oldest message */ if (i == message__last) break; /* Extract "distance" from "head" */ ! q = (message__head + MESSAGE_BUF - message__ptr[i]) % MESSAGE_BUF; ! /* Do not optimize over large distance */ ! if (q > MESSAGE_BUF / 2) continue; /* Access the old string */ ! old = &message__buf[message__ptr[i]]; ! /* Compare */ ! if (!streq(old, str)) continue; ! /* Get the next message index, advance */ ! x = message__next++; ! /* Handle wrap */ ! if (message__next == MESSAGE_MAX) message__next = 0; ! /* Kill last message if needed */ ! if (message__next == message__last) message__last++; ! /* Handle wrap */ ! if (message__last == MESSAGE_MAX) message__last = 0; /* Assign the starting address */ message__ptr[x] = message__ptr[i]; --- 1942,1995 ---- k = message_num() / 4; /* Limit number of messages to check */ ! if (k > 32) k = 32; ! /* Start just after the most recent message */ ! i = message__next; ! ! /* Check the last few messages for duplication */ ! for ( ; k; k--) { u16b q; cptr old; ! /* Back up, wrap if needed */ if (i-- == 0) i = MESSAGE_MAX - 1; /* Stop before oldest message */ if (i == message__last) break; + /* Index */ + o = message__ptr[i]; + /* Extract "distance" from "head" */ ! q = (message__head + MESSAGE_BUF - o) % MESSAGE_BUF; ! /* Do not optimize over large distances */ ! if (q >= MESSAGE_BUF / 4) continue; /* Access the old string */ ! old = &message__buf[o]; ! /* Inline 'streq(str, old)' */ ! for (s = str, t = old; (*s == *t) && *s; ++s, ++t) /* loop */ ; ! /* Continue if not equal */ ! if (*s) continue; ! /* Get the next available message index */ ! x = message__next; ! /* Advance 'message__next', wrap if needed */ ! if (++message__next == MESSAGE_MAX) message__next = 0; ! /* Kill last message if needed */ ! if (message__next == message__last) ! { ! /* Advance 'message__last', wrap if needed */ ! if (++message__last == MESSAGE_MAX) message__last = 0; ! } /* Assign the starting address */ message__ptr[x] = message__ptr[i]; *************** *** 2216,2223 **** /*** Step 3 -- Ensure space before end of buffer ***/ ! /* Kill messages and Wrap if needed */ ! if (message__head + n + 1 >= MESSAGE_BUF) { /* Kill all "dead" messages */ for (i = message__last; TRUE; i++) --- 2001,2008 ---- /*** Step 3 -- Ensure space before end of buffer ***/ ! /* Kill messages, and wrap, if needed */ ! if (message__head + (n + 1) >= MESSAGE_BUF) { /* Kill all "dead" messages */ for (i = message__last; TRUE; i++) *************** *** 2228,2235 **** /* Stop before the new message */ if (i == message__next) break; /* Kill "dead" messages */ ! if (message__ptr[i] >= message__head) { /* Track oldest message */ message__last = i + 1; --- 2013,2023 ---- /* Stop before the new message */ if (i == message__next) break; + /* Get offset */ + o = message__ptr[i]; + /* Kill "dead" messages */ ! if (o >= message__head) { /* Track oldest message */ message__last = i + 1; *************** *** 2244,2259 **** } ! /*** Step 4 -- Ensure space before next message ***/ ! /* Kill messages if needed */ ! if (message__head + n + 1 > message__tail) { ! /* Grab new "tail" */ ! message__tail = message__head + n + 1; ! ! /* Advance tail while possible past first "nul" */ ! while (message__buf[message__tail-1]) message__tail++; /* Kill all "dead" messages */ for (i = message__last; TRUE; i++) --- 2032,2044 ---- } ! /*** Step 4 -- Ensure space for actual characters ***/ ! /* Kill messages, if needed */ ! if (message__head + (n + 1) > message__tail) { ! /* Advance to new "tail" location */ ! message__tail += (MESSAGE_BUF / 4); /* Kill all "dead" messages */ for (i = message__last; TRUE; i++) *************** *** 2264,2272 **** /* Stop before the new message */ if (i == message__next) break; /* Kill "dead" messages */ ! if ((message__ptr[i] >= message__head) && ! (message__ptr[i] < message__tail)) { /* Track oldest message */ message__last = i + 1; --- 2049,2059 ---- /* Stop before the new message */ if (i == message__next) break; + /* Get offset */ + o = message__ptr[i]; + /* Kill "dead" messages */ ! if ((o >= message__head) && (o < message__tail)) { /* Track oldest message */ message__last = i + 1; *************** *** 2275,2313 **** } ! /*** Step 5 -- Grab a new message index ***/ ! /* Get the next message index, advance */ ! x = message__next++; ! /* Handle wrap */ ! if (message__next == MESSAGE_MAX) message__next = 0; ! /* Kill last message if needed */ ! if (message__next == message__last) message__last++; - /* Handle wrap */ - if (message__last == MESSAGE_MAX) message__last = 0; ! /*** Step 6 -- Insert the message text ***/ - /* Assign the starting address */ - message__ptr[x] = message__head; - /* Append the new part of the message */ - for (i = 0; i < n; i++) - { - /* Copy the message */ - message__buf[message__head + i] = str[i]; - } - /* Terminate */ - message__buf[message__head + i] = '\0'; ! /* Advance the "head" pointer */ ! message__head += n + 1; } --- 2062,2169 ---- } ! /*** Step 5 -- Grab a new message index ***/ ! ! /* Get the next available message index */ ! x = message__next; ! ! /* Advance 'message__next', wrap if needed */ ! if (++message__next == MESSAGE_MAX) message__next = 0; ! ! /* Kill last message if needed */ ! if (message__next == message__last) ! { ! /* Advance 'message__last', wrap if needed */ ! if (++message__last == MESSAGE_MAX) message__last = 0; ! } ! ! ! /*** Step 6 -- Insert the message text ***/ ! /* Assign the starting address */ ! message__ptr[x] = message__head; ! /* Inline 'strcpy(message__buf + message__head, str)' */ ! v = message__buf + message__head; ! for (u = str; *u; ) *v++ = *u++; ! *v = '\0'; ! /* Advance the "head" pointer */ ! message__head += (n + 1); ! } + /* + * Initialize the "message" package + */ + errr message_init(void) + { + /* Message variables */ + C_MAKE(message__ptr, MESSAGE_MAX, u16b); + C_MAKE(message__buf, MESSAGE_BUF, char); + /* Hack -- No messages yet */ + message__tail = MESSAGE_BUF; ! /* Success */ ! return (0); ! } ! /* ! * XXX XXX XXX Important note about "colors" XXX XXX XXX ! * ! * The "TERM_*" color definitions list the "composition" of each ! * "Angband color" in terms of "quarters" of each of the three color ! * components (Red, Green, Blue), for example, TERM_UMBER is defined ! * as 2/4 Red, 1/4 Green, 0/4 Blue. ! * ! * The following info is from "Torbjorn Lindgren" (see "main-xaw.c"). ! * ! * These values are NOT gamma-corrected. On most machines (with the ! * Macintosh being an important exception), you must "gamma-correct" ! * the given values, that is, "correct for the intrinsic non-linearity ! * of the phosphor", by converting the given intensity levels based ! * on the "gamma" of the target screen, which is usually 1.7 (or 1.5). ! * ! * The actual formula for conversion is unknown to me at this time, ! * but you can use the table below for the most common gamma values. ! * ! * So, on most machines, simply convert the values based on the "gamma" ! * of the target screen, which is usually in the range 1.5 to 1.7, and ! * usually is closest to 1.7. The converted value for each of the five ! * different "quarter" values is given below: ! * ! * Given Gamma 1.0 Gamma 1.5 Gamma 1.7 Hex 1.7 ! * ----- ---- ---- ---- --- ! * 0/4 0.00 0.00 0.00 #00 ! * 1/4 0.25 0.27 0.28 #47 ! * 2/4 0.50 0.55 0.56 #8f ! * 3/4 0.75 0.82 0.84 #d7 ! * 4/4 1.00 1.00 1.00 #ff ! * ! * Note that some machines (i.e. most IBM machines) are limited to a ! * hard-coded set of colors, and so the information above is useless. ! * ! * Also, some machines are limited to a pre-determined set of colors, ! * for example, the IBM can only display 16 colors, and only 14 of ! * those colors resemble colors used by Angband, and then only when ! * you ignore the fact that "Slate" and "cyan" are not really matches, ! * so on the IBM, we use "orange" for both "Umber", and "Light Umber" ! * in addition to the obvious "Orange", since by combining all of the ! * "indeterminate" colors into a single color, the rest of the colors ! * are left with "meaningful" values. ! */ ! ! ! /* ! * Move the cursor ! */ ! void move_cursor(int row, int col) ! { ! Term_gotoxy(col, row); } *************** *** 2329,2335 **** if (quick_messages) break; if ((cmd == ESCAPE) || (cmd == ' ')) break; if ((cmd == '\n') || (cmd == '\r')) break; ! bell(); } /* Clear the line */ --- 2185,2191 ---- if (quick_messages) break; if ((cmd == ESCAPE) || (cmd == ' ')) break; if ((cmd == '\n') || (cmd == '\r')) break; ! bell("Illegal response to a 'more' prompt!"); } /* Clear the line */ *************** *** 2348,2370 **** * * These messages are memorized for later reference (see above). * ! * We could do "Term_fresh()" to provide "flicker" if needed. ! * ! * The global "msg_flag" variable can be cleared to tell us to ! * "erase" any "pending" messages still on the screen. * ! * XXX XXX XXX Note that we must be very careful about using the ! * "msg_print()" functions without explicitly calling the special ! * "msg_print(NULL)" function, since this may result in the loss ! * of information if the screen is cleared, or if anything is ! * displayed on the top line. * ! * XXX XXX XXX Note that "msg_print(NULL)" will clear the top line ! * even if no messages are pending. This is probably a hack. */ void msg_print(cptr msg) { ! static p = 0; int n; --- 2204,2226 ---- * * These messages are memorized for later reference (see above). * ! * We could do a "Term_fresh()" to provide "flicker" if needed. * ! * The global "msg_flag" variable can be cleared to tell us to "erase" any ! * "pending" messages still on the screen, instead of using "msg_flush()". ! * This should only be done when the user is known to have read the message. ! * ! * We must be very careful about using the "msg_print()" functions without ! * explicitly calling the special "msg_print(NULL)" function, since this may ! * result in the loss of information if the screen is cleared, or if anything ! * is displayed on the top line. * ! * Hack -- Note that "msg_print(NULL)" will clear the top line even if no ! * messages are pending. */ void msg_print(cptr msg) { ! static int p = 0; int n; *************** *** 2469,2475 **** p += n + 1; /* Optional refresh */ ! if (fresh_message) Term_fresh(); } --- 2325,2331 ---- p += n + 1; /* Optional refresh */ ! if (fresh_after) Term_fresh(); } *************** *** 2498,2503 **** --- 2354,2401 ---- /* + * Hack -- prevent "accidents" in "screen_save()" or "screen_load()" + */ + static int screen_depth = 0; + + + /* + * Save the screen, and increase the "icky" depth. + * + * This function must match exactly one call to "screen_load()". + */ + void screen_save(void) + { + /* Hack -- Flush messages */ + msg_print(NULL); + + /* Save the screen (if legal) */ + if (screen_depth++ == 0) Term_save(); + + /* Increase "icky" depth */ + character_icky++; + } + + + /* + * Load the screen, and decrease the "icky" depth. + * + * This function must match exactly one call to "screen_save()". + */ + void screen_load(void) + { + /* Hack -- Flush messages */ + msg_print(NULL); + + /* Load the screen (if legal) */ + if (--screen_depth == 0) Term_load(); + + /* Decrease "icky" depth */ + character_icky--; + } + + + /* * Display a string on the screen using an attribute. * * At the given location, using the given attribute, if allowed, *************** *** 2652,2657 **** --- 2550,2556 ---- } } + /* * As above, but in "white" */ *************** *** 2692,2697 **** --- 2591,2597 ---- * Backspace clears the default or deletes the final char. * ESCAPE clears the buffer and the window and returns FALSE. * RETURN accepts the current buffer contents and returns TRUE. + * The buffer must be large enough for 'len+1' characters. */ bool askfor_aux(char *buf, int len) { *************** *** 2740,2770 **** switch (i) { case ESCAPE: ! k = 0; ! done = TRUE; ! break; case '\n': case '\r': ! k = strlen(buf); ! done = TRUE; ! break; case 0x7F: case '\010': - if (k > 0) k--; - break; - - default: - if ((k < len) && (isprint(i))) { ! buf[k++] = i; } ! else { ! bell(); } - break; } /* Terminate */ --- 2640,2678 ---- switch (i) { case ESCAPE: ! { ! k = 0; ! done = TRUE; ! break; ! } case '\n': case '\r': ! { ! k = strlen(buf); ! done = TRUE; ! break; ! } case 0x7F: case '\010': { ! if (k > 0) k--; ! break; } ! ! default: { ! if ((k < len) && (isprint(i))) ! { ! buf[k++] = i; ! } ! else ! { ! bell("Illegal edit key!"); ! } ! break; } } /* Terminate */ *************** *** 2814,2819 **** --- 2722,2789 ---- } + + /* + * Request a "quantity" from the user + * + * Allow "p_ptr->command_arg" to specify a quantity + */ + s16b get_quantity(cptr prompt, int max) + { + int amt = 1; + + + /* Use "command_arg" */ + if (p_ptr->command_arg) + { + /* Extract a number */ + amt = p_ptr->command_arg; + + /* Clear "command_arg" */ + p_ptr->command_arg = 0; + } + + /* Prompt if needed */ + else if ((max != 1) && allow_quantity) + { + char tmp[80]; + + char buf[80]; + + /* Build a prompt if needed */ + if (!prompt) + { + /* Build a prompt */ + sprintf(tmp, "Quantity (0-%d): ", max); + + /* Use that prompt */ + prompt = tmp; + } + + /* Build the default */ + sprintf(buf, "%d", amt); + + /* Ask for a quantity */ + if (!get_string(prompt, buf, 6)) return (0); + + /* Extract a number */ + amt = atoi(buf); + + /* A letter means "all" */ + if (isalpha(buf[0])) amt = max; + } + + /* Enforce the maximum */ + if (amt > max) amt = max; + + /* Enforce the minimum */ + if (amt < 0) amt = 0; + + /* Return the result */ + return (amt); + } + + /* * Verify something with the user * *************** *** 2843,2849 **** if (quick_messages) break; if (i == ESCAPE) break; if (strchr("YyNn", i)) break; ! bell(); } /* Erase the prompt */ --- 2813,2819 ---- if (quick_messages) break; if (i == ESCAPE) break; if (strchr("YyNn", i)) break; ! bell("Illegal response to a 'yes/no' question!"); } /* Erase the prompt */ *************** *** 2887,2893 **** /* ! * Pause for user response XXX XXX XXX */ void pause_line(int row) { --- 2857,2865 ---- /* ! * Pause for user response ! * ! * This function is stupid. XXX XXX XXX */ void pause_line(int row) { *************** *** 2901,2919 **** /* * Request a command from the user. * ! * Sets p_ptr->command_cmd, p_ptr->command_dir, p_ptr->command_rep, p_ptr->command_arg. * ! * Note that "caret" ("^") is treated special, and is used to * allow manual input of control characters. This can be used * on many machines to request repeated tunneling (Ctrl-H) and * on the Macintosh to request "Control-Caret". * * Note that this command is used both in the dungeon and in * stores, and must be careful to work in both situations. */ void request_command(bool shopping) { --- 2873,2902 ---- + /* + * Hack -- special buffer to hold the action of the current keymap + */ + static char request_command_buffer[256]; + /* * Request a command from the user. * ! * Sets p_ptr->command_cmd, p_ptr->command_dir, p_ptr->command_rep, ! * p_ptr->command_arg. May modify p_ptr->command_new. * ! * Note that "caret" ("^") is treated specially, and is used to * allow manual input of control characters. This can be used * on many machines to request repeated tunneling (Ctrl-H) and * on the Macintosh to request "Control-Caret". * + * Note that "backslash" is treated specially, and is used to bypass any + * keymap entry for the following character. This is useful for macros. + * * Note that this command is used both in the dungeon and in * stores, and must be careful to work in both situations. + * + * Note that "p_ptr->command_new" may not work any more. XXX XXX XXX */ void request_command(bool shopping) { *************** *** 2921,2926 **** --- 2904,2926 ---- char cmd; + int mode; + + cptr act; + + + /* Roguelike */ + if (rogue_like_commands) + { + mode = KEYMAP_MODE_ROGUE; + } + + /* Original */ + else + { + mode = KEYMAP_MODE_ORIG; + } + /* No command yet */ p_ptr->command_cmd = 0; *************** *** 2932,3097 **** p_ptr->command_dir = 0; ! /* Hack -- Optional flush */ ! if (flush_command) flush(); ! ! ! /* Hack -- auto-commands */ ! if (p_ptr->command_new) { ! /* Flush messages */ ! msg_print(NULL); ! ! /* Use auto-command */ ! cmd = p_ptr->command_new; ! /* Forget it */ ! p_ptr->command_new = 0; ! } ! /* Get a keypress in "command" mode */ ! else ! { ! /* Hack -- no flush needed */ ! msg_flag = FALSE; ! /* Activate "command mode" */ ! inkey_flag = TRUE; ! /* Get a command */ ! cmd = inkey(); ! } ! /* Clear top line */ ! prt("", 0, 0); - /* Command Count */ - if (cmd == '0') - { - /* Begin the input */ - prt("Count: ", 0, 0); ! /* Get a command count */ ! while (1) { ! /* Get a new keypress */ ! cmd = inkey(); ! /* Simple editing (delete or backspace) */ ! if ((cmd == 0x7F) || (cmd == KTRL('H'))) ! { ! /* Delete a digit */ ! p_ptr->command_arg = p_ptr->command_arg / 10; ! /* Show current count */ ! prt(format("Count: %d", p_ptr->command_arg), 0, 0); ! } ! /* Actual numeric data */ ! else if (cmd >= '0' && cmd <= '9') { ! /* Stop count at 9999 */ ! if (p_ptr->command_arg >= 1000) { ! /* Warn */ ! bell(); ! /* Limit */ ! p_ptr->command_arg = 9999; } ! /* Increase count */ else { ! /* Incorporate that digit */ ! p_ptr->command_arg = p_ptr->command_arg * 10 + D2I(cmd); } /* Show current count */ prt(format("Count: %d", p_ptr->command_arg), 0, 0); } ! /* Exit on "unusable" input */ ! else { ! break; } - } ! /* Handle "zero" */ ! if (p_ptr->command_arg == 0) ! { ! /* Default to 99 */ ! p_ptr->command_arg = 99; ! /* Show current count */ ! prt(format("Count: %d", p_ptr->command_arg), 0, 0); } ! /* Hack -- white-space means "enter command now" */ ! if ((cmd == ' ') || (cmd == '\n') || (cmd == '\r')) { /* Get a real command */ ! (void)(get_com("Command: ", &cmd)); ! } ! } - /* Bypass "keymap" */ - if (cmd == '\\') - { - /* Get a char to use without casting */ - (void)(get_com("Command: ", &cmd)); ! /* Hack -- allow "control chars" to be entered */ if (cmd == '^') { ! /* Get a char to "cast" into a control char */ ! (void)(get_com("Command: Control: ", &cmd)); ! ! /* Convert */ ! cmd = KTRL(cmd); } - /* Use the key directly */ - p_ptr->command_cmd = cmd; - } ! /* Utilize "keymap" */ ! else ! { ! /* Hack -- allow "control chars" to be entered */ ! if (cmd == '^') { ! /* Get a char to "cast" into a control char */ ! (void)(get_com("Control: ", &cmd)); ! /* Convert */ ! cmd = KTRL(cmd); } - /* Access the array info */ - p_ptr->command_cmd = keymap_cmds[cmd & 0x7F]; - p_ptr->command_dir = keymap_dirs[cmd & 0x7F]; - } ! /* Paranoia */ ! if (!p_ptr->command_cmd) p_ptr->command_cmd = ESCAPE; /* Hack -- Auto-repeat certain commands */ if (always_repeat && (p_ptr->command_arg <= 0)) { ! /* Hack -- Tunnel, Bash, Disarm, Open, Close, Alter */ ! if (strchr("TBDoc+", p_ptr->command_cmd)) p_ptr->command_arg = 99; } /* Shopping */ if (shopping) { ! /* Convert */ switch (p_ptr->command_cmd) { /* Command "p" -> "purchase" (get) */ --- 2932,3127 ---- p_ptr->command_dir = 0; ! /* Get command */ ! while (1) { ! /* Hack -- auto-commands */ ! if (p_ptr->command_new) ! { ! /* Flush messages */ ! msg_print(NULL); ! /* Use auto-command */ ! cmd = p_ptr->command_new; ! /* Forget it */ ! p_ptr->command_new = 0; ! } ! /* Get a keypress in "command" mode */ ! else ! { ! /* Hack -- no flush needed */ ! msg_flag = FALSE; ! /* Activate "command mode" */ ! inkey_flag = TRUE; ! /* Get a command */ ! cmd = inkey(); ! } + /* Clear top line */ + prt("", 0, 0); ! /* Command Count */ ! if (cmd == '0') { ! int old_arg = p_ptr->command_arg; ! /* Reset */ ! p_ptr->command_arg = 0; ! /* Begin the input */ ! prt("Count: ", 0, 0); ! /* Get a command count */ ! while (1) { ! /* Get a new keypress */ ! cmd = inkey(); ! ! /* Simple editing (delete or backspace) */ ! if ((cmd == 0x7F) || (cmd == KTRL('H'))) { ! /* Delete a digit */ ! p_ptr->command_arg = p_ptr->command_arg / 10; ! /* Show current count */ ! prt(format("Count: %d", p_ptr->command_arg), 0, 0); } ! /* Actual numeric data */ ! else if (cmd >= '0' && cmd <= '9') ! { ! /* Stop count at 9999 */ ! if (p_ptr->command_arg >= 1000) ! { ! /* Warn */ ! bell("Invalid repeat count!"); ! ! /* Limit */ ! p_ptr->command_arg = 9999; ! } ! ! /* Increase count */ ! else ! { ! /* Incorporate that digit */ ! p_ptr->command_arg = p_ptr->command_arg * 10 + D2I(cmd); ! } ! ! /* Show current count */ ! prt(format("Count: %d", p_ptr->command_arg), 0, 0); ! } ! ! /* Exit on "unusable" input */ else { ! break; } + } + + /* Hack -- Handle "zero" */ + if (p_ptr->command_arg == 0) + { + /* Default to 99 */ + p_ptr->command_arg = 99; /* Show current count */ prt(format("Count: %d", p_ptr->command_arg), 0, 0); } ! /* Hack -- Handle "old_arg" */ ! if (old_arg != 0) { ! /* Restore old_arg */ ! p_ptr->command_arg = old_arg; ! ! /* Show current count */ ! prt(format("Count: %d", p_ptr->command_arg), 0, 0); } ! /* Hack -- white-space means "enter command now" */ ! if ((cmd == ' ') || (cmd == '\n') || (cmd == '\r')) ! { ! /* Get a real command */ ! if (!get_com("Command: ", &cmd)) ! { ! /* Clear count */ ! p_ptr->command_arg = 0; ! /* Continue */ ! continue; ! } ! } } ! ! /* Allow "keymaps" to be bypassed */ ! if (cmd == '\\') { /* Get a real command */ ! (void)get_com("Command: ", &cmd); + /* Hack -- bypass keymaps */ + if (!inkey_next) inkey_next = ""; + } ! /* Allow "control chars" to be entered */ if (cmd == '^') { ! /* Get a new command and controlify it */ ! if (get_com("Control: ", &cmd)) cmd = KTRL(cmd); } ! /* Look up applicable keymap */ ! act = keymap_act[mode][(byte)(cmd)]; ! ! /* Apply keymap if not inside a keymap already */ ! if (act && !inkey_next) { ! /* Install the keymap (limited buffer size) */ ! strnfmt(request_command_buffer, 256, "%s", act); ! ! /* Start using the buffer */ ! inkey_next = request_command_buffer; ! /* Continue */ ! continue; } ! /* Paranoia */ ! if (!cmd) continue; + /* Use command */ + p_ptr->command_cmd = cmd; + + /* Done */ + break; + } + /* Hack -- Auto-repeat certain commands */ if (always_repeat && (p_ptr->command_arg <= 0)) { ! /* Hack -- auto repeat certain commands */ ! if (strchr("TBDoc+", p_ptr->command_cmd)) ! { ! /* Repeat 99 times */ ! p_ptr->command_arg = 99; ! } } /* Shopping */ if (shopping) { ! /* Hack -- Convert a few special keys */ switch (p_ptr->command_cmd) { /* Command "p" -> "purchase" (get) */ *************** *** 3106,3114 **** } ! /* Scan equipment */ ! for (i = INVEN_WIELD; i < INVEN_TOTAL; i++) ! { cptr s; object_type *o_ptr = &inventory[i]; --- 3136,3144 ---- } ! /* Hack -- Scan equipment */ ! for (i = INVEN_WIELD; i < INVEN_TOTAL; i++) ! { cptr s; object_type *o_ptr = &inventory[i]; *************** *** 3119,3135 **** /* No inscription */ if (!o_ptr->note) continue; ! /* Find a '!' */ ! s = strchr(quark_str(o_ptr->note), '^'); /* Process preventions */ while (s) { ! /* Check the "restriction" */ if ((s[1] == p_ptr->command_cmd) || (s[1] == '*')) { ! /* Verify command (or convert to "return") */ ! if (!get_check("Are you sure? ")) p_ptr->command_cmd = '\r'; } /* Find another '^' */ --- 3149,3172 ---- /* No inscription */ if (!o_ptr->note) continue; ! /* Obtain the inscription */ ! s = quark_str(o_ptr->note); ! ! /* Find a '^' */ ! s = strchr(s, '^'); /* Process preventions */ while (s) { ! /* Check the "restriction" character */ if ((s[1] == p_ptr->command_cmd) || (s[1] == '*')) { ! /* Hack -- Verify command */ ! if (!get_check("Are you sure? ")) ! { ! /* Hack -- Use space */ ! p_ptr->command_cmd = ' '; ! } } /* Find another '^' */ *************** *** 3140,3145 **** --- 3177,3207 ---- /* Hack -- erase the message line. */ prt("", 0, 0); + } + + + + + /* + * Generates damage for "2d6" style dice rolls + */ + uint damroll(uint num, uint sides) + { + int i, sum = 0; + for (i = 0; i < num; i++) + { + sum += (rand_int(sides) + 1); + } + return (sum); + } + + + /* + * Same as above, but always maximal + */ + uint maxroll(uint num, uint sides) + { + return (num * sides); } diff -c -r angband-282/src/variable.c angband-283/src/variable.c *** angband-282/src/variable.c Fri Sep 5 13:31:51 1997 --- angband-283/src/variable.c Mon Feb 9 01:49:54 1998 *************** *** 67,74 **** bool character_loaded; /* The character was loaded from a savefile */ bool character_saved; /* The character was just saved to a savefile */ ! bool character_icky; /* The game is in an icky full screen mode */ ! bool character_xtra; /* The game is in an icky startup mode */ u32b seed_flavor; /* Hack -- consistent object colors */ u32b seed_town; /* Hack -- consistent town layout */ --- 67,74 ---- bool character_loaded; /* The character was loaded from a savefile */ bool character_saved; /* The character was just saved to a savefile */ ! s16b character_icky; /* Depth of the game in special mode */ ! s16b character_xtra; /* Depth of the game in startup mode */ u32b seed_flavor; /* Hack -- consistent object colors */ u32b seed_town; /* Hack -- consistent town layout */ *************** *** 139,166 **** /* - * Array of grids lit by player lite (see "cave.c") - */ - s16b lite_n; - byte lite_y[LITE_MAX]; - byte lite_x[LITE_MAX]; - - /* - * Array of grids viewable to the player (see "cave.c") - */ - s16b view_n; - byte view_y[VIEW_MAX]; - byte view_x[VIEW_MAX]; - - /* - * Array of grids for use by various functions (see "cave.c") - */ - s16b temp_n; - byte temp_y[TEMP_MAX]; - byte temp_x[TEMP_MAX]; - - - /* * Number of active macros. */ s16b macro__num; --- 139,144 ---- *************** *** 175,198 **** */ cptr *macro__act; - /* - * Array of macro types [MACRO_MAX] - */ - bool *macro__cmd; - - /* - * Current macro action [1024] - */ - char *macro__buf; - /* ! * The number of quarks */ ! s16b quark__num; /* ! * The pointers to the quarks [QUARK_MAX] */ cptr *quark__str; --- 153,166 ---- */ cptr *macro__act; /* ! * The number of quarks (first quark is NULL) */ ! s16b quark__num = 1; /* ! * The array[QUARK_MAX] of pointers to the quarks */ cptr *quark__str; *************** *** 218,241 **** u16b message__tail; /* ! * The array of offsets, by index [MESSAGE_MAX] */ u16b *message__ptr; /* ! * The array of chars, by offset [MESSAGE_BUF] */ char *message__buf; /* ! * The array of window pointers */ term *angband_term[8]; /* ! * Standard window names */ char angband_term_name[8][16] = { --- 186,209 ---- u16b message__tail; /* ! * The array[MESSAGE_MAX] of offsets, by index */ u16b *message__ptr; /* ! * The array[MESSAGE_BUF] of chars, by offset */ char *message__buf; /* ! * The array[8] of window pointers */ term *angband_term[8]; /* ! * The array[8] of window names (modifiable?) */ char angband_term_name[8][16] = { *************** *** 275,281 **** /* ! * Standard sound names */ char angband_sound_name[SOUND_MAX][16] = { --- 243,249 ---- /* ! * Standard sound names (modifiable?) */ char angband_sound_name[SOUND_MAX][16] = { *************** *** 307,339 **** }; - #ifdef MONSTER_FLOW - /* ! * The array of cave grid flow "cost" values */ ! byte cave_cost[DUNGEON_HGT][DUNGEON_WID]; /* ! * The array of cave grid flow "when" stamps */ ! byte cave_when[DUNGEON_HGT][DUNGEON_WID]; - #endif /* MONSTER_FLOW */ /* ! * The array of cave grid info flags */ ! byte cave_info[DUNGEON_HGT][DUNGEON_WID]; /* ! * The array of cave grid feature codes */ ! byte cave_feat[DUNGEON_HGT][DUNGEON_WID]; /* ! * The array of cave grid object indexes * * Note that this array yields the index of the top object in the stack of * objects in a given grid, using the "next_o_idx" field in that object to --- 275,311 ---- }; /* ! * Array[VIEW_MAX] used by "update_view()" */ ! sint view_n = 0; ! u16b *view_g; /* ! * Arrays[TEMP_MAX] used for various things */ ! sint temp_n = 0; ! u16b *temp_g; ! byte *temp_y; ! byte *temp_x; /* ! * Array[DUNGEON_HGT][256] of cave grid info flags (padded) ! * ! * This array is padded to a width of 256 to allow fast access to elements ! * in the array via "grid" values (see the GRID() macros). */ ! byte (*cave_info)[256]; /* ! * Array[DUNGEON_HGT][DUNGEON_WID] of cave grid feature codes */ ! byte (*cave_feat)[DUNGEON_WID]; /* ! * Array[DUNGEON_HGT][DUNGEON_WID] of cave grid object indexes * * Note that this array yields the index of the top object in the stack of * objects in a given grid, using the "next_o_idx" field in that object to *************** *** 343,352 **** * any object is in a grid, and relatively fast determination of which objects * are in a grid. */ ! s16b cave_o_idx[DUNGEON_HGT][DUNGEON_WID]; /* ! * The array of cave grid monster indexes * * Note that this array yields the index of the monster or player in a grid, * where negative numbers are used to represent the player, positive numbers --- 315,324 ---- * any object is in a grid, and relatively fast determination of which objects * are in a grid. */ ! s16b (*cave_o_idx)[DUNGEON_WID]; /* ! * Array[DUNGEON_HGT][DUNGEON_WID] of cave grid monster indexes * * Note that this array yields the index of the monster or player in a grid, * where negative numbers are used to represent the player, positive numbers *************** *** 355,386 **** * the player structure, but provides extremely fast determination of which, * if any, monster or player is in any given grid. */ ! s16b cave_m_idx[DUNGEON_HGT][DUNGEON_WID]; /* ! * The array of dungeon objects */ ! object_type o_list[MAX_O_IDX]; /* ! * The array of dungeon monsters */ ! monster_type m_list[MAX_M_IDX]; /* ! * Hack -- Quest array */ ! quest q_list[MAX_Q_IDX]; /* ! * The stores [MAX_STORES] */ store_type *store; /* ! * The player's inventory [INVEN_TOTAL] */ object_type *inventory; --- 327,372 ---- * the player structure, but provides extremely fast determination of which, * if any, monster or player is in any given grid. */ ! s16b (*cave_m_idx)[DUNGEON_WID]; + #ifdef MONSTER_FLOW + + /* + * Array[DUNGEON_HGT][DUNGEON_WID] of cave grid flow "cost" values + */ + byte (*cave_cost)[DUNGEON_WID]; + + /* + * Array[DUNGEON_HGT][DUNGEON_WID] of cave grid flow "when" stamps + */ + byte (*cave_when)[DUNGEON_WID]; + + #endif /* MONSTER_FLOW */ + /* ! * Array[MAX_O_IDX] of dungeon objects */ ! object_type *o_list; /* ! * Array[MAX_M_IDX] of dungeon monsters */ ! monster_type *m_list; /* ! * Hack -- Array[MAX_Q_IDX] of quests */ ! quest *q_list; /* ! * Array[MAX_STORES] of stores */ store_type *store; /* ! * Array[INVEN_TOTAL] of objects in the player's inventory */ object_type *inventory; *************** *** 391,397 **** s16b alloc_kind_size; /* ! * The entries in the "kind allocator table" */ alloc_entry *alloc_kind_table; --- 377,383 ---- s16b alloc_kind_size; /* ! * The array[alloc_kind_size] of entries in the "kind allocator table" */ alloc_entry *alloc_kind_table; *************** *** 402,418 **** s16b alloc_race_size; /* ! * The entries in the "race allocator table" */ alloc_entry *alloc_race_table; /* * Specify attr/char pairs for visual special effects ! * Be sure to use "index & 0x7F" to avoid illegal access */ ! byte misc_to_attr[128]; ! char misc_to_char[128]; /* --- 388,404 ---- s16b alloc_race_size; /* ! * The array[alloc_race_size] of entries in the "race allocator table" */ alloc_entry *alloc_race_table; /* * Specify attr/char pairs for visual special effects ! * Be sure to use "index & 0xFF" to avoid illegal access */ ! byte misc_to_attr[256]; ! char misc_to_char[256]; /* *************** *** 421,440 **** */ byte tval_to_attr[128]; /* ! * Simple keymap method, see "init.c" and "cmd6.c". ! * Be sure to use "index & 0x7F" to avoid illegal access */ ! byte keymap_cmds[128]; ! byte keymap_dirs[128]; /*** Player information ***/ /* ! * Pointer to the player tables ! * (sex, race, class, magic) */ player_sex *sp_ptr; player_race *rp_ptr; --- 407,430 ---- */ byte tval_to_attr[128]; + /* ! * Current (or recent) macro action ! */ ! char macro_buffer[1024]; ! ! ! /* ! * Keymaps for each "mode" associated with each keypress. */ ! cptr keymap_act[KEYMAP_MODES][256]; /*** Player information ***/ /* ! * Pointer to the player tables (sex, race, class, magic) */ player_sex *sp_ptr; player_race *rp_ptr; *************** *** 502,508 **** char *e_name; char *e_text; - /* * The monster race arrays */ --- 492,497 ---- *************** *** 631,634 **** --- 620,625 ---- * Hack -- function hook to restrict "get_obj_num_prep()" function */ bool (*get_obj_num_hook)(int k_idx); + + diff -c -r angband-282/src/wizard1.c angband-283/src/wizard1.c *** angband-282/src/wizard1.c Wed Sep 3 11:57:34 1997 --- angband-283/src/wizard1.c Fri Feb 6 04:10:31 1998 *************** *** 64,70 **** /* ! * Item Spoilers by: benh@voicenet.com (Ben Harrison) */ --- 64,70 ---- /* ! * Item Spoilers by Ben Harrison (benh@phial.com) */ *************** *** 2232,2242 **** int i; ! /* Enter "icky" mode */ ! character_icky = TRUE; ! ! /* Save the screen */ ! Term_save(); /* Drop priv's */ --- 2232,2239 ---- int i; ! /* Save screen */ ! screen_save(); /* Drop priv's */ *************** *** 2297,2303 **** /* Oops */ else { ! bell(); } /* Flush messages */ --- 2294,2300 ---- /* Oops */ else { ! bell("Illegal command for spoilers!"); } /* Flush messages */ *************** *** 2309,2319 **** safe_setuid_grab(); ! /* Restore the screen */ ! Term_load(); ! ! /* Leave "icky" mode */ ! character_icky = FALSE; } --- 2306,2313 ---- safe_setuid_grab(); ! /* Load screen */ ! screen_load(); } diff -c -r angband-282/src/wizard2.c angband-283/src/wizard2.c *** angband-282/src/wizard2.c Thu Sep 4 10:17:55 1997 --- angband-283/src/wizard2.c Wed Feb 11 06:30:29 1998 *************** *** 12,18 **** ! #ifdef ALLOW_WIZARD /* --- 12,18 ---- ! #ifdef ALLOW_DEBUG /* *************** *** 20,27 **** */ static void do_cmd_wiz_hack_ben(void) { /* Oops */ ! msg_print("Oops."); } --- 20,91 ---- */ static void do_cmd_wiz_hack_ben(void) { + + #ifdef MONSTER_FLOW + + int py = p_ptr->py; + int px = p_ptr->px; + + int i, y, x; + + + for (i = 0; i < MONSTER_FLOW_DEPTH; ++i) + { + /* Update map */ + for (y = p_ptr->wy; y < p_ptr->wy + SCREEN_HGT; y++) + { + for (x = p_ptr->wx; x < p_ptr->wx + SCREEN_WID; x++) + { + byte a = TERM_RED; + + /* Display proper cost */ + if (cave_cost[y][x] != i) continue; + + /* Reliability in yellow */ + if (cave_when[y][x] == cave_when[py][px]) + { + a = TERM_YELLOW; + } + + /* Display player/floors/walls */ + if ((y == py) && (x == px)) + { + print_rel('@', a, y, x); + } + else if (cave_floor_bold(y, x)) + { + print_rel('*', a, y, x); + } + else + { + print_rel('#', a, y, x); + } + } + } + + /* Prompt */ + prt(format("Depth %d: ", i), 0, 0); + + /* Get key */ + if (inkey() == ESCAPE) break; + + /* Redraw map */ + prt_map(); + } + + /* Done */ + prt("", 0, 0); + + /* Redraw map */ + prt_map(); + + #else /* MONSTER_FLOW */ + /* Oops */ ! msg_print("Oops"); ! ! #endif /* MONSTER_FLOW */ ! } *************** *** 58,67 **** static void do_cmd_wiz_bamf(void) { /* Must have a target */ ! if (!p_ptr->target_who) return; ! ! /* Teleport to the target */ ! teleport_player_to(p_ptr->target_row, p_ptr->target_col); } --- 122,132 ---- static void do_cmd_wiz_bamf(void) { /* Must have a target */ ! if (target_okay()) ! { ! /* Teleport to the target */ ! teleport_player_to(p_ptr->target_row, p_ptr->target_col); ! } } *************** *** 351,357 **** /* * Hack -- title for each column * ! * XXX XXX XXX This will not work with "EBCDIC", I would think. */ static char head[3] = { 'a', 'A', '0' }; --- 416,422 ---- /* * Hack -- title for each column * ! * This will not work with "EBCDIC", I would think. XXX XXX XXX */ static char head[3] = { 'a', 'A', '0' }; *************** *** 578,584 **** p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* Window stuff */ ! p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER); } } --- 643,649 ---- p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* Window stuff */ ! p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER_0 | PW_PLAYER_1); } } *************** *** 614,620 **** cptr q = "Rolls: %ld, Matches: %ld, Better: %ld, Worse: %ld, Other: %ld"; ! /* XXX XXX XXX Mega-Hack -- allow multiple artifacts */ if (artifact_p(o_ptr)) a_info[o_ptr->name1].cur_num = 0; --- 679,685 ---- cptr q = "Rolls: %ld, Matches: %ld, Better: %ld, Worse: %ld, Other: %ld"; ! /* Mega-Hack -- allow multiple artifacts XXX XXX XXX */ if (artifact_p(o_ptr)) a_info[o_ptr->name1].cur_num = 0; *************** *** 697,703 **** make_object(i_ptr, good, great); ! /* XXX XXX XXX Mega-Hack -- allow multiple artifacts */ if (artifact_p(i_ptr)) a_info[i_ptr->name1].cur_num = 0; --- 762,768 ---- make_object(i_ptr, good, great); ! /* Mega-Hack -- allow multiple artifacts XXX XXX XXX */ if (artifact_p(i_ptr)) a_info[i_ptr->name1].cur_num = 0; *************** *** 829,839 **** changed = FALSE; ! /* Icky */ ! character_icky = TRUE; ! ! /* Save the screen */ ! Term_save(); /* Get local object */ --- 894,901 ---- changed = FALSE; ! /* Save screen */ ! screen_save(); /* Get local object */ *************** *** 884,894 **** } ! /* Restore the screen */ ! Term_load(); ! ! /* Not Icky */ ! character_icky = FALSE; /* Accept change */ --- 946,953 ---- } ! /* Load screen */ ! screen_load(); /* Accept change */ *************** *** 907,913 **** p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* Window stuff */ ! p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER); } /* Ignore change */ --- 966,972 ---- p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* Window stuff */ ! p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER_0 | PW_PLAYER_1); } /* Ignore change */ *************** *** 937,956 **** int k_idx; ! /* Icky */ ! character_icky = TRUE; ! ! /* Save the screen */ ! Term_save(); /* Get object base type */ k_idx = wiz_create_itemtype(); ! /* Restore the screen */ ! Term_load(); ! ! /* Not Icky */ ! character_icky = FALSE; /* Return if failed */ --- 996,1009 ---- int k_idx; ! /* Save screen */ ! screen_save(); /* Get object base type */ k_idx = wiz_create_itemtype(); ! /* Load screen */ ! screen_load(); /* Return if failed */ *************** *** 1130,1136 **** p_ptr->redraw |= (PR_HP); /* Window stuff */ ! p_ptr->window |= (PW_SPELL | PW_PLAYER); /* Handle stuff */ handle_stuff(); --- 1183,1189 ---- p_ptr->redraw |= (PR_HP); /* Window stuff */ ! p_ptr->window |= (PW_PLAYER_0 | PW_PLAYER_1); /* Handle stuff */ handle_stuff(); *************** *** 1160,1166 **** /* * Summon a creature of the specified type * ! * XXX XXX XXX This function is rather dangerous */ static void do_cmd_wiz_named(int r_idx, int slp) { --- 1213,1219 ---- /* * Summon a creature of the specified type * ! * This function is rather dangerous XXX XXX XXX */ static void do_cmd_wiz_named(int r_idx, int slp) { *************** *** 1245,1250 **** --- 1298,1384 ---- } + /* + * Query the dungeon + */ + static void do_cmd_wiz_query(void) + { + int py = p_ptr->py; + int px = p_ptr->px; + + int y, x; + + char cmd; + + u16b mask = 0x00; + + + /* Get a "debug command" */ + if (!get_com("Debug Command Query: ", &cmd)) return; + + /* Extract a flag */ + switch (cmd) + { + case '0': mask = (1 << 0); break; + case '1': mask = (1 << 1); break; + case '2': mask = (1 << 2); break; + case '3': mask = (1 << 3); break; + case '4': mask = (1 << 4); break; + case '5': mask = (1 << 5); break; + case '6': mask = (1 << 6); break; + case '7': mask = (1 << 7); break; + + case 'm': mask |= (CAVE_MARK); break; + case 'g': mask |= (CAVE_GLOW); break; + case 'r': mask |= (CAVE_ROOM); break; + case 'i': mask |= (CAVE_ICKY); break; + case 's': mask |= (CAVE_SEEN); break; + case 'v': mask |= (CAVE_VIEW); break; + case 't': mask |= (CAVE_TEMP); break; + case 'w': mask |= (CAVE_WALL); break; + } + + /* Scan map */ + for (y = p_ptr->wy; y < p_ptr->wy + SCREEN_HGT; y++) + { + for (x = p_ptr->wx; x < p_ptr->wx + SCREEN_WID; x++) + { + byte a = TERM_RED; + + /* Given mask, show only those grids */ + if (mask && !(cave_info[y][x] & mask)) continue; + + /* Given no mask, show unknown grids */ + if (!mask && (cave_info[y][x] & (CAVE_MARK))) continue; + + /* Color */ + if (cave_floor_bold(y, x)) a = TERM_YELLOW; + + /* Display player/floors/walls */ + if ((y == py) && (x == px)) + { + print_rel('@', a, y, x); + } + else if (cave_floor_bold(y, x)) + { + print_rel('*', a, y, x); + } + else + { + print_rel('#', a, y, x); + } + } + } + + /* Get keypress */ + msg_print("Press any key."); + msg_print(NULL); + + /* Redraw map */ + prt_map(); + } + + #ifdef ALLOW_SPOILERS *************** *** 1266,1271 **** --- 1400,1406 ---- /* * Ask for and parse a "debug command" + * * The "p_ptr->command_arg" may have been set. */ void do_cmd_debug(void) *************** *** 1277,1283 **** /* Get a "debug command" */ ! (void)(get_com("Debug Command: ", &cmd)); /* Analyze the command */ switch (cmd) --- 1412,1418 ---- /* Get a "debug command" */ ! if (!get_com("Debug Command: ", &cmd)) return; /* Analyze the command */ switch (cmd) *************** *** 1422,1427 **** --- 1557,1569 ---- break; } + /* Query the dungeon */ + case 'q': + { + do_cmd_wiz_query(); + break; + } + /* Summon Random Monster(s) */ case 's': { *************** *** 1506,1509 **** --- 1648,1652 ---- #endif #endif + diff -c -r angband-282/src/xtra1.c angband-283/src/xtra1.c *** angband-282/src/xtra1.c Thu Sep 4 10:17:55 1997 --- angband-283/src/xtra1.c Wed Feb 11 06:30:29 1998 *************** *** 491,504 **** i = n / 100; text[9] = '0'; text[8] = '0'; ! text[7] = '0' + (i % 10); if (i >= 10) { i = i / 10; ! text[6] = '0' + (i % 10); if (i >= 10) { ! text[5] = '0' + (i / 10); } } } --- 491,504 ---- i = n / 100; text[9] = '0'; text[8] = '0'; ! text[7] = I2D(i % 10); if (i >= 10) { i = i / 10; ! text[6] = I2D(i % 10); if (i >= 10) { ! text[5] = I2D(i / 10); } } } *************** *** 507,531 **** else if (n >= 100) { i = n; ! text[9] = '0' + (i % 10); i = i / 10; ! text[8] = '0' + (i % 10); ! text[7] = '0' + (i / 10); } /* Medium (timed) rest */ else if (n >= 10) { i = n; ! text[9] = '0' + (i % 10); ! text[8] = '0' + (i / 10); } /* Short (timed) rest */ else if (n > 0) { i = n; ! text[9] = '0' + (i); } /* Rest until healed */ --- 507,531 ---- else if (n >= 100) { i = n; ! text[9] = I2D(i % 10); i = i / 10; ! text[8] = I2D(i % 10); ! text[7] = I2D(i / 10); } /* Medium (timed) rest */ else if (n >= 10) { i = n; ! text[9] = I2D(i % 10); ! text[8] = I2D(i / 10); } /* Short (timed) rest */ else if (n > 0) { i = n; ! text[9] = I2D(i); } /* Rest until healed */ *************** *** 902,910 **** /* ! * Hack -- display flags in sub-windows */ ! static void fix_pflags(void) { int j; --- 902,910 ---- /* ! * Hack -- display player in sub-windows (mode 0) */ ! static void fix_player_0(void) { int j; *************** *** 917,929 **** if (!angband_term[j]) continue; /* No relevant flags */ ! if (!(op_ptr->window_flag[j] & (PW_SPELL))) continue; /* Activate */ Term_activate(angband_term[j]); ! /* Display flags */ ! display_player(2); /* Fresh */ Term_fresh(); --- 917,929 ---- if (!angband_term[j]) continue; /* No relevant flags */ ! if (!(op_ptr->window_flag[j] & (PW_PLAYER_0))) continue; /* Activate */ Term_activate(angband_term[j]); ! /* Display player */ ! display_player(0); /* Fresh */ Term_fresh(); *************** *** 934,943 **** } /* ! * Hack -- display character in sub-windows */ ! static void fix_player(void) { int j; --- 934,944 ---- } + /* ! * Hack -- display player in sub-windows (mode 1) */ ! static void fix_player_1(void) { int j; *************** *** 950,962 **** if (!angband_term[j]) continue; /* No relevant flags */ ! if (!(op_ptr->window_flag[j] & (PW_PLAYER))) continue; /* Activate */ Term_activate(angband_term[j]); ! /* Display player */ ! display_player(0); /* Fresh */ Term_fresh(); --- 951,963 ---- if (!angband_term[j]) continue; /* No relevant flags */ ! if (!(op_ptr->window_flag[j] & (PW_PLAYER_1))) continue; /* Activate */ Term_activate(angband_term[j]); ! /* Display flags */ ! display_player(1); /* Fresh */ Term_fresh(); *************** *** 967,977 **** } - /* * Hack -- display recent messages in sub-windows * ! * XXX XXX XXX Adjust for width and split messages */ static void fix_message(void) { --- 968,977 ---- } /* * Hack -- display recent messages in sub-windows * ! * Adjust for width and split messages. XXX XXX XXX */ static void fix_message(void) { *************** *** 1499,1505 **** p_ptr->redraw |= (PR_MANA); /* Window stuff */ ! p_ptr->window |= (PW_SPELL | PW_PLAYER); } --- 1499,1505 ---- p_ptr->redraw |= (PR_MANA); /* Window stuff */ ! p_ptr->window |= (PW_PLAYER_0 | PW_PLAYER_1); } *************** *** 1579,1585 **** p_ptr->redraw |= (PR_HP); /* Window stuff */ ! p_ptr->window |= (PW_SPELL | PW_PLAYER); } } --- 1579,1585 ---- p_ptr->redraw |= (PR_HP); /* Window stuff */ ! p_ptr->window |= (PW_PLAYER_0 | PW_PLAYER_1); } } *************** *** 1627,1637 **** /* Notice changes in the "lite radius" */ if (p_ptr->old_lite != p_ptr->cur_lite) { ! /* Update the lite */ ! p_ptr->update |= (PU_LITE); ! ! /* Update the monsters */ ! p_ptr->update |= (PU_MONSTERS); /* Remember the old lite */ p_ptr->old_lite = p_ptr->cur_lite; --- 1627,1634 ---- /* Notice changes in the "lite radius" */ if (p_ptr->old_lite != p_ptr->cur_lite) { ! /* Update the visuals */ ! p_ptr->update |= (PU_UPDATE_VIEW | PU_MONSTERS); /* Remember the old lite */ p_ptr->old_lite = p_ptr->cur_lite; *************** *** 2133,2139 **** /* Extract the "weight limit" (in tenth pounds) */ i = weight_limit(); ! /* XXX XXX XXX Apply "encumbrance" from weight */ if (j > i/2) p_ptr->pspeed -= ((j - (i/2)) / (i / 10)); /* Bloating slows the player down (a little) */ --- 2130,2136 ---- /* Extract the "weight limit" (in tenth pounds) */ i = weight_limit(); ! /* Apply "encumbrance" from weight */ if (j > i/2) p_ptr->pspeed -= ((j - (i/2)) / (i / 10)); /* Bloating slows the player down (a little) */ *************** *** 2423,2429 **** p_ptr->redraw |= (PR_STATS); /* Window stuff */ ! p_ptr->window |= (PW_SPELL | PW_PLAYER); } /* Notice changes */ --- 2420,2426 ---- p_ptr->redraw |= (PR_STATS); /* Window stuff */ ! p_ptr->window |= (PW_PLAYER_0 | PW_PLAYER_1); } /* Notice changes */ *************** *** 2433,2439 **** p_ptr->redraw |= (PR_STATS); /* Window stuff */ ! p_ptr->window |= (PW_SPELL | PW_PLAYER); } /* Notice changes */ --- 2430,2436 ---- p_ptr->redraw |= (PR_STATS); /* Window stuff */ ! p_ptr->window |= (PW_PLAYER_0 | PW_PLAYER_1); } /* Notice changes */ *************** *** 2493,2499 **** p_ptr->redraw |= (PR_ARMOR); /* Window stuff */ ! p_ptr->window |= (PW_SPELL | PW_PLAYER); } /* Hack -- handle "xtra" mode */ --- 2490,2496 ---- p_ptr->redraw |= (PR_ARMOR); /* Window stuff */ ! p_ptr->window |= (PW_PLAYER_0 | PW_PLAYER_1); } /* Hack -- handle "xtra" mode */ *************** *** 2638,2672 **** if (character_icky) return; ! if (p_ptr->update & (PU_UN_LITE)) ! { ! p_ptr->update &= ~(PU_UN_LITE); ! forget_lite(); ! } ! ! if (p_ptr->update & (PU_UN_VIEW)) { ! p_ptr->update &= ~(PU_UN_VIEW); forget_view(); } ! ! if (p_ptr->update & (PU_VIEW)) { ! p_ptr->update &= ~(PU_VIEW); update_view(); } ! if (p_ptr->update & (PU_LITE)) { ! p_ptr->update &= ~(PU_LITE); ! update_lite(); } ! ! if (p_ptr->update & (PU_FLOW)) { ! p_ptr->update &= ~(PU_FLOW); update_flow(); } --- 2635,2662 ---- if (character_icky) return; ! if (p_ptr->update & (PU_FORGET_VIEW)) { ! p_ptr->update &= ~(PU_FORGET_VIEW); forget_view(); } ! if (p_ptr->update & (PU_UPDATE_VIEW)) { ! p_ptr->update &= ~(PU_UPDATE_VIEW); update_view(); } ! ! if (p_ptr->update & (PU_FORGET_FLOW)) { ! p_ptr->update &= ~(PU_FORGET_FLOW); ! forget_flow(); } ! if (p_ptr->update & (PU_UPDATE_FLOW)) { ! p_ptr->update &= ~(PU_UPDATE_FLOW); update_flow(); } *************** *** 2683,2688 **** --- 2673,2685 ---- p_ptr->update &= ~(PU_MONSTERS); update_monsters(FALSE); } + + + if (p_ptr->update & (PU_PANEL)) + { + p_ptr->update &= ~(PU_PANEL); + verify_panel(); + } } *************** *** 2704,2718 **** - /* Hack -- clear the screen */ - if (p_ptr->redraw & (PR_WIPE)) - { - p_ptr->redraw &= ~(PR_WIPE); - msg_print(NULL); - Term_clear(); - } - - if (p_ptr->redraw & (PR_MAP)) { p_ptr->redraw &= ~(PR_MAP); --- 2701,2706 ---- *************** *** 2921,2938 **** fix_equip(); } ! /* Display pflags */ ! if (p_ptr->window & (PW_SPELL)) { ! p_ptr->window &= ~(PW_SPELL); ! fix_pflags(); } ! /* Display player */ ! if (p_ptr->window & (PW_PLAYER)) { ! p_ptr->window &= ~(PW_PLAYER); ! fix_player(); } /* Display overhead view */ --- 2909,2926 ---- fix_equip(); } ! /* Display player (mode 0) */ ! if (p_ptr->window & (PW_PLAYER_0)) { ! p_ptr->window &= ~(PW_PLAYER_0); ! fix_player_0(); } ! /* Display player (mode 1) */ ! if (p_ptr->window & (PW_PLAYER_1)) { ! p_ptr->window &= ~(PW_PLAYER_1); ! fix_player_1(); } /* Display overhead view */ diff -c -r angband-282/src/xtra2.c angband-283/src/xtra2.c *** angband-282/src/xtra2.c Thu Sep 4 10:17:55 1997 --- angband-283/src/xtra2.c Wed Feb 11 06:30:29 1998 *************** *** 15,24 **** /* * Set "p_ptr->blind", notice observable changes * ! * Note the use of "PU_UN_LITE" and "PU_UN_VIEW", which is needed to ! * memorize any terrain features which suddenly become "visible". ! * Note that blindness is currently the only thing which can affect ! * "player_can_see_bold()". */ bool set_blind(int v) { --- 15,24 ---- /* * Set "p_ptr->blind", notice observable changes * ! * Note the use of "PU_FORGET_VIEW" and "PU_UPDATE_VIEW", which are needed ! * because "p_ptr->blind" affects the "CAVE_SEEN" flag, and "PU_MONSTERS", ! * because "p_ptr->blind" affects monster visibility, and "PU_MAP", because ! * "p_ptr->blind" affects the way in which many cave grids are displayed. */ bool set_blind(int v) { *************** *** 56,69 **** /* Disturb */ if (disturb_state) disturb(0, 0); ! /* Forget stuff */ ! p_ptr->update |= (PU_UN_VIEW | PU_UN_LITE); ! ! /* Update stuff */ ! p_ptr->update |= (PU_VIEW | PU_LITE); ! ! /* Update the monsters */ ! p_ptr->update |= (PU_MONSTERS); /* Redraw map */ p_ptr->redraw |= (PR_MAP); --- 56,63 ---- /* Disturb */ if (disturb_state) disturb(0, 0); ! /* Fully update the visuals */ ! p_ptr->update |= (PU_FORGET_VIEW | PU_UPDATE_VIEW | PU_MONSTERS); /* Redraw map */ p_ptr->redraw |= (PR_MAP); *************** *** 285,291 **** /* * Set "p_ptr->image", notice observable changes * ! * Note that we must redraw the map when hallucination changes. */ bool set_image(int v) { --- 279,286 ---- /* * Set "p_ptr->image", notice observable changes * ! * Note the use of "PR_MAP", which is needed because "p_ptr->image" affects ! * the way in which monsters, objects, and some normal grids, are displayed. */ bool set_image(int v) { *************** *** 326,334 **** /* Redraw map */ p_ptr->redraw |= (PR_MAP); - /* Update monsters */ - p_ptr->update |= (PU_MONSTERS); - /* Window stuff */ p_ptr->window |= (PW_OVERHEAD); --- 321,326 ---- *************** *** 740,745 **** --- 732,740 ---- /* * Set "p_ptr->tim_invis", notice observable changes + * + * Note the use of "PU_MONSTERS", which is needed because + * "p_ptr->tim_image" affects monster visibility. */ bool set_tim_invis(int v) { *************** *** 780,786 **** /* Recalculate bonuses */ p_ptr->update |= (PU_BONUS); ! /* Update the monsters */ p_ptr->update |= (PU_MONSTERS); /* Handle stuff */ --- 775,781 ---- /* Recalculate bonuses */ p_ptr->update |= (PU_BONUS); ! /* Update the monsters XXX */ p_ptr->update |= (PU_MONSTERS); /* Handle stuff */ *************** *** 793,798 **** --- 788,796 ---- /* * Set "p_ptr->tim_infra", notice observable changes + * + * Note the use of "PU_MONSTERS", which is needed because because + * "p_ptr->tim_infra" affects monster visibility. */ bool set_tim_infra(int v) { *************** *** 833,839 **** /* Recalculate bonuses */ p_ptr->update |= (PU_BONUS); ! /* Update the monsters */ p_ptr->update |= (PU_MONSTERS); /* Handle stuff */ --- 831,837 ---- /* Recalculate bonuses */ p_ptr->update |= (PU_BONUS); ! /* Update the monsters XXX */ p_ptr->update |= (PU_MONSTERS); /* Handle stuff */ *************** *** 1698,1704 **** p_ptr->redraw |= (PR_LEV | PR_TITLE); /* Window stuff */ ! p_ptr->window |= (PW_SPELL | PW_PLAYER); /* Handle stuff */ handle_stuff(); --- 1696,1702 ---- p_ptr->redraw |= (PR_LEV | PR_TITLE); /* Window stuff */ ! p_ptr->window |= (PW_PLAYER_0 | PW_PLAYER_1); /* Handle stuff */ handle_stuff(); *************** *** 1729,1735 **** p_ptr->redraw |= (PR_LEV | PR_TITLE); /* Window stuff */ ! p_ptr->window |= (PW_SPELL | PW_PLAYER); /* Handle stuff */ handle_stuff(); --- 1727,1733 ---- p_ptr->redraw |= (PR_LEV | PR_TITLE); /* Window stuff */ ! p_ptr->window |= (PW_PLAYER_0 | PW_PLAYER_1); /* Handle stuff */ handle_stuff(); *************** *** 1779,1785 **** * Hack -- Return the "automatic coin type" of a monster race * Used to allocate proper treasure when "Creeping coins" die * ! * XXX XXX XXX Note the use of actual "monster names" */ static int get_coin_type(monster_race *r_ptr) { --- 1777,1783 ---- * Hack -- Return the "automatic coin type" of a monster race * Used to allocate proper treasure when "Creeping coins" die * ! * Note the use of actual "monster names". XXX XXX XXX */ static int get_coin_type(monster_race *r_ptr) { *************** *** 1953,1959 **** /* Make some gold */ if (!make_gold(i_ptr)) continue; ! /* XXX XXX XXX */ dump_gold++; } --- 1951,1957 ---- /* Make some gold */ if (!make_gold(i_ptr)) continue; ! /* Assume seen XXX XXX XXX */ dump_gold++; } *************** *** 1963,1969 **** /* Make an object */ if (!make_object(i_ptr, good, great)) continue; ! /* XXX XXX XXX */ dump_item++; } --- 1961,1967 ---- /* Make an object */ if (!make_object(i_ptr, good, great)) continue; ! /* Assume seen XXX XXX XXX */ dump_item++; } *************** *** 2016,2022 **** y = ny; x = nx; } ! /* XXX XXX XXX */ delete_object(y, x); /* Explain the staircase */ --- 2014,2020 ---- y = ny; x = nx; } ! /* Destroy any objects */ delete_object(y, x); /* Explain the staircase */ *************** *** 2025,2032 **** /* Create stairs down */ cave_set_feat(y, x, FEAT_MORE); ! /* Remember to update everything */ ! p_ptr->update |= (PU_VIEW | PU_LITE | PU_FLOW | PU_MONSTERS); } --- 2023,2033 ---- /* Create stairs down */ cave_set_feat(y, x, FEAT_MORE); ! /* Update the visuals */ ! p_ptr->update |= (PU_UPDATE_VIEW | PU_MONSTERS); ! ! /* Fully update the flow */ ! p_ptr->update |= (PU_FORGET_FLOW | PU_UPDATE_FLOW); } *************** *** 2226,2232 **** /* Hack -- note fear */ (*fear) = TRUE; ! /* XXX XXX XXX Hack -- Add some timed fear */ m_ptr->monfear = (randint(10) + (((dam >= m_ptr->hp) && (percentage > 7)) ? 20 : ((11 - percentage) * 5))); --- 2227,2233 ---- /* Hack -- note fear */ (*fear) = TRUE; ! /* Hack -- Add some timed fear */ m_ptr->monfear = (randint(10) + (((dam >= m_ptr->hp) && (percentage > 7)) ? 20 : ((11 - percentage) * 5))); *************** *** 2316,2324 **** /* Optional disturb on "panel change" */ if (disturb_panel) disturb(0, 0); - /* Update stuff */ - p_ptr->update |= (PU_MONSTERS); - /* Redraw map */ p_ptr->redraw |= (PR_MAP); --- 2317,2322 ---- *************** *** 2449,2454 **** --- 2447,2503 ---- /* + * Extract a direction (or zero) from a character + */ + sint target_dir(char ch) + { + int d; + + int mode; + + cptr act; + + cptr s; + + + /* Default direction */ + d = (isdigit(ch) ? D2I(ch) : 0); + + /* Roguelike */ + if (rogue_like_commands) + { + mode = KEYMAP_MODE_ROGUE; + } + + /* Original */ + else + { + mode = KEYMAP_MODE_ORIG; + } + + /* Extract the action (if any) */ + act = keymap_act[mode][(byte)(ch)]; + + /* Analyze */ + if (act) + { + /* Convert to a direction */ + for (s = act; *s; ++s) + { + /* Use any digits in keymap */ + if (isdigit(*s)) d = D2I(*s); + } + } + + /* Paranoia */ + if (d == 5) d = 0; + + /* Return direction */ + return (d); + } + + + /* * Determine is a monster makes a reasonable target * * The concept of "targetting" was stolen from "Morgul" (?) *************** *** 2487,2493 **** /* Hack -- no targeting hallucinations */ if (p_ptr->image) return (FALSE); ! /* XXX XXX XXX Hack -- Never target trappers */ /* if (CLEAR_ATTR && (CLEAR_CHAR)) return (FALSE); */ /* Assume okay */ --- 2536,2542 ---- /* Hack -- no targeting hallucinations */ if (p_ptr->image) return (FALSE); ! /* Hack -- Never target trappers XXX XXX XXX */ /* if (CLEAR_ATTR && (CLEAR_CHAR)) return (FALSE); */ /* Assume okay */ *************** *** 2504,2519 **** */ bool target_okay(void) { ! /* Accept stationary targets */ ! if (p_ptr->target_who < 0) return (TRUE); ! /* Check moving targets */ if (p_ptr->target_who > 0) { /* Accept reasonable targets */ ! if (target_able(p_ptr->target_who)) { ! monster_type *m_ptr = &m_list[p_ptr->target_who]; /* Acquire monster location */ p_ptr->target_row = m_ptr->fy; --- 2553,2573 ---- */ bool target_okay(void) { ! /* No target */ ! if (!p_ptr->target_set) return (FALSE); ! /* Accept "location" targets */ ! if (p_ptr->target_who == 0) return (TRUE); ! ! /* Check "monster" targets */ if (p_ptr->target_who > 0) { + int m_idx = p_ptr->target_who; + /* Accept reasonable targets */ ! if (target_able(m_idx)) { ! monster_type *m_ptr = &m_list[m_idx]; /* Acquire monster location */ p_ptr->target_row = m_ptr->fy; *************** *** 2529,2534 **** --- 2583,2643 ---- } + /* + * Set the target to a monster (or nobody) + */ + void target_set_monster(int m_idx) + { + /* Acceptable target */ + if ((m_idx > 0) && target_able(m_idx)) + { + monster_type *m_ptr = &m_list[m_idx]; + + /* Save target info */ + p_ptr->target_set = TRUE; + p_ptr->target_who = m_idx; + p_ptr->target_row = m_ptr->fy; + p_ptr->target_col = m_ptr->fx; + } + + /* Clear target */ + else + { + /* Reset target info */ + p_ptr->target_set = FALSE; + p_ptr->target_who = 0; + p_ptr->target_row = 0; + p_ptr->target_col = 0; + } + } + + + /* + * Set the target to a location + */ + void target_set_location(int y, int x) + { + /* Legal target */ + if (in_bounds_fully(y, x)) + { + /* Save target info */ + p_ptr->target_set = TRUE; + p_ptr->target_who = 0; + p_ptr->target_row = y; + p_ptr->target_col = x; + } + + /* Clear target */ + else + { + /* Reset target info */ + p_ptr->target_set = FALSE; + p_ptr->target_who = 0; + p_ptr->target_row = 0; + p_ptr->target_col = 0; + } + } + /* * Sorting hook -- comp function -- by "distance to player" *************** *** 2629,2635 **** /* Approximate Double Distance */ v = ((x4 > y4) ? (x4 + x4 + y4) : (y4 + y4 + x4)); ! /* XXX XXX XXX Penalize location */ /* Track best */ if ((b_i >= 0) && (v >= b_v)) continue; --- 2738,2744 ---- /* Approximate Double Distance */ v = ((x4 > y4) ? (x4 + x4 + y4) : (y4 + y4 + x4)); ! /* Penalize location XXX XXX XXX */ /* Track best */ if ((b_i >= 0) && (v >= b_v)) continue; *************** *** 2646,2652 **** /* * Hack -- determine if a given location is "interesting" */ ! static bool target_set_accept(int y, int x) { s16b this_o_idx, next_o_idx = 0; --- 2755,2761 ---- /* * Hack -- determine if a given location is "interesting" */ ! static bool target_set_interactive_accept(int y, int x) { s16b this_o_idx, next_o_idx = 0; *************** *** 2723,2733 **** /* ! * Prepare the "temp" array for "target_set" * * Return the number of target_able monsters in the set. */ ! static void target_set_prepare(int mode) { int y, x; --- 2832,2842 ---- /* ! * Prepare the "temp" array for "target_interactive_set" * * Return the number of target_able monsters in the set. */ ! static void target_set_interactive_prepare(int mode) { int y, x; *************** *** 2743,2749 **** if (!expand_look && !player_has_los_bold(y, x)) continue; /* Require "interesting" contents */ ! if (!target_set_accept(y, x)) continue; /* Special mode */ if (mode & (TARGET_KILL)) --- 2852,2858 ---- if (!expand_look && !player_has_los_bold(y, x)) continue; /* Require "interesting" contents */ ! if (!target_set_interactive_accept(y, x)) continue; /* Special mode */ if (mode & (TARGET_KILL)) *************** *** 2787,2798 **** * Note that if a monster is in the grid, we update both the monster * recall info and the health bar info to track that monster. * ! * Eventually, we may allow multiple objects per grid, or objects ! * and terrain features in the same grid. XXX XXX XXX * * This function must handle blindness/hallucination. */ ! static int target_set_aux(int y, int x, int mode, cptr info) { s16b this_o_idx, next_o_idx = 0; --- 2896,2907 ---- * Note that if a monster is in the grid, we update both the monster * recall info and the health bar info to track that monster. * ! * This function correctly handles multiple objects per grid, and objects ! * and terrain features in the same grid, though the latter never happens. * * This function must handle blindness/hallucination. */ ! static int target_set_interactive_aux(int y, int x, int mode, cptr info) { s16b this_o_idx, next_o_idx = 0; *************** *** 2886,2893 **** /* Recall */ if (recall) { ! /* Save */ ! Term_save(); /* Recall on screen */ screen_roff(m_ptr->r_idx); --- 2995,3002 ---- /* Recall */ if (recall) { ! /* Save screen */ ! screen_save(); /* Recall on screen */ screen_roff(m_ptr->r_idx); *************** *** 2898,2905 **** /* Command */ query = inkey(); ! /* Restore */ ! Term_load(); } /* Normal */ --- 3007,3014 ---- /* Command */ query = inkey(); ! /* Load screen */ ! screen_load(); } /* Normal */ *************** *** 3120,3126 **** * This command will cancel any old target, even if used from * inside the "look" command. */ ! bool target_set(int mode) { int py = p_ptr->py; int px = p_ptr->px; --- 3229,3235 ---- * This command will cancel any old target, even if used from * inside the "look" command. */ ! bool target_set_interactive(int mode) { int py = p_ptr->py; int px = p_ptr->px; *************** *** 3140,3146 **** /* Cancel target */ ! p_ptr->target_who = 0; /* Cancel tracking */ --- 3249,3255 ---- /* Cancel target */ ! target_set_monster(0); /* Cancel tracking */ *************** *** 3148,3154 **** /* Prepare the "temp" array */ ! target_set_prepare(mode); /* Start near the player */ m = 0; --- 3257,3263 ---- /* Prepare the "temp" array */ ! target_set_interactive_prepare(mode); /* Start near the player */ m = 0; *************** *** 3175,3181 **** } /* Describe and Prompt */ ! query = target_set_aux(y, x, mode, info); /* Cancel tracking */ /* health_track(0); */ --- 3284,3290 ---- } /* Describe and Prompt */ ! query = target_set_interactive_aux(y, x, mode, info); /* Cancel tracking */ /* health_track(0); */ *************** *** 3193,3218 **** break; } - case 't': - case '.': - case '5': - case '0': - { - if ((cave_m_idx[y][x] > 0) && target_able(cave_m_idx[y][x])) - { - health_track(cave_m_idx[y][x]); - p_ptr->target_who = cave_m_idx[y][x]; - p_ptr->target_row = y; - p_ptr->target_col = x; - done = TRUE; - } - else - { - bell(); - } - break; - } - case ' ': case '*': case '+': --- 3302,3307 ---- *************** *** 3252,3261 **** break; } default: { ! d = keymap_dirs[query & 0x7F]; ! if (!d) bell(); break; } } --- 3341,3373 ---- break; } + case 't': + case '5': + case '0': + { + int m_idx = cave_m_idx[y][x]; + + if ((m_idx > 0) && target_able(m_idx)) + { + health_track(m_idx); + target_set_monster(m_idx); + done = TRUE; + } + else + { + bell("Illegal target!"); + } + break; + } + default: { ! /* Extract direction */ ! d = target_dir(query); ! ! /* Oops */ ! if (!d) bell("Illegal command for target mode!"); ! break; } } *************** *** 3278,3284 **** strcpy(info, "q,t,p,m,+,-,"); /* Describe and Prompt (enable "TARGET_LOOK") */ ! query = target_set_aux(y, x, mode | TARGET_LOOK, info); /* Cancel tracking */ /* health_track(0); */ --- 3390,3396 ---- strcpy(info, "q,t,p,m,+,-,"); /* Describe and Prompt (enable "TARGET_LOOK") */ ! query = target_set_interactive_aux(y, x, mode | TARGET_LOOK, info); /* Cancel tracking */ /* health_track(0); */ *************** *** 3296,3313 **** break; } - case 't': - case '.': - case '5': - case '0': - { - p_ptr->target_who = -1; - p_ptr->target_row = y; - p_ptr->target_col = x; - done = TRUE; - break; - } - case ' ': case '*': case '+': --- 3408,3413 ---- *************** *** 3333,3342 **** break; } default: { ! d = keymap_dirs[query & 0x7F]; ! if (!d) bell(); break; } } --- 3433,3455 ---- break; } + case 't': + case '5': + case '0': + { + target_set_location(y, x); + done = TRUE; + break; + } + default: { ! /* Extract a direction */ ! d = target_dir(query); ! ! /* Oops */ ! if (!d) bell("Illegal command for target mode!"); ! break; } } *************** *** 3366,3372 **** prt("", 0, 0); /* Failure to set target */ ! if (!p_ptr->target_who) return (FALSE); /* Success */ return (TRUE); --- 3479,3485 ---- prt("", 0, 0); /* Failure to set target */ ! if (!p_ptr->target_set) return (FALSE); /* Success */ return (TRUE); *************** *** 3393,3399 **** { int dir; ! char command; cptr p; --- 3506,3512 ---- { int dir; ! char ch; cptr p; *************** *** 3421,3461 **** } /* Get a command (or Cancel) */ ! if (!get_com(p, &command)) break; ! /* Convert various keys to "standard" keys */ ! switch (command) { ! /* Use current target */ ! case 'T': ! case 't': ! case '.': ! case '5': ! case '0': { ! dir = 5; break; } ! /* Set new target */ ! case '*': { ! if (target_set(TARGET_KILL)) dir = 5; break; } default: { ! dir = keymap_dirs[command & 0x7F]; break; } } - /* Verify requested targets */ - if ((dir == 5) && !target_okay()) dir = 0; - /* Error */ ! if (!dir) bell(); } /* No direction */ --- 3534,3570 ---- } /* Get a command (or Cancel) */ ! if (!get_com(p, &ch)) break; ! /* Analyze */ ! switch (ch) { ! /* Set new target, use target if legal */ ! case '*': { ! if (target_set_interactive(TARGET_KILL)) dir = 5; break; } ! /* Use current target, if set and legal */ ! case 't': ! case '5': ! case '0': { ! if (target_okay()) dir = 5; break; } + /* Possible direction */ default: { ! dir = target_dir(ch); break; } } /* Error */ ! if (!dir) bell("Illegal aim direction!"); } /* No direction */ *************** *** 3467,3473 **** /* Check for confusion */ if (p_ptr->confused) { - /* XXX XXX XXX */ /* Random direction */ dir = ddd[rand_int(8)]; } --- 3576,3581 ---- *************** *** 3498,3504 **** * as all commands which must reference a grid adjacent to the player, * and which may not reference the grid under the player. * ! * Direction "5" (and "0") are illegal and will not be accepted. * * This function tracks and uses the "global direction", and uses * that as the "desired direction", if it is set. --- 3606,3612 ---- * as all commands which must reference a grid adjacent to the player, * and which may not reference the grid under the player. * ! * Directions "5" and "0" are illegal and will not be accepted. * * This function tracks and uses the "global direction", and uses * that as the "desired direction", if it is set. *************** *** 3507,3512 **** --- 3615,3624 ---- { int dir; + char ch; + + cptr p; + /* Initialize */ (*dp) = 0; *************** *** 3517,3535 **** /* Get a direction */ while (!dir) { ! char ch; /* Get a command (or Cancel) */ ! if (!get_com("Direction (Escape to cancel)? ", &ch)) break; ! ! /* Look up the direction */ ! dir = keymap_dirs[ch & 0x7F]; ! /* Prevent weirdness */ ! if (dir == 5) dir = 0; /* Oops */ ! if (!dir) bell(); } /* Aborted */ --- 3629,3645 ---- /* Get a direction */ while (!dir) { ! /* Choose a prompt */ ! p = "Direction (Escape to cancel)? "; /* Get a command (or Cancel) */ ! if (!get_com(p, &ch)) break; ! /* Convert keypress into a direction */ ! dir = target_dir(ch); /* Oops */ ! if (!dir) bell("Illegal repeatable direction!"); } /* Aborted */ *************** *** 3561,3567 **** /* Apply "confusion" */ if (p_ptr->confused) { ! /* Apply confusion */ if ((dir == 5) || (rand_int(100) < 75)) { /* Random direction */ --- 3671,3677 ---- /* Apply "confusion" */ if (p_ptr->confused) { ! /* Apply confusion XXX XXX XXX */ if ((dir == 5) || (rand_int(100) < 75)) { /* Random direction */ *************** *** 3585,3588 **** --- 3695,3699 ---- /* Not confused */ return (FALSE); } + diff -c -r angband-282/src/z-form.h angband-283/src/z-form.h *** angband-282/src/z-form.h Wed Sep 3 11:57:34 1997 --- angband-283/src/z-form.h Fri Feb 6 04:10:31 1998 *************** *** 53,55 **** --- 53,57 ---- #endif + + diff -c -r angband-282/src/z-rand.c angband-283/src/z-rand.c *** angband-282/src/z-rand.c Wed Sep 3 11:57:34 1997 --- angband-283/src/z-rand.c Fri Feb 6 04:10:31 1998 *************** *** 8,50 **** * are included in all such copies. Other copyrights may also apply. */ - /* Purpose: a simple random number generator -BEN- */ - - #include "z-rand.h" - - - /* ! * Angband 2.7.9 introduced a new (optimized) random number generator, ! * based loosely on the old "random.c" from Berkeley but with some major ! * optimizations and algorithm changes. See below for more details. ! * ! * Code by myself (benh@voicenet.com) and Randy (randy@stat.tamu.edu). ! * ! * This code provides (1) a "decent" RNG, based on the "BSD-degree-63-RNG" ! * used in Angband 2.7.8, but rather optimized, and (2) a "simple" RNG, ! * based on the simple "LCRNG" currently used in Angband, but "corrected" ! * to give slightly better values. Both of these are available in two ! * flavors, first, the simple "mod" flavor, which is fast, but slightly ! * biased at high values, and second, the simple "div" flavor, which is ! * less fast (and potentially non-terminating) but which is not biased ! * and is much less subject to low-bit-non-randomness problems. * - * You can select your favorite flavor by proper definition of the - * "rand_int()" macro in the "defines.h" file. * ! * Note that, in Angband 2.8.0, the "state" table will be saved in the ! * savefile, so a special "initialization" phase will be necessary. * * Note the use of the "simple" RNG, first you activate it via * "Rand_quick = TRUE" and "Rand_value = seed" and then it is used * automatically used instead of the "complex" RNG, and when you are * done, you de-activate it via "Rand_quick = FALSE" or choose a new * seed via "Rand_value = seed". */ /* * Random Number Generator -- Linear Congruent RNG */ --- 8,48 ---- * are included in all such copies. Other copyrights may also apply. */ /* ! * This file provides an optimized random number generator. * * ! * This code provides both a "quick" random number generator (4 bytes of ! * state), and a "decent" random number generator (256 bytes of state), ! * both available in two flavors, first, the simple "mod" flavor, which ! * is fast, but slightly biased at high values, and second, the simple ! * "div" flavor, which is less fast (and potentially non-terminating) ! * but which is not biased and is much less subject to non-randomness ! * problems in the low bits. Note the "rand_int()" macro in "z-rand.h", ! * which must specify a "default" flavor. * * Note the use of the "simple" RNG, first you activate it via * "Rand_quick = TRUE" and "Rand_value = seed" and then it is used * automatically used instead of the "complex" RNG, and when you are * done, you de-activate it via "Rand_quick = FALSE" or choose a new * seed via "Rand_value = seed". + * + * + * This (optimized) random number generator is based loosely on the old + * "random.c" file from Berkeley but with some major optimizations and + * algorithm changes. See below for more details. + * + * Some code by Ben Harrison (benh@phial.com). + * + * Some code by Randy (randy@stat.tamu.edu). */ + + #include "z-rand.h" + + /* * Random Number Generator -- Linear Congruent RNG */ *************** *** 111,117 **** * Note that "m" should probably be less than 500000, or the * results may be rather biased towards low values. */ ! s32b Rand_mod(s32b m) { int j; u32b r; --- 109,115 ---- * Note that "m" should probably be less than 500000, or the * results may be rather biased towards low values. */ ! u32b Rand_mod(u32b m) { int j; u32b r; *************** *** 161,168 **** * * This method has no bias, and is much less affected by patterns * in the "low" bits of the underlying RNG's. */ ! s32b Rand_div(s32b m) { u32b r, n; --- 159,169 ---- * * This method has no bias, and is much less affected by patterns * in the "low" bits of the underlying RNG's. + * + * Note that "m" must not be greater than 0x1000000, or division + * by zero will result. */ ! u32b Rand_div(u32b m) { u32b r, n; *************** *** 223,241 **** /* ! * The number of entries in the "randnor_table" */ #define RANDNOR_NUM 256 /* ! * The standard deviation of the "randnor_table" */ #define RANDNOR_STD 64 /* ! * The normal distribution table for the "randnor()" function (below) */ ! static s16b randnor_table[RANDNOR_NUM] = { 206, 613, 1022, 1430, 1838, 2245, 2652, 3058, 3463, 3867, 4271, 4673, 5075, 5475, 5874, 6271, --- 224,242 ---- /* ! * The number of entries in the "Rand_normal_table" */ #define RANDNOR_NUM 256 /* ! * The standard deviation of the "Rand_normal_table" */ #define RANDNOR_STD 64 /* ! * The normal distribution table for the "Rand_normal()" function (below) */ ! static s16b Rand_normal_table[RANDNOR_NUM] = { 206, 613, 1022, 1430, 1838, 2245, 2652, 3058, 3463, 3867, 4271, 4673, 5075, 5475, 5874, 6271, *************** *** 295,301 **** * * Note that the binary search takes up to 16 quick iterations. */ ! s16b randnor(int mean, int stand) { s16b tmp; s16b offset; --- 296,302 ---- * * Note that the binary search takes up to 16 quick iterations. */ ! s16b Rand_normal(int mean, int stand) { s16b tmp; s16b offset; *************** *** 315,321 **** int mid = (low + high) >> 1; /* Move right if forced */ ! if (randnor_table[mid] < tmp) { low = mid + 1; } --- 316,322 ---- int mid = (low + high) >> 1; /* Move right if forced */ ! if (Rand_normal_table[mid] < tmp) { low = mid + 1; } *************** *** 336,362 **** /* One half should be positive */ return (mean + offset); } - - - - /* - * Generates damage for "2d6" style dice rolls - */ - s16b damroll(int num, int sides) - { - int i, sum = 0; - for (i = 0; i < num; i++) sum += randint(sides); - return (sum); - } - - - /* - * Same as above, but always maximal - */ - s16b maxroll(int num, int sides) - { - return (num * sides); - } - --- 337,341 ---- diff -c -r angband-282/src/z-rand.h angband-283/src/z-rand.h *** angband-282/src/z-rand.h Wed Sep 3 11:57:34 1997 --- angband-283/src/z-rand.h Fri Feb 6 04:10:31 1998 *************** *** 19,25 **** /* ! * Random Number Generator -- Degree of "complex" RNG -- see "misc.c" * This value is hard-coded at 63 for a wide variety of reasons. */ #define RAND_DEG 63 --- 19,25 ---- /* ! * The "degree" of the "complex" Random Number Generator. * This value is hard-coded at 63 for a wide variety of reasons. */ #define RAND_DEG 63 *************** *** 36,42 **** * For example, if M is 100, you get "percentile dice" */ #define rand_int(M) \ ! (Rand_div(M)) /* * Generates a random long integer X where A<=X<=B --- 36,42 ---- * For example, if M is 100, you get "percentile dice" */ #define rand_int(M) \ ! ((s32b)(Rand_div(M))) /* * Generates a random long integer X where A<=X<=B *************** *** 55,76 **** ((A) + (rand_int(1+(D)+(D))) - (D)) - /* - * Generate a random long integer X where 1<=X<=M - * Also, "correctly" handle the case of M<=1 - */ - #define randint(M) \ - (rand_int(M) + 1) - - - /* - * Evaluate to TRUE "P" percent of the time - */ - #define magik(P) \ - (rand_int(100) < (P)) - - - /**** Available Variables ****/ --- 55,60 ---- *************** *** 85,95 **** extern void Rand_state_init(u32b seed); ! extern s32b Rand_mod(s32b m); ! extern s32b Rand_div(s32b m); ! extern s16b randnor(int mean, int stand); ! extern s16b damroll(int num, int sides); ! extern s16b maxroll(int num, int sides); #endif --- 69,77 ---- extern void Rand_state_init(u32b seed); ! extern u32b Rand_mod(u32b m); ! extern u32b Rand_div(u32b m); ! extern s16b Rand_normal(int mean, int stand); #endif diff -c -r angband-282/src/z-term.c angband-283/src/z-term.c *** angband-282/src/z-term.c Wed Sep 3 11:57:34 1997 --- angband-283/src/z-term.c Fri Feb 6 04:10:31 1998 *************** *** 529,535 **** * * Display text using "Term_pict()" */ ! static void Term_fresh_row_pict(int y) { int x; --- 529,535 ---- * * Display text using "Term_pict()" */ ! static void Term_fresh_row_pict(int y, int x1, int x2) { int x; *************** *** 552,559 **** char nc; ! /* Scan the columns marked as "modified" */ ! for (x = Term->x1[y]; x <= Term->x2[y]; x++) { /* See what is currently here */ oa = old_aa[x]; --- 552,559 ---- char nc; ! /* Scan "modified" columns */ ! for (x = x1; x <= x2; x++) { /* See what is currently here */ oa = old_aa[x]; *************** *** 606,612 **** * Display text using "Term_text()" and "Term_wipe()", * but use "Term_pict()" for high-bit attr/char pairs */ ! static void Term_fresh_row_both(int y) { int x; --- 606,612 ---- * Display text using "Term_text()" and "Term_wipe()", * but use "Term_pict()" for high-bit attr/char pairs */ ! static void Term_fresh_row_both(int y, int x1, int x2) { int x; *************** *** 635,642 **** char nc; ! /* Scan the columns marked as "modified" */ ! for (x = Term->x1[y]; x <= Term->x2[y]; x++) { /* See what is currently here */ oa = old_aa[x]; --- 635,642 ---- char nc; ! /* Scan "modified" columns */ ! for (x = x1; x <= x2; x++) { /* See what is currently here */ oa = old_aa[x]; *************** *** 758,764 **** * * Display text using "Term_text()" and "Term_wipe()" */ ! static void Term_fresh_row_text(int y) { int x; --- 758,764 ---- * * Display text using "Term_text()" and "Term_wipe()" */ ! static void Term_fresh_row_text(int y, int x1, int x2) { int x; *************** *** 787,794 **** char nc; ! /* Scan the columns marked as "modified" */ ! for (x = Term->x1[y]; x <= Term->x2[y]; x++) { /* See what is currently here */ oa = old_aa[x]; --- 787,794 ---- char nc; ! /* Scan "modified" columns */ ! for (x = x1; x <= x2; x++) { /* See what is currently here */ oa = old_aa[x]; *************** *** 975,981 **** * On systems with a "soft" cursor, we must explicitly erase the cursor * before flushing the output, if needed, to prevent a "jumpy" refresh. * The actual method for this is horrible, but there is very little that ! * we can do to simplify it. XXX XXX XXX * * On systems with a "hard" cursor, we will "hide" the cursor before * flushing the output, if needed, to avoid a "flickery" refresh. It --- 975,981 ---- * On systems with a "soft" cursor, we must explicitly erase the cursor * before flushing the output, if needed, to prevent a "jumpy" refresh. * The actual method for this is horrible, but there is very little that ! * we can do to simplify it efficiently. XXX XXX XXX * * On systems with a "hard" cursor, we will "hide" the cursor before * flushing the output, if needed, to avoid a "flickery" refresh. It *************** *** 998,1003 **** --- 998,1006 ---- int w = Term->wid; int h = Term->hgt; + int y1 = Term->y1; + int y2 = Term->y2; + term_win *old = Term->old; term_win *scr = Term->scr; *************** *** 1007,1013 **** /* Trivial Refresh */ ! if ((Term->y1 > Term->y2) && (scr->cu == old->cu) && (scr->cv == old->cv) && (scr->cx == old->cx) && --- 1010,1016 ---- /* Trivial Refresh */ ! if ((y1 > y2) && (scr->cu == old->cu) && (scr->cv == old->cv) && (scr->cx == old->cx) && *************** *** 1029,1036 **** /* Handle "total erase" */ if (Term->total_erase) { ! byte a = Term->attr_blank; ! char c = Term->char_blank; /* Physically erase the entire window */ Term_xtra(TERM_XTRA_CLEAR, 0); --- 1032,1039 ---- /* Handle "total erase" */ if (Term->total_erase) { ! byte na = Term->attr_blank; ! char nc = Term->char_blank; /* Physically erase the entire window */ Term_xtra(TERM_XTRA_CLEAR, 0); *************** *** 1048,1061 **** for (x = 0; x < w; x++) { /* Wipe each grid */ ! *aa++ = a; ! *cc++ = c; } } /* Redraw every row */ ! Term->y1 = 0; ! Term->y2 = h - 1; /* Redraw every column */ for (y = 0; y < h; y++) --- 1051,1064 ---- for (x = 0; x < w; x++) { /* Wipe each grid */ ! *aa++ = na; ! *cc++ = nc; } } /* Redraw every row */ ! Term->y1 = y1 = 0; ! Term->y2 = y2 = h - 1; /* Redraw every column */ for (y = 0; y < h; y++) *************** *** 1081,1105 **** byte *old_aa = old->a[ty]; char *old_cc = old->c[ty]; ! byte a = old_aa[tx]; ! char c = old_cc[tx]; /* Hack -- use "Term_pict()" always */ if (Term->always_pict) { ! (void)((*Term->pict_hook)(tx, ty, 1, &a, &c)); } /* Hack -- use "Term_pict()" sometimes */ ! else if (Term->higher_pict && (a & 0x80) && (c & 0x80)) { ! (void)((*Term->pict_hook)(tx, ty, 1, &a, &c)); } /* Hack -- restore the actual character */ ! else if (a || Term->always_text) { ! (void)((*Term->text_hook)(tx, ty, 1, a, &c)); } /* Hack -- erase the grid */ --- 1084,1108 ---- byte *old_aa = old->a[ty]; char *old_cc = old->c[ty]; ! byte oa = old_aa[tx]; ! char oc = old_cc[tx]; /* Hack -- use "Term_pict()" always */ if (Term->always_pict) { ! (void)((*Term->pict_hook)(tx, ty, 1, &oa, &oc)); } /* Hack -- use "Term_pict()" sometimes */ ! else if (Term->higher_pict && (oa & 0x80) && (oc & 0x80)) { ! (void)((*Term->pict_hook)(tx, ty, 1, &oa, &oc)); } /* Hack -- restore the actual character */ ! else if (oa || Term->always_text) { ! (void)((*Term->text_hook)(tx, ty, 1, oa, &oc)); } /* Hack -- erase the grid */ *************** *** 1123,1135 **** /* Something to update */ ! if (Term->y1 <= Term->y2) { /* Handle "icky corner" */ if (Term->icky_corner) { /* Avoid the corner */ ! if (Term->y2 > h - 2) { /* Avoid the corner */ if (Term->x2[h - 1] > w - 2) --- 1126,1138 ---- /* Something to update */ ! if (y1 <= y2) { /* Handle "icky corner" */ if (Term->icky_corner) { /* Avoid the corner */ ! if (y2 >= h - 1) { /* Avoid the corner */ if (Term->x2[h - 1] > w - 2) *************** *** 1142,1171 **** /* Scan the "modified" rows */ ! for (y = Term->y1; y <= Term->y2; ++y) { /* Flush each "modified" row */ ! if (Term->x1[y] <= Term->x2[y]) { /* Always use "Term_pict()" */ if (Term->always_pict) { /* Flush the row */ ! Term_fresh_row_pict(y); } /* Sometimes use "Term_pict()" */ else if (Term->higher_pict) { /* Flush the row */ ! Term_fresh_row_both(y); } /* Never use "Term_pict()" */ else { /* Flush the row */ ! Term_fresh_row_text(y); } /* This row is all done */ --- 1145,1177 ---- /* Scan the "modified" rows */ ! for (y = y1; y <= y2; ++y) { + int x1 = Term->x1[y]; + int x2 = Term->x2[y]; + /* Flush each "modified" row */ ! if (x1 <= x2) { /* Always use "Term_pict()" */ if (Term->always_pict) { /* Flush the row */ ! Term_fresh_row_pict(y, x1, x2); } /* Sometimes use "Term_pict()" */ else if (Term->higher_pict) { /* Flush the row */ ! Term_fresh_row_both(y, x1, x2); } /* Never use "Term_pict()" */ else { /* Flush the row */ ! Term_fresh_row_text(y, x1, x2); } /* This row is all done */ *************** *** 1528,1535 **** int w = Term->wid; int h = Term->hgt; ! byte a = Term->attr_blank; ! char c = Term->char_blank; /* Cursor usable */ Term->scr->cu = 0; --- 1534,1541 ---- int w = Term->wid; int h = Term->hgt; ! byte na = Term->attr_blank; ! char nc = Term->char_blank; /* Cursor usable */ Term->scr->cu = 0; *************** *** 1546,1553 **** /* Wipe each column */ for (x = 0; x < w; x++) { ! scr_aa[x] = a; ! scr_cc[x] = c; } /* This row has changed */ --- 1552,1559 ---- /* Wipe each column */ for (x = 0; x < w; x++) { ! scr_aa[x] = na; ! scr_cc[x] = nc; } /* This row has changed */ *************** *** 1664,1705 **** /* - * XXX XXX XXX Mega-Hack -- special "Term_inkey_hook" hook - * - * This special function hook basically acts as a replacement function - * for both "Term_flush()" and "Term_inkey()", depending on whether the - * first parameter is NULL or not, and is currently used only to allow - * the "Borg" to bypass the "standard" keypress routines, and instead - * use its own internal algorithms to "generate" keypress values. - * - * Note that this function hook can do anything it wants, including - * in most cases simply doing exactly what is normally done by the - * functions below, and in other cases, doing some of the same things - * to check for "interuption" by the user, and replacing the rest of - * the code with specialized "think about the world" code. - * - * Similar results could be obtained by "stealing" the "Term->xtra_hook" - * hook, and doing special things for "TERM_XTRA_EVENT", "TERM_XTRA_FLUSH", - * and "TERM_XTRA_BORED", but this method is a lot "cleaner", and gives - * much better results when "profiling" the code. - * - * See the "Borg" documentation for more details. - */ - errr (*Term_inkey_hook)(char *ch, bool wait, bool take) = NULL; - - - /* * Flush and forget the input */ errr Term_flush(void) { - /* XXX XXX XXX */ - if (Term_inkey_hook) - { - /* Special "Borg" hook (flush keys) */ - return ((*Term_inkey_hook)(NULL, 0, 0)); - } - /* Hack -- Flush all events */ Term_xtra(TERM_XTRA_FLUSH, 0); --- 1670,1679 ---- *************** *** 1784,1796 **** /* Assume no key */ (*ch) = '\0'; - /* XXX XXX XXX */ - if (Term_inkey_hook) - { - /* Special "Borg" hook (generate keys) */ - return ((*Term_inkey_hook)(ch, wait, take)); - } - /* Hack -- get bored */ if (!Term->never_bored) { --- 1758,1763 ---- *************** *** 1972,1979 **** term_win *hold_tmp; /* Ignore illegal changes */ ! if ((w < 1) || (h < 1)) return (1); /* Ignore non-changes */ if ((Term->wid == w) && (Term->hgt == h)) return (1); --- 1939,1951 ---- term_win *hold_tmp; + /* Resizing is forbidden */ + if (Term->fixed_shape) return (-1); + + /* Ignore illegal changes */ ! if ((w < 1) || (h < 1)) return (-1); ! /* Ignore non-changes */ if ((Term->wid == w) && (Term->hgt == h)) return (1); diff -c -r angband-282/src/z-term.h angband-283/src/z-term.h *** angband-282/src/z-term.h Wed Sep 3 11:57:34 1997 --- angband-283/src/z-term.h Fri Feb 6 04:10:31 1998 *************** *** 50,58 **** /* * An actual "term" structure * ! * - Extra info (used by application) * ! * - Extra data (used by implementation) * * * - Flag "active_flag" --- 50,66 ---- /* * An actual "term" structure * ! * - Extra "user" info (used by application) * ! * - Extra "data" info (used by implementation) ! * ! * ! * - Flag "user_flag" ! * An extra "user" flag (used by application) ! * ! * ! * - Flag "data_flag" ! * An extra "data" flag (used by implementation) * * * - Flag "active_flag" *************** *** 64,69 **** --- 72,80 ---- * - Flag "total_erase" * This "term" should be fully erased * + * - Flag "fixed_shape" + * This "term" is not allowed to resize + * * - Flag "icky_corner" * This "term" has an "icky" corner grid * *************** *** 79,84 **** --- 90,98 ---- * - Flag "always_text" * Use the "Term_text()" routine for invisible text * + * - Flag "unused_flag" + * Reserved for future use + * * - Flag "never_bored" * Never call the "TERM_XTRA_BORED" action * *************** *** 141,154 **** --- 155,174 ---- vptr data; + bool user_flag; + + bool data_flag; + bool active_flag; bool mapped_flag; bool total_erase; + bool fixed_shape; bool icky_corner; bool soft_cursor; bool always_pict; bool higher_pict; bool always_text; + bool unused_flag; bool never_bored; bool never_frosh; *************** *** 283,286 **** --- 303,307 ---- #endif + diff -c -r angband-282/src/z-util.h angband-283/src/z-util.h *** angband-282/src/z-util.h Wed Sep 3 11:57:34 1997 --- angband-283/src/z-util.h Fri Feb 6 04:10:31 1998 *************** *** 90,92 **** --- 90,93 ---- #endif +